Merge pie-platform-release to aosp-master - DO NOT MERGE

Change-Id: Ib1c12dfcaff433999e9aa6db0dc5f0a48e115ebc
diff --git a/.gitignore b/.gitignore
index a73b2cd..7131b22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@
 .idea/
 *.iml
 *.ipr
+extensions/**/build/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index b9b79e0..58a8877 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,10 +1,14 @@
 language: java
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.m2
 
 jdk:
+  - oraclejdk9
   - oraclejdk8
-  - oraclejdk7
   - openjdk7
-  - openjdk6
 
 env:
   global:
@@ -14,7 +18,7 @@
   matrix:
     - LABEL=ant        CMD="ant dist test.dist" INSTALL="/bin/true"
     - LABEL=ant_no_aop CMD="ant -f build/no_aop/build.xml dist test.dist" INSTALL="ant no_aop"
-    - LABEL=mvn        CMD="mvn -P!standard-with-extra-repos verify --fail-at-end -Dsource.skip=true -Dmaven.javadoc.skip=true" INSTALL="mvn -P!standard-with-extra-repos dependency:go-offline test clean --quiet --fail-never -DskipTests=true"
+    - LABEL=mvn        CMD="mvn -B -P!standard-with-extra-repos verify --fail-at-end -Dsource.skip=true -Dmaven.javadoc.skip=true" INSTALL="mvn -P!standard-with-extra-repos dependency:go-offline test clean --quiet --fail-never -DskipTests=true"
 
 install:
   - ${INSTALL}
@@ -22,11 +26,6 @@
 script:
   - ${CMD}
 
-notifications:
-  email:
-    recipients:
-      - google-guice-dev+ci@googlegroups.com
-
 after_success:
   - util/generate-latest-docs.sh
   - util/compareBuilds.sh
diff --git a/Android.bp b/Android.bp
index 154cee3..3fdc2cb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -104,4 +104,19 @@
     ],
 }
 
+// Variation that doesn't link guava statically
+java_library_static {
+    name: "guice-no-guava",
+    host_supported: true,
+    hostdex: true,
+    sdk_version: "core_current",
+    srcs: [":guice_munged_srcs"],
+    libs: [
+        "guava",
+    ],
+    static_libs: [
+        "jsr330",
+    ],
+}
+
 // TODO: Consider adding tests.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1405580..c104f59 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -54,7 +54,7 @@
   1. Finally, push the commits to your fork and submit a [pull request][].
 
 [forking]: https://help.github.com/articles/fork-a-repo
-[java style guide]: http://google-styleguide.googlecode.com/svn/trunk/javaguide.html
+[java style guide]: https://google.github.io/styleguide/javaguide.html
 [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
 [pull request]: https://help.github.com/articles/creating-a-pull-request
 
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..010701d
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,18 @@
+name: "guice"
+description: "Guice (pronounced \'juice\') is a lightweight dependency injection framework for Java 6 and above."
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://github.com/google/guice"
+  }
+  url {
+    type: ARCHIVE
+    value: "https://github.com/google/guice/archive/4.2.tar.gz"
+  }
+  version: "4.2"
+  last_upgrade_date {
+    year: 2018
+    month: 8
+    day: 27
+  }
+}
diff --git a/README.md b/README.md
index a86d992..9061809 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
 Guice
 ====
 
-**Latest version: [4.0](https://github.com/google/guice/wiki/Guice40)!**
+**Latest release: [4.1](https://github.com/google/guice/wiki/Guice41)**
 
-**Documentation:** [User Guide](https://github.com/google/guice/wiki/Motivation), [4.0 javadocs](http://google.github.io/guice/api-docs/4.0/javadoc/packages.html), [Latest javadocs](http://google.github.io/guice/api-docs/latest/javadoc/index.html) <br/>
+**Documentation:** [User Guide](https://github.com/google/guice/wiki/Motivation), [4.1 javadocs](http://google.github.io/guice/api-docs/4.1/javadoc/index.html), [Latest javadocs](http://google.github.io/guice/api-docs/latest/javadoc/index.html) <br/>
 **Continuous Integration:** [![Build Status](https://api.travis-ci.org/google/guice.png?branch=master)](https://travis-ci.org/google/guice) <br
 />
-**Mailing Lists:** [User Mailing List](http://groups.google.com/group/google-guice), [Developer Mailing List](http://groups.google.com/group/google-guice-dev) <br/>
+**Mailing Lists:** [User Mailing List](http://groups.google.com/group/google-guice) <br/>
 **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)
 
 Put simply, Guice alleviates the need for factories and the use of new in your Java code. Think of Guice's @Inject as the new new. You will still need to write factories in some cases, but your code will not depend directly on them. Your code will be easier to change, unit test and reuse in other contexts.
diff --git a/README.version b/README.version
deleted file mode 100644
index d3de1cd..0000000
--- a/README.version
+++ /dev/null
@@ -1,4 +0,0 @@
-URL: https://github.com/google/guice
-Version: 4.0 (5a209e98e0dedf3dbb2cc657514e7daf1707296c)
-BugComponent: 99142
-Owners: iam
diff --git a/bom/pom.xml b/bom/pom.xml
index 81d2315..759bfca 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject</groupId>
     <artifactId>guice-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <packaging>pom</packaging>
@@ -61,11 +61,6 @@
       </dependency>
       <dependency>
         <groupId>com.google.inject.extensions</groupId>
-        <artifactId>guice-multibindings</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.google.inject.extensions</groupId>
         <artifactId>guice-persist</artifactId>
         <version>${project.version}</version>
       </dependency>
diff --git a/build.properties b/build.properties
index cca000c..244cb5b 100644
--- a/build.properties
+++ b/build.properties
@@ -7,7 +7,6 @@
 jmx.src.dir=extensions/jmx/src
 jndi.src.dir=extensions/jndi/src
 throwingproviders.src.dir=extensions/throwingproviders/src
-multibindings.src.dir=extensions/multibindings/src
 daggeradapter.src.dir=extensions/dagger-adapter/src
 privatemodules.src.dir=extensions/privatemodules/src
 lifecycle.src.dir=extensions/lifecycle/src
diff --git a/build.xml b/build.xml
index 3d0c772..b524258 100644
--- a/build.xml
+++ b/build.xml
@@ -34,7 +34,6 @@
     <ant antfile="extensions/jmx/build.xml" target="distjars" inheritAll="false"/>
     <ant antfile="extensions/jndi/build.xml" target="distjars" inheritAll="false"/>
     <ant antfile="extensions/throwingproviders/build.xml" target="distjars" inheritAll="false"/>
-    <ant antfile="extensions/multibindings/build.xml" target="distjars" inheritAll="false"/>
     <ant antfile="extensions/dagger-adapter/build.xml" target="distjars" inheritAll="false"/>
     <ant antfile="extensions/persist/build.xml" target="distjars" inheritAll="false"/>
     <ant antfile="extensions/grapher/build.xml" target="distjars" inheritAll="false"/>
@@ -62,9 +61,6 @@
       <fileset dir="extensions/throwingproviders/build" includes="*.jar"/>
     </copy>
     <copy toDir="${build.dir}/dist">
-      <fileset dir="extensions/multibindings/build" includes="*.jar"/>
-    </copy>
-    <copy toDir="${build.dir}/dist">
       <fileset dir="extensions/dagger-adapter/build" includes="*.jar"/>
     </copy>
     <copy toDir="${build.dir}/dist">
@@ -120,10 +116,11 @@
         <pathelement location="${build.dir}/dist/guice-${version}.jar"/>
         <pathelement location="lib/javax.inject.jar"/>
         <pathelement location="lib/aopalliance.jar"/>
-        <pathelement location="lib/guava-16.0.1.jar"/>
-        <pathelement location="lib/build/guava-testlib-16.0.1.jar"/>
+        <pathelement location="lib/guava-19.0.jar"/>
+        <pathelement location="lib/build/guava-testlib-19.0.jar"/>
         <pathelement location="lib/build/junit.jar"/>
         <pathelement location="lib/build/servlet-api-2.5.jar"/>
+        <pathelement location="lib/build/truth-0.36.jar"/>
         <pathelement location="lib/build/easymock.jar"/>
         <pathelement location="lib/build/javax.inject-tck.jar"/>
         <pathelement location="lib/build/bnd-0.0.384.jar"/>
@@ -139,7 +136,7 @@
     </java>
   </target>
 
-  <property name="old.api" value="3.0"/>
+  <property name="old.api" value="4.1"/>
   <property name="new.api" value="latest"/>
   <target name="jdiff" depends="compile">
     <property name="jdiff.home" value="lib/build/jdiff"/>
@@ -162,7 +159,6 @@
       <fileset dir="${jmx.src.dir}"/>
       <fileset dir="${jndi.src.dir}"/>
       <fileset dir="${throwingproviders.src.dir}"/>
-      <fileset dir="${multibindings.src.dir}"/>
       <fileset dir="${daggeradapter.src.dir}"/>
       <fileset dir="${persist.src.dir}"/>
       <fileset dir="${struts2.src.dir}"/>
@@ -204,7 +200,7 @@
              windowtitle="Guice ${new.api} API"
              author="false"
              protected="true">
-      <group title="Guice Core" packages="com.google.inject:com.google.inject.util:com.google.inject.spi:com.google.inject.name:com.google.inject.matcher:com.google.inject.binder"/>
+      <group title="Guice Core" packages="com.google.inject:com.google.inject.util:com.google.inject.spi:com.google.inject.name:com.google.inject.matcher:com.google.inject.binder:com.google.inject.multibindings:"/>
       <fileset dir="${src.dir}" defaultexcludes="yes">
         <include name="com/google/inject/**"/>
         <exclude name="com/google/inject/internal/**"/>
@@ -216,9 +212,6 @@
       <group title="AssistedInject Extension" packages="com.google.inject.assistedinject"/>
       <fileset dir="${assistedinject.src.dir}"/>
       
-      <group title="Multibinder Extension" packages="com.google.inject.multibindings"/>
-      <fileset dir="${multibindings.src.dir}"/>
-
       <group title="Dagger Adapter" packages="com.google.inject.daggeradapter"/>
       <fileset dir="${daggeradapter.src.dir}"/>
 
@@ -286,13 +279,13 @@
       <arg value="-DNO_AOP" />
     </munge>
     <replace file="build/no_aop/common.xml" value="">
-      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-5.0.3.jar"/>]]></replacetoken>
+      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-6.0.jar"/>]]></replacetoken>
     </replace>
     <replace file="build/no_aop/common.xml" value="">
-      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"/>]]></replacetoken>
+      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"/>]]></replacetoken>
     </replace>
     <replace file="build/no_aop/common.xml" value="">
-      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"><include name="LICENSE"/><include name="NOTICE"/></zipfileset>]]></replacetoken>
+      <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"><include name="LICENSE"/><include name="NOTICE"/></zipfileset>]]></replacetoken>
     </replace>
     <replace file="build/no_aop/common.xml" value='Bundle-Name" value="$${ant.project.name} (no_aop)'>
       <replacetoken><![CDATA[Bundle-Name" value="${ant.project.name}]]></replacetoken>
@@ -309,7 +302,6 @@
     <ant dir="extensions/jmx" antfile="build.xml" target="clean"/>
     <ant dir="extensions/jndi" antfile="build.xml" target="clean"/>
     <ant dir="extensions/throwingproviders" antfile="build.xml" target="clean"/>
-    <ant dir="extensions/multibindings" antfile="build.xml" target="clean"/>
     <ant dir="extensions/dagger-adapter" antfile="build.xml" target="clean"/>
     <ant dir="extensions/persist" antfile="build.xml" target="clean"/>
     <ant dir="extensions/grapher" antfile="build.xml" target="clean"/>
diff --git a/common.xml b/common.xml
index a23eb90..0f66192 100644
--- a/common.xml
+++ b/common.xml
@@ -14,7 +14,7 @@
     <javac srcdir="${src.dir}"
          debug="on"
          destdir="${build.dir}/classes"
-         source="1.6" target="1.6" includeantruntime="false">
+         source="1.7" target="1.7" includeantruntime="false">
       <compilerarg value="-Xlint:all,-serial"/>
       <classpath refid="compile.classpath"/>
     </javac>
@@ -39,7 +39,7 @@
     <property name="Bundle-DocURL" value="https://github.com/google/guice"/>
     <property name="Bundle-Copyright" value="Copyright (C) 2006 Google Inc."/>
     <property name="Bundle-License" value="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
-    <property name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.6"/>
+    <property name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.7"/>
     <property name="Bundle-Vendor" value="Google, Inc."/>
 
     <property name="Export-Package" value="!${module}.internal.*,${module}.*;version=${api.version}"/>
@@ -76,7 +76,7 @@
     <javac srcdir="${test.dir}"
          debug="on"
          destdir="${build.dir}/test"
-         source="1.6" target="1.6" includeantruntime="false">
+         source="1.7" target="1.7" includeantruntime="false">
       <classpath path="${build.dir}/classes"/>
       <classpath path="${build.dir}/test"/>
       <classpath refid="compile.classpath"/>
@@ -144,8 +144,8 @@
         classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
     <jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
       <fileset dir="${build.dir}/classes"/>
-      <zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"/>
-      <zipfileset src="${common.basedir}/lib/build/asm-5.0.3.jar"/>
+      <zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"/>
+      <zipfileset src="${common.basedir}/lib/build/asm-6.0.jar"/>
       <rule pattern="net.sf.cglib.*" result="com.google.inject.internal.cglib.$@1"/>
       <rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib.@1.$@2"/>
       <rule pattern="org.objectweb.asm.*" result="com.google.inject.internal.asm.$@1"/>
diff --git a/core/pom.xml b/core/pom.xml
index 5a11a23..f2ab9ca 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject</groupId>
     <artifactId>guice-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice</artifactId>
@@ -70,6 +70,11 @@
       <version>3.0.5</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -126,6 +131,11 @@
             <exclude>LICENSE</exclude>
             <exclude>NOTICE</exclude>
           </excludes>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
         </configuration>
       </plugin>
       <!--
diff --git a/core/src/com/google/inject/AbstractModule.java b/core/src/com/google/inject/AbstractModule.java
index fafbd12..7fece9f 100644
--- a/core/src/com/google/inject/AbstractModule.java
+++ b/core/src/com/google/inject/AbstractModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,15 +27,13 @@
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.TypeListener;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
 /**
- * A support class for {@link Module}s which reduces repetition and results in
- * a more readable configuration. Simply extend this class, implement {@link
- * #configure()}, and call the inherited methods which mirror those found in
- * {@link Binder}. For example:
+ * A support class for {@link Module}s which reduces repetition and results in a more readable
+ * configuration. Simply extend this class, implement {@link #configure()}, and call the inherited
+ * methods which mirror those found in {@link Binder}. For example:
  *
  * <pre>
  * public class MyModule extends AbstractModule {
@@ -54,84 +52,63 @@
 
   Binder binder;
 
+  @Override
   public final synchronized void configure(Binder builder) {
     checkState(this.binder == null, "Re-entry is not allowed.");
 
     this.binder = checkNotNull(builder, "builder");
     try {
       configure();
-    }
-    finally {
+    } finally {
       this.binder = null;
     }
   }
 
-  /**
-   * Configures a {@link Binder} via the exposed methods.
-   */
-  protected abstract void configure();
+  /** Configures a {@link Binder} via the exposed methods. */
+  protected void configure() {}
 
-  /**
-   * Gets direct access to the underlying {@code Binder}.
-   */
+  /** Gets direct access to the underlying {@code Binder}. */
   protected Binder binder() {
     checkState(binder != null, "The binder can only be used inside configure()");
     return binder;
   }
 
-  /**
-   * @see Binder#bindScope(Class, Scope)
-   */
-  protected void bindScope(Class<? extends Annotation> scopeAnnotation,
-      Scope scope) {
+  /** @see Binder#bindScope(Class, Scope) */
+  protected void bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope) {
     binder().bindScope(scopeAnnotation, scope);
   }
 
-  /**
-   * @see Binder#bind(Key)
-   */
+  /** @see Binder#bind(Key) */
   protected <T> LinkedBindingBuilder<T> bind(Key<T> key) {
     return binder().bind(key);
   }
 
-  /**
-   * @see Binder#bind(TypeLiteral)
-   */
+  /** @see Binder#bind(TypeLiteral) */
   protected <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
     return binder().bind(typeLiteral);
   }
 
-  /**
-   * @see Binder#bind(Class)
-   */
+  /** @see Binder#bind(Class) */
   protected <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
     return binder().bind(clazz);
   }
 
-  /**
-   * @see Binder#bindConstant()
-   */
+  /** @see Binder#bindConstant() */
   protected AnnotatedConstantBindingBuilder bindConstant() {
     return binder().bindConstant();
   }
 
-  /**
-   * @see Binder#install(Module)
-   */
+  /** @see Binder#install(Module) */
   protected void install(Module module) {
     binder().install(module);
   }
 
-  /**
-   * @see Binder#addError(String, Object[])
-   */
+  /** @see Binder#addError(String, Object[]) */
   protected void addError(String message, Object... arguments) {
     binder().addError(message, arguments);
   }
 
-  /**
-   * @see Binder#addError(Throwable) 
-   */
+  /** @see Binder#addError(Throwable) */
   protected void addError(Throwable t) {
     binder().addError(t);
   }
@@ -152,9 +129,7 @@
     binder().requestInjection(instance);
   }
 
-  /**
-   * @see Binder#requestStaticInjection(Class[])
-   */
+  /** @see Binder#requestStaticInjection(Class[]) */
   protected void requestStaticInjection(Class<?>... types) {
     binder().requestStaticInjection(types);
   }
@@ -162,10 +137,10 @@
   /*if[AOP]*/
   /**
    * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
-   *  com.google.inject.matcher.Matcher,
-   *  org.aopalliance.intercept.MethodInterceptor[])
+   *     com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
    */
-  protected void bindInterceptor(Matcher<? super Class<?>> classMatcher,
+  protected void bindInterceptor(
+      Matcher<? super Class<?>> classMatcher,
       Matcher<? super Method> methodMatcher,
       org.aopalliance.intercept.MethodInterceptor... interceptors) {
     binder().bindInterceptor(classMatcher, methodMatcher, interceptors);
@@ -173,10 +148,9 @@
   /*end[AOP]*/
 
   /**
-   * Adds a dependency from this module to {@code key}. When the injector is
-   * created, Guice will report an error if {@code key} cannot be injected.
-   * Note that this requirement may be satisfied by implicit binding, such as
-   * a public no-arguments constructor.
+   * Adds a dependency from this module to {@code key}. When the injector is created, Guice will
+   * report an error if {@code key} cannot be injected. Note that this requirement may be satisfied
+   * by implicit binding, such as a public no-arguments constructor.
    *
    * @since 2.0
    */
@@ -185,10 +159,9 @@
   }
 
   /**
-   * Adds a dependency from this module to {@code type}. When the injector is
-   * created, Guice will report an error if {@code type} cannot be injected.
-   * Note that this requirement may be satisfied by implicit binding, such as
-   * a public no-arguments constructor.
+   * Adds a dependency from this module to {@code type}. When the injector is created, Guice will
+   * report an error if {@code type} cannot be injected. Note that this requirement may be satisfied
+   * by implicit binding, such as a public no-arguments constructor.
    *
    * @since 2.0
    */
@@ -216,13 +189,13 @@
    * @see Binder#convertToTypes
    * @since 2.0
    */
-  protected void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeConverter converter) {
+  protected void convertToTypes(
+      Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
     binder().convertToTypes(typeMatcher, converter);
   }
 
   /**
-   * @see Binder#currentStage() 
+   * @see Binder#currentStage()
    * @since 2.0
    */
   protected Stage currentStage() {
@@ -246,21 +219,19 @@
   }
 
   /**
-   * @see Binder#bindListener(com.google.inject.matcher.Matcher,
-   *  com.google.inject.spi.TypeListener)
+   * @see Binder#bindListener(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeListener)
    * @since 2.0
    */
-  protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeListener listener) {
+  protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
     binder().bindListener(typeMatcher, listener);
   }
-  
+
   /**
    * @see Binder#bindListener(Matcher, ProvisionListener...)
    * @since 4.0
    */
-  protected void bindListener(Matcher<? super Binding<?>> bindingMatcher,
-      ProvisionListener... listener) {
+  protected void bindListener(
+      Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listener) {
     binder().bindListener(bindingMatcher, listener);
   }
 }
diff --git a/core/src/com/google/inject/Binder.java b/core/src/com/google/inject/Binder.java
index e930c3b..e3fab86 100644
--- a/core/src/com/google/inject/Binder.java
+++ b/core/src/com/google/inject/Binder.java
@@ -26,129 +26,111 @@
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.TypeListener;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 
 /**
- * Collects configuration information (primarily <i>bindings</i>) which will be
- * used to create an {@link Injector}. Guice provides this object to your
- * application's {@link Module} implementors so they may each contribute
- * their own bindings and other registrations.
+ * Collects configuration information (primarily <i>bindings</i>) which will be used to create an
+ * {@link Injector}. Guice provides this object to your application's {@link Module} implementors so
+ * they may each contribute their own bindings and other registrations.
  *
  * <h3>The Guice Binding EDSL</h3>
  *
- * Guice uses an <i>embedded domain-specific language</i>, or EDSL, to help you
- * create bindings simply and readably.  This approach is great for overall
- * usability, but it does come with a small cost: <b>it is difficult to
- * learn how to use the Binding EDSL by reading
- * method-level javadocs</b>.  Instead, you should consult the series of
- * examples below.  To save space, these examples omit the opening
- * {@code binder}, just as you will if your module extends
- * {@link AbstractModule}.
+ * Guice uses an <i>embedded domain-specific language</i>, or EDSL, to help you create bindings
+ * simply and readably. This approach is great for overall usability, but it does come with a small
+ * cost: <b>it is difficult to learn how to use the Binding EDSL by reading method-level
+ * javadocs</b>. Instead, you should consult the series of examples below. To save space, these
+ * examples omit the opening {@code binder}, just as you will if your module extends {@link
+ * AbstractModule}.
  *
  * <pre>
  *     bind(ServiceImpl.class);</pre>
  *
- * This statement does essentially nothing; it "binds the {@code ServiceImpl}
- * class to itself" and does not change Guice's default behavior.  You may still
- * want to use this if you prefer your {@link Module} class to serve as an
- * explicit <i>manifest</i> for the services it provides.  Also, in rare cases,
- * Guice may be unable to validate a binding at injector creation time unless it
- * is given explicitly.
+ * This statement does essentially nothing; it "binds the {@code ServiceImpl} class to itself" and
+ * does not change Guice's default behavior. You may still want to use this if you prefer your
+ * {@link Module} class to serve as an explicit <i>manifest</i> for the services it provides. Also,
+ * in rare cases, Guice may be unable to validate a binding at injector creation time unless it is
+ * given explicitly.
  *
  * <pre>
  *     bind(Service.class).to(ServiceImpl.class);</pre>
  *
- * Specifies that a request for a {@code Service} instance with no binding
- * annotations should be treated as if it were a request for a
- * {@code ServiceImpl} instance. This <i>overrides</i> the function of any
- * {@link ImplementedBy @ImplementedBy} or {@link ProvidedBy @ProvidedBy}
- * annotations found on {@code Service}, since Guice will have already
- * "moved on" to {@code ServiceImpl} before it reaches the point when it starts
- * looking for these annotations.
+ * Specifies that a request for a {@code Service} instance with no binding annotations should be
+ * treated as if it were a request for a {@code ServiceImpl} instance. This <i>overrides</i> the
+ * function of any {@link ImplementedBy @ImplementedBy} or {@link ProvidedBy @ProvidedBy}
+ * annotations found on {@code Service}, since Guice will have already "moved on" to {@code
+ * ServiceImpl} before it reaches the point when it starts looking for these annotations.
  *
  * <pre>
  *     bind(Service.class).toProvider(ServiceProvider.class);</pre>
  *
- * In this example, {@code ServiceProvider} must extend or implement
- * {@code Provider<Service>}. This binding specifies that Guice should resolve
- * an unannotated injection request for {@code Service} by first resolving an
- * instance of {@code ServiceProvider} in the regular way, then calling
- * {@link Provider#get get()} on the resulting Provider instance to obtain the
- * {@code Service} instance.
+ * In this example, {@code ServiceProvider} must extend or implement {@code Provider<Service>}. This
+ * binding specifies that Guice should resolve an unannotated injection request for {@code Service}
+ * by first resolving an instance of {@code ServiceProvider} in the regular way, then calling {@link
+ * Provider#get get()} on the resulting Provider instance to obtain the {@code Service} instance.
  *
- * <p>The {@link Provider} you use here does not have to be a "factory"; that
- * is, a provider which always <i>creates</i> each instance it provides.
- * However, this is generally a good practice to follow.  You can then use
- * Guice's concept of {@link Scope scopes} to guide when creation should happen
- * -- "letting Guice work for you".
+ * <p>The {@link Provider} you use here does not have to be a "factory"; that is, a provider which
+ * always <i>creates</i> each instance it provides. However, this is generally a good practice to
+ * follow. You can then use Guice's concept of {@link Scope scopes} to guide when creation should
+ * happen -- "letting Guice work for you".
  *
  * <pre>
  *     bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);</pre>
  *
- * Like the previous example, but only applies to injection requests that use
- * the binding annotation {@code @Red}.  If your module also includes bindings
- * for particular <i>values</i> of the {@code @Red} annotation (see below),
- * then this binding will serve as a "catch-all" for any values of {@code @Red}
- * that have no exact match in the bindings.
- * 
+ * Like the previous example, but only applies to injection requests that use the binding annotation
+ * {@code @Red}. If your module also includes bindings for particular <i>values</i> of the
+ * {@code @Red} annotation (see below), then this binding will serve as a "catch-all" for any values
+ * of {@code @Red} that have no exact match in the bindings.
+ *
  * <pre>
  *     bind(ServiceImpl.class).in(Singleton.class);
  *     // or, alternatively
  *     bind(ServiceImpl.class).in(Scopes.SINGLETON);</pre>
  *
- * Either of these statements places the {@code ServiceImpl} class into
- * singleton scope.  Guice will create only one instance of {@code ServiceImpl}
- * and will reuse it for all injection requests of this type.  Note that it is
- * still possible to bind another instance of {@code ServiceImpl} if the second
- * binding is qualified by an annotation as in the previous example.  Guice is
- * not overly concerned with <i>preventing</i> you from creating multiple
- * instances of your "singletons", only with <i>enabling</i> your application to
- * share only one instance if that's all you tell Guice you need.
+ * Either of these statements places the {@code ServiceImpl} class into singleton scope. Guice will
+ * create only one instance of {@code ServiceImpl} and will reuse it for all injection requests of
+ * this type. Note that it is still possible to bind another instance of {@code ServiceImpl} if the
+ * second binding is qualified by an annotation as in the previous example. Guice is not overly
+ * concerned with <i>preventing</i> you from creating multiple instances of your "singletons", only
+ * with <i>enabling</i> your application to share only one instance if that's all you tell Guice you
+ * need.
  *
- * <p><b>Note:</b> a scope specified in this way <i>overrides</i> any scope that
- * was specified with an annotation on the {@code ServiceImpl} class.
- * 
- * <p>Besides {@link Singleton}/{@link Scopes#SINGLETON}, there are
- * servlet-specific scopes available in
- * {@code com.google.inject.servlet.ServletScopes}, and your Modules can
- * contribute their own custom scopes for use here as well.
+ * <p><b>Note:</b> a scope specified in this way <i>overrides</i> any scope that was specified with
+ * an annotation on the {@code ServiceImpl} class.
+ *
+ * <p>Besides {@link Singleton}/{@link Scopes#SINGLETON}, there are servlet-specific scopes
+ * available in {@code com.google.inject.servlet.ServletScopes}, and your Modules can contribute
+ * their own custom scopes for use here as well.
  *
  * <pre>
  *     bind(new TypeLiteral&lt;PaymentService&lt;CreditCard>>() {})
  *         .to(CreditCardPaymentService.class);</pre>
  *
- * This admittedly odd construct is the way to bind a parameterized type. It
- * tells Guice how to honor an injection request for an element of type
- * {@code PaymentService<CreditCard>}. The class
- * {@code CreditCardPaymentService} must implement the
- * {@code PaymentService<CreditCard>} interface.  Guice cannot currently bind or
- * inject a generic type, such as {@code Set<E>}; all type parameters must be
- * fully specified.
+ * This admittedly odd construct is the way to bind a parameterized type. It tells Guice how to
+ * honor an injection request for an element of type {@code PaymentService<CreditCard>}. The class
+ * {@code CreditCardPaymentService} must implement the {@code PaymentService<CreditCard>} interface.
+ * Guice cannot currently bind or inject a generic type, such as {@code Set<E>}; all type parameters
+ * must be fully specified.
  *
  * <pre>
  *     bind(Service.class).toInstance(new ServiceImpl());
  *     // or, alternatively
  *     bind(Service.class).toInstance(SomeLegacyRegistry.getService());</pre>
  *
- * In this example, your module itself, <i>not Guice</i>, takes responsibility
- * for obtaining a {@code ServiceImpl} instance, then asks Guice to always use
- * this single instance to fulfill all {@code Service} injection requests.  When
- * the {@link Injector} is created, it will automatically perform field
- * and method injection for this instance, but any injectable constructor on
- * {@code ServiceImpl} is simply ignored.  Note that using this approach results
- * in "eager loading" behavior that you can't control.
+ * In this example, your module itself, <i>not Guice</i>, takes responsibility for obtaining a
+ * {@code ServiceImpl} instance, then asks Guice to always use this single instance to fulfill all
+ * {@code Service} injection requests. When the {@link Injector} is created, it will automatically
+ * perform field and method injection for this instance, but any injectable constructor on {@code
+ * ServiceImpl} is simply ignored. Note that using this approach results in "eager loading" behavior
+ * that you can't control.
  *
  * <pre>
  *     bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre>
  *
- * Sets up a constant binding. Constant injections must always be annotated.
- * When a constant binding's value is a string, it is eligile for conversion to
- * all primitive types, to {@link Enum#valueOf(Class, String) all enums}, and to
- * {@link Class#forName class literals}. Conversions for other types can be
- * configured using {@link #convertToTypes(Matcher, TypeConverter)
+ * Sets up a constant binding. Constant injections must always be annotated. When a constant
+ * binding's value is a string, it is eligile for conversion to all primitive types, to {@link
+ * Enum#valueOf(Class, String) all enums}, and to {@link Class#forName class literals}. Conversions
+ * for other types can be configured using {@link #convertToTypes(Matcher, TypeConverter)
  * convertToTypes()}.
  *
  * <pre>
@@ -157,46 +139,42 @@
  *     red = MyModule.class.getDeclaredField("red").getAnnotation(Color.class);
  *     bind(Service.class).annotatedWith(red).to(RedService.class);</pre>
  *
- * If your binding annotation has parameters you can apply different bindings to
- * different specific values of your annotation.  Getting your hands on the
- * right instance of the annotation is a bit of a pain -- one approach, shown
- * above, is to apply a prototype annotation to a field in your module class, so
- * that you can read this annotation instance and give it to Guice.
+ * If your binding annotation has parameters you can apply different bindings to different specific
+ * values of your annotation. Getting your hands on the right instance of the annotation is a bit of
+ * a pain -- one approach, shown above, is to apply a prototype annotation to a field in your module
+ * class, so that you can read this annotation instance and give it to Guice.
  *
  * <pre>
  *     bind(Service.class)
  *         .annotatedWith(Names.named("blue"))
  *         .to(BlueService.class);</pre>
  *
- * Differentiating by names is a common enough use case that we provided a
- * standard annotation, {@link com.google.inject.name.Named @Named}.  Because of
- * Guice's library support, binding by name is quite easier than in the
- * arbitrary binding annotation case we just saw.  However, remember that these
- * names will live in a single flat namespace with all the other names used in
- * your application.
+ * Differentiating by names is a common enough use case that we provided a standard annotation,
+ * {@link com.google.inject.name.Named @Named}. Because of Guice's library support, binding by name
+ * is quite easier than in the arbitrary binding annotation case we just saw. However, remember that
+ * these names will live in a single flat namespace with all the other names used in your
+ * application.
  *
  * <pre>
  *     Constructor<T> loneCtor = getLoneCtorFromServiceImplViaReflection();
  *     bind(ServiceImpl.class)
  *         .toConstructor(loneCtor);</pre>
  *
- * In this example, we directly tell Guice which constructor to use in a concrete
- * class implementation. It means that we do not need to place {@literal @}Inject
- * on any of the constructors and that Guice treats the provided constructor as though
- * it were annotated so. It is useful for cases where you cannot modify existing
- * classes and is a bit simpler than using a {@link Provider}.
+ * In this example, we directly tell Guice which constructor to use in a concrete class
+ * implementation. It means that we do not need to place {@literal @}Inject on any of the
+ * constructors and that Guice treats the provided constructor as though it were annotated so. It is
+ * useful for cases where you cannot modify existing classes and is a bit simpler than using a
+ * {@link Provider}.
  *
- * <p>The above list of examples is far from exhaustive.  If you can think of
- * how the concepts of one example might coexist with the concepts from another,
- * you can most likely weave the two together.  If the two concepts make no
- * sense with each other, you most likely won't be able to do it.  In a few
- * cases Guice will let something bogus slip by, and will then inform you of
- * the problems at runtime, as soon as you try to create your Injector.
+ * <p>The above list of examples is far from exhaustive. If you can think of how the concepts of one
+ * example might coexist with the concepts from another, you can most likely weave the two together.
+ * If the two concepts make no sense with each other, you most likely won't be able to do it. In a
+ * few cases Guice will let something bogus slip by, and will then inform you of the problems at
+ * runtime, as soon as you try to create your Injector.
  *
- * <p>The other methods of Binder such as {@link #bindScope},
- * {@link #bindInterceptor}, {@link #install}, {@link #requestStaticInjection},
- * {@link #addError} and {@link #currentStage} are not part of the Binding EDSL;
- * you can learn how to use these in the usual way, from the method
+ * <p>The other methods of Binder such as {@link #bindScope}, {@link #bindInterceptor}, {@link
+ * #install}, {@link #requestStaticInjection}, {@link #addError} and {@link #currentStage} are not
+ * part of the Binding EDSL; you can learn how to use these in the usual way, from the method
  * documentation.
  *
  * @author crazybob@google.com (Bob Lee)
@@ -211,51 +189,41 @@
    * eligible for interception if:
    *
    * <ul>
-   *  <li>Guice created the instance the method is on</li>
-   *  <li>Neither the enclosing type nor the method is final</li>
-   *  <li>And the method is package-private, protected, or public</li>
+   * <li>Guice created the instance the method is on
+   * <li>Neither the enclosing type nor the method is final
+   * <li>And the method is package-private, protected, or public
    * </ul>
    *
-   * @param classMatcher matches classes the interceptor should apply to. For
-   *     example: {@code only(Runnable.class)}.
-   * @param methodMatcher matches methods the interceptor should apply to. For
-   *     example: {@code annotatedWith(Transactional.class)}.
-   * @param interceptors to bind.  The interceptors are called in the order they
-   *     are given.
+   * @param classMatcher matches classes the interceptor should apply to. For example: {@code
+   *     only(Runnable.class)}.
+   * @param methodMatcher matches methods the interceptor should apply to. For example: {@code
+   *     annotatedWith(Transactional.class)}.
+   * @param interceptors to bind. The interceptors are called in the order they are given.
    */
-  void bindInterceptor(Matcher<? super Class<?>> classMatcher,
+  void bindInterceptor(
+      Matcher<? super Class<?>> classMatcher,
       Matcher<? super Method> methodMatcher,
       org.aopalliance.intercept.MethodInterceptor... interceptors);
   /*end[AOP]*/
 
-  /**
-   * Binds a scope to an annotation.
-   */
+  /** Binds a scope to an annotation. */
   void bindScope(Class<? extends Annotation> annotationType, Scope scope);
 
-  /**
-   * See the EDSL examples at {@link Binder}.
-   */
+  /** See the EDSL examples at {@link Binder}. */
   <T> LinkedBindingBuilder<T> bind(Key<T> key);
 
-  /**
-   * See the EDSL examples at {@link Binder}.
-   */
+  /** See the EDSL examples at {@link Binder}. */
   <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral);
 
-  /**
-   * See the EDSL examples at {@link Binder}.
-   */
+  /** See the EDSL examples at {@link Binder}. */
   <T> AnnotatedBindingBuilder<T> bind(Class<T> type);
 
-  /**
-   * See the EDSL examples at {@link Binder}.
-   */
+  /** See the EDSL examples at {@link Binder}. */
   AnnotatedConstantBindingBuilder bindConstant();
 
   /**
-   * Upon successful creation, the {@link Injector} will inject instance fields
-   * and methods of the given object.
+   * Upon successful creation, the {@link Injector} will inject instance fields and methods of the
+   * given object.
    *
    * @param type of instance
    * @param instance for which members will be injected
@@ -264,8 +232,8 @@
   <T> void requestInjection(TypeLiteral<T> type, T instance);
 
   /**
-   * Upon successful creation, the {@link Injector} will inject instance fields
-   * and methods of the given object.
+   * Upon successful creation, the {@link Injector} will inject instance fields and methods of the
+   * given object.
    *
    * @param instance for which members will be injected
    * @since 2.0
@@ -273,37 +241,30 @@
   void requestInjection(Object instance);
 
   /**
-   * Upon successful creation, the {@link Injector} will inject static fields
-   * and methods in the given classes.
+   * Upon successful creation, the {@link Injector} will inject static fields and methods in the
+   * given classes.
    *
    * @param types for which static members will be injected
    */
   void requestStaticInjection(Class<?>... types);
 
-  /**
-   * Uses the given module to configure more bindings.
-   */
+  /** Uses the given module to configure more bindings. */
   void install(Module module);
 
-  /**
-   * Gets the current stage.
-   */
+  /** Gets the current stage. */
   Stage currentStage();
 
   /**
-   * Records an error message which will be presented to the user at a later
-   * time. Unlike throwing an exception, this enable us to continue
-   * configuring the Injector and discover more errors. Uses {@link
-   * String#format(String, Object[])} to insert the arguments into the
-   * message.
+   * Records an error message which will be presented to the user at a later time. Unlike throwing
+   * an exception, this enable us to continue configuring the Injector and discover more errors.
+   * Uses {@link String#format(String, Object[])} to insert the arguments into the message.
    */
   void addError(String message, Object... arguments);
 
   /**
-   * Records an exception, the full details of which will be logged, and the
-   * message of which will be presented to the user at a later
-   * time. If your Module calls something that you worry may fail, you should
-   * catch the exception and pass it into this.
+   * Records an exception, the full details of which will be logged, and the message of which will
+   * be presented to the user at a later time. If your Module calls something that you worry may
+   * fail, you should catch the exception and pass it into this.
    */
   void addError(Throwable t);
 
@@ -315,32 +276,29 @@
   void addError(Message message);
 
   /**
-   * Returns the provider used to obtain instances for the given injection key.
-   * The returned provider will not be valid until the {@link Injector} has been
-   * created. The provider will throw an {@code IllegalStateException} if you
-   * try to use it beforehand.
+   * Returns the provider used to obtain instances for the given injection key. The returned
+   * provider will not be valid until the {@link Injector} has been created. The provider will throw
+   * an {@code IllegalStateException} if you try to use it beforehand.
    *
    * @since 2.0
    */
   <T> Provider<T> getProvider(Key<T> key);
 
   /**
-   * Returns the provider used to obtain instances for the given injection key.
-   * The returned provider will be attached to the injection point and will
-   * follow the nullability specified in the dependency.
-   * Additionally, the returned provider will not be valid until the {@link Injector} 
-   * has been created. The provider will throw an {@code IllegalStateException} if you
-   * try to use it beforehand.
+   * Returns the provider used to obtain instances for the given injection key. The returned
+   * provider will be attached to the injection point and will follow the nullability specified in
+   * the dependency. Additionally, the returned provider will not be valid until the {@link
+   * Injector} has been created. The provider will throw an {@code IllegalStateException} if you try
+   * to use it beforehand.
    *
    * @since 4.0
    */
   <T> Provider<T> getProvider(Dependency<T> dependency);
 
   /**
-   * Returns the provider used to obtain instances for the given injection type.
-   * The returned provider will not be valid until the {@link Injector} has been
-   * created. The provider will throw an {@code IllegalStateException} if you
-   * try to use it beforehand.
+   * Returns the provider used to obtain instances for the given injection type. The returned
+   * provider will not be valid until the {@link Injector} has been created. The provider will throw
+   * an {@code IllegalStateException} if you try to use it beforehand.
    *
    * @since 2.0
    */
@@ -369,15 +327,14 @@
   <T> MembersInjector<T> getMembersInjector(Class<T> type);
 
   /**
-   * Binds a type converter. The injector will use the given converter to
-   * convert string constants to matching types as needed.
+   * Binds a type converter. The injector will use the given converter to convert string constants
+   * to matching types as needed.
    *
    * @param typeMatcher matches types the converter can handle
    * @param converter converts values
    * @since 2.0
    */
-  void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeConverter converter);
+  void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter);
 
   /**
    * Registers a listener for injectable types. Guice will notify the listener when it encounters
@@ -387,43 +344,38 @@
    * @param listener for injectable types matched by typeMatcher
    * @since 2.0
    */
-  void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeListener listener);
+  void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener);
 
   /**
-   * Registers listeners for provisioned objects. Guice will notify the
-   * listeners just before and after the object is provisioned. Provisioned
-   * objects that are also injectable (everything except objects provided
-   * through Providers) can also be notified through TypeListeners registered in
-   * {@link #bindListener}.
-   * 
-   * @param bindingMatcher that matches bindings of provisioned objects the listener
-   *          should be notified of
-   * @param listeners for provisioned objects matched by bindingMatcher 
+   * Registers listeners for provisioned objects. Guice will notify the listeners just before and
+   * after the object is provisioned. Provisioned objects that are also injectable (everything
+   * except objects provided through Providers) can also be notified through TypeListeners
+   * registered in {@link #bindListener}.
+   *
+   * @param bindingMatcher that matches bindings of provisioned objects the listener should be
+   *     notified of
+   * @param listeners for provisioned objects matched by bindingMatcher
    * @since 4.0
    */
   void bindListener(Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listeners);
 
   /**
-   * Returns a binder that uses {@code source} as the reference location for
-   * configuration errors. This is typically a {@link StackTraceElement}
-   * for {@code .java} source but it could any binding source, such as the
-   * path to a {@code .properties} file.
+   * Returns a binder that uses {@code source} as the reference location for configuration errors.
+   * This is typically a {@link StackTraceElement} for {@code .java} source but it could any binding
+   * source, such as the path to a {@code .properties} file.
    *
-   * @param source any object representing the source location and has a
-   *     concise {@link Object#toString() toString()} value
+   * @param source any object representing the source location and has a concise {@link
+   *     Object#toString() toString()} value
    * @return a binder that shares its configuration with this binder
    * @since 2.0
    */
   Binder withSource(Object source);
 
   /**
-   * Returns a binder that skips {@code classesToSkip} when identify the
-   * calling code. The caller's {@link StackTraceElement} is used to locate
-   * the source of configuration errors.
+   * Returns a binder that skips {@code classesToSkip} when identify the calling code. The caller's
+   * {@link StackTraceElement} is used to locate the source of configuration errors.
    *
-   * @param classesToSkip library classes that create bindings on behalf of
-   *      their clients.
+   * @param classesToSkip library classes that create bindings on behalf of their clients.
    * @return a binder that shares its configuration with this binder.
    * @since 2.0
    */
@@ -435,75 +387,69 @@
    * PrivateModule} for details.
    *
    * @return a binder that inherits configuration from this binder. Only exposed configuration on
-   *      the returned binder will be visible to this binder.
+   *     the returned binder will be visible to this binder.
    * @since 2.0
    */
   PrivateBinder newPrivateBinder();
 
   /**
-   * Instructs the Injector that bindings must be listed in a Module in order to
-   * be injected. Classes that are not explicitly bound in a module cannot be
-   * injected. Bindings created through a linked binding
-   * (<code>bind(Foo.class).to(FooImpl.class)</code>) are allowed, but the
-   * implicit binding (<code>FooImpl</code>) cannot be directly injected unless
-   * it is also explicitly bound (<code>bind(FooImpl.class)</code>).
-   * <p>
-   * Tools can still retrieve bindings for implicit bindings (bindings created
-   * through a linked binding) if explicit bindings are required, however
-   * {@link Binding#getProvider} will fail.
-   * <p>
-   * By default, explicit bindings are not required.
-   * <p>
-   * If a parent injector requires explicit bindings, then all child injectors
-   * (and private modules within that injector) also require explicit bindings.
-   * If a parent does not require explicit bindings, a child injector or private
-   * module may optionally declare itself as requiring explicit bindings. If it
-   * does, the behavior is limited only to that child or any grandchildren. No
-   * siblings of the child will require explicit bindings.
-   * <p>
-   * In the absence of an explicit binding for the target, linked bindings in
-   * child injectors create a binding for the target in the parent. Since this
-   * behavior can be surprising, it causes an error instead if explicit bindings
-   * are required. To avoid this error, add an explicit binding for the target,
-   * either in the child or the parent.
-   * 
+   * Instructs the Injector that bindings must be listed in a Module in order to be injected.
+   * Classes that are not explicitly bound in a module cannot be injected. Bindings created through
+   * a linked binding (<code>bind(Foo.class).to(FooImpl.class)</code>) are allowed, but the implicit
+   * binding (<code>FooImpl</code>) cannot be directly injected unless it is also explicitly bound (
+   * <code>bind(FooImpl.class)</code>).
+   *
+   * <p>Tools can still retrieve bindings for implicit bindings (bindings created through a linked
+   * binding) if explicit bindings are required, however {@link Binding#getProvider} will fail.
+   *
+   * <p>By default, explicit bindings are not required.
+   *
+   * <p>If a parent injector requires explicit bindings, then all child injectors (and private
+   * modules within that injector) also require explicit bindings. If a parent does not require
+   * explicit bindings, a child injector or private module may optionally declare itself as
+   * requiring explicit bindings. If it does, the behavior is limited only to that child or any
+   * grandchildren. No siblings of the child will require explicit bindings.
+   *
+   * <p>In the absence of an explicit binding for the target, linked bindings in child injectors
+   * create a binding for the target in the parent. Since this behavior can be surprising, it causes
+   * an error instead if explicit bindings are required. To avoid this error, add an explicit
+   * binding for the target, either in the child or the parent.
+   *
    * @since 3.0
    */
   void requireExplicitBindings();
-  
+
   /**
-   * Prevents Guice from constructing a {@link Proxy} when a circular dependency
-   * is found.  By default, circular proxies are not disabled.
-   * <p>
-   * If a parent injector disables circular proxies, then all child injectors
-   * (and private modules within that injector) also disable circular proxies.
-   * If a parent does not disable circular proxies, a child injector or private
-   * module may optionally declare itself as disabling circular proxies. If it
-   * does, the behavior is limited only to that child or any grandchildren. No
-   * siblings of the child will disable circular proxies.
-   * 
+   * Prevents Guice from injecting dependencies that form a cycle, unless broken by a {@link
+   * Provider}. By default, circular dependencies are not disabled.
+   *
+   * <p>If a parent injector disables circular dependencies, then all child injectors (and private
+   * modules within that injector) also disable circular dependencies. If a parent does not disable
+   * circular dependencies, a child injector or private module may optionally declare itself as
+   * disabling circular dependencies. If it does, the behavior is limited only to that child or any
+   * grandchildren. No siblings of the child will disable circular dependencies.
+   *
    * @since 3.0
    */
   void disableCircularProxies();
-  
+
   /**
    * Requires that a {@literal @}{@link Inject} annotation exists on a constructor in order for
    * Guice to consider it an eligible injectable class. By default, Guice will inject classes that
    * have a no-args constructor if no {@literal @}{@link Inject} annotation exists on any
    * constructor.
-   * <p>
-   * If the class is bound using {@link LinkedBindingBuilder#toConstructor}, Guice will still inject
-   * that constructor regardless of annotations.
+   *
+   * <p>If the class is bound using {@link LinkedBindingBuilder#toConstructor}, Guice will still
+   * inject that constructor regardless of annotations.
    *
    * @since 4.0
    */
   void requireAtInjectOnConstructors();
 
   /**
-   * Requires that Guice finds an exactly matching binding annotation.  This disables the
-   * error-prone feature in Guice where it can substitute a binding for
-   * <code>{@literal @}Named Foo</code> when attempting to inject
-   * <code>{@literal @}Named("foo") Foo</code>.
+   * Requires that Guice finds an exactly matching binding annotation. This disables the error-prone
+   * feature in Guice where it can substitute a binding for <code>{@literal @}Named Foo</code> when
+   * attempting to inject <code>{@literal @}Named("foo") Foo</code>.
    *
    * @since 4.0
    */
diff --git a/core/src/com/google/inject/Binding.java b/core/src/com/google/inject/Binding.java
index 332237e..caf52f0 100644
--- a/core/src/com/google/inject/Binding.java
+++ b/core/src/com/google/inject/Binding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,55 +22,50 @@
 
 /**
  * A mapping from a key (type and optional annotation) to the strategy for getting instances of the
- * type. This interface is part of the introspection API and is intended primarily for use by 
- * tools.
+ * type. This interface is part of the introspection API and is intended primarily for use by tools.
  *
  * <p>Bindings are created in several ways:
+ *
  * <ul>
- *     <li>Explicitly in a module, via {@code bind()} and {@code bindConstant()}
- *         statements:
- * <pre>
+ * <li>Explicitly in a module, via {@code bind()} and {@code bindConstant()} statements:
+ *     <pre>
  *     bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);
- *     bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre></li>
- *     <li>Implicitly by the Injector by following a type's {@link ImplementedBy
- *         pointer} {@link ProvidedBy annotations} or by using its {@link Inject annotated} or
- *         default constructor.</li>
- *     <li>By converting a bound instance to a different type.</li>
- *     <li>For {@link Provider providers}, by delegating to the binding for the provided type.</li>
+ *     bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre>
+ *
+ * <li>Implicitly by the Injector by following a type's {@link ImplementedBy pointer} {@link
+ *     ProvidedBy annotations} or by using its {@link Inject annotated} or default constructor.
+ * <li>By converting a bound instance to a different type.
+ * <li>For {@link Provider providers}, by delegating to the binding for the provided type.
  * </ul>
  *
- *
  * <p>They exist on both modules and on injectors, and their behaviour is different for each:
+ *
  * <ul>
- *     <li><strong>Module bindings</strong> are incomplete and cannot be used to provide instances.
- *         This is because the applicable scopes and interceptors may not be known until an injector
- *         is created. From a tool's perspective, module bindings are like the injector's source
- *         code. They can be inspected or rewritten, but this analysis must be done statically.</li>
- *     <li><strong>Injector bindings</strong> are complete and valid and can be used to provide
- *         instances. From a tools' perspective, injector bindings are like reflection for an
- *         injector. They have full runtime information, including the complete graph of injections
- *         necessary to satisfy a binding.</li>
+ * <li><strong>Module bindings</strong> are incomplete and cannot be used to provide instances. This
+ *     is because the applicable scopes and interceptors may not be known until an injector is
+ *     created. From a tool's perspective, module bindings are like the injector's source code. They
+ *     can be inspected or rewritten, but this analysis must be done statically.
+ * <li><strong>Injector bindings</strong> are complete and valid and can be used to provide
+ *     instances. From a tools' perspective, injector bindings are like reflection for an injector.
+ *     They have full runtime information, including the complete graph of injections necessary to
+ *     satisfy a binding.
  * </ul>
  *
  * @param <T> the bound type. The injected is always assignable to this type.
- *
  * @author crazybob@google.com (Bob Lee)
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public interface Binding<T> extends Element {
 
-  /**
-   * Returns the key for this binding.
-   */
+  /** Returns the key for this binding. */
   Key<T> getKey();
 
   /**
-   * Returns the scoped provider guice uses to fulfill requests for this
-   * binding.
+   * Returns the scoped provider guice uses to fulfill requests for this binding.
    *
-   * @throws UnsupportedOperationException when invoked on a {@link Binding}
-   *      created via {@link com.google.inject.spi.Elements#getElements}. This
-   *      method is only supported on {@link Binding}s returned from an injector.
+   * @throws UnsupportedOperationException when invoked on a {@link Binding} created via {@link
+   *     com.google.inject.spi.Elements#getElements}. This method is only supported on {@link
+   *     Binding}s returned from an injector.
    */
   Provider<T> getProvider();
 
diff --git a/core/src/com/google/inject/BindingAnnotation.java b/core/src/com/google/inject/BindingAnnotation.java
index 2d373e4..5a2050e 100644
--- a/core/src/com/google/inject/BindingAnnotation.java
+++ b/core/src/com/google/inject/BindingAnnotation.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,9 +23,9 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotates annotations which are used for binding. Only one such annotation
- * may apply to a single injection point. You must also annotate binder
- * annotations with {@code @Retention(RUNTIME)}. For example:
+ * Annotates annotations which are used for binding. Only one such annotation may apply to a single
+ * injection point. You must also annotate binder annotations with {@code @Retention(RUNTIME)}. For
+ * example:
  *
  * <pre>
  *   {@code @}Retention(RUNTIME)
diff --git a/core/src/com/google/inject/ConfigurationException.java b/core/src/com/google/inject/ConfigurationException.java
index e298cff..3d3b73c 100644
--- a/core/src/com/google/inject/ConfigurationException.java
+++ b/core/src/com/google/inject/ConfigurationException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,8 @@
 
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.internal.Errors;
+import com.google.inject.internal.Messages;
 import com.google.inject.spi.Message;
-
 import java.util.Collection;
 
 /**
@@ -33,13 +31,13 @@
  */
 public final class ConfigurationException extends RuntimeException {
 
-  private final ImmutableSet<Message> messages;
+  private final com.google.common.collect.ImmutableSet<Message> messages;
   private Object partialValue = null;
 
   /** Creates a ConfigurationException containing {@code messages}. */
   public ConfigurationException(Iterable<Message> messages) {
-    this.messages = ImmutableSet.copyOf(messages); 
-    initCause(Errors.getOnlyCause(this.messages));
+    this.messages = com.google.common.collect.ImmutableSet.copyOf(messages);
+    initCause(Messages.getOnlyCause(this.messages));
   }
 
   /** Returns a copy of this configuration exception with the specified partial value. */
@@ -57,20 +55,23 @@
   }
 
   /**
-   * Returns a value that was only partially computed due to this exception. The caller can use
-   * this while collecting additional configuration problems.
+   * Returns a value that was only partially computed due to this exception. The caller can use this
+   * while collecting additional configuration problems.
    *
    * @return the partial value, or {@code null} if none was set. The type of the partial value is
-   *      specified by the throwing method.
+   *     specified by the throwing method.
    */
-  @SuppressWarnings("unchecked") // this is *extremely* unsafe. We trust the caller here.
+  @SuppressWarnings({
+    "unchecked",
+    "TypeParameterUnusedInFormals"
+  }) // this is *extremely* unsafe. We trust the caller here.
   public <E> E getPartialValue() {
     return (E) partialValue;
   }
 
   @Override public String getMessage() {
-    return Errors.format("Guice configuration errors", messages);
+    return Messages.formatMessages("Guice configuration errors", messages);
   }
 
   private static final long serialVersionUID = 0;
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/CreationException.java b/core/src/com/google/inject/CreationException.java
index 4f84c22..38e8281 100644
--- a/core/src/com/google/inject/CreationException.java
+++ b/core/src/com/google/inject/CreationException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,9 +19,8 @@
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.inject.internal.Errors;
+import com.google.inject.internal.Messages;
 import com.google.inject.spi.Message;
-
 import java.util.Collection;
 
 /**
@@ -38,7 +37,7 @@
   public CreationException(Collection<Message> messages) {
     this.messages = ImmutableSet.copyOf(messages);
     checkArgument(!this.messages.isEmpty());
-    initCause(Errors.getOnlyCause(this.messages));
+    initCause(Messages.getOnlyCause(this.messages));
   }
 
   /** Returns messages for the errors that caused this exception. */
@@ -46,8 +45,9 @@
     return messages;
   }
 
-  @Override public String getMessage() {
-    return Errors.format("Unable to create injector, see the following errors", messages);
+  @Override
+  public String getMessage() {
+    return Messages.formatMessages("Unable to create injector, see the following errors", messages);
   }
 
   private static final long serialVersionUID = 0;
diff --git a/core/src/com/google/inject/Exposed.java b/core/src/com/google/inject/Exposed.java
index 45a448f..9e2e441 100644
--- a/core/src/com/google/inject/Exposed.java
+++ b/core/src/com/google/inject/Exposed.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,5 +30,7 @@
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
  */
-@Target(ElementType.METHOD) @Retention(RUNTIME) @Documented
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
 public @interface Exposed {}
diff --git a/core/src/com/google/inject/Guice.java b/core/src/com/google/inject/Guice.java
index 703187f..ae8d43b 100644
--- a/core/src/com/google/inject/Guice.java
+++ b/core/src/com/google/inject/Guice.java
@@ -17,19 +17,17 @@
 package com.google.inject;
 
 import com.google.inject.internal.InternalInjectorCreator;
-
 import java.util.Arrays;
 
 /**
- * The entry point to the Guice framework. Creates {@link Injector}s from
- * {@link Module}s.
+ * The entry point to the Guice framework. Creates {@link Injector}s from {@link Module}s.
  *
- * <p>Guice supports a model of development that draws clear boundaries between
- * APIs, Implementations of these APIs, Modules which configure these
- * implementations, and finally Applications which consist of a collection of
- * Modules. It is the Application, which typically defines your {@code main()}
- * method, that bootstraps the Guice Injector using the {@code Guice} class, as
- * in this example:
+ * <p>Guice supports a model of development that draws clear boundaries between APIs,
+ * Implementations of these APIs, Modules which configure these implementations, and finally
+ * Applications which consist of a collection of Modules. It is the Application, which typically
+ * defines your {@code main()} method, that bootstraps the Guice Injector using the {@code Guice}
+ * class, as in this example:
+ *
  * <pre>
  *     public class FooApplication {
  *       public static void main(String[] args) {
@@ -52,50 +50,40 @@
   private Guice() {}
 
   /**
-   * Creates an injector for the given set of modules. This is equivalent to
-   * calling {@link #createInjector(Stage, Module...)} with Stage.DEVELOPMENT.
+   * Creates an injector for the given set of modules. This is equivalent to calling {@link
+   * #createInjector(Stage, Module...)} with Stage.DEVELOPMENT.
    *
-   * @throws CreationException if one or more errors occur during injector
-   *     construction
+   * @throws CreationException if one or more errors occur during injector construction
    */
   public static Injector createInjector(Module... modules) {
     return createInjector(Arrays.asList(modules));
   }
 
   /**
-   * Creates an injector for the given set of modules. This is equivalent to
-   * calling {@link #createInjector(Stage, Iterable)} with Stage.DEVELOPMENT.
+   * Creates an injector for the given set of modules. This is equivalent to calling {@link
+   * #createInjector(Stage, Iterable)} with Stage.DEVELOPMENT.
    *
-   * @throws CreationException if one or more errors occur during injector
-   *     creation
+   * @throws CreationException if one or more errors occur during injector creation
    */
   public static Injector createInjector(Iterable<? extends Module> modules) {
     return createInjector(Stage.DEVELOPMENT, modules);
   }
 
   /**
-   * Creates an injector for the given set of modules, in a given development
-   * stage.
+   * Creates an injector for the given set of modules, in a given development stage.
    *
-   * @throws CreationException if one or more errors occur during injector
-   *     creation.
+   * @throws CreationException if one or more errors occur during injector creation.
    */
   public static Injector createInjector(Stage stage, Module... modules) {
     return createInjector(stage, Arrays.asList(modules));
   }
 
   /**
-   * Creates an injector for the given set of modules, in a given development
-   * stage.
+   * Creates an injector for the given set of modules, in a given development stage.
    *
-   * @throws CreationException if one or more errors occur during injector
-   *     construction
+   * @throws CreationException if one or more errors occur during injector construction
    */
-  public static Injector createInjector(Stage stage,
-      Iterable<? extends Module> modules) {
-    return new InternalInjectorCreator()
-        .stage(stage)
-        .addModules(modules)
-        .build();
+  public static Injector createInjector(Stage stage, Iterable<? extends Module> modules) {
+    return new InternalInjectorCreator().stage(stage).addModules(modules).build();
   }
 }
diff --git a/core/src/com/google/inject/ImplementedBy.java b/core/src/com/google/inject/ImplementedBy.java
index 464a279..f19bb86 100644
--- a/core/src/com/google/inject/ImplementedBy.java
+++ b/core/src/com/google/inject/ImplementedBy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,8 +31,6 @@
 @Target(TYPE)
 public @interface ImplementedBy {
 
-  /**
-   * The implementation type.
-   */
+  /** The implementation type. */
   Class<?> value();
 }
diff --git a/core/src/com/google/inject/Inject.java b/core/src/com/google/inject/Inject.java
index 535c0a4..3c4b396 100644
--- a/core/src/com/google/inject/Inject.java
+++ b/core/src/com/google/inject/Inject.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,44 +26,37 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotates members of your implementation class (constructors, methods
- * and fields) into which the {@link Injector} should inject values.
- * The Injector fulfills injection requests for:
+ * Annotates members of your implementation class (constructors, methods and fields) into which the
+ * {@link Injector} should inject values. The Injector fulfills injection requests for:
  *
  * <ul>
- * <li>Every instance it constructs. The class being constructed must have
- * exactly one of its constructors marked with {@code @Inject} or must have a
- * constructor taking no parameters. The Injector then proceeds to perform
- * field and method injections.
- * 
- * <li>Pre-constructed instances passed to {@link Injector#injectMembers},
- * {@link com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and
- * {@link com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}.
- * In this case all constructors are, of course, ignored.
- *
- * <li>Static fields and methods of classes which any {@link Module} has
- * specifically requested static injection for, using
- * {@link Binder#requestStaticInjection}.
+ * <li>Every instance it constructs. The class being constructed must have exactly one of its
+ *     constructors marked with {@code @Inject} or must have a constructor taking no parameters. The
+ *     Injector then proceeds to perform field and method injections.
+ * <li>Pre-constructed instances passed to {@link Injector#injectMembers}, {@link
+ *     com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and {@link
+ *     com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}. In this
+ *     case all constructors are, of course, ignored.
+ * <li>Static fields and methods of classes which any {@link Module} has specifically requested
+ *     static injection for, using {@link Binder#requestStaticInjection}.
  * </ul>
  *
- * In all cases, a member can be injected regardless of its Java access
- * specifier (private, default, protected, public).
+ * In all cases, a member can be injected regardless of its Java access specifier (private, default,
+ * protected, public).
  *
  * @author crazybob@google.com (Bob Lee)
  */
-@Target({ METHOD, CONSTRUCTOR, FIELD })
+@Target({METHOD, CONSTRUCTOR, FIELD})
 @Retention(RUNTIME)
 @Documented
 public @interface Inject {
 
   /**
-   * If true, and the appropriate binding is not found,
-   * the Injector will skip injection of this method or field rather than
-   * produce an error. When applied to a field, any default value already
-   * assigned to the field will remain (guice will not actively null out the
-   * field). When applied to a method, the method will only be invoked if
-   * bindings for <i>all</i> parameters are found. When applied to a
-   * constructor, an error will result upon Injector creation.
+   * If true, and the appropriate binding is not found, the Injector will skip injection of this
+   * method or field rather than produce an error. When applied to a field, any default value
+   * already assigned to the field will remain (guice will not actively null out the field). When
+   * applied to a method, the method will only be invoked if bindings for <i>all</i> parameters are
+   * found. When applied to a constructor, an error will result upon Injector creation.
    */
   boolean optional() default false;
 }
diff --git a/core/src/com/google/inject/Injector.java b/core/src/com/google/inject/Injector.java
index 42c7331..d2ac498 100644
--- a/core/src/com/google/inject/Injector.java
+++ b/core/src/com/google/inject/Injector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject;
 
 import com.google.inject.spi.TypeConverterBinding;
-
 import java.lang.annotation.Annotation;
 import java.util.List;
 import java.util.Map;
@@ -64,9 +63,8 @@
    * you, you'll never need to use this method.
    *
    * @param instance to inject members on
-   *
    * @see Binder#getMembersInjector(Class) for a preferred alternative that supports checks before
-   *  run time
+   *     run time
    */
   void injectMembers(Object instance);
 
@@ -76,7 +74,7 @@
    *
    * @param typeLiteral type to get members injector for
    * @see Binder#getMembersInjector(TypeLiteral) for an alternative that offers up front error
-   *  detection
+   *     detection
    * @since 2.0
    */
   <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral);
@@ -87,8 +85,7 @@
    * instead to get increased up front error detection.
    *
    * @param type type to get members injector for
-   * @see Binder#getMembersInjector(Class) for an alternative that offers up front error
-   *  detection
+   * @see Binder#getMembersInjector(Class) for an alternative that offers up front error detection
    * @since 2.0
    */
   <T> MembersInjector<T> getMembersInjector(Class<T> type);
@@ -97,9 +94,9 @@
    * Returns this injector's <strong>explicit</strong> bindings.
    *
    * <p>The returned map does not include bindings inherited from a {@link #getParent() parent
-   * injector}, should one exist. The returned map is guaranteed to iterate (for example, with
-   * its {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in
-   * which bindings appear in user Modules.
+   * injector}, should one exist. The returned map is guaranteed to iterate (for example, with its
+   * {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in which
+   * bindings appear in user Modules.
    *
    * <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
    */
@@ -108,14 +105,15 @@
   /**
    * Returns a snapshot of this injector's bindings, <strong>both explicit and
    * just-in-time</strong>. The returned map is immutable; it contains only the bindings that were
-   * present when {@code getAllBindings()} was invoked. Subsequent calls may return a map with
-   * additional just-in-time bindings.
+   * present when {@code getAllBindings()} was invoked. Just-in-time bindings are only present if
+   * they have been requested at least once. Subsequent calls may return a map with additional
+   * just-in-time bindings.
    *
    * <p>The returned map does not include bindings inherited from a {@link #getParent() parent
    * injector}, should one exist.
    *
    * <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
-   * 
+   *
    * @since 3.0
    */
   Map<Key<?>, Binding<?>> getAllBindings();
@@ -142,17 +140,17 @@
    * @since 2.0
    */
   <T> Binding<T> getBinding(Class<T> type);
-  
+
   /**
-   * Returns the binding if it already exists, or null if does not exist. Unlike
-   * {@link #getBinding(Key)}, this does not attempt to create just-in-time bindings
-   * for keys that aren't bound.
-   * 
-   * <p> This method is part of the Guice SPI and is intended for use by tools and extensions.
-   * 
+   * Returns the binding if it already exists, or null if does not exist. Unlike {@link
+   * #getBinding(Key)}, this does not attempt to create just-in-time bindings for keys that aren't
+   * bound.
+   *
+   * <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+   *
    * @since 3.0
    */
-  <T> Binding<T> getExistingBinding(Key<T> key);  
+  <T> Binding<T> getExistingBinding(Key<T> key);
 
   /**
    * Returns all explicit bindings for {@code type}.
@@ -171,8 +169,8 @@
   <T> Provider<T> getProvider(Key<T> key);
 
   /**
-   * Returns the provider used to obtain instances for the given type. When feasible, avoid
-   * using this method, in favor of having Guice inject your dependencies ahead of time.
+   * Returns the provider used to obtain instances for the given type. When feasible, avoid using
+   * this method, in favor of having Guice inject your dependencies ahead of time.
    *
    * @throws ConfigurationException if this injector cannot find or create the provider.
    * @see Binder#getProvider(Class) for an alternative that offers up front error detection
@@ -213,9 +211,9 @@
    *
    * <p>Just-in-time bindings created for child injectors will be created in an ancestor injector
    * whenever possible. This allows for scoped instances to be shared between injectors. Use
-   * explicit bindings to prevent bindings from being shared with the parent injector.  Optional
-   * injections in just-in-time bindings (created in the parent injector) may be silently
-   * ignored if the optional dependencies are from the child injector.
+   * explicit bindings to prevent bindings from being shared with the parent injector. Optional
+   * injections in just-in-time bindings (created in the parent injector) may be silently ignored if
+   * the optional dependencies are from the child injector.
    *
    * <p>No key may be bound by both an injector and one of its ancestors. This includes just-in-time
    * bindings. The lone exception is the key for {@code Injector.class}, which is bound by each
@@ -243,12 +241,12 @@
   Injector createChildInjector(Module... modules);
 
   /**
-   * Returns a map containing all scopes in the injector. The maps keys are scoping annotations
-   * like {@code Singleton.class}, and the values are scope instances, such as {@code
-   * Scopes.SINGLETON}. The returned map is immutable.
+   * Returns a map containing all scopes in the injector. The maps keys are scoping annotations like
+   * {@code Singleton.class}, and the values are scope instances, such as {@code Scopes.SINGLETON}.
+   * The returned map is immutable.
    *
    * <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
-   * 
+   *
    * @since 3.0
    */
   Map<Class<? extends Annotation>, Scope> getScopeBindings();
@@ -258,7 +256,7 @@
    * immutable.
    *
    * <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
-   * 
+   *
    * @since 3.0
    */
   Set<TypeConverterBinding> getTypeConverterBindings();
diff --git a/core/src/com/google/inject/Key.java b/core/src/com/google/inject/Key.java
index c93dabf..55779f3 100644
--- a/core/src/com/google/inject/Key.java
+++ b/core/src/com/google/inject/Key.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,20 +21,16 @@
 import static com.google.inject.internal.Annotations.generateAnnotation;
 import static com.google.inject.internal.Annotations.isAllDefaultMethods;
 
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
 import com.google.inject.internal.Annotations;
 import com.google.inject.internal.MoreTypes;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
 /**
- * Binding key consisting of an injection type and an optional annotation.
- * Matches the type and annotation at a point of injection.
+ * Binding key consisting of an injection type and an optional annotation. Matches the type and
+ * annotation at a point of injection.
  *
- * <p>For example, {@code Key.get(Service.class, Transactional.class)} will
- * match:
+ * <p>For example, {@code Key.get(Service.class, Transactional.class)} will match:
  *
  * <pre>
  *   {@literal @}Inject
@@ -43,12 +39,11 @@
  *   }
  * </pre>
  *
- * <p>{@code Key} supports generic types via subclassing just like {@link
- * TypeLiteral}.
+ * <p>{@code Key} supports generic types via subclassing just like {@link TypeLiteral}.
  *
- * <p>Keys do not differentiate between primitive types (int, char, etc.) and
- * their corresponding wrapper types (Integer, Character, etc.). Primitive
- * types will be replaced with their wrapper types when keys are created.
+ * <p>Keys do not differentiate between primitive types (int, char, etc.) and their corresponding
+ * wrapper types (Integer, Character, etc.). Primitive types will be replaced with their wrapper
+ * types when keys are created.
  *
  * @author crazybob@google.com (Bob Lee)
  */
@@ -58,38 +53,37 @@
 
   private final TypeLiteral<T> typeLiteral;
   private final int hashCode;
-  private final Supplier<String> toStringSupplier;
+  // This field is updated using the 'Data-Race-Ful' lazy intialization pattern
+  // See http://jeremymanson.blogspot.com/2008/12/benign-data-races-in-java.html for a detailed
+  // explanation.
+  private String toString;
 
   /**
    * Constructs a new key. Derives the type from this class's type parameter.
    *
-   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
-   * parameter in the anonymous class's type hierarchy so we can reconstitute it
-   * at runtime despite erasure.
+   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
+   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
    *
-   * <p>Example usage for a binding of type {@code Foo} annotated with
-   * {@code @Bar}:
+   * <p>Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
    *
    * <p>{@code new Key<Foo>(Bar.class) {}}.
    */
   @SuppressWarnings("unchecked")
   protected Key(Class<? extends Annotation> annotationType) {
     this.annotationStrategy = strategyFor(annotationType);
-    this.typeLiteral = MoreTypes.canonicalizeForKey(
-        (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
+    this.typeLiteral =
+        MoreTypes.canonicalizeForKey(
+            (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
     this.hashCode = computeHashCode();
-    this.toStringSupplier = createToStringSupplier();
   }
 
   /**
    * Constructs a new key. Derives the type from this class's type parameter.
    *
-   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
-   * parameter in the anonymous class's type hierarchy so we can reconstitute it
-   * at runtime despite erasure.
+   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
+   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
    *
-   * <p>Example usage for a binding of type {@code Foo} annotated with
-   * {@code @Bar}:
+   * <p>Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
    *
    * <p>{@code new Key<Foo>(new Bar()) {}}.
    */
@@ -97,18 +91,17 @@
   protected Key(Annotation annotation) {
     // no usages, not test-covered
     this.annotationStrategy = strategyFor(annotation);
-    this.typeLiteral = MoreTypes.canonicalizeForKey(
-        (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
+    this.typeLiteral =
+        MoreTypes.canonicalizeForKey(
+            (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
     this.hashCode = computeHashCode();
-    this.toStringSupplier = createToStringSupplier();
   }
 
   /**
    * Constructs a new key. Derives the type from this class's type parameter.
    *
-   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
-   * parameter in the anonymous class's type hierarchy so we can reconstitute it
-   * at runtime despite erasure.
+   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
+   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
    *
    * <p>Example usage for a binding of type {@code Foo}:
    *
@@ -117,21 +110,18 @@
   @SuppressWarnings("unchecked")
   protected Key() {
     this.annotationStrategy = NullAnnotationStrategy.INSTANCE;
-    this.typeLiteral = MoreTypes.canonicalizeForKey(
-        (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
+    this.typeLiteral =
+        MoreTypes.canonicalizeForKey(
+            (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
     this.hashCode = computeHashCode();
-    this.toStringSupplier = createToStringSupplier();
   }
 
-  /**
-   * Unsafe. Constructs a key from a manually specified type.
-   */
+  /** Unsafe. Constructs a key from a manually specified type. */
   @SuppressWarnings("unchecked")
   private Key(Type type, AnnotationStrategy annotationStrategy) {
     this.annotationStrategy = annotationStrategy;
     this.typeLiteral = MoreTypes.canonicalizeForKey((TypeLiteral<T>) TypeLiteral.get(type));
     this.hashCode = computeHashCode();
-    this.toStringSupplier = createToStringSupplier();
   }
 
   /** Constructs a key from a manually specified type. */
@@ -139,46 +129,24 @@
     this.annotationStrategy = annotationStrategy;
     this.typeLiteral = MoreTypes.canonicalizeForKey(typeLiteral);
     this.hashCode = computeHashCode();
-    this.toStringSupplier = createToStringSupplier();
   }
 
-  /**
-   * Computes the hash code for this key.
-   */
+  /** Computes the hash code for this key. */
   private int computeHashCode() {
     return typeLiteral.hashCode() * 31 + annotationStrategy.hashCode();
   }
 
-  /**
-   * @return a {@link Supplier} which memoizes the value for lazy initialization.
-   */
-  private Supplier<String> createToStringSupplier() {
-    // The performance hit on access is acceptable since the intended use is for non-performance-
-    // critical applications such as debugging and logging.
-    return Suppliers.memoize(new Supplier<String>() {
-      @Override public String get() {
-        return "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
-      }
-    });
-  }
-  
-  /**
-   * Gets the key type.
-   */
+  /** Gets the key type. */
   public final TypeLiteral<T> getTypeLiteral() {
     return typeLiteral;
   }
 
-  /**
-   * Gets the annotation type.
-   */
+  /** Gets the annotation type. */
   public final Class<? extends Annotation> getAnnotationType() {
     return annotationStrategy.getAnnotationType();
   }
 
-  /**
-   * Gets the annotation.
-   */
+  /** Gets the annotation. */
   public final Annotation getAnnotation() {
     return annotationStrategy.getAnnotation();
   }
@@ -201,14 +169,13 @@
     return typeLiteral.getRawType();
   }
 
-  /**
-   * Gets the key of this key's provider.
-   */
+  /** Gets the key of this key's provider. */
   Key<Provider<T>> providerKey() {
     return ofType(typeLiteral.providerType());
   }
 
-  @Override public final boolean equals(Object o) {
+  @Override
+  public final boolean equals(Object o) {
     if (o == this) {
       return true;
     }
@@ -220,92 +187,76 @@
         && typeLiteral.equals(other.typeLiteral);
   }
 
-  @Override public final int hashCode() {
+  @Override
+  public final int hashCode() {
     return this.hashCode;
   }
 
-  @Override public final String toString() {
-    return toStringSupplier.get();
+  @Override
+  public final String toString() {
+    // Note: to not introduce dangerous data races the field should only be read once in this
+    // method.
+    String local = toString;
+    if (local == null) {
+      local = "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
+      toString = local;
+    }
+    return local;
   }
 
-  /**
-   * Gets a key for an injection type and an annotation strategy.
-   */
-  static <T> Key<T> get(Class<T> type,
-      AnnotationStrategy annotationStrategy) {
+  /** Gets a key for an injection type and an annotation strategy. */
+  static <T> Key<T> get(Class<T> type, AnnotationStrategy annotationStrategy) {
     return new Key<T>(type, annotationStrategy);
   }
 
-  /**
-   * Gets a key for an injection type.
-   */
+  /** Gets a key for an injection type. */
   public static <T> Key<T> get(Class<T> type) {
     return new Key<T>(type, NullAnnotationStrategy.INSTANCE);
   }
 
-  /**
-   * Gets a key for an injection type and an annotation type.
-   */
-  public static <T> Key<T> get(Class<T> type,
-      Class<? extends Annotation> annotationType) {
+  /** Gets a key for an injection type and an annotation type. */
+  public static <T> Key<T> get(Class<T> type, Class<? extends Annotation> annotationType) {
     return new Key<T>(type, strategyFor(annotationType));
   }
 
-  /**
-   * Gets a key for an injection type and an annotation.
-   */
+  /** Gets a key for an injection type and an annotation. */
   public static <T> Key<T> get(Class<T> type, Annotation annotation) {
     return new Key<T>(type, strategyFor(annotation));
   }
 
-  /**
-   * Gets a key for an injection type.
-   */
+  /** Gets a key for an injection type. */
   public static Key<?> get(Type type) {
     return new Key<Object>(type, NullAnnotationStrategy.INSTANCE);
   }
 
-  /**
-   * Gets a key for an injection type and an annotation type.
-   */
-  public static Key<?> get(Type type,
-      Class<? extends Annotation> annotationType) {
+  /** Gets a key for an injection type and an annotation type. */
+  public static Key<?> get(Type type, Class<? extends Annotation> annotationType) {
     return new Key<Object>(type, strategyFor(annotationType));
   }
 
-  /**
-   * Gets a key for an injection type and an annotation.
-   */
+  /** Gets a key for an injection type and an annotation. */
   public static Key<?> get(Type type, Annotation annotation) {
     return new Key<Object>(type, strategyFor(annotation));
   }
 
-  /**
-   * Gets a key for an injection type.
-   */
+  /** Gets a key for an injection type. */
   public static <T> Key<T> get(TypeLiteral<T> typeLiteral) {
     return new Key<T>(typeLiteral, NullAnnotationStrategy.INSTANCE);
   }
 
-  /**
-   * Gets a key for an injection type and an annotation type.
-   */
-  public static <T> Key<T> get(TypeLiteral<T> typeLiteral,
-      Class<? extends Annotation> annotationType) {
+  /** Gets a key for an injection type and an annotation type. */
+  public static <T> Key<T> get(
+      TypeLiteral<T> typeLiteral, Class<? extends Annotation> annotationType) {
     return new Key<T>(typeLiteral, strategyFor(annotationType));
   }
 
-  /**
-   * Gets a key for an injection type and an annotation.
-   */
-  public static <T> Key<T> get(TypeLiteral<T> typeLiteral,
-      Annotation annotation) {
+  /** Gets a key for an injection type and an annotation. */
+  public static <T> Key<T> get(TypeLiteral<T> typeLiteral, Annotation annotation) {
     return new Key<T>(typeLiteral, strategyFor(annotation));
   }
 
   /**
-   * Returns a new key of the specified type with the same annotation as this
-   * key.
+   * Returns a new key of the specified type with the same annotation as this key.
    *
    * @since 3.0
    */
@@ -314,8 +265,7 @@
   }
 
   /**
-   * Returns a new key of the specified type with the same annotation as this
-   * key.
+   * Returns a new key of the specified type with the same annotation as this key.
    *
    * @since 3.0
    */
@@ -324,8 +274,7 @@
   }
 
   /**
-   * Returns a new key of the specified type with the same annotation as this
-   * key.
+   * Returns a new key of the specified type with the same annotation as this key.
    *
    * @since 3.0
    */
@@ -343,8 +292,7 @@
   }
 
   /**
-   * Returns this key without annotation attributes, i.e. with only the
-   * annotation type.
+   * Returns this key without annotation attributes, i.e. with only the annotation type.
    *
    * @since 3.0
    */
@@ -354,14 +302,15 @@
 
   interface AnnotationStrategy {
     Annotation getAnnotation();
+
     Class<? extends Annotation> getAnnotationType();
+
     boolean hasAttributes();
+
     AnnotationStrategy withoutAttributes();
   }
 
-  /**
-   * Gets the strategy for an annotation.
-   */
+  /** Gets the strategy for an annotation. */
   static AnnotationStrategy strategyFor(Annotation annotation) {
     checkNotNull(annotation, "annotation");
     Class<? extends Annotation> annotationType = annotation.annotationType();
@@ -375,9 +324,7 @@
     return new AnnotationInstanceStrategy(Annotations.canonicalizeIfNamed(annotation));
   }
 
-  /**
-   * Gets the strategy for an annotation type.
-   */
+  /** Gets the strategy for an annotation type. */
   static AnnotationStrategy strategyFor(Class<? extends Annotation> annotationType) {
     annotationType = Annotations.canonicalizeIfNamed(annotationType);
     if (isAllDefaultMethods(annotationType)) {
@@ -388,18 +335,18 @@
     ensureRetainedAtRuntime(annotationType);
     ensureIsBindingAnnotation(annotationType);
     return new AnnotationTypeStrategy(annotationType, null);
-
   }
 
-  private static void ensureRetainedAtRuntime(
-      Class<? extends Annotation> annotationType) {
-    checkArgument(Annotations.isRetainedAtRuntime(annotationType),
+  private static void ensureRetainedAtRuntime(Class<? extends Annotation> annotationType) {
+    checkArgument(
+        Annotations.isRetainedAtRuntime(annotationType),
         "%s is not retained at runtime. Please annotate it with @Retention(RUNTIME).",
         annotationType.getName());
   }
 
   private static void ensureIsBindingAnnotation(Class<? extends Annotation> annotationType) {
-    checkArgument(Annotations.isBindingAnnotation(annotationType),
+    checkArgument(
+        Annotations.isBindingAnnotation(annotationType),
         "%s is not a binding annotation. Please annotate it with @BindingAnnotation.",
         annotationType.getName());
   }
@@ -407,23 +354,28 @@
   static enum NullAnnotationStrategy implements AnnotationStrategy {
     INSTANCE;
 
+    @Override
     public boolean hasAttributes() {
       return false;
     }
 
+    @Override
     public AnnotationStrategy withoutAttributes() {
       throw new UnsupportedOperationException("Key already has no attributes.");
     }
 
+    @Override
     public Annotation getAnnotation() {
       return null;
     }
 
+    @Override
     public Class<? extends Annotation> getAnnotationType() {
       return null;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "[none]";
     }
   }
@@ -437,23 +389,28 @@
       this.annotation = checkNotNull(annotation, "annotation");
     }
 
+    @Override
     public boolean hasAttributes() {
       return true;
     }
 
+    @Override
     public AnnotationStrategy withoutAttributes() {
       return new AnnotationTypeStrategy(getAnnotationType(), annotation);
     }
 
+    @Override
     public Annotation getAnnotation() {
       return annotation;
     }
 
+    @Override
     public Class<? extends Annotation> getAnnotationType() {
       return annotation.annotationType();
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
       if (!(o instanceof AnnotationInstanceStrategy)) {
         return false;
       }
@@ -462,11 +419,13 @@
       return annotation.equals(other.annotation);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return annotation.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return annotation.toString();
     }
   }
@@ -478,29 +437,33 @@
     // Keep the instance around if we have it so the client can request it.
     final Annotation annotation;
 
-    AnnotationTypeStrategy(Class<? extends Annotation> annotationType,
-        Annotation annotation) {
+    AnnotationTypeStrategy(Class<? extends Annotation> annotationType, Annotation annotation) {
       this.annotationType = checkNotNull(annotationType, "annotation type");
       this.annotation = annotation;
     }
 
+    @Override
     public boolean hasAttributes() {
       return false;
     }
 
+    @Override
     public AnnotationStrategy withoutAttributes() {
       throw new UnsupportedOperationException("Key already has no attributes.");
     }
 
+    @Override
     public Annotation getAnnotation() {
       return annotation;
     }
 
+    @Override
     public Class<? extends Annotation> getAnnotationType() {
       return annotationType;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
       if (!(o instanceof AnnotationTypeStrategy)) {
         return false;
       }
@@ -509,11 +472,13 @@
       return annotationType.equals(other.annotationType);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return annotationType.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "@" + annotationType.getName();
     }
   }
diff --git a/core/src/com/google/inject/MembersInjector.java b/core/src/com/google/inject/MembersInjector.java
index b50dedb..349eb0d 100644
--- a/core/src/com/google/inject/MembersInjector.java
+++ b/core/src/com/google/inject/MembersInjector.java
@@ -21,7 +21,6 @@
  * presence or absence of an injectable constructor.
  *
  * @param <T> type to inject members of
- *
  * @author crazybob@google.com (Bob Lee)
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
diff --git a/core/src/com/google/inject/Module.java b/core/src/com/google/inject/Module.java
index f22d93f..52cdd30 100644
--- a/core/src/com/google/inject/Module.java
+++ b/core/src/com/google/inject/Module.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,18 +17,16 @@
 package com.google.inject;
 
 /**
- * A module contributes configuration information, typically interface
- * bindings, which will be used to create an {@link Injector}. A Guice-based
- * application is ultimately composed of little more than a set of
- * {@code Module}s and some bootstrapping code.
+ * A module contributes configuration information, typically interface bindings, which will be used
+ * to create an {@link Injector}. A Guice-based application is ultimately composed of little more
+ * than a set of {@code Module}s and some bootstrapping code.
  *
- * <p>Your Module classes can use a more streamlined syntax by extending
- * {@link AbstractModule} rather than implementing this interface directly.
+ * <p>Your Module classes can use a more streamlined syntax by extending {@link AbstractModule}
+ * rather than implementing this interface directly.
  *
- * <p>In addition to the bindings configured via {@link #configure}, bindings
- * will be created for all methods annotated with {@literal @}{@link Provides}.
- * Use scope and binding annotations on these methods to configure the
- * bindings.
+ * <p>In addition to the bindings configured via {@link #configure}, bindings will be created for
+ * all methods annotated with {@literal @}{@link Provides}. Use scope and binding annotations on
+ * these methods to configure the bindings.
  */
 public interface Module {
 
diff --git a/core/src/com/google/inject/OutOfScopeException.java b/core/src/com/google/inject/OutOfScopeException.java
index 430fa23..7199b6b 100644
--- a/core/src/com/google/inject/OutOfScopeException.java
+++ b/core/src/com/google/inject/OutOfScopeException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +17,8 @@
 package com.google.inject;
 
 /**
- * Thrown from {@link Provider#get} when an attempt is made to access a scoped
- * object while the scope in question is not currently active.
+ * Thrown from {@link Provider#get} when an attempt is made to access a scoped object while the
+ * scope in question is not currently active.
  *
  * @author kevinb@google.com (Kevin Bourrillion)
  * @since 2.0
diff --git a/core/src/com/google/inject/PrivateBinder.java b/core/src/com/google/inject/PrivateBinder.java
index 21a833f..9e7fcd3 100644
--- a/core/src/com/google/inject/PrivateBinder.java
+++ b/core/src/com/google/inject/PrivateBinder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,7 @@
 /**
  * Returns a binder whose configuration information is hidden from its environment by default. See
  * {@link com.google.inject.PrivateModule PrivateModule} for details.
- * 
+ *
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
  */
@@ -32,8 +32,8 @@
 
   /**
    * Makes a binding for {@code type} available to the enclosing environment. Use {@link
-   * com.google.inject.binder.AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to expose {@code type} with a
-   * binding annotation.
+   * com.google.inject.binder.AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to
+   * expose {@code type} with a binding annotation.
    */
   AnnotatedElementBuilder expose(Class<?> type);
 
@@ -44,7 +44,9 @@
    */
   AnnotatedElementBuilder expose(TypeLiteral<?> type);
 
+  @Override
   PrivateBinder withSource(Object source);
 
+  @Override
   PrivateBinder skipSources(Class... classesToSkip);
 }
diff --git a/core/src/com/google/inject/PrivateModule.java b/core/src/com/google/inject/PrivateModule.java
index ba2f722..e43e1f9 100644
--- a/core/src/com/google/inject/PrivateModule.java
+++ b/core/src/com/google/inject/PrivateModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,7 +27,6 @@
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.TypeListener;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
@@ -37,14 +36,14 @@
  * This module may expose the bindings it creates and the bindings of the modules it installs.
  *
  * <p>A private module can be nested within a regular module or within another private module using
- * {@link Binder#install install()}.  Its bindings live in a new environment that inherits bindings,
- * type converters, scopes, and interceptors from the surrounding ("parent") environment.  When you
+ * {@link Binder#install install()}. Its bindings live in a new environment that inherits bindings,
+ * type converters, scopes, and interceptors from the surrounding ("parent") environment. When you
  * nest multiple private modules, the result is a tree of environments where the injector's
  * environment is the root.
  *
  * <p>Guice EDSL bindings can be exposed with {@link #expose(Class) expose()}. {@literal @}{@link
- * com.google.inject.Provides Provides} bindings can be exposed with the {@literal @}{@link
- * Exposed} annotation:
+ * com.google.inject.Provides Provides} bindings can be exposed with the {@literal @}{@link Exposed}
+ * annotation:
  *
  * <pre>
  * public class FooBarBazModule extends PrivateModule {
@@ -69,7 +68,7 @@
  * <p>Private modules are implemented using {@link Injector#createChildInjector(Module[]) parent
  * injectors}. When it can satisfy their dependencies, just-in-time bindings will be created in the
  * root environment. Such bindings are shared among all environments in the tree.
- * 
+ *
  * <p>The scope of a binding is constrained to its environment. A singleton bound in a private
  * module will be unique to its environment. But a binding for the same type in a different private
  * module will yield a different instance.
@@ -79,6 +78,7 @@
  * gets access to all bindings in the child environment.
  *
  * <p>To promote a just-in-time binding to an explicit binding, bind it:
+ *
  * <pre>
  *   bind(FooImpl.class);
  * </pre>
@@ -91,6 +91,7 @@
   /** Like abstract module, the binder of the current private module */
   private PrivateBinder binder;
 
+  @Override
   public final synchronized void configure(Binder binder) {
     checkState(this.binder == null, "Re-entry is not allowed.");
 
@@ -134,155 +135,120 @@
 
   // everything below is copied from AbstractModule
 
-  /**
-   * Returns the current binder.
-   */
+  /** Returns the current binder. */
   protected final PrivateBinder binder() {
     checkState(binder != null, "The binder can only be used inside configure()");
     return binder;
   }
 
-  /**
-   * @see Binder#bindScope(Class, Scope)
-   */
+  /** @see Binder#bindScope(Class, Scope) */
   protected final void bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope) {
     binder().bindScope(scopeAnnotation, scope);
   }
 
-  /**
-   * @see Binder#bind(Key)
-   */
+  /** @see Binder#bind(Key) */
   protected final <T> LinkedBindingBuilder<T> bind(Key<T> key) {
     return binder().bind(key);
   }
 
-  /**
-   * @see Binder#bind(TypeLiteral)
-   */
+  /** @see Binder#bind(TypeLiteral) */
   protected final <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
     return binder().bind(typeLiteral);
   }
 
-  /**
-   * @see Binder#bind(Class)  
-   */
+  /** @see Binder#bind(Class) */
   protected final <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
     return binder().bind(clazz);
   }
 
-  /**
-   * @see Binder#bindConstant()
-   */
+  /** @see Binder#bindConstant() */
   protected final AnnotatedConstantBindingBuilder bindConstant() {
     return binder().bindConstant();
   }
 
-  /**
-   * @see Binder#install(Module)
-   */
+  /** @see Binder#install(Module) */
   protected final void install(Module module) {
     binder().install(module);
   }
 
-  /**
-   * @see Binder#addError(String, Object[])
-   */
+  /** @see Binder#addError(String, Object[]) */
   protected final void addError(String message, Object... arguments) {
     binder().addError(message, arguments);
   }
 
-  /**
-   * @see Binder#addError(Throwable)
-   */
+  /** @see Binder#addError(Throwable) */
   protected final void addError(Throwable t) {
     binder().addError(t);
   }
 
-  /**
-   * @see Binder#addError(Message)
-   */
+  /** @see Binder#addError(Message) */
   protected final void addError(Message message) {
     binder().addError(message);
   }
 
-  /**
-   * @see Binder#requestInjection(Object)
-   */
+  /** @see Binder#requestInjection(Object) */
   protected final void requestInjection(Object instance) {
     binder().requestInjection(instance);
   }
 
-  /**
-   * @see Binder#requestStaticInjection(Class[])
-   */
+  /** @see Binder#requestStaticInjection(Class[]) */
   protected final void requestStaticInjection(Class<?>... types) {
     binder().requestStaticInjection(types);
   }
 
   /*if[AOP]*/
   /**
-   * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher, com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
+   * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
+   *     com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
    */
-  protected final void bindInterceptor(Matcher<? super Class<?>> classMatcher,
+  protected final void bindInterceptor(
+      Matcher<? super Class<?>> classMatcher,
       Matcher<? super Method> methodMatcher,
       org.aopalliance.intercept.MethodInterceptor... interceptors) {
     binder().bindInterceptor(classMatcher, methodMatcher, interceptors);
   }
   /*end[AOP]*/
 
-  /**
-   * Instructs Guice to require a binding to the given key.
-   */
+  /** Instructs Guice to require a binding to the given key. */
   protected final void requireBinding(Key<?> key) {
     binder().getProvider(key);
   }
 
-  /**
-   * Instructs Guice to require a binding to the given type.
-   */
+  /** Instructs Guice to require a binding to the given type. */
   protected final void requireBinding(Class<?> type) {
     binder().getProvider(type);
   }
 
-  /**
-   * @see Binder#getProvider(Key)
-   */
+  /** @see Binder#getProvider(Key) */
   protected final <T> Provider<T> getProvider(Key<T> key) {
     return binder().getProvider(key);
   }
-  
-  /**
-   * @see Binder#getProvider(Class)
-   */
+
+  /** @see Binder#getProvider(Class) */
   protected final <T> Provider<T> getProvider(Class<T> type) {
     return binder().getProvider(type);
   }
 
   /**
-   * @see Binder#convertToTypes(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeConverter)
+   * @see Binder#convertToTypes(com.google.inject.matcher.Matcher,
+   *     com.google.inject.spi.TypeConverter)
    */
-  protected final void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeConverter converter) {
+  protected final void convertToTypes(
+      Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
     binder().convertToTypes(typeMatcher, converter);
   }
 
-  /**
-   * @see Binder#currentStage()
-   */
+  /** @see Binder#currentStage() */
   protected final Stage currentStage() {
     return binder().currentStage();
   }
 
-  /**
-   * @see Binder#getMembersInjector(Class)
-   */
+  /** @see Binder#getMembersInjector(Class) */
   protected <T> MembersInjector<T> getMembersInjector(Class<T> type) {
     return binder().getMembersInjector(type);
   }
 
-  /**
-   * @see Binder#getMembersInjector(TypeLiteral)
-   */
+  /** @see Binder#getMembersInjector(TypeLiteral) */
   protected <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> type) {
     return binder().getMembersInjector(type);
   }
@@ -290,17 +256,16 @@
   /**
    * @see Binder#bindListener(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeListener)
    */
-  protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeListener listener) {
+  protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
     binder().bindListener(typeMatcher, listener);
   }
-  
+
   /**
    * @see Binder#bindListener(Matcher, ProvisionListener...)
    * @since 4.0
    */
-  protected void bindListener(Matcher<? super Binding<?>> bindingMatcher,
-      ProvisionListener... listeners) {
+  protected void bindListener(
+      Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listeners) {
     binder().bindListener(bindingMatcher, listeners);
   }
 }
diff --git a/core/src/com/google/inject/ProvidedBy.java b/core/src/com/google/inject/ProvidedBy.java
index 7ad12f7..bb92431 100644
--- a/core/src/com/google/inject/ProvidedBy.java
+++ b/core/src/com/google/inject/ProvidedBy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,8 +31,6 @@
 @Target(TYPE)
 public @interface ProvidedBy {
 
-  /**
-   * The implementation type.
-   */
-  Class<? extends Provider<?>> value();
+  /** The implementation type. */
+  Class<? extends javax.inject.Provider<?>> value();
 }
diff --git a/core/src/com/google/inject/Provider.java b/core/src/com/google/inject/Provider.java
index 3295a2b..4ce1e31 100644
--- a/core/src/com/google/inject/Provider.java
+++ b/core/src/com/google/inject/Provider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,35 +22,32 @@
  *
  * <ul>
  * <li>When the default means for obtaining instances (an injectable or parameterless constructor)
- * is insufficient for a particular binding, the module can specify a custom {@code Provider}
- * instead, to control exactly how Guice creates or obtains instances for the binding.
- *
+ *     is insufficient for a particular binding, the module can specify a custom {@code Provider}
+ *     instead, to control exactly how Guice creates or obtains instances for the binding.
  * <li>An implementation class may always choose to have a {@code Provider<T>} instance injected,
- * rather than having a {@code T} injected directly.  This may give you access to multiple
- * instances, instances you wish to safely mutate and discard, instances which are out of scope
- * (e.g. using a {@code @RequestScoped} object from within a {@code @SessionScoped} object), or
- * instances that will be initialized lazily.
- *
+ *     rather than having a {@code T} injected directly. This may give you access to multiple
+ *     instances, instances you wish to safely mutate and discard, instances which are out of scope
+ *     (e.g. using a {@code @RequestScoped} object from within a {@code @SessionScoped} object), or
+ *     instances that will be initialized lazily.
  * <li>A custom {@link Scope} is implemented as a decorator of {@code Provider<T>}, which decides
- * when to delegate to the backing provider and when to provide the instance some other way.
- *
- * <li>The {@link Injector} offers access to the {@code Provider<T>} it uses to fulfill requests
- * for a given key, via the {@link Injector#getProvider} methods.
+ *     when to delegate to the backing provider and when to provide the instance some other way.
+ * <li>The {@link Injector} offers access to the {@code Provider<T>} it uses to fulfill requests for
+ *     a given key, via the {@link Injector#getProvider} methods.
  * </ul>
  *
  * @param <T> the type of object this provides
- *
  * @author crazybob@google.com (Bob Lee)
  */
 public interface Provider<T> extends javax.inject.Provider<T> {
 
   /**
-   * Provides an instance of {@code T}. Must never return {@code null}.
+   * Provides an instance of {@code T}.
    *
    * @throws OutOfScopeException when an attempt is made to access a scoped object while the scope
    *     in question is not currently active
    * @throws ProvisionException if an instance cannot be provided. Such exceptions include messages
    *     and throwables to describe why provision failed.
    */
+  @Override
   T get();
 }
diff --git a/core/src/com/google/inject/Provides.java b/core/src/com/google/inject/Provides.java
index c66a428..ba8f72b 100644
--- a/core/src/com/google/inject/Provides.java
+++ b/core/src/com/google/inject/Provides.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,5 +30,7 @@
  * @author crazybob@google.com (Bob Lee)
  * @since 2.0
  */
-@Documented @Target(METHOD) @Retention(RUNTIME)
+@Documented
+@Target(METHOD)
+@Retention(RUNTIME)
 public @interface Provides {}
diff --git a/core/src/com/google/inject/ProvisionException.java b/core/src/com/google/inject/ProvisionException.java
index 3c590b9..0c132c5 100644
--- a/core/src/com/google/inject/ProvisionException.java
+++ b/core/src/com/google/inject/ProvisionException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,14 +19,14 @@
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.inject.internal.Errors;
+import com.google.inject.internal.Messages;
 import com.google.inject.spi.Message;
-
 import java.util.Collection;
 
 /**
  * Indicates that there was a runtime failure while providing an instance.
  *
+ *
  * @author kevinb@google.com (Kevin Bourrillion)
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
@@ -39,7 +39,7 @@
   public ProvisionException(Iterable<Message> messages) {
     this.messages = ImmutableSet.copyOf(messages);
     checkArgument(!this.messages.isEmpty());
-    initCause(Errors.getOnlyCause(this.messages));
+    initCause(Messages.getOnlyCause(this.messages));
   }
 
   public ProvisionException(String message, Throwable cause) {
@@ -56,8 +56,9 @@
     return messages;
   }
 
-  @Override public String getMessage() {
-    return Errors.format("Unable to provision, see the following errors", messages);
+  @Override
+  public String getMessage() {
+    return Messages.formatMessages("Unable to provision, see the following errors", messages);
   }
 
   private static final long serialVersionUID = 0;
diff --git a/core/src/com/google/inject/Scope.java b/core/src/com/google/inject/Scope.java
index 949270c..331d9c3 100644
--- a/core/src/com/google/inject/Scope.java
+++ b/core/src/com/google/inject/Scope.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,13 +17,11 @@
 package com.google.inject;
 
 /**
- * A scope is a level of visibility that instances provided by Guice may have.
- * By default, an instance created by the {@link Injector} has <i>no scope</i>,
- * meaning it has no state from the framework's perspective -- the
- * {@code Injector} creates it, injects it once into the class that required it,
- * and then immediately forgets it. Associating a scope with a particular
- * binding allows the created instance to be "remembered" and possibly used
- * again for other injections.
+ * A scope is a level of visibility that instances provided by Guice may have. By default, an
+ * instance created by the {@link Injector} has <i>no scope</i>, meaning it has no state from the
+ * framework's perspective -- the {@code Injector} creates it, injects it once into the class that
+ * required it, and then immediately forgets it. Associating a scope with a particular binding
+ * allows the created instance to be "remembered" and possibly used again for other injections.
  *
  * <p>An example of a scope is {@link Scopes#SINGLETON}.
  *
@@ -32,28 +30,24 @@
 public interface Scope {
 
   /**
-   * Scopes a provider. The returned provider returns objects from this scope.
-   * If an object does not exist in this scope, the provider can use the given
-   * unscoped provider to retrieve one.
+   * Scopes a provider. The returned provider returns objects from this scope. If an object does not
+   * exist in this scope, the provider can use the given unscoped provider to retrieve one.
    *
-   * <p>Scope implementations are strongly encouraged to override
-   * {@link Object#toString} in the returned provider and include the backing
-   * provider's {@code toString()} output.
+   * <p>Scope implementations are strongly encouraged to override {@link Object#toString} in the
+   * returned provider and include the backing provider's {@code toString()} output.
    *
    * @param key binding key
-   * @param unscoped locates an instance when one doesn't already exist in this
-   *  scope.
-   * @return a new provider which only delegates to the given unscoped provider
-   *  when an instance of the requested object doesn't already exist in this
-   *  scope
+   * @param unscoped locates an instance when one doesn't already exist in this scope.
+   * @return a new provider which only delegates to the given unscoped provider when an instance of
+   *     the requested object doesn't already exist in this scope
    */
   public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped);
 
   /**
-   * A short but useful description of this scope.  For comparison, the standard
-   * scopes that ship with guice use the descriptions
-   * {@code "Scopes.SINGLETON"}, {@code "ServletScopes.SESSION"} and
+   * A short but useful description of this scope. For comparison, the standard scopes that ship
+   * with guice use the descriptions {@code "Scopes.SINGLETON"}, {@code "ServletScopes.SESSION"} and
    * {@code "ServletScopes.REQUEST"}.
    */
+  @Override
   String toString();
 }
diff --git a/core/src/com/google/inject/ScopeAnnotation.java b/core/src/com/google/inject/ScopeAnnotation.java
index 8f869a0..c0b651a 100644
--- a/core/src/com/google/inject/ScopeAnnotation.java
+++ b/core/src/com/google/inject/ScopeAnnotation.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,9 +23,9 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotates annotations which are used for scoping. Only one such annotation
- * may apply to a single implementation class. You must also annotate scope
- * annotations with {@code @Retention(RUNTIME)}. For example:
+ * Annotates annotations which are used for scoping. Only one such annotation may apply to a single
+ * implementation class. You must also annotate scope annotations with {@code @Retention(RUNTIME)}.
+ * For example:
  *
  * <pre>
  *   {@code @}Retention(RUNTIME)
diff --git a/core/src/com/google/inject/Scopes.java b/core/src/com/google/inject/Scopes.java
index 6c893e5..20be102 100644
--- a/core/src/com/google/inject/Scopes.java
+++ b/core/src/com/google/inject/Scopes.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
 import com.google.inject.internal.SingletonScope;
 import com.google.inject.spi.BindingScopingVisitor;
 import com.google.inject.spi.ExposedBinding;
-
 import java.lang.annotation.Annotation;
 
 /**
@@ -33,47 +32,51 @@
 
   private Scopes() {}
 
-  /**
-   * One instance per {@link Injector}. Also see {@code @}{@link Singleton}.
-   */
+  /** One instance per {@link Injector}. Also see {@code @}{@link Singleton}. */
   public static final Scope SINGLETON = new SingletonScope();
 
   /**
-   * No scope; the same as not applying any scope at all.  Each time the
-   * Injector obtains an instance of an object with "no scope", it injects this
-   * instance then immediately forgets it.  When the next request for the same
-   * binding arrives it will need to obtain the instance over again.
+   * No scope; the same as not applying any scope at all. Each time the Injector obtains an instance
+   * of an object with "no scope", it injects this instance then immediately forgets it. When the
+   * next request for the same binding arrives it will need to obtain the instance over again.
    *
-   * <p>This exists only in case a class has been annotated with a scope
-   * annotation such as {@link Singleton @Singleton}, and you need to override
-   * this to "no scope" in your binding.
+   * <p>This exists only in case a class has been annotated with a scope annotation such as {@link
+   * Singleton @Singleton}, and you need to override this to "no scope" in your binding.
    *
    * @since 2.0
    */
-  public static final Scope NO_SCOPE = new Scope() {
-    public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
-      return unscoped;
-    }
-    @Override public String toString() {
-      return "Scopes.NO_SCOPE";
-    }
-  };
+  public static final Scope NO_SCOPE =
+      new Scope() {
+        @Override
+        public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
+          return unscoped;
+        }
 
-  private static final BindingScopingVisitor<Boolean> IS_SINGLETON_VISITOR
-      = new BindingScopingVisitor<Boolean>() {
+        @Override
+        public String toString() {
+          return "Scopes.NO_SCOPE";
+        }
+      };
+
+  private static final BindingScopingVisitor<Boolean> IS_SINGLETON_VISITOR =
+      new BindingScopingVisitor<Boolean>() {
+        @Override
         public Boolean visitNoScoping() {
           return false;
         }
 
+        @Override
         public Boolean visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
           return scopeAnnotation == Singleton.class
               || scopeAnnotation == javax.inject.Singleton.class;
         }
 
+        @Override
         public Boolean visitScope(Scope scope) {
           return scope == Scopes.SINGLETON;
         }
 
+        @Override
         public Boolean visitEagerSingleton() {
           return true;
         }
@@ -101,8 +104,8 @@
           binding = injector.getBinding(linkedBinding.getLinkedKey());
           continue;
         }
-      } else if(binding instanceof ExposedBinding) {
-        ExposedBinding<?> exposedBinding = (ExposedBinding)binding;
+      } else if (binding instanceof ExposedBinding) {
+        ExposedBinding<?> exposedBinding = (ExposedBinding) binding;
         Injector injector = exposedBinding.getPrivateElements().getInjector();
         if (injector != null) {
           binding = injector.getBinding(exposedBinding.getKey());
@@ -115,7 +118,6 @@
   }
 
   /**
-
    * Returns true if {@code binding} has the given scope. If the binding is a {@link
    * com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (ie. it
    * was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will
@@ -126,26 +128,32 @@
    * @param scopeAnnotation scope annotation class
    * @since 4.0
    */
-  public static boolean isScoped(Binding<?> binding, final Scope scope,
-      final Class<? extends Annotation> scopeAnnotation) {
+  public static boolean isScoped(
+      Binding<?> binding, final Scope scope, final Class<? extends Annotation> scopeAnnotation) {
     do {
-      boolean matches = binding.acceptScopingVisitor(new BindingScopingVisitor<Boolean>() {
-        public Boolean visitNoScoping() {
-          return false;
-        }
+      boolean matches =
+          binding.acceptScopingVisitor(
+              new BindingScopingVisitor<Boolean>() {
+                @Override
+                public Boolean visitNoScoping() {
+                  return false;
+                }
 
-        public Boolean visitScopeAnnotation(Class<? extends Annotation> visitedAnnotation) {
-          return visitedAnnotation == scopeAnnotation;
-        }
+                @Override
+                public Boolean visitScopeAnnotation(Class<? extends Annotation> visitedAnnotation) {
+                  return visitedAnnotation == scopeAnnotation;
+                }
 
-        public Boolean visitScope(Scope visitedScope) {
-          return visitedScope == scope;
-        }
+                @Override
+                public Boolean visitScope(Scope visitedScope) {
+                  return visitedScope == scope;
+                }
 
-        public Boolean visitEagerSingleton() {
-          return false;
-        }
-      });
+                @Override
+                public Boolean visitEagerSingleton() {
+                  return false;
+                }
+              });
 
       if (matches) {
         return true;
@@ -158,8 +166,8 @@
           binding = injector.getBinding(linkedBinding.getLinkedKey());
           continue;
         }
-      } else if(binding instanceof ExposedBinding) {
-        ExposedBinding<?> exposedBinding = (ExposedBinding)binding;
+      } else if (binding instanceof ExposedBinding) {
+        ExposedBinding<?> exposedBinding = (ExposedBinding) binding;
         Injector injector = exposedBinding.getPrivateElements().getInjector();
         if (injector != null) {
           binding = injector.getBinding(exposedBinding.getKey());
@@ -172,12 +180,11 @@
   }
 
   /**
-   * Returns true if the object is a proxy for a circular dependency,
-   * constructed by Guice because it encountered a circular dependency. Scope
-   * implementations should be careful to <b>not cache circular proxies</b>,
-   * because the proxies are not intended for general purpose use. (They are
-   * designed just to fulfill the immediate injection, not all injections.
-   * Caching them can lead to IllegalArgumentExceptions or ClassCastExceptions.)
+   * Returns true if the object is a proxy for a circular dependency, constructed by Guice because
+   * it encountered a circular dependency. Scope implementations should be careful to <b>not cache
+   * circular proxies</b>, because the proxies are not intended for general purpose use. (They are
+   * designed just to fulfill the immediate injection, not all injections. Caching them can lead to
+   * IllegalArgumentExceptions or ClassCastExceptions.)
    *
    * @since 4.0
    */
diff --git a/core/src/com/google/inject/Singleton.java b/core/src/com/google/inject/Singleton.java
index 0ea9a14..59a2b44 100644
--- a/core/src/com/google/inject/Singleton.java
+++ b/core/src/com/google/inject/Singleton.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,12 +23,12 @@
 import java.lang.annotation.Target;
 
 /**
- * Apply this to implementation classes when you want only one instance
- * (per {@link Injector}) to be reused for all injections for that binding.
+ * Apply this to implementation classes when you want only one instance (per {@link Injector}) to be
+ * reused for all injections for that binding.
  *
  * @author crazybob@google.com (Bob Lee)
  */
-@Target({ ElementType.TYPE, ElementType.METHOD })
+@Target({ElementType.TYPE, ElementType.METHOD})
 @Retention(RUNTIME)
 @ScopeAnnotation
 public @interface Singleton {}
diff --git a/core/src/com/google/inject/Stage.java b/core/src/com/google/inject/Stage.java
index f9b4e35..19f256e 100644
--- a/core/src/com/google/inject/Stage.java
+++ b/core/src/com/google/inject/Stage.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,8 +26,8 @@
   /**
    * We're running in a tool (an IDE plugin for example). We need binding meta data but not a
    * functioning Injector. Do not inject members of instances. Do not load eager singletons. Do as
-   * little as possible so our tools run nice and snappy. Injectors created in this stage cannot
-   * be used to satisfy injections.
+   * little as possible so our tools run nice and snappy. Injectors created in this stage cannot be
+   * used to satisfy injections.
    */
   TOOL,
 
@@ -37,8 +37,6 @@
    */
   DEVELOPMENT,
 
-  /**
-   * We want to catch errors as early as possible and take performance hits up front.
-   */
+  /** We want to catch errors as early as possible and take performance hits up front. */
   PRODUCTION
 }
diff --git a/core/src/com/google/inject/TypeLiteral.java b/core/src/com/google/inject/TypeLiteral.java
index d18087d..0f928da 100644
--- a/core/src/com/google/inject/TypeLiteral.java
+++ b/core/src/com/google/inject/TypeLiteral.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.common.collect.ImmutableList;
 import com.google.inject.internal.MoreTypes;
 import com.google.inject.util.Types;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
@@ -36,26 +35,25 @@
 import java.util.List;
 
 /**
- * Represents a generic type {@code T}. Java doesn't yet provide a way to
- * represent generic types, so this class does. Forces clients to create a
- * subclass of this class which enables retrieval the type information even at
- * runtime.
+ * Represents a generic type {@code T}. Java doesn't yet provide a way to represent generic types,
+ * so this class does. Forces clients to create a subclass of this class which enables retrieval of
+ * the type information even at runtime.
  *
- * <p>For example, to create a type literal for {@code List<String>}, you can
- * create an empty anonymous inner class:
+ * <p>For example, to create a type literal for {@code List<String>}, you can create an empty
+ * anonymous inner class:
  *
- * <p>
- * {@code TypeLiteral<List<String>> list = new TypeLiteral<List<String>>() {};}
+ * <p>{@code TypeLiteral<List<String>> list = new TypeLiteral<List<String>>() {};}
  *
- * <p>Along with modeling generic types, this class can resolve type parameters.
- * For example, to figure out what type {@code keySet()} returns on a {@code
- * Map<Integer, String>}, use this code:<pre>   {@code
+ * <p>Along with modeling generic types, this class can resolve type parameters. For example, to
+ * figure out what type {@code keySet()} returns on a {@code Map<Integer, String>}, use this code:
  *
- *   TypeLiteral<Map<Integer, String>> mapType
- *       = new TypeLiteral<Map<Integer, String>>() {};
- *   TypeLiteral<?> keySetType
- *       = mapType.getReturnType(Map.class.getMethod("keySet"));
- *   System.out.println(keySetType); // prints "Set<Integer>"}</pre>
+ * <pre>{@code
+ * TypeLiteral<Map<Integer, String>> mapType
+ *     = new TypeLiteral<Map<Integer, String>>() {};
+ * TypeLiteral<?> keySetType
+ *     = mapType.getReturnType(Map.class.getMethod("keySet"));
+ * System.out.println(keySetType); // prints "Set<Integer>"
+ * }</pre>
  *
  * @author crazybob@google.com (Bob Lee)
  * @author jessewilson@google.com (Jesse Wilson)
@@ -67,12 +65,10 @@
   final int hashCode;
 
   /**
-   * Constructs a new type literal. Derives represented class from type
-   * parameter.
+   * Constructs a new type literal. Derives represented class from type parameter.
    *
-   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
-   * parameter in the anonymous class's type hierarchy so we can reconstitute it
-   * at runtime despite erasure.
+   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
+   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
    */
   @SuppressWarnings("unchecked")
   protected TypeLiteral() {
@@ -81,9 +77,7 @@
     this.hashCode = type.hashCode();
   }
 
-  /**
-   * Unsafe. Constructs a type literal manually.
-   */
+  /** Unsafe. Constructs a type literal manually. */
   @SuppressWarnings("unchecked")
   TypeLiteral(Type type) {
     this.type = canonicalize(checkNotNull(type, "type"));
@@ -104,32 +98,26 @@
     return canonicalize(parameterized.getActualTypeArguments()[0]);
   }
 
-  /**
-   * Gets type literal from super class's type parameter.
-   */
+  /** Gets type literal from super class's type parameter. */
   static TypeLiteral<?> fromSuperclassTypeParameter(Class<?> subclass) {
     return new TypeLiteral<Object>(getSuperclassTypeParameter(subclass));
   }
 
   /**
    * Returns the raw (non-generic) type for this type.
-   * 
+   *
    * @since 2.0
    */
   public final Class<? super T> getRawType() {
     return rawType;
   }
 
-  /**
-   * Gets underlying {@code Type} instance.
-   */
+  /** Gets underlying {@code Type} instance. */
   public final Type getType() {
     return type;
   }
 
-  /**
-   * Gets the type of this type's provider.
-   */
+  /** Gets the type of this type's provider. */
   @SuppressWarnings("unchecked")
   final TypeLiteral<Provider<T>> providerType() {
     // This cast is safe and wouldn't generate a warning if Type had a type
@@ -137,34 +125,31 @@
     return (TypeLiteral<Provider<T>>) get(Types.providerOf(getType()));
   }
 
-  @Override public final int hashCode() {
+  @Override
+  public final int hashCode() {
     return this.hashCode;
   }
 
-  @Override public final boolean equals(Object o) {
-    return o instanceof TypeLiteral<?>
-        && MoreTypes.equals(type, ((TypeLiteral) o).type);
+  @Override
+  public final boolean equals(Object o) {
+    return o instanceof TypeLiteral<?> && MoreTypes.equals(type, ((TypeLiteral) o).type);
   }
 
-  @Override public final String toString() {
+  @Override
+  public final String toString() {
     return MoreTypes.typeToString(type);
   }
 
-  /**
-   * Gets type literal for the given {@code Type} instance.
-   */
+  /** Gets type literal for the given {@code Type} instance. */
   public static TypeLiteral<?> get(Type type) {
     return new TypeLiteral<Object>(type);
   }
 
-  /**
-   * Gets type literal for the given {@code Class} instance.
-   */
+  /** Gets type literal for the given {@code Class} instance. */
   public static <T> TypeLiteral<T> get(Class<T> type) {
     return new TypeLiteral<T>(type);
   }
 
-
   /** Returns an immutable list of the resolved types. */
   private List<TypeLiteral<?>> resolveAll(Type[] types) {
     TypeLiteral<?>[] result = new TypeLiteral<?>[types.length];
@@ -174,9 +159,7 @@
     return ImmutableList.copyOf(result);
   }
 
-  /**
-   * Resolves known type parameters in {@code toResolve} and returns the result.
-   */
+  /** Resolves known type parameters in {@code toResolve} and returns the result. */
   TypeLiteral<?> resolve(Type toResolve) {
     return TypeLiteral.get(resolveType(toResolve));
   }
@@ -195,9 +178,7 @@
         GenericArrayType original = (GenericArrayType) toResolve;
         Type componentType = original.getGenericComponentType();
         Type newComponentType = resolveType(componentType);
-        return componentType == newComponentType
-            ? original
-            : Types.arrayOf(newComponentType);
+        return componentType == newComponentType ? original : Types.arrayOf(newComponentType);
 
       } else if (toResolve instanceof ParameterizedType) {
         ParameterizedType original = (ParameterizedType) toResolve;
@@ -254,8 +235,8 @@
    * @since 2.0
    */
   public TypeLiteral<?> getSupertype(Class<?> supertype) {
-    checkArgument(supertype.isAssignableFrom(rawType),
-        "%s is not a supertype of %s", supertype, this.type);
+    checkArgument(
+        supertype.isAssignableFrom(rawType), "%s is not a supertype of %s", supertype, this.type);
     return resolve(MoreTypes.getGenericSupertype(type, rawType, supertype));
   }
 
@@ -266,8 +247,11 @@
    * @since 2.0
    */
   public TypeLiteral<?> getFieldType(Field field) {
-    checkArgument(field.getDeclaringClass().isAssignableFrom(rawType),
-        "%s is not defined by a supertype of %s", field, type);
+    checkArgument(
+        field.getDeclaringClass().isAssignableFrom(rawType),
+        "%s is not defined by a supertype of %s",
+        field,
+        type);
     return resolve(field.getGenericType());
   }
 
@@ -282,14 +266,20 @@
 
     if (methodOrConstructor instanceof Method) {
       Method method = (Method) methodOrConstructor;
-      checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
-          "%s is not defined by a supertype of %s", method, type);
+      checkArgument(
+          method.getDeclaringClass().isAssignableFrom(rawType),
+          "%s is not defined by a supertype of %s",
+          method,
+          type);
       genericParameterTypes = method.getGenericParameterTypes();
 
     } else if (methodOrConstructor instanceof Constructor) {
       Constructor<?> constructor = (Constructor<?>) methodOrConstructor;
-      checkArgument(constructor.getDeclaringClass().isAssignableFrom(rawType),
-          "%s does not construct a supertype of %s", constructor, type);
+      checkArgument(
+          constructor.getDeclaringClass().isAssignableFrom(rawType),
+          "%s does not construct a supertype of %s",
+          constructor,
+          type);
       genericParameterTypes = constructor.getGenericParameterTypes();
 
     } else {
@@ -310,14 +300,20 @@
 
     if (methodOrConstructor instanceof Method) {
       Method method = (Method) methodOrConstructor;
-      checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
-          "%s is not defined by a supertype of %s", method, type);
+      checkArgument(
+          method.getDeclaringClass().isAssignableFrom(rawType),
+          "%s is not defined by a supertype of %s",
+          method,
+          type);
       genericExceptionTypes = method.getGenericExceptionTypes();
 
     } else if (methodOrConstructor instanceof Constructor) {
       Constructor<?> constructor = (Constructor<?>) methodOrConstructor;
-      checkArgument(constructor.getDeclaringClass().isAssignableFrom(rawType),
-          "%s does not construct a supertype of %s", constructor, type);
+      checkArgument(
+          constructor.getDeclaringClass().isAssignableFrom(rawType),
+          "%s does not construct a supertype of %s",
+          constructor,
+          type);
       genericExceptionTypes = constructor.getGenericExceptionTypes();
 
     } else {
@@ -334,8 +330,11 @@
    * @since 2.0
    */
   public TypeLiteral<?> getReturnType(Method method) {
-    checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
-        "%s is not defined by a supertype of %s", method, type);
+    checkArgument(
+        method.getDeclaringClass().isAssignableFrom(rawType),
+        "%s is not defined by a supertype of %s",
+        method,
+        type);
     return resolve(method.getGenericReturnType());
   }
 }
diff --git a/core/src/com/google/inject/binder/AnnotatedBindingBuilder.java b/core/src/com/google/inject/binder/AnnotatedBindingBuilder.java
index 5b430c3..62ac3d4 100644
--- a/core/src/com/google/inject/binder/AnnotatedBindingBuilder.java
+++ b/core/src/com/google/inject/binder/AnnotatedBindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,14 +25,9 @@
  */
 public interface AnnotatedBindingBuilder<T> extends LinkedBindingBuilder<T> {
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
-  LinkedBindingBuilder<T> annotatedWith(
-      Class<? extends Annotation> annotationType);
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
+  LinkedBindingBuilder<T> annotatedWith(Class<? extends Annotation> annotationType);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   LinkedBindingBuilder<T> annotatedWith(Annotation annotation);
 }
diff --git a/core/src/com/google/inject/binder/AnnotatedConstantBindingBuilder.java b/core/src/com/google/inject/binder/AnnotatedConstantBindingBuilder.java
index 417027f..fa57d78 100644
--- a/core/src/com/google/inject/binder/AnnotatedConstantBindingBuilder.java
+++ b/core/src/com/google/inject/binder/AnnotatedConstantBindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,14 +25,9 @@
  */
 public interface AnnotatedConstantBindingBuilder {
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
-  ConstantBindingBuilder annotatedWith(
-      Class<? extends Annotation> annotationType);
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
+  ConstantBindingBuilder annotatedWith(Class<? extends Annotation> annotationType);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   ConstantBindingBuilder annotatedWith(Annotation annotation);
 }
diff --git a/core/src/com/google/inject/binder/AnnotatedElementBuilder.java b/core/src/com/google/inject/binder/AnnotatedElementBuilder.java
index f6feddf..04b2281 100644
--- a/core/src/com/google/inject/binder/AnnotatedElementBuilder.java
+++ b/core/src/com/google/inject/binder/AnnotatedElementBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,13 +26,9 @@
  */
 public interface AnnotatedElementBuilder {
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   void annotatedWith(Class<? extends Annotation> annotationType);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   void annotatedWith(Annotation annotation);
 }
diff --git a/core/src/com/google/inject/binder/ConstantBindingBuilder.java b/core/src/com/google/inject/binder/ConstantBindingBuilder.java
index 7ddbcf9..cf1274b 100644
--- a/core/src/com/google/inject/binder/ConstantBindingBuilder.java
+++ b/core/src/com/google/inject/binder/ConstantBindingBuilder.java
@@ -16,65 +16,43 @@
 
 package com.google.inject.binder;
 
-/**
- * Binds to a constant value.
- */
+/** Binds to a constant value. */
 public interface ConstantBindingBuilder {
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(String value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(int value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(long value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(boolean value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(double value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(float value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(short value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(char value);
 
   /**
    * Binds constant to the given value.
-   * 
+   *
    * @since 3.0
    */
   void to(byte value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   void to(Class<?> value);
 
-  /**
-   * Binds constant to the given value.
-   */
+  /** Binds constant to the given value. */
   <E extends Enum<E>> void to(E value);
 }
diff --git a/core/src/com/google/inject/binder/LinkedBindingBuilder.java b/core/src/com/google/inject/binder/LinkedBindingBuilder.java
index 99ea185..219e145 100644
--- a/core/src/com/google/inject/binder/LinkedBindingBuilder.java
+++ b/core/src/com/google/inject/binder/LinkedBindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,6 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
-
 import java.lang.reflect.Constructor;
 
 /**
@@ -29,19 +28,13 @@
  */
 public interface LinkedBindingBuilder<T> extends ScopedBindingBuilder {
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   ScopedBindingBuilder to(Class<? extends T> implementation);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   ScopedBindingBuilder to(TypeLiteral<? extends T> implementation);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   ScopedBindingBuilder to(Key<? extends T> targetKey);
 
   /**
@@ -57,7 +50,7 @@
    * @see com.google.inject.Injector#injectMembers
    */
   ScopedBindingBuilder toProvider(Provider<? extends T> provider);
-  
+
   /**
    * See the EDSL examples at {@link com.google.inject.Binder}.
    *
@@ -66,34 +59,26 @@
    */
   ScopedBindingBuilder toProvider(javax.inject.Provider<? extends T> provider);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
-  ScopedBindingBuilder toProvider(
-      Class<? extends javax.inject.Provider<? extends T>> providerType);
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
+  ScopedBindingBuilder toProvider(Class<? extends javax.inject.Provider<? extends T>> providerType);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   ScopedBindingBuilder toProvider(
       TypeLiteral<? extends javax.inject.Provider<? extends T>> providerType);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
-  ScopedBindingBuilder toProvider(
-      Key<? extends javax.inject.Provider<? extends T>> providerKey);
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
+  ScopedBindingBuilder toProvider(Key<? extends javax.inject.Provider<? extends T>> providerKey);
 
   /**
    * See the EDSL examples at {@link com.google.inject.Binder}.
-   * 
+   *
    * @since 3.0
    */
   <S extends T> ScopedBindingBuilder toConstructor(Constructor<S> constructor);
 
   /**
    * See the EDSL examples at {@link com.google.inject.Binder}.
-   * 
+   *
    * @since 3.0
    */
   <S extends T> ScopedBindingBuilder toConstructor(
diff --git a/core/src/com/google/inject/binder/ScopedBindingBuilder.java b/core/src/com/google/inject/binder/ScopedBindingBuilder.java
index ceb8497..e907362 100644
--- a/core/src/com/google/inject/binder/ScopedBindingBuilder.java
+++ b/core/src/com/google/inject/binder/ScopedBindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.binder;
 
 import com.google.inject.Scope;
-
 import java.lang.annotation.Annotation;
 
 /**
@@ -27,20 +26,15 @@
  */
 public interface ScopedBindingBuilder {
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   void in(Class<? extends Annotation> scopeAnnotation);
 
-  /**
-   * See the EDSL examples at {@link com.google.inject.Binder}.
-   */
+  /** See the EDSL examples at {@link com.google.inject.Binder}. */
   void in(Scope scope);
 
   /**
-   * Instructs the {@link com.google.inject.Injector} to eagerly initialize this
-   * singleton-scoped binding upon creation. Useful for application
-   * initialization logic.  See the EDSL examples at
+   * Instructs the {@link com.google.inject.Injector} to eagerly initialize this singleton-scoped
+   * binding upon creation. Useful for application initialization logic. See the EDSL examples at
    * {@link com.google.inject.Binder}.
    */
   void asEagerSingleton();
diff --git a/core/src/com/google/inject/binder/package-info.java b/core/src/com/google/inject/binder/package-info.java
index 57ed875..14e701f 100644
--- a/core/src/com/google/inject/binder/package-info.java
+++ b/core/src/com/google/inject/binder/package-info.java
@@ -14,8 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Interfaces which make up {@link com.google.inject.Binder}'s
- * expression language.
- */
-package com.google.inject.binder;
\ No newline at end of file
+/** Interfaces which make up {@link com.google.inject.Binder}'s expression language. */
+package com.google.inject.binder;
diff --git a/core/src/com/google/inject/internal/AbstractBindingBuilder.java b/core/src/com/google/inject/internal/AbstractBindingBuilder.java
index e803b75..6eb07e7 100644
--- a/core/src/com/google/inject/internal/AbstractBindingBuilder.java
+++ b/core/src/com/google/inject/internal/AbstractBindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.Scope;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.InstanceBinding;
-
 import java.lang.annotation.Annotation;
 import java.util.List;
 
@@ -35,14 +34,15 @@
 public abstract class AbstractBindingBuilder<T> {
 
   public static final String IMPLEMENTATION_ALREADY_SET = "Implementation is set more than once.";
-  public static final String SINGLE_INSTANCE_AND_SCOPE
-      = "Setting the scope is not permitted when binding to a single instance.";
+  public static final String SINGLE_INSTANCE_AND_SCOPE =
+      "Setting the scope is not permitted when binding to a single instance.";
   public static final String SCOPE_ALREADY_SET = "Scope is set more than once.";
-  public static final String BINDING_TO_NULL = "Binding to null instances is not allowed. "
-      + "Use toProvider(Providers.of(null)) if this is your intended behaviour.";
+  public static final String BINDING_TO_NULL =
+      "Binding to null instances is not allowed. "
+          + "Use toProvider(Providers.of(null)) if this is your intended behaviour.";
   public static final String CONSTANT_VALUE_ALREADY_SET = "Constant value is set more than once.";
-  public static final String ANNOTATION_ALREADY_SPECIFIED
-      = "More than one annotation is specified for this binding.";
+  public static final String ANNOTATION_ALREADY_SPECIFIED =
+      "More than one annotation is specified for this binding.";
 
   protected static final Key<?> NULL_KEY = Key.get(Void.class);
 
@@ -55,7 +55,7 @@
     this.binder = binder;
     this.elements = elements;
     this.position = elements.size();
-    this.binding = new UntargettedBindingImpl<T>(source, key, Scoping.UNSCOPED);
+    this.binding = new UntargettedBindingImpl<>(source, key, Scoping.UNSCOPED);
     elements.add(position, this.binding);
   }
 
@@ -73,16 +73,15 @@
   protected BindingImpl<T> annotatedWithInternal(Class<? extends Annotation> annotationType) {
     checkNotNull(annotationType, "annotationType");
     checkNotAnnotated();
-    return setBinding(binding.withKey(
-        Key.get(this.binding.getKey().getTypeLiteral(), annotationType)));
+    return setBinding(
+        binding.withKey(Key.get(this.binding.getKey().getTypeLiteral(), annotationType)));
   }
 
   /** Sets the binding to a copy with the specified annotation on the bound key */
   protected BindingImpl<T> annotatedWithInternal(Annotation annotation) {
     checkNotNull(annotation, "annotation");
     checkNotAnnotated();
-    return setBinding(binding.withKey(
-        Key.get(this.binding.getKey().getTypeLiteral(), annotation)));
+    return setBinding(binding.withKey(Key.get(this.binding.getKey().getTypeLiteral(), annotation)));
   }
 
   public void in(final Class<? extends Annotation> scopeAnnotation) {
@@ -129,4 +128,4 @@
       binder.addError(SCOPE_ALREADY_SET);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/AbstractBindingProcessor.java b/core/src/com/google/inject/internal/AbstractBindingProcessor.java
index e1a0bba..5d2640d 100644
--- a/core/src/com/google/inject/internal/AbstractBindingProcessor.java
+++ b/core/src/com/google/inject/internal/AbstractBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,11 +30,9 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
 
-import java.util.Set;
-
 /**
  * Guarantees that processing of Binding elements happens in a sane way.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 abstract class AbstractBindingProcessor extends AbstractProcessor {
@@ -42,21 +40,22 @@
   // It's unfortunate that we have to maintain a blacklist of specific
   // classes, but we can't easily block the whole package because of
   // all our unit tests.
-  private static final Set<Class<?>> FORBIDDEN_TYPES = ImmutableSet.<Class<?>>of(
-      AbstractModule.class,
-      Binder.class,
-      Binding.class,
-      Injector.class,
-      Key.class,
-      MembersInjector.class,
-      Module.class,
-      Provider.class,
-      Scope.class,
-      Stage.class,
-      TypeLiteral.class);
-  
+  private static final ImmutableSet<Class<?>> FORBIDDEN_TYPES =
+      ImmutableSet.<Class<?>>of(
+          AbstractModule.class,
+          Binder.class,
+          Binding.class,
+          Injector.class,
+          Key.class,
+          MembersInjector.class,
+          Module.class,
+          Provider.class,
+          Scope.class,
+          Stage.class,
+          TypeLiteral.class);
+
   protected final ProcessedBindingData bindingData;
-  
+
   AbstractBindingProcessor(Errors errors, ProcessedBindingData bindingData) {
     super(errors);
     this.bindingData = bindingData;
@@ -66,7 +65,7 @@
       InjectorImpl injector, Key<T> key, Object source) {
     return new UntargettedBindingImpl<T>(injector, key, source);
   }
-  
+
   protected void putBinding(BindingImpl<?> binding) {
     Key<?> key = binding.getKey();
 
@@ -81,11 +80,11 @@
       // If it failed because of an explicit duplicate binding...
       if (injector.state.getExplicitBinding(key) != null) {
         try {
-          if(!isOkayDuplicate(original, binding, injector.state)) {
+          if (!isOkayDuplicate(original, binding, injector.state)) {
             errors.bindingAlreadySet(key, original.getSource());
             return;
           }
-        } catch(Throwable t) {
+        } catch (Throwable t) {
           errors.errorCheckingDuplicateBinding(key, original.getSource(), t);
           return;
         }
@@ -103,8 +102,8 @@
   }
 
   /**
-   * We tolerate duplicate bindings if one exposes the other or if the two bindings
-   * are considered duplicates (see {@link Bindings#areDuplicates(BindingImpl, BindingImpl)}.
+   * We tolerate duplicate bindings if one exposes the other or if the two bindings are considered
+   * duplicates (see {@link Bindings#areDuplicates(BindingImpl, BindingImpl)}.
    *
    * @param original the binding in the parent injector (candidate for an exposing binding)
    * @param binding the binding to check (candidate for the exposed binding)
@@ -115,46 +114,63 @@
       InjectorImpl exposedFrom = (InjectorImpl) exposed.getPrivateElements().getInjector();
       return (exposedFrom == binding.getInjector());
     } else {
-      original = (BindingImpl<?>)state.getExplicitBindingsThisLevel().get(binding.getKey());
+      original = (BindingImpl<?>) state.getExplicitBindingsThisLevel().get(binding.getKey());
       // If no original at this level, the original was on a parent, and we don't
       // allow deduplication between parents & children.
-      if(original == null) {
+      if (original == null) {
         return false;
       } else {
         return original.equals(binding);
       }
     }
   }
-  
+
   private <T> void validateKey(Object source, Key<T> key) {
     Annotations.checkForMisplacedScopeAnnotations(
         key.getTypeLiteral().getRawType(), source, errors);
   }
-  
-  /** 
-   * Processor for visiting bindings.  Each overriden method that wants to
-   * actually process the binding should call prepareBinding first.
+
+  /**
+   * Processor for visiting bindings. Each overriden method that wants to actually process the
+   * binding should call prepareBinding first.
    */
   abstract class Processor<T, V> extends DefaultBindingTargetVisitor<T, V> {
     final Object source;
     final Key<T> key;
     final Class<? super T> rawType;
     Scoping scoping;
-    
+
     Processor(BindingImpl<T> binding) {
       source = binding.getSource();
       key = binding.getKey();
       rawType = key.getTypeLiteral().getRawType();
       scoping = binding.getScoping();
     }
-    
-    protected void prepareBinding() {      
+
+    protected void prepareBinding() {
       validateKey(source, key);
       scoping = Scoping.makeInjectable(scoping, injector, errors);
     }
 
-    protected void scheduleInitialization(final BindingImpl<?> binding) {
-      bindingData.addUninitializedBinding(new Runnable() {
+    /**
+     * Schedule initialization of this binding to occur immediately after all bindings have been
+     * initialially processed.
+     */
+    protected void scheduleInitialization(BindingImpl<?> binding) {
+      bindingData.addUninitializedBinding(asRunnable(binding));
+    }
+
+    /**
+     * Schedule initialization for this binding to occur after all other static initialization of
+     * bindings.
+     */
+    protected void scheduleDelayedInitialization(BindingImpl<?> binding) {
+      bindingData.addDelayedUninitializedBinding(asRunnable(binding));
+    }
+
+    private Runnable asRunnable(final BindingImpl<?> binding) {
+      return new Runnable() {
+        @Override
         public void run() {
           try {
             binding.getInjector().initializeBinding(binding, errors.withSource(source));
@@ -162,7 +178,7 @@
             errors.merge(e.getErrors());
           }
         }
-      });
+      };
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/AbstractProcessor.java b/core/src/com/google/inject/internal/AbstractProcessor.java
index 2697a99..6132dd3 100644
--- a/core/src/com/google/inject/internal/AbstractProcessor.java
+++ b/core/src/com/google/inject/internal/AbstractProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,16 +18,14 @@
 
 import com.google.inject.spi.DefaultElementVisitor;
 import com.google.inject.spi.Element;
-
 import java.util.Iterator;
 import java.util.List;
 
 /**
  * Abstract base class for creating an injector from module elements.
  *
- * <p>Extending classes must return {@code true} from any overridden
- * {@code visit*()} methods, in order for the element processor to remove the
- * handled element.
+ * <p>Extending classes must return {@code true} from any overridden {@code visit*()} methods, in
+ * order for the element processor to remove the handled element.
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
@@ -63,7 +61,7 @@
       this.injector = null;
     }
   }
-  
+
   @Override
   protected Boolean visitOther(Element element) {
     return false;
diff --git a/core/src/com/google/inject/internal/Annotations.java b/core/src/com/google/inject/internal/Annotations.java
index 4c994a9..c815973 100644
--- a/core/src/com/google/inject/internal/Annotations.java
+++ b/core/src/com/google/inject/internal/Annotations.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,8 @@
 
 package com.google.inject.internal;
 
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Joiner.MapJoiner;
@@ -32,7 +34,6 @@
 import com.google.inject.internal.util.Classes;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -43,7 +44,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
-
 import javax.inject.Qualifier;
 
 /**
@@ -53,9 +53,7 @@
  */
 public class Annotations {
 
-  /**
-   * Returns {@code true} if the given annotation type has no attributes.
-   */
+  /** Returns {@code true} if the given annotation type has no attributes. */
   public static boolean isMarker(Class<? extends Annotation> annotationType) {
     return annotationType.getDeclaredMethods().length == 0;
   }
@@ -72,13 +70,15 @@
   }
 
   private static final LoadingCache<Class<? extends Annotation>, Annotation> cache =
-      CacheBuilder.newBuilder().weakKeys().build(
-          new CacheLoader<Class<? extends Annotation>, Annotation>() {
-            @Override
-            public Annotation load(Class<? extends Annotation> input) {
-              return generateAnnotationImpl(input);
-            }
-          });
+      CacheBuilder.newBuilder()
+          .weakKeys()
+          .build(
+              new CacheLoader<Class<? extends Annotation>, Annotation>() {
+                @Override
+                public Annotation load(Class<? extends Annotation> input) {
+                  return generateAnnotationImpl(input);
+                }
+              });
 
   /**
    * Generates an Annotation for the annotation class. Requires that the annotation is all
@@ -87,31 +87,32 @@
   public static <T extends Annotation> T generateAnnotation(Class<T> annotationType) {
     Preconditions.checkState(
         isAllDefaultMethods(annotationType), "%s is not all default methods", annotationType);
-    return (T)cache.getUnchecked(annotationType);
+    return (T) cache.getUnchecked(annotationType);
   }
 
   private static <T extends Annotation> T generateAnnotationImpl(final Class<T> annotationType) {
     final Map<String, Object> members = resolveMembers(annotationType);
-    return annotationType.cast(Proxy.newProxyInstance(
-        annotationType.getClassLoader(),
-        new Class<?>[] { annotationType },
-        new InvocationHandler() {
-          @Override
-          public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
-            String name = method.getName();
-            if (name.equals("annotationType")) {
-              return annotationType;
-            } else if (name.equals("toString")) {
-              return annotationToString(annotationType, members);
-            } else if (name.equals("hashCode")) {
-              return annotationHashCode(annotationType, members);
-            } else if (name.equals("equals")) {
-              return annotationEquals(annotationType, members, args[0]);
-            } else {
-              return members.get(name);
-            }
-          }
-        }));
+    return annotationType.cast(
+        Proxy.newProxyInstance(
+            annotationType.getClassLoader(),
+            new Class<?>[] {annotationType},
+            new InvocationHandler() {
+              @Override
+              public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
+                String name = method.getName();
+                if (name.equals("annotationType")) {
+                  return annotationType;
+                } else if (name.equals("toString")) {
+                  return annotationToString(annotationType, members);
+                } else if (name.equals("hashCode")) {
+                  return annotationHashCode(annotationType, members);
+                } else if (name.equals("equals")) {
+                  return annotationEquals(annotationType, members, args[0]);
+                } else {
+                  return members.get(name);
+                }
+              }
+            }));
   }
 
   private static ImmutableMap<String, Object> resolveMembers(
@@ -124,8 +125,9 @@
   }
 
   /** Implements {@link Annotation#equals}. */
-  private static boolean annotationEquals(Class<? extends Annotation> type,
-      Map<String, Object> members, Object other) throws Exception {
+  private static boolean annotationEquals(
+      Class<? extends Annotation> type, Map<String, Object> members, Object other)
+      throws Exception {
     if (!type.isInstance(other)) {
       return false;
     }
@@ -140,8 +142,8 @@
   }
 
   /** Implements {@link Annotation#hashCode}. */
-  private static int annotationHashCode(Class<? extends Annotation> type,
-      Map<String, Object> members) throws Exception {
+  private static int annotationHashCode(
+      Class<? extends Annotation> type, Map<String, Object> members) throws Exception {
     int result = 0;
     for (Method method : type.getDeclaredMethods()) {
       String name = method.getName();
@@ -153,25 +155,24 @@
 
   private static final MapJoiner JOINER = Joiner.on(", ").withKeyValueSeparator("=");
 
-  private static final Function<Object, String> DEEP_TO_STRING_FN = new Function<Object, String>() {
-    @Override
-    public String apply(Object arg) {
-      String s = Arrays.deepToString(new Object[] {arg});
-      return s.substring(1, s.length() - 1); // cut off brackets
-    }
-  };
+  private static final Function<Object, String> DEEP_TO_STRING_FN =
+      new Function<Object, String>() {
+        @Override
+        public String apply(Object arg) {
+          String s = Arrays.deepToString(new Object[] {arg});
+          return s.substring(1, s.length() - 1); // cut off brackets
+        }
+      };
 
   /** Implements {@link Annotation#toString}. */
-  private static String annotationToString(Class<? extends Annotation> type,
-      Map<String, Object> members) throws Exception {
+  private static String annotationToString(
+      Class<? extends Annotation> type, Map<String, Object> members) throws Exception {
     StringBuilder sb = new StringBuilder().append("@").append(type.getName()).append("(");
     JOINER.appendTo(sb, Maps.transformValues(members, DEEP_TO_STRING_FN));
     return sb.append(")").toString();
   }
 
-  /**
-   * Returns true if the given annotation is retained at runtime.
-   */
+  /** Returns true if the given annotation is retained at runtime. */
   public static boolean isRetainedAtRuntime(Class<? extends Annotation> annotationType) {
     Retention retention = annotationType.getAnnotation(Retention.class);
     return retention != null && retention.value() == RetentionPolicy.RUNTIME;
@@ -184,7 +185,8 @@
   }
 
   /** Returns the scoping annotation, or null if there isn't one. */
-  public static Class<? extends Annotation> findScopeAnnotation(Errors errors, Annotation[] annotations) {
+  public static Class<? extends Annotation> findScopeAnnotation(
+      Errors errors, Annotation[] annotations) {
     Class<? extends Annotation> found = null;
 
     for (Annotation annotation : annotations) {
@@ -212,53 +214,77 @@
     return false;
   }
 
+  private static final boolean QUOTE_MEMBER_VALUES = determineWhetherToQuote();
+
   /**
-   * Checks for the presence of annotations. Caches results because Android doesn't.
+   * Returns {@code value}, quoted if annotation implementations quote their member values. In Java
+   * 9, annotations quote their string members.
    */
+  public static String memberValueString(String value) {
+    return QUOTE_MEMBER_VALUES ? "\"" + value + "\"" : value;
+  }
+
+  @Retention(RUNTIME)
+  private @interface TestAnnotation {
+    String value();
+  }
+
+  @TestAnnotation("determineWhetherToQuote")
+  private static boolean determineWhetherToQuote() {
+    try {
+      String annotation =
+          Annotations.class
+              .getDeclaredMethod("determineWhetherToQuote")
+              .getAnnotation(TestAnnotation.class)
+              .toString();
+      return annotation.contains("\"determineWhetherToQuote\"");
+    } catch (NoSuchMethodException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /** Checks for the presence of annotations. Caches results because Android doesn't. */
   static class AnnotationChecker {
     private final Collection<Class<? extends Annotation>> annotationTypes;
 
     /** Returns true if the given class has one of the desired annotations. */
     private CacheLoader<Class<? extends Annotation>, Boolean> hasAnnotations =
         new CacheLoader<Class<? extends Annotation>, Boolean>() {
-      public Boolean load(Class<? extends Annotation> annotationType) {
-        for (Annotation annotation : annotationType.getAnnotations()) {
-          if (annotationTypes.contains(annotation.annotationType())) {
-            return true;
+          @Override
+          public Boolean load(Class<? extends Annotation> annotationType) {
+            for (Annotation annotation : annotationType.getAnnotations()) {
+              if (annotationTypes.contains(annotation.annotationType())) {
+                return true;
+              }
+            }
+            return false;
           }
-        }
-        return false;
-      }
-    };
+        };
 
-    final LoadingCache<Class<? extends Annotation>, Boolean> cache = CacheBuilder.newBuilder().weakKeys()
-        .build(hasAnnotations);
+    final LoadingCache<Class<? extends Annotation>, Boolean> cache =
+        CacheBuilder.newBuilder().weakKeys().build(hasAnnotations);
 
-    /**
-     * Constructs a new checker that looks for annotations of the given types.
-     */
+    /** Constructs a new checker that looks for annotations of the given types. */
     AnnotationChecker(Collection<Class<? extends Annotation>> annotationTypes) {
       this.annotationTypes = annotationTypes;
     }
 
-    /**
-     * Returns true if the given type has one of the desired annotations.
-     */
+    /** Returns true if the given type has one of the desired annotations. */
     boolean hasAnnotations(Class<? extends Annotation> annotated) {
       return cache.getUnchecked(annotated);
     }
   }
 
-  private static final AnnotationChecker scopeChecker = new AnnotationChecker(
-      Arrays.asList(ScopeAnnotation.class, javax.inject.Scope.class));
+  private static final AnnotationChecker scopeChecker =
+      new AnnotationChecker(Arrays.asList(ScopeAnnotation.class, javax.inject.Scope.class));
 
   public static boolean isScopeAnnotation(Class<? extends Annotation> annotationType) {
     return scopeChecker.hasAnnotations(annotationType);
   }
 
   /**
-   * Adds an error if there is a misplaced annotations on {@code type}. Scoping
-   * annotations are not allowed on abstract classes or interfaces.
+   * Adds an error if there is a misplaced annotations on {@code type}. Scoping annotations are not
+   * allowed on abstract classes or interfaces.
    */
   public static void checkForMisplacedScopeAnnotations(
       Class<?> type, Object source, Errors errors) {
@@ -274,18 +300,20 @@
     }
   }
 
+  // NOTE: getKey/findBindingAnnotation are used by Gin which is abandoned.  So changing this API
+  // will prevent Gin users from upgrading Guice version.
+
   /** Gets a key for the given type, member and annotations. */
-  public static Key<?> getKey(TypeLiteral<?> type, Member member, Annotation[] annotations,
-      Errors errors) throws ErrorsException {
+  public static Key<?> getKey(
+      TypeLiteral<?> type, Member member, Annotation[] annotations, Errors errors)
+      throws ErrorsException {
     int numErrorsBefore = errors.size();
     Annotation found = findBindingAnnotation(errors, member, annotations);
     errors.throwIfNewErrors(numErrorsBefore);
     return found == null ? Key.get(type) : Key.get(type, found);
   }
 
-  /**
-   * Returns the binding annotation on {@code member}, or null if there isn't one.
-   */
+  /** Returns the binding annotation on {@code member}, or null if there isn't one. */
   public static Annotation findBindingAnnotation(
       Errors errors, Member member, Annotation[] annotations) {
     Annotation found = null;
@@ -304,23 +332,21 @@
     return found;
   }
 
-  private static final AnnotationChecker bindingAnnotationChecker = new AnnotationChecker(
-      Arrays.asList(BindingAnnotation.class, Qualifier.class));
+  private static final AnnotationChecker bindingAnnotationChecker =
+      new AnnotationChecker(Arrays.asList(BindingAnnotation.class, Qualifier.class));
 
-  /**
-   * Returns true if annotations of the specified type are binding annotations.
-   */
+  /** Returns true if annotations of the specified type are binding annotations. */
   public static boolean isBindingAnnotation(Class<? extends Annotation> annotationType) {
     return bindingAnnotationChecker.hasAnnotations(annotationType);
   }
 
   /**
    * If the annotation is an instance of {@code javax.inject.Named}, canonicalizes to
-   * com.google.guice.name.Named.  Returns the given annotation otherwise.
+   * com.google.guice.name.Named. Returns the given annotation otherwise.
    */
   public static Annotation canonicalizeIfNamed(Annotation annotation) {
-    if(annotation instanceof javax.inject.Named) {
-      return Names.named(((javax.inject.Named)annotation).value());
+    if (annotation instanceof javax.inject.Named) {
+      return Names.named(((javax.inject.Named) annotation).value());
     } else {
       return annotation;
     }
@@ -338,4 +364,22 @@
       return annotationType;
     }
   }
+
+  /**
+   * Returns the name the binding should use. This is based on the annotation. If the annotation has
+   * an instance and is not a marker annotation, we ask the annotation for its toString. If it was a
+   * marker annotation or just an annotation type, we use the annotation's name. Otherwise, the name
+   * is the empty string.
+   */
+  public static String nameOf(Key<?> key) {
+    Annotation annotation = key.getAnnotation();
+    Class<? extends Annotation> annotationType = key.getAnnotationType();
+    if (annotation != null && !isMarker(annotationType)) {
+      return key.getAnnotation().toString();
+    } else if (key.getAnnotationType() != null) {
+      return "@" + key.getAnnotationType().getName();
+    } else {
+      return "";
+    }
+  }
 }
diff --git a/core/src/com/google/inject/internal/BindingBuilder.java b/core/src/com/google/inject/internal/BindingBuilder.java
index 36c31ff..100137e 100644
--- a/core/src/com/google/inject/internal/BindingBuilder.java
+++ b/core/src/com/google/inject/internal/BindingBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,7 +29,6 @@
 import com.google.inject.spi.Element;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.Message;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.util.List;
@@ -47,33 +46,39 @@
     super(binder, elements, source, key);
   }
 
+  @Override
   public BindingBuilder<T> annotatedWith(Class<? extends Annotation> annotationType) {
     annotatedWithInternal(annotationType);
     return this;
   }
 
+  @Override
   public BindingBuilder<T> annotatedWith(Annotation annotation) {
     annotatedWithInternal(annotation);
     return this;
   }
 
+  @Override
   public BindingBuilder<T> to(Class<? extends T> implementation) {
     return to(Key.get(implementation));
   }
 
+  @Override
   public BindingBuilder<T> to(TypeLiteral<? extends T> implementation) {
     return to(Key.get(implementation));
   }
 
+  @Override
   public BindingBuilder<T> to(Key<? extends T> linkedKey) {
     checkNotNull(linkedKey, "linkedKey");
     checkNotTargetted();
     BindingImpl<T> base = getBinding();
-    setBinding(new LinkedBindingImpl<T>(
-        base.getSource(), base.getKey(), base.getScoping(), linkedKey));
+    setBinding(
+        new LinkedBindingImpl<T>(base.getSource(), base.getKey(), base.getScoping(), linkedKey));
     return this;
   }
 
+  @Override
   public void toInstance(T instance) {
     checkNotTargetted();
 
@@ -92,14 +97,17 @@
     }
 
     BindingImpl<T> base = getBinding();
-    setBinding(new InstanceBindingImpl<T>(
-        base.getSource(), base.getKey(), Scoping.EAGER_SINGLETON, injectionPoints, instance));
+    setBinding(
+        new InstanceBindingImpl<T>(
+            base.getSource(), base.getKey(), Scoping.EAGER_SINGLETON, injectionPoints, instance));
   }
 
+  @Override
   public BindingBuilder<T> toProvider(Provider<? extends T> provider) {
     return toProvider((javax.inject.Provider<T>) provider);
   }
 
+  @Override
   public BindingBuilder<T> toProvider(javax.inject.Provider<? extends T> provider) {
     checkNotNull(provider, "provider");
     checkNotTargetted();
@@ -114,38 +122,45 @@
     }
 
     BindingImpl<T> base = getBinding();
-    setBinding(new ProviderInstanceBindingImpl<T>(
-        base.getSource(), base.getKey(), base.getScoping(), injectionPoints, provider));
+    setBinding(
+        new ProviderInstanceBindingImpl<T>(
+            base.getSource(), base.getKey(), base.getScoping(), injectionPoints, provider));
     return this;
   }
 
+  @Override
   public BindingBuilder<T> toProvider(
       Class<? extends javax.inject.Provider<? extends T>> providerType) {
     return toProvider(Key.get(providerType));
   }
 
+  @Override
   public BindingBuilder<T> toProvider(
       TypeLiteral<? extends javax.inject.Provider<? extends T>> providerType) {
     return toProvider(Key.get(providerType));
   }
 
+  @Override
   public BindingBuilder<T> toProvider(
       Key<? extends javax.inject.Provider<? extends T>> providerKey) {
     checkNotNull(providerKey, "providerKey");
     checkNotTargetted();
 
     BindingImpl<T> base = getBinding();
-    setBinding(new LinkedProviderBindingImpl<T>(
-        base.getSource(), base.getKey(), base.getScoping(), providerKey));
+    setBinding(
+        new LinkedProviderBindingImpl<T>(
+            base.getSource(), base.getKey(), base.getScoping(), providerKey));
     return this;
   }
 
+  @Override
   public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S> constructor) {
     return toConstructor(constructor, TypeLiteral.get(constructor.getDeclaringClass()));
   }
 
-  public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S> constructor,
-      TypeLiteral<? extends S> type) {
+  @Override
+  public <S extends T> ScopedBindingBuilder toConstructor(
+      Constructor<S> constructor, TypeLiteral<? extends S> type) {
     checkNotNull(constructor, "constructor");
     checkNotNull(type, "type");
     checkNotTargetted();
@@ -162,16 +177,22 @@
 
     try {
       InjectionPoint constructorPoint = InjectionPoint.forConstructor(constructor, type);
-      setBinding(new ConstructorBindingImpl<T>(base.getKey(), base.getSource(), base.getScoping(),
-          constructorPoint, injectionPoints));
+      setBinding(
+          new ConstructorBindingImpl<T>(
+              base.getKey(),
+              base.getSource(),
+              base.getScoping(),
+              constructorPoint,
+              injectionPoints));
     } catch (ConfigurationException e) {
       copyErrorsToBinder(e);
     }
 
     return this;
   }
-  
-  @Override public String toString() {
+
+  @Override
+  public String toString() {
     return "BindingBuilder<" + getBinding().getKey().getTypeLiteral() + ">";
   }
 
diff --git a/core/src/com/google/inject/internal/BindingImpl.java b/core/src/com/google/inject/internal/BindingImpl.java
index 3228e3d..4259296 100644
--- a/core/src/com/google/inject/internal/BindingImpl.java
+++ b/core/src/com/google/inject/internal/BindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
 
 package com.google.inject.internal;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.Binding;
 import com.google.inject.Key;
 import com.google.inject.Provider;
@@ -24,9 +24,7 @@
 import com.google.inject.spi.ElementVisitor;
 import com.google.inject.spi.InstanceBinding;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public abstract class BindingImpl<T> implements Binding<T> {
 
   private final InjectorImpl injector;
@@ -35,8 +33,12 @@
   private final Scoping scoping;
   private final InternalFactory<? extends T> internalFactory;
 
-  public BindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Scoping scoping) {
+  public BindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping) {
     this.injector = injector;
     this.key = key;
     this.source = source;
@@ -52,16 +54,19 @@
     this.scoping = scoping;
   }
 
+  @Override
   public Key<T> getKey() {
     return key;
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
   private volatile Provider<T> provider;
 
+  @Override
   public Provider<T> getProvider() {
     if (provider == null) {
       if (injector == null) {
@@ -82,17 +87,19 @@
   }
 
   /**
-   * Is this a constant binding? This returns true for constant bindings as
-   * well as toInstance() bindings.
+   * Is this a constant binding? This returns true for constant bindings as well as toInstance()
+   * bindings.
    */
   public boolean isConstant() {
     return this instanceof InstanceBinding;
   }
 
+  @Override
   public <V> V acceptVisitor(ElementVisitor<V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public <V> V acceptScopingVisitor(BindingScopingVisitor<V> visitor) {
     return scoping.acceptVisitor(visitor);
   }
@@ -104,9 +111,10 @@
   protected BindingImpl<T> withKey(Key<T> key) {
     throw new AssertionError();
   }
-  
-  @Override public String toString() {
-    return Objects.toStringHelper(Binding.class)
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(Binding.class)
         .add("key", key)
         .add("scope", scoping)
         .add("source", source)
diff --git a/core/src/com/google/inject/internal/BindingProcessor.java b/core/src/com/google/inject/internal/BindingProcessor.java
index b3c869e..e9c52b4 100644
--- a/core/src/com/google/inject/internal/BindingProcessor.java
+++ b/core/src/com/google/inject/internal/BindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,7 +31,6 @@
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderKeyBinding;
 import com.google.inject.spi.UntargettedBinding;
-
 import java.util.Set;
 
 /**
@@ -49,7 +48,8 @@
     this.initializer = initializer;
   }
 
-  @Override public <T> Boolean visit(Binding<T> command) {
+  @Override
+  public <T> Boolean visit(Binding<T> command) {
     Class<?> rawType = command.getKey().getTypeLiteral().getRawType();
     if (Void.class.equals(rawType)) {
       if (command instanceof ProviderInstanceBinding
@@ -61,127 +61,183 @@
       }
       return true;
     }
-    
+
     if (rawType == Provider.class) {
       errors.bindingToProvider();
       return true;
     }
-    
-    return command.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)command) {
-      @Override
-      public Boolean visit(ConstructorBinding<? extends T> binding) {
-        prepareBinding();
-        try {
-          ConstructorBindingImpl<T> onInjector = ConstructorBindingImpl.create(injector, key, 
-              binding.getConstructor(), source, scoping, errors, false, false);
-          scheduleInitialization(onInjector);
-          putBinding(onInjector);
-        } catch (ErrorsException e) {
-          errors.merge(e.getErrors());
-          putBinding(invalidBinding(injector, key, source));
-        }
-        return true;
-      }
 
-      @Override
-      public Boolean visit(InstanceBinding<? extends T> binding) {
-        prepareBinding();
-        Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
-        T instance = binding.getInstance();
-        @SuppressWarnings("unchecked") // safe to cast to binding<T> because
-                                       // the processor was constructed w/ it
-        Initializable<T> ref = initializer.requestInjection(
-            injector, instance, (Binding<T>) binding, source, injectionPoints);
-        ConstantFactory<? extends T> factory = new ConstantFactory<T>(ref);
-        InternalFactory<? extends T> scopedFactory
-            = Scoping.scope(key, injector, factory, source, scoping);
-        putBinding(new InstanceBindingImpl<T>(injector, key, source, scopedFactory, injectionPoints,
-            instance));
-        return true;
-      }
+    return command.acceptTargetVisitor(
+        new Processor<T, Boolean>((BindingImpl<T>) command) {
+          @Override
+          public Boolean visit(ConstructorBinding<? extends T> binding) {
+            prepareBinding();
+            try {
+              ConstructorBindingImpl<T> onInjector =
+                  ConstructorBindingImpl.create(
+                      injector,
+                      key,
+                      binding.getConstructor(),
+                      source,
+                      scoping,
+                      errors,
+                      false,
+                      false);
+              scheduleInitialization(onInjector);
+              putBinding(onInjector);
+            } catch (ErrorsException e) {
+              errors.merge(e.getErrors());
+              putBinding(invalidBinding(injector, key, source));
+            }
+            return true;
+          }
 
-      @Override
-      public Boolean visit(ProviderInstanceBinding<? extends T> binding) {
-        prepareBinding();
-        javax.inject.Provider<? extends T> provider = binding.getUserSuppliedProvider();
-        Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
-        Initializable<? extends javax.inject.Provider<? extends T>> initializable =
-            initializer.<javax.inject.Provider<? extends T>>requestInjection(
-                injector, provider, null, source, injectionPoints);
-        // always visited with Binding<T>
-        @SuppressWarnings("unchecked") 
-        InternalFactory<T> factory = new InternalFactoryToInitializableAdapter<T>(
-            initializable, source,
-            injector.provisionListenerStore.get((ProviderInstanceBinding<T>)binding));
-        InternalFactory<? extends T> scopedFactory
-            = Scoping.scope(key, injector, factory, source, scoping);
-        putBinding(new ProviderInstanceBindingImpl<T>(injector, key, source, scopedFactory, scoping,
-            provider, injectionPoints));
-        return true;
-      }
+          @Override
+          public Boolean visit(InstanceBinding<? extends T> binding) {
+            prepareBinding();
+            Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
+            T instance = binding.getInstance();
+            @SuppressWarnings("unchecked") // safe to cast to binding<T> because
+            // the processor was constructed w/ it
+            Initializable<T> ref =
+                initializer.requestInjection(
+                    injector, instance, (Binding<T>) binding, source, injectionPoints);
+            ConstantFactory<? extends T> factory = new ConstantFactory<>(ref);
+            InternalFactory<? extends T> scopedFactory =
+                Scoping.scope(key, injector, factory, source, scoping);
+            putBinding(
+                new InstanceBindingImpl<T>(
+                    injector, key, source, scopedFactory, injectionPoints, instance));
+            return true;
+          }
 
-      @Override
-      public Boolean visit(ProviderKeyBinding<? extends T> binding) {
-        prepareBinding();
-        Key<? extends javax.inject.Provider<? extends T>> providerKey = binding.getProviderKey();
-        // always visited with Binding<T>
-        @SuppressWarnings("unchecked") 
-        BoundProviderFactory<T> boundProviderFactory = new BoundProviderFactory<T>(
-            injector, providerKey, source,
-            injector.provisionListenerStore.get((ProviderKeyBinding<T>) binding));
-        bindingData.addCreationListener(boundProviderFactory);
-        InternalFactory<? extends T> scopedFactory = Scoping.scope(
-            key, injector, (InternalFactory<? extends T>) boundProviderFactory, source, scoping);
-        putBinding(new LinkedProviderBindingImpl<T>(
-            injector, key, source, scopedFactory, scoping, providerKey));
-        return true;
-      }
+          @Override
+          public Boolean visit(ProviderInstanceBinding<? extends T> binding) {
+            prepareBinding();
+            javax.inject.Provider<? extends T> provider = binding.getUserSuppliedProvider();
+            if (provider instanceof InternalProviderInstanceBindingImpl.Factory) {
+              @SuppressWarnings("unchecked")
+              InternalProviderInstanceBindingImpl.Factory<T> asProviderMethod =
+                  (InternalProviderInstanceBindingImpl.Factory<T>) provider;
+              return visitInternalProviderInstanceBindingFactory(asProviderMethod);
+            }
+            Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
+            Initializable<? extends javax.inject.Provider<? extends T>> initializable =
+                initializer.<javax.inject.Provider<? extends T>>requestInjection(
+                    injector, provider, null, source, injectionPoints);
+            // always visited with Binding<T>
+            @SuppressWarnings("unchecked")
+            InternalFactory<T> factory =
+                new InternalFactoryToInitializableAdapter<T>(
+                    initializable,
+                    source,
+                    injector.provisionListenerStore.get((ProviderInstanceBinding<T>) binding));
+            InternalFactory<? extends T> scopedFactory =
+                Scoping.scope(key, injector, factory, source, scoping);
+            putBinding(
+                new ProviderInstanceBindingImpl<T>(
+                    injector, key, source, scopedFactory, scoping, provider, injectionPoints));
+            return true;
+          }
 
-      @Override
-      public Boolean visit(LinkedKeyBinding<? extends T> binding) {
-        prepareBinding();
-        Key<? extends T> linkedKey = binding.getLinkedKey();
-        if (key.equals(linkedKey)) {
-          errors.recursiveBinding();
-        }
+          @Override
+          public Boolean visit(ProviderKeyBinding<? extends T> binding) {
+            prepareBinding();
+            Key<? extends javax.inject.Provider<? extends T>> providerKey =
+                binding.getProviderKey();
+            // always visited with Binding<T>
+            @SuppressWarnings("unchecked")
+            BoundProviderFactory<T> boundProviderFactory =
+                new BoundProviderFactory<T>(
+                    injector,
+                    providerKey,
+                    source,
+                    injector.provisionListenerStore.get((ProviderKeyBinding<T>) binding));
+            bindingData.addCreationListener(boundProviderFactory);
+            InternalFactory<? extends T> scopedFactory =
+                Scoping.scope(
+                    key,
+                    injector,
+                    (InternalFactory<? extends T>) boundProviderFactory,
+                    source,
+                    scoping);
+            putBinding(
+                new LinkedProviderBindingImpl<T>(
+                    injector, key, source, scopedFactory, scoping, providerKey));
+            return true;
+          }
 
-        FactoryProxy<T> factory = new FactoryProxy<T>(injector, key, linkedKey, source);
-        bindingData.addCreationListener(factory);
-        InternalFactory<? extends T> scopedFactory
-            = Scoping.scope(key, injector, factory, source, scoping);
-        putBinding(
-            new LinkedBindingImpl<T>(injector, key, source, scopedFactory, scoping, linkedKey));
-        return true;
-      }
+          @Override
+          public Boolean visit(LinkedKeyBinding<? extends T> binding) {
+            prepareBinding();
+            Key<? extends T> linkedKey = binding.getLinkedKey();
+            if (key.equals(linkedKey)) {
+              errors.recursiveBinding();
+            }
 
-      @Override
-      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
-        return false;
-      }
+            FactoryProxy<T> factory = new FactoryProxy<>(injector, key, linkedKey, source);
+            bindingData.addCreationListener(factory);
+            InternalFactory<? extends T> scopedFactory =
+                Scoping.scope(key, injector, factory, source, scoping);
+            putBinding(
+                new LinkedBindingImpl<T>(injector, key, source, scopedFactory, scoping, linkedKey));
+            return true;
+          }
 
-      @Override
-      public Boolean visit(ExposedBinding<? extends T> binding) {
-        throw new IllegalArgumentException("Cannot apply a non-module element");
-      }
-      
-      @Override
-      public Boolean visit(ConvertedConstantBinding<? extends T> binding) {
-        throw new IllegalArgumentException("Cannot apply a non-module element");
-      }
-      
-      @Override
-      public Boolean visit(ProviderBinding<? extends T> binding) {
-        throw new IllegalArgumentException("Cannot apply a non-module element");
-      }
-      
-      @Override
-      protected Boolean visitOther(Binding<? extends T> binding) {
-        throw new IllegalStateException("BindingProcessor should override all visitations");
-      }
-    });
+          /** Handle ProviderMethods specially. */
+          private Boolean visitInternalProviderInstanceBindingFactory(
+              InternalProviderInstanceBindingImpl.Factory<T> provider) {
+            InternalProviderInstanceBindingImpl<T> binding =
+                new InternalProviderInstanceBindingImpl<T>(
+                    injector,
+                    key,
+                    source,
+                    provider,
+                    Scoping.scope(key, injector, provider, source, scoping),
+                    scoping);
+            switch (binding.getInitializationTiming()) {
+              case DELAYED:
+                scheduleDelayedInitialization(binding);
+                break;
+              case EAGER:
+                scheduleInitialization(binding);
+                break;
+              default:
+                throw new AssertionError();
+            }
+            putBinding(binding);
+            return true;
+          }
+
+          @Override
+          public Boolean visit(UntargettedBinding<? extends T> untargetted) {
+            return false;
+          }
+
+          @Override
+          public Boolean visit(ExposedBinding<? extends T> binding) {
+            throw new IllegalArgumentException("Cannot apply a non-module element");
+          }
+
+          @Override
+          public Boolean visit(ConvertedConstantBinding<? extends T> binding) {
+            throw new IllegalArgumentException("Cannot apply a non-module element");
+          }
+
+          @Override
+          public Boolean visit(ProviderBinding<? extends T> binding) {
+            throw new IllegalArgumentException("Cannot apply a non-module element");
+          }
+
+          @Override
+          protected Boolean visitOther(Binding<? extends T> binding) {
+            throw new IllegalStateException("BindingProcessor should override all visitations");
+          }
+        });
   }
 
-  @Override public Boolean visit(PrivateElements privateElements) {
+  @Override
+  public Boolean visit(PrivateElements privateElements) {
     for (Key<?> key : privateElements.getExposedKeys()) {
       bindExposed(privateElements, key);
     }
@@ -189,9 +245,14 @@
   }
 
   private <T> void bindExposed(PrivateElements privateElements, Key<T> key) {
-    ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key, privateElements);
+    ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<>(key, privateElements);
     bindingData.addCreationListener(exposedKeyFactory);
-    putBinding(new ExposedBindingImpl<T>(
-        injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements));
+    putBinding(
+        new ExposedBindingImpl<T>(
+            injector,
+            privateElements.getExposedSource(key),
+            key,
+            exposedKeyFactory,
+            privateElements));
   }
 }
diff --git a/core/src/com/google/inject/internal/BoundProviderFactory.java b/core/src/com/google/inject/internal/BoundProviderFactory.java
index 9f523df..eaaf767 100644
--- a/core/src/com/google/inject/internal/BoundProviderFactory.java
+++ b/core/src/com/google/inject/internal/BoundProviderFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,17 +16,12 @@
 
 package com.google.inject.internal;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import com.google.inject.Key;
 import com.google.inject.internal.InjectorImpl.JitLimitation;
 import com.google.inject.spi.Dependency;
-
 import javax.inject.Provider;
 
-/**
- * Delegates to a custom factory which is also bound in the injector.
- */
+/** Delegates to a custom factory which is also bound in the injector. */
 final class BoundProviderFactory<T> extends ProviderInternalFactory<T> implements CreationListener {
 
   private final ProvisionListenerStackCallback<T> provisionCallback;
@@ -40,42 +35,53 @@
       Object source,
       ProvisionListenerStackCallback<T> provisionCallback) {
     super(source);
-    this.provisionCallback = checkNotNull(provisionCallback, "provisionCallback");
+    this.provisionCallback = provisionCallback;
     this.injector = injector;
     this.providerKey = providerKey;
   }
 
+  @Override
   public void notify(Errors errors) {
     try {
-      providerFactory = injector.getInternalFactory(providerKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT);
+      providerFactory =
+          injector.getInternalFactory(
+              providerKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT);
     } catch (ErrorsException e) {
       errors.merge(e.getErrors());
     }
   }
 
-  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException {
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
     context.pushState(providerKey, source);
+
     try {
-      errors = errors.withSource(providerKey);
-      javax.inject.Provider<? extends T> provider = providerFactory.get(errors, context, dependency, true);
-      return circularGet(provider, errors, context, dependency, provisionCallback);
-    } finally {
-      context.popState();
+      javax.inject.Provider<? extends T> provider = providerFactory.get(context, dependency, true);
+      return circularGet(provider, context, dependency, provisionCallback);
+    } catch (InternalProvisionException ipe) {
+      throw ipe.addSource(providerKey);
+      } finally {
+        context.popState();
+
     }
   }
-  
+
   @Override
-  protected T provision(Provider<? extends T> provider, Errors errors, Dependency<?> dependency,
-      ConstructionContext<T> constructionContext) throws ErrorsException {
+  protected T provision(
+      Provider<? extends T> provider,
+      Dependency<?> dependency,
+      ConstructionContext<T> constructionContext)
+      throws InternalProvisionException {
     try {
-      return super.provision(provider, errors, dependency, constructionContext);
-    } catch(RuntimeException userException) {
-      throw errors.errorInProvider(userException).toException();
-    } 
+      return super.provision(provider, dependency, constructionContext);
+    } catch (RuntimeException userException) {
+      throw InternalProvisionException.errorInProvider(userException);
+    }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return providerKey.toString();
   }
 }
diff --git a/core/src/com/google/inject/internal/BytecodeGen.java b/core/src/com/google/inject/internal/BytecodeGen.java
index ed01cd1..2ec96cb 100644
--- a/core/src/com/google/inject/internal/BytecodeGen.java
+++ b/core/src/com/google/inject/internal/BytecodeGen.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,13 +22,13 @@
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.inject.internal.InternalFlags.CustomClassLoadingOption;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -37,24 +37,26 @@
  * interceptors} and to proxy circular dependencies.
  *
  * <p>When loading classes, we need to be careful of:
+ *
  * <ul>
- *   <li><strong>Memory leaks.</strong> Generated classes need to be garbage collected in long-lived
- *       applications. Once an injector and any instances it created can be garbage collected, the
- *       corresponding generated classes should be collectable.
- *   <li><strong>Visibility.</strong> Containers like <code>OSGi</code> use class loader boundaries
- *       to enforce modularity at runtime.
+ * <li><strong>Memory leaks.</strong> Generated classes need to be garbage collected in long-lived
+ *     applications. Once an injector and any instances it created can be garbage collected, the
+ *     corresponding generated classes should be collectable.
+ * <li><strong>Visibility.</strong> Containers like <code>OSGi</code> use class loader boundaries to
+ *     enforce modularity at runtime.
  * </ul>
  *
  * <p>For each generated class, there's multiple class loaders involved:
+ *
  * <ul>
- *    <li><strong>The related class's class loader.</strong> Every generated class services exactly
- *        one user-supplied class. This class loader must be used to access members with private and
- *        package visibility.
- *    <li><strong>Guice's class loader.</strong>
- *    <li><strong>Our bridge class loader.</strong> This is a child of the user's class loader. It
- *        selectively delegates to either the user's class loader (for user classes) or the Guice
- *        class loader (for internal classes that are used by the generated classes). This class
- *        loader that owns the classes generated by Guice.
+ * <li><strong>The related class's class loader.</strong> Every generated class services exactly one
+ *     user-supplied class. This class loader must be used to access members with protected and
+ *     package visibility.
+ * <li><strong>Guice's class loader.</strong>
+ * <li><strong>Our bridge class loader.</strong> This is a child of the user's class loader. It
+ *     selectively delegates to either the user's class loader (for user classes) or the Guice class
+ *     loader (for internal classes that are used by the generated classes). This class loader that
+ *     owns the classes generated by Guice.
  * </ul>
  *
  * @author mcculls@gmail.com (Stuart McCulloch)
@@ -72,56 +74,57 @@
   }
 
   /** ie. "com.google.inject.internal" */
-  static final String GUICE_INTERNAL_PACKAGE
-      = BytecodeGen.class.getName().replaceFirst("\\.internal\\..*$", ".internal");
+  static final String GUICE_INTERNAL_PACKAGE =
+      BytecodeGen.class.getName().replaceFirst("\\.internal\\..*$", ".internal");
 
   /*if[AOP]*/
   /** either "net.sf.cglib", or "com.google.inject.internal.cglib" */
-  static final String CGLIB_PACKAGE
-      = net.sf.cglib.proxy.Enhancer.class.getName().replaceFirst("\\.cglib\\..*$", ".cglib");
+  static final String CGLIB_PACKAGE =
+      net.sf.cglib.proxy.Enhancer.class.getName().replaceFirst("\\.cglib\\..*$", ".cglib");
 
-  static final net.sf.cglib.core.NamingPolicy FASTCLASS_NAMING_POLICY
-      = new net.sf.cglib.core.DefaultNamingPolicy() {
-    @Override protected String getTag() {
-      return "ByGuice";
-    }
+  static final net.sf.cglib.core.NamingPolicy FASTCLASS_NAMING_POLICY =
+      new net.sf.cglib.core.DefaultNamingPolicy() {
+        @Override
+        protected String getTag() {
+          return "ByGuice";
+        }
 
-    @Override
-    public String getClassName(String prefix, String source, Object key,
-        net.sf.cglib.core.Predicate names) {
-      // we explicitly set the source here to "FastClass" so that our jarjar renaming
-      // to $FastClass doesn't leak into the class names.  if we did not do this,
-      // classes would end up looking like $$$FastClassByGuice$$, with the extra $
-      // at the front.
-      return super.getClassName(prefix, "FastClass", key, names);
-    }
-  };
+        @Override
+        public String getClassName(
+            String prefix, String source, Object key, net.sf.cglib.core.Predicate names) {
+          // we explicitly set the source here to "FastClass" so that our jarjar renaming
+          // to $FastClass doesn't leak into the class names.  if we did not do this,
+          // classes would end up looking like $$$FastClassByGuice$$, with the extra $
+          // at the front.
+          return super.getClassName(prefix, "FastClass", key, names);
+        }
+      };
 
-  static final net.sf.cglib.core.NamingPolicy ENHANCER_NAMING_POLICY
-      = new net.sf.cglib.core.DefaultNamingPolicy() {
-    @Override
-    protected String getTag() {
-      return "ByGuice";
-    }
+  static final net.sf.cglib.core.NamingPolicy ENHANCER_NAMING_POLICY =
+      new net.sf.cglib.core.DefaultNamingPolicy() {
+        @Override
+        protected String getTag() {
+          return "ByGuice";
+        }
 
-    @Override
-    public String getClassName(String prefix, String source, Object key,
-        net.sf.cglib.core.Predicate names) {
-      // we explicitly set the source here to "Enhancer" so that our jarjar renaming
-      // to $Enhancer doesn't leak into the class names.  if we did not do this,
-      // classes would end up looking like $$$EnhancerByGuice$$, with the extra $
-      // at the front.
-      return super.getClassName(prefix, "Enhancer", key, names);
-    }
-  };
+        @Override
+        public String getClassName(
+            String prefix, String source, Object key, net.sf.cglib.core.Predicate names) {
+          // we explicitly set the source here to "Enhancer" so that our jarjar renaming
+          // to $Enhancer doesn't leak into the class names.  if we did not do this,
+          // classes would end up looking like $$$EnhancerByGuice$$, with the extra $
+          // at the front.
+          return super.getClassName(prefix, "Enhancer", key, names);
+        }
+      };
   /*end[AOP]*/
   /*if[NO_AOP]
   private static final String CGLIB_PACKAGE = " "; // any string that's illegal in a package name
   end[NO_AOP]*/
 
   /**
-   * Weak cache of bridge class loaders that make the Guice implementation
-   * classes visible to various code-generated proxies of client classes.
+   * Weak cache of bridge class loaders that make the Guice implementation classes visible to
+   * various code-generated proxies of client classes.
    */
   private static final LoadingCache<ClassLoader, ClassLoader> CLASS_LOADER_CACHE;
 
@@ -130,30 +133,32 @@
     if (getCustomClassLoadingOption() == CustomClassLoadingOption.OFF) {
       builder.maximumSize(0);
     }
-    CLASS_LOADER_CACHE = builder.build(
-        new CacheLoader<ClassLoader, ClassLoader>() {
-          @Override public ClassLoader load(final ClassLoader typeClassLoader) {
-            logger.fine("Creating a bridge ClassLoader for " + typeClassLoader);
-            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
-              public ClassLoader run() {
-                return new BridgeClassLoader(typeClassLoader);
+    CLASS_LOADER_CACHE =
+        builder.build(
+            new CacheLoader<ClassLoader, ClassLoader>() {
+              @Override
+              public ClassLoader load(final ClassLoader typeClassLoader) {
+                logger.fine("Creating a bridge ClassLoader for " + typeClassLoader);
+                return AccessController.doPrivileged(
+                    new PrivilegedAction<ClassLoader>() {
+                      @Override
+                      public ClassLoader run() {
+                        return new BridgeClassLoader(typeClassLoader);
+                      }
+                    });
               }
             });
-          }
-        });
   }
 
   /**
-   * Attempts to canonicalize null references to the system class loader.
-   * May return null if for some reason the system loader is unavailable.
+   * Attempts to canonicalize null references to the system class loader. May return null if for
+   * some reason the system loader is unavailable.
    */
   private static ClassLoader canonicalize(ClassLoader classLoader) {
     return classLoader != null ? classLoader : SystemBridgeHolder.SYSTEM_BRIDGE.getParent();
   }
 
-  /**
-   * Returns the class loader to host generated classes for {@code type}.
-   */
+  /** Returns the class loader to host generated classes for {@code type}. */
   public static ClassLoader getClassLoader(Class<?> type) {
     return getClassLoader(type, type.getClassLoader());
   }
@@ -191,19 +196,108 @@
   }
 
   /*if[AOP]*/
-  // use fully-qualified names so imports don't need preprocessor statements 
-  public static net.sf.cglib.reflect.FastClass newFastClass(Class<?> type, Visibility visibility) {
-    net.sf.cglib.reflect.FastClass.Generator generator
-        = new net.sf.cglib.reflect.FastClass.Generator();
-    generator.setType(type);
-    if (visibility == Visibility.PUBLIC) {
+  // use fully-qualified names so imports don't need preprocessor statements
+  /**
+   * Returns a FastClass proxy for invoking the given member or {@code null} if access rules
+   * disallow it.
+   *
+   * @see #newFastClassForMember(Class, Member) for a full description
+   */
+  public static net.sf.cglib.reflect.FastClass newFastClassForMember(Member member) {
+    return newFastClassForMember(member.getDeclaringClass(), member);
+  }
+
+  /**
+   * Returns a FastClass proxy for invoking the given member or {@code null} if access rules
+   * disallow it.
+   *
+   * <p>FastClass works by generating a type in the same package as the target {@code type}. This
+   * may or may not work depending on the access level of the class/member. It breaks down into the
+   * following cases depending on accessibility:
+   *
+   * <ul>
+   * <li>Public: This always works since we can generate the type into the {@link BridgeClassLoader}
+   *     which ensures there are no versioning issues.
+   * <li>Package private and Protected: This works as long as:
+   *     <ul>
+   *     <li>We can generate into the same classloader as the type. This is not possible for JDK
+   *         types which use the 'bootstrap' loader.
+   *     <li>The classloader of the type has the same version of {@code FastClass} as we do. This
+   *         may be violated when running in OSGI bundles.
+   *     </ul>
+   *
+   * <li>Private: This never works.
+   * </ul>
+   *
+   * If we are unable to generate the type, then we return null and callers should work around by
+   * using normal java reflection.
+   */
+  public static net.sf.cglib.reflect.FastClass newFastClassForMember(Class<?> type, Member member) {
+    if (!new net.sf.cglib.core.VisibilityPredicate(type, false).evaluate(member)) {
+      // the member cannot be indexed by fast class.  Bail out.
+      return null;
+    }
+
+    boolean publiclyCallable = isPubliclyCallable(member);
+    if (!publiclyCallable && !hasSameVersionOfCglib(type.getClassLoader())) {
+      // The type is in a classloader with a different version of cglib and is not publicly visible
+      // (so we can't use the bridge classloader to work around).  Bail out.
+      return null;
+    }
+    net.sf.cglib.reflect.FastClass.Generator generator =
+        new net.sf.cglib.reflect.FastClass.Generator();
+    if (publiclyCallable) {
+      // Use the bridge classloader if we can
       generator.setClassLoader(getClassLoader(type));
     }
+    generator.setType(type);
     generator.setNamingPolicy(FASTCLASS_NAMING_POLICY);
-    logger.fine("Loading " + type + " FastClass with " + generator.getClassLoader());
+    if (logger.isLoggable(Level.FINE)) {
+      logger.fine("Loading " + type + " FastClass with " + generator.getClassLoader());
+    }
     return generator.create();
   }
 
+  /**
+   * Returns true if the types classloader has the same version of cglib that BytecodeGen has. This
+   * only returns false in strange OSGI situations, but it prevents us from using FastClass for non
+   * public members.
+   */
+  private static boolean hasSameVersionOfCglib(ClassLoader classLoader) {
+    Class<?> fc = net.sf.cglib.reflect.FastClass.class;
+    try {
+      return classLoader.loadClass(fc.getName()) == fc;
+    } catch (ClassNotFoundException e) {
+      return false;
+    }
+  }
+
+  /**
+   * Returns true if the member can be called by a fast class generated in a different classloader.
+   */
+  private static boolean isPubliclyCallable(Member member) {
+    if (!Modifier.isPublic(member.getModifiers())) {
+      return false;
+    }
+    Class<?>[] parameterTypes;
+    if (member instanceof Constructor) {
+      parameterTypes = ((Constructor) member).getParameterTypes();
+    } else {
+      Method method = (Method) member;
+      if (!Modifier.isPublic(method.getReturnType().getModifiers())) {
+        return false;
+      }
+      parameterTypes = method.getParameterTypes();
+    }
+
+    for (Class<?> type : parameterTypes) {
+      if (!Modifier.isPublic(type.getModifiers())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   public static net.sf.cglib.proxy.Enhancer newEnhancer(Class<?> type, Visibility visibility) {
     net.sf.cglib.proxy.Enhancer enhancer = new net.sf.cglib.proxy.Enhancer();
     enhancer.setSuperclass(type);
@@ -298,10 +392,10 @@
       super(usersClassLoader);
     }
 
-    @Override protected Class<?> loadClass(String name, boolean resolve)
-        throws ClassNotFoundException {
+    @Override
+    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
 
-      if (name.startsWith("sun.reflect")) {
+      if (name.startsWith("sun.reflect") || name.startsWith("jdk.internal.reflect")) {
         // these reflection classes must be loaded from bootstrap class loader
         return SystemBridgeHolder.SYSTEM_BRIDGE.classicLoadClass(name, resolve);
       }
@@ -326,8 +420,7 @@
     }
 
     // make the classic delegating loadClass method visible
-    Class<?> classicLoadClass(String name, boolean resolve)
-      throws ClassNotFoundException {
+    Class<?> classicLoadClass(String name, boolean resolve) throws ClassNotFoundException {
       return super.loadClass(name, resolve);
     }
   }
diff --git a/core/src/com/google/inject/internal/CircularDependencyProxy.java b/core/src/com/google/inject/internal/CircularDependencyProxy.java
index fe894a4..dc12748 100644
--- a/core/src/com/google/inject/internal/CircularDependencyProxy.java
+++ b/core/src/com/google/inject/internal/CircularDependencyProxy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +16,7 @@
 
 package com.google.inject.internal;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public interface CircularDependencyProxy {
   // marker interface
 }
diff --git a/core/src/com/google/inject/internal/ConstantBindingBuilderImpl.java b/core/src/com/google/inject/internal/ConstantBindingBuilderImpl.java
index 8a0c5c6..1c11cfe 100644
--- a/core/src/com/google/inject/internal/ConstantBindingBuilderImpl.java
+++ b/core/src/com/google/inject/internal/ConstantBindingBuilderImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.binder.ConstantBindingBuilder;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.annotation.Annotation;
 import java.util.List;
 
@@ -32,8 +31,7 @@
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
-public final class ConstantBindingBuilderImpl<T>
-    extends AbstractBindingBuilder<T>
+public final class ConstantBindingBuilderImpl<T> extends AbstractBindingBuilder<T>
     implements AnnotatedConstantBindingBuilder, ConstantBindingBuilder {
 
   @SuppressWarnings("unchecked") // constant bindings start out with T unknown
@@ -41,56 +39,69 @@
     super(binder, elements, source, (Key<T>) NULL_KEY);
   }
 
+  @Override
   public ConstantBindingBuilder annotatedWith(Class<? extends Annotation> annotationType) {
     annotatedWithInternal(annotationType);
     return this;
   }
 
+  @Override
   public ConstantBindingBuilder annotatedWith(Annotation annotation) {
     annotatedWithInternal(annotation);
     return this;
   }
 
+  @Override
   public void to(final String value) {
     toConstant(String.class, value);
   }
 
+  @Override
   public void to(final int value) {
     toConstant(Integer.class, value);
   }
 
+  @Override
   public void to(final long value) {
     toConstant(Long.class, value);
   }
 
+  @Override
   public void to(final boolean value) {
     toConstant(Boolean.class, value);
   }
 
+  @Override
   public void to(final double value) {
     toConstant(Double.class, value);
   }
 
+  @Override
   public void to(final float value) {
     toConstant(Float.class, value);
   }
 
+  @Override
   public void to(final short value) {
     toConstant(Short.class, value);
   }
 
+  @Override
   public void to(final char value) {
     toConstant(Character.class, value);
   }
 
+  @Override
   public void to(final byte value) {
     toConstant(Byte.class, value);
-  }  
+  }
 
+  @Override
   public void to(final Class<?> value) {
     toConstant(Class.class, value);
   }
 
+  @Override
   public <E extends Enum<E>> void to(final E value) {
     toConstant(value.getDeclaringClass(), value);
   }
@@ -121,11 +132,17 @@
       binder.addError(BINDING_TO_NULL);
     }
 
-    setBinding(new InstanceBindingImpl<T>(
-        base.getSource(), key, base.getScoping(), ImmutableSet.<InjectionPoint>of(), instanceAsT));
+    setBinding(
+        new InstanceBindingImpl<T>(
+            base.getSource(),
+            key,
+            base.getScoping(),
+            ImmutableSet.<InjectionPoint>of(),
+            instanceAsT));
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "ConstantBindingBuilder";
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/ConstantFactory.java b/core/src/com/google/inject/internal/ConstantFactory.java
index 633d5de..d932003 100644
--- a/core/src/com/google/inject/internal/ConstantFactory.java
+++ b/core/src/com/google/inject/internal/ConstantFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,12 +16,10 @@
 
 package com.google.inject.internal;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.spi.Dependency;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 final class ConstantFactory<T> implements InternalFactory<T> {
 
   private final Initializable<T> initializable;
@@ -30,14 +28,14 @@
     this.initializable = initializable;
   }
 
-  public T get(Errors errors, InternalContext context, Dependency dependency, boolean linked)
-      throws ErrorsException {
-    return initializable.get(errors);
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
+    return initializable.get();
   }
 
+  @Override
   public String toString() {
-    return Objects.toStringHelper(ConstantFactory.class)
-        .add("value", initializable)
-        .toString();
+    return MoreObjects.toStringHelper(ConstantFactory.class).add("value", initializable).toString();
   }
 }
diff --git a/core/src/com/google/inject/internal/ConstructionContext.java b/core/src/com/google/inject/internal/ConstructionContext.java
index ced388f..25786f5 100644
--- a/core/src/com/google/inject/internal/ConstructionContext.java
+++ b/core/src/com/google/inject/internal/ConstructionContext.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.internal;
 
 import com.google.inject.internal.InjectorImpl.InjectorOptions;
-
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.List;
@@ -59,28 +58,31 @@
     invocationHandlers = null;
   }
 
-  public Object createProxy(Errors errors, InjectorOptions injectorOptions,
-      Class<?> expectedType) throws ErrorsException {
+  public Object createProxy(InjectorOptions injectorOptions, Class<?> expectedType)
+      throws InternalProvisionException {
     if (injectorOptions.disableCircularProxies) {
-      throw errors.circularProxiesDisabled(expectedType).toException();
+      throw InternalProvisionException.circularDependenciesDisabled(expectedType);
     }
     if (!expectedType.isInterface()) {
-      throw errors.cannotSatisfyCircularDependency(expectedType).toException();
+      throw InternalProvisionException.cannotProxyClass(expectedType);
     }
 
     if (invocationHandlers == null) {
-      invocationHandlers = new ArrayList<DelegatingInvocationHandler<T>>();
+      invocationHandlers = new ArrayList<>();
     }
 
-    DelegatingInvocationHandler<T> invocationHandler = new DelegatingInvocationHandler<T>();
+    DelegatingInvocationHandler<T> invocationHandler = new DelegatingInvocationHandler<>();
     invocationHandlers.add(invocationHandler);
 
     // TODO: if I create a proxy which implements all the interfaces of
     // the implementation type, I'll be able to get away with one proxy
     // instance (as opposed to one per caller).
     ClassLoader classLoader = BytecodeGen.getClassLoader(expectedType);
-    return expectedType.cast(Proxy.newProxyInstance(classLoader,
-        new Class[] { expectedType, CircularDependencyProxy.class }, invocationHandler));
+    return expectedType.cast(
+        Proxy.newProxyInstance(
+            classLoader,
+            new Class[] {expectedType, CircularDependencyProxy.class},
+            invocationHandler));
   }
 
   public void setProxyDelegates(T delegate) {
diff --git a/core/src/com/google/inject/internal/ConstructionProxy.java b/core/src/com/google/inject/internal/ConstructionProxy.java
index 6c6f3fc..2f56cf0 100644
--- a/core/src/com/google/inject/internal/ConstructionProxy.java
+++ b/core/src/com/google/inject/internal/ConstructionProxy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,28 +18,22 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.List;
 
 /**
- * Proxies calls to a {@link java.lang.reflect.Constructor} for a class
- * {@code T}.
+ * Proxies calls to a {@link java.lang.reflect.Constructor} for a class {@code T}.
  *
  * @author crazybob@google.com (Bob Lee)
  */
 interface ConstructionProxy<T> {
 
-  /**
-   * Constructs an instance of {@code T} for the given arguments.
-   */
+  /** Constructs an instance of {@code T} for the given arguments. */
   T newInstance(Object... arguments) throws InvocationTargetException;
 
-  /**
-   * Returns the injection point for this constructor.
-   */
+  /** Returns the injection point for this constructor. */
   InjectionPoint getInjectionPoint();
 
   /**
@@ -49,9 +43,7 @@
   Constructor<T> getConstructor();
 
   /*if[AOP]*/
-  /**
-   * Returns the interceptors applied to each method, in order of invocation.
-   */
+  /** Returns the interceptors applied to each method, in order of invocation. */
   ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>> getMethodInterceptors();
   /*end[AOP]*/
 }
diff --git a/core/src/com/google/inject/internal/ConstructionProxyFactory.java b/core/src/com/google/inject/internal/ConstructionProxyFactory.java
index 0eca0fe..5122524 100644
--- a/core/src/com/google/inject/internal/ConstructionProxyFactory.java
+++ b/core/src/com/google/inject/internal/ConstructionProxyFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,8 +23,6 @@
  */
 interface ConstructionProxyFactory<T> {
 
-  /**
-   * Gets a construction proxy for the given constructor.
-   */
+  /** Gets a construction proxy for the given constructor. */
   ConstructionProxy<T> create() throws ErrorsException;
 }
diff --git a/core/src/com/google/inject/internal/ConstructorBindingImpl.java b/core/src/com/google/inject/internal/ConstructorBindingImpl.java
index 8fb2103..d141d65 100644
--- a/core/src/com/google/inject/internal/ConstructorBindingImpl.java
+++ b/core/src/com/google/inject/internal/ConstructorBindingImpl.java
@@ -19,6 +19,7 @@
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.inject.internal.Annotations.findScopeAnnotation;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
@@ -31,7 +32,6 @@
 import com.google.inject.spi.ConstructorBinding;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -46,44 +46,60 @@
   private final Factory<T> factory;
   private final InjectionPoint constructorInjectionPoint;
 
-  private ConstructorBindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> scopedFactory, Scoping scoping, Factory<T> factory,
+  private ConstructorBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> scopedFactory,
+      Scoping scoping,
+      Factory<T> factory,
       InjectionPoint constructorInjectionPoint) {
     super(injector, key, source, scopedFactory, scoping);
     this.factory = factory;
     this.constructorInjectionPoint = constructorInjectionPoint;
   }
 
-  public ConstructorBindingImpl(Key<T> key, Object source, Scoping scoping,
-      InjectionPoint constructorInjectionPoint, Set<InjectionPoint> injectionPoints) {
+  public ConstructorBindingImpl(
+      Key<T> key,
+      Object source,
+      Scoping scoping,
+      InjectionPoint constructorInjectionPoint,
+      Set<InjectionPoint> injectionPoints) {
     super(source, key, scoping);
-    this.factory = new Factory<T>(false, key);
-    ConstructionProxy<T> constructionProxy
-        = new DefaultConstructionProxyFactory<T>(constructorInjectionPoint).create();
+    this.factory = new Factory<>(false, key);
+    ConstructionProxy<T> constructionProxy =
+        new DefaultConstructionProxyFactory<T>(constructorInjectionPoint).create();
     this.constructorInjectionPoint = constructorInjectionPoint;
-    factory.constructorInjector = new ConstructorInjector<T>(
-        injectionPoints, constructionProxy, null, null);
+    factory.constructorInjector =
+        new ConstructorInjector<T>(injectionPoints, constructionProxy, null, null);
   }
 
   /**
    * @param constructorInjector the constructor to use, or {@code null} to use the default.
-   * @param failIfNotLinked true if this ConstructorBindingImpl's InternalFactory should
-   *                             only succeed if retrieved from a linked binding
+   * @param failIfNotLinked true if this ConstructorBindingImpl's InternalFactory should only
+   *     succeed if retrieved from a linked binding
    */
-  static <T> ConstructorBindingImpl<T> create(InjectorImpl injector, Key<T> key,
-      InjectionPoint constructorInjector, Object source, Scoping scoping, Errors errors,
-      boolean failIfNotLinked, boolean failIfNotExplicit)
+  static <T> ConstructorBindingImpl<T> create(
+      InjectorImpl injector,
+      Key<T> key,
+      InjectionPoint constructorInjector,
+      Object source,
+      Scoping scoping,
+      Errors errors,
+      boolean failIfNotLinked,
+      boolean failIfNotExplicit)
       throws ErrorsException {
     int numErrors = errors.size();
 
     @SuppressWarnings("unchecked") // constructorBinding guarantees type is consistent
-    Class<? super T> rawType = constructorInjector == null
-        ? key.getTypeLiteral().getRawType()
-        : (Class) constructorInjector.getDeclaringType().getRawType();
+    Class<? super T> rawType =
+        constructorInjector == null
+            ? key.getTypeLiteral().getRawType()
+            : (Class) constructorInjector.getDeclaringType().getRawType();
 
     // We can't inject abstract classes.
     if (Modifier.isAbstract(rawType.getModifiers())) {
-      errors.missingImplementation(key);
+      errors.missingImplementationWithHint(key, injector);
     }
 
     // Error: Inner class.
@@ -110,16 +126,17 @@
       Class<?> annotatedType = constructorInjector.getMember().getDeclaringClass();
       Class<? extends Annotation> scopeAnnotation = findScopeAnnotation(errors, annotatedType);
       if (scopeAnnotation != null) {
-        scoping = Scoping.makeInjectable(Scoping.forAnnotation(scopeAnnotation),
-            injector, errors.withSource(rawType));
+        scoping =
+            Scoping.makeInjectable(
+                Scoping.forAnnotation(scopeAnnotation), injector, errors.withSource(rawType));
       }
     }
 
     errors.throwIfNewErrors(numErrors);
 
-    Factory<T> factoryFactory = new Factory<T>(failIfNotLinked, key);
-    InternalFactory<? extends T> scopedFactory
-        = Scoping.scope(key, injector, factoryFactory, source, scoping);
+    Factory<T> factoryFactory = new Factory<>(failIfNotLinked, key);
+    InternalFactory<? extends T> scopedFactory =
+        Scoping.scope(key, injector, factoryFactory, source, scoping);
 
     return new ConstructorBindingImpl<T>(
         injector, key, source, scopedFactory, scoping, factoryFactory, constructorInjector);
@@ -131,12 +148,12 @@
         || cxtor.isAnnotationPresent(javax.inject.Inject.class);
   }
 
+  @Override
   @SuppressWarnings("unchecked") // the result type always agrees with the ConstructorInjector type
   public void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
     factory.constructorInjector =
         (ConstructorInjector<T>) injector.constructors.get(constructorInjectionPoint, errors);
-    factory.provisionCallback =
-      injector.provisionListenerStore.get(this);
+    factory.provisionCallback = injector.provisionListenerStore.get(this);
   }
 
   /** True if this binding has been initialized and is ready for use. */
@@ -146,7 +163,7 @@
 
   /** Returns an injection point that can be used to clean up the constructor store. */
   InjectionPoint getInternalConstructor() {
-    if(factory.constructorInjector != null) {
+    if (factory.constructorInjector != null) {
       return factory.constructorInjector.getConstructionProxy().getInjectionPoint();
     } else {
       return constructorInjectionPoint;
@@ -156,69 +173,87 @@
   /** Returns a set of dependencies that can be iterated over to clean up stray JIT bindings. */
   Set<Dependency<?>> getInternalDependencies() {
     ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
-    if(factory.constructorInjector == null) {
+    if (factory.constructorInjector == null) {
       builder.add(constructorInjectionPoint);
       // If the below throws, it's OK -- we just ignore those dependencies, because no one
       // could have used them anyway.
       try {
-        builder.addAll(InjectionPoint.forInstanceMethodsAndFields(constructorInjectionPoint.getDeclaringType()));
-      } catch(ConfigurationException ignored) {}
+        builder.addAll(
+            InjectionPoint.forInstanceMethodsAndFields(
+                constructorInjectionPoint.getDeclaringType()));
+      } catch (ConfigurationException ignored) {
+      }
     } else {
-      builder.add(getConstructor())
-             .addAll(getInjectableMembers());
+      builder.add(getConstructor()).addAll(getInjectableMembers());
     }
 
     return Dependency.forInjectionPoints(builder.build());
   }
 
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     checkState(factory.constructorInjector != null, "not initialized");
     return visitor.visit(this);
   }
 
+  @Override
   public InjectionPoint getConstructor() {
     checkState(factory.constructorInjector != null, "Binding is not ready");
     return factory.constructorInjector.getConstructionProxy().getInjectionPoint();
   }
 
+  @Override
   public Set<InjectionPoint> getInjectableMembers() {
     checkState(factory.constructorInjector != null, "Binding is not ready");
     return factory.constructorInjector.getInjectableMembers();
   }
 
   /*if[AOP]*/
+  @Override
   public Map<Method, List<org.aopalliance.intercept.MethodInterceptor>> getMethodInterceptors() {
     checkState(factory.constructorInjector != null, "Binding is not ready");
     return factory.constructorInjector.getConstructionProxy().getMethodInterceptors();
   }
   /*end[AOP]*/
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
-    return Dependency.forInjectionPoints(new ImmutableSet.Builder<InjectionPoint>()
-        .add(getConstructor())
-        .addAll(getInjectableMembers())
-        .build());
+    return Dependency.forInjectionPoints(
+        new ImmutableSet.Builder<InjectionPoint>()
+            .add(getConstructor())
+            .addAll(getInjectableMembers())
+            .build());
   }
 
-  @Override protected BindingImpl<T> withScoping(Scoping scoping) {
+  @Override
+  protected BindingImpl<T> withScoping(Scoping scoping) {
     return new ConstructorBindingImpl<T>(
         null, getKey(), getSource(), factory, scoping, factory, constructorInjectionPoint);
   }
 
-  @Override protected BindingImpl<T> withKey(Key<T> key) {
+  @Override
+  protected BindingImpl<T> withKey(Key<T> key) {
     return new ConstructorBindingImpl<T>(
         null, key, getSource(), factory, getScoping(), factory, constructorInjectionPoint);
   }
 
+  @Override
   @SuppressWarnings("unchecked") // the raw constructor member and declaring type always agree
   public void applyTo(Binder binder) {
     InjectionPoint constructor = getConstructor();
-    getScoping().applyTo(binder.withSource(getSource()).bind(getKey()).toConstructor(
-        (Constructor) getConstructor().getMember(), (TypeLiteral) constructor.getDeclaringType()));
+    getScoping()
+        .applyTo(
+            binder
+                .withSource(getSource())
+                .bind(getKey())
+                .toConstructor(
+                    (Constructor) getConstructor().getMember(),
+                    (TypeLiteral) constructor.getDeclaringType()));
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(ConstructorBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(ConstructorBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("scope", getScoping())
@@ -227,11 +262,11 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof ConstructorBindingImpl) {
-      ConstructorBindingImpl<?> o = (ConstructorBindingImpl<?>)obj;
+    if (obj instanceof ConstructorBindingImpl) {
+      ConstructorBindingImpl<?> o = (ConstructorBindingImpl<?>) obj;
       return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping())
-        && Objects.equal(constructorInjectionPoint, o.constructorInjectionPoint);
+          && getScoping().equals(o.getScoping())
+          && Objects.equal(constructorInjectionPoint, o.constructorInjectionPoint);
     } else {
       return false;
     }
@@ -253,19 +288,22 @@
       this.key = key;
     }
 
+    @Override
     @SuppressWarnings("unchecked")
-    public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-        throws ErrorsException {
-      checkState(constructorInjector != null, "Constructor not ready");
+    public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+        throws InternalProvisionException {
+      ConstructorInjector<T> localInjector = constructorInjector;
+      if (localInjector == null) {
+        throw new IllegalStateException("Constructor not ready");
+      }
 
-      if(failIfNotLinked && !linked) {
-        throw errors.jitDisabled(key).toException();
+      if (!linked && failIfNotLinked) {
+        throw InternalProvisionException.jitDisabled(key);
       }
 
       // This may not actually be safe because it could return a super type of T (if that's all the
       // client needs), but it should be OK in practice thanks to the wonders of erasure.
-      return (T) constructorInjector.construct(errors, context,
-          dependency.getKey().getTypeLiteral().getRawType(), provisionCallback);
+      return (T) localInjector.construct(context, dependency, provisionCallback);
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/ConstructorInjector.java b/core/src/com/google/inject/internal/ConstructorInjector.java
index 1ff4be1..13e1147 100644
--- a/core/src/com/google/inject/internal/ConstructorInjector.java
+++ b/core/src/com/google/inject/internal/ConstructorInjector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +18,8 @@
 
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
+import com.google.inject.spi.Dependency;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.reflect.InvocationTargetException;
 import java.util.Set;
 
@@ -36,7 +36,8 @@
   private final ConstructionProxy<T> constructionProxy;
   private final MembersInjectorImpl<T> membersInjector;
 
-  ConstructorInjector(Set<InjectionPoint> injectableMembers,
+  ConstructorInjector(
+      Set<InjectionPoint> injectableMembers,
       ConstructionProxy<T> constructionProxy,
       SingleParameterInjector<?>[] parameterInjectors,
       MembersInjectorImpl<T> membersInjector) {
@@ -55,40 +56,48 @@
   }
 
   /**
-   * Construct an instance. Returns {@code Object} instead of {@code T} because
-   * it may return a proxy.
+   * Construct an instance. Returns {@code Object} instead of {@code T} because it may return a
+   * proxy.
    */
-  Object construct(final Errors errors, final InternalContext context,
-      Class<?> expectedType,
-      ProvisionListenerStackCallback<T> provisionCallback)
-      throws ErrorsException {
+  Object construct(
+      final InternalContext context,
+      Dependency<?> dependency,
+      /* @Nullable */ ProvisionListenerStackCallback<T> provisionCallback)
+      throws InternalProvisionException {
     final ConstructionContext<T> constructionContext = context.getConstructionContext(this);
-
     // We have a circular reference between constructors. Return a proxy.
     if (constructionContext.isConstructing()) {
       // TODO (crazybob): if we can't proxy this object, can we proxy the other object?
       return constructionContext.createProxy(
-          errors, context.getInjectorOptions(), expectedType);
+          context.getInjectorOptions(), dependency.getKey().getTypeLiteral().getRawType());
     }
 
     // If we're re-entering this factory while injecting fields or methods,
     // return the same instance. This prevents infinite loops.
     T t = constructionContext.getCurrentReference();
     if (t != null) {
-      return t;
+      if (context.getInjectorOptions().disableCircularProxies) {
+        throw InternalProvisionException.circularDependenciesDisabled(
+            dependency.getKey().getTypeLiteral().getRawType());
+      } else {
+        return t;
+      }
     }
 
     constructionContext.startConstruction();
     try {
       // Optimization: Don't go through the callback stack if we have no listeners.
-      if (!provisionCallback.hasListeners()) {
-        return provision(errors, context, constructionContext);
+      if (provisionCallback == null) {
+        return provision(context, constructionContext);
       } else {
-        return provisionCallback.provision(errors, context, new ProvisionCallback<T>() {
-          public T call() throws ErrorsException {
-            return provision(errors, context, constructionContext);
-          }
-        });
+        return provisionCallback.provision(
+            context,
+            new ProvisionCallback<T>() {
+              @Override
+              public T call() throws InternalProvisionException {
+                return provision(context, constructionContext);
+              }
+            });
       }
     } finally {
       constructionContext.finishConstruction();
@@ -96,12 +105,12 @@
   }
 
   /** Provisions a new T. */
-  private T provision(Errors errors, InternalContext context,
-      ConstructionContext<T> constructionContext) throws ErrorsException {
+  private T provision(InternalContext context, ConstructionContext<T> constructionContext)
+      throws InternalProvisionException {
     try {
       T t;
       try {
-        Object[] parameters = SingleParameterInjector.getAll(errors, context, parameterInjectors);
+        Object[] parameters = SingleParameterInjector.getAll(context, parameterInjectors);
         t = constructionProxy.newInstance(parameters);
         constructionContext.setProxyDelegates(t);
       } finally {
@@ -111,16 +120,15 @@
       // Store reference. If an injector re-enters this factory, they'll get the same reference.
       constructionContext.setCurrentReference(t);
 
-      membersInjector.injectMembers(t, errors, context, false);
-      membersInjector.notifyListeners(t, errors);
+      MembersInjectorImpl<T> localMembersInjector = membersInjector;
+      localMembersInjector.injectMembers(t, context, false);
+      localMembersInjector.notifyListeners(t);
 
       return t;
     } catch (InvocationTargetException userException) {
-      Throwable cause = userException.getCause() != null
-          ? userException.getCause()
-          : userException;
-      throw errors.withSource(constructionProxy.getInjectionPoint())
-          .errorInjectingConstructor(cause).toException();
+      Throwable cause = userException.getCause() != null ? userException.getCause() : userException;
+      throw InternalProvisionException.errorInjectingConstructor(cause)
+          .addSource(constructionProxy.getInjectionPoint());
     } finally {
       constructionContext.removeCurrentReference();
     }
diff --git a/core/src/com/google/inject/internal/ConstructorInjectorStore.java b/core/src/com/google/inject/internal/ConstructorInjectorStore.java
index b8e4867..eb17a54 100644
--- a/core/src/com/google/inject/internal/ConstructorInjectorStore.java
+++ b/core/src/com/google/inject/internal/ConstructorInjectorStore.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,35 +29,33 @@
 final class ConstructorInjectorStore {
   private final InjectorImpl injector;
 
-  private final FailableCache<InjectionPoint, ConstructorInjector<?>>  cache
-      = new FailableCache<InjectionPoint, ConstructorInjector<?>> () {
-    @Override
-    protected ConstructorInjector<?> create(InjectionPoint constructorInjector, Errors errors)
-        throws ErrorsException {
-      return createConstructor(constructorInjector, errors);
-    }
-  };
+  private final FailableCache<InjectionPoint, ConstructorInjector<?>> cache =
+      new FailableCache<InjectionPoint, ConstructorInjector<?>>() {
+        @Override
+        protected ConstructorInjector<?> create(InjectionPoint constructorInjector, Errors errors)
+            throws ErrorsException {
+          return createConstructor(constructorInjector, errors);
+        }
+      };
 
   ConstructorInjectorStore(InjectorImpl injector) {
     this.injector = injector;
   }
 
-  /**
-   * Returns a new complete constructor injector with injection listeners registered.
-   */
+  /** Returns a new complete constructor injector with injection listeners registered. */
   public ConstructorInjector<?> get(InjectionPoint constructorInjector, Errors errors)
       throws ErrorsException {
     return cache.get(constructorInjector, errors);
   }
-  
+
   /**
    * Purges an injection point from the cache. Use this only if the cache is not actually valid and
    * needs to be purged. (See issue 319 and
    * ImplicitBindingTest#testCircularJitBindingsLeaveNoResidue and
    * #testInstancesRequestingProvidersForThemselvesWithChildInjectors for examples of when this is
    * necessary.)
-   * 
-   * Returns true if the injector for that point was stored in the cache, false otherwise.
+   *
+   * <p>Returns true if the injector for that point was stored in the cache, false otherwise.
    */
   boolean remove(InjectionPoint ip) {
     return cache.remove(ip);
@@ -67,27 +65,32 @@
       throws ErrorsException {
     int numErrorsBefore = errors.size();
 
-    SingleParameterInjector<?>[] constructorParameterInjectors
-        = injector.getParametersInjectors(injectionPoint.getDependencies(), errors);
+    SingleParameterInjector<?>[] constructorParameterInjectors =
+        injector.getParametersInjectors(injectionPoint.getDependencies(), errors);
 
     @SuppressWarnings("unchecked") // the injector type agrees with the injection point type
-    MembersInjectorImpl<T> membersInjector = (MembersInjectorImpl<T>) injector.membersInjectorStore
-        .get(injectionPoint.getDeclaringType(), errors);
+    MembersInjectorImpl<T> membersInjector =
+        (MembersInjectorImpl<T>)
+            injector.membersInjectorStore.get(injectionPoint.getDeclaringType(), errors);
 
     /*if[AOP]*/
     ImmutableList<MethodAspect> injectorAspects = injector.state.getMethodAspects();
-    ImmutableList<MethodAspect> methodAspects = membersInjector.getAddedAspects().isEmpty()
-        ? injectorAspects
-        : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects()));
-    ConstructionProxyFactory<T> factory = new ProxyFactory<T>(injectionPoint, methodAspects);
+    ImmutableList<MethodAspect> methodAspects =
+        membersInjector.getAddedAspects().isEmpty()
+            ? injectorAspects
+            : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects()));
+    ConstructionProxyFactory<T> factory = new ProxyFactory<>(injectionPoint, methodAspects);
     /*end[AOP]*/
     /*if[NO_AOP]
-    ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<T>(injectionPoint);
+    ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<>(injectionPoint);
     end[NO_AOP]*/
 
     errors.throwIfNewErrors(numErrorsBefore);
 
-    return new ConstructorInjector<T>(membersInjector.getInjectionPoints(), factory.create(),
-        constructorParameterInjectors, membersInjector);
+    return new ConstructorInjector<T>(
+        membersInjector.getInjectionPoints(),
+        factory.create(),
+        constructorParameterInjectors,
+        membersInjector);
   }
 }
diff --git a/core/src/com/google/inject/internal/ContextualCallable.java b/core/src/com/google/inject/internal/ContextualCallable.java
deleted file mode 100644
index 56c0630..0000000
--- a/core/src/com/google/inject/internal/ContextualCallable.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (C) 2006 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.internal;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
-interface ContextualCallable<T> {
-  T call(InternalContext context) throws ErrorsException;
-}
diff --git a/core/src/com/google/inject/internal/CreationListener.java b/core/src/com/google/inject/internal/CreationListener.java
index 1779204..53a61ee 100644
--- a/core/src/com/google/inject/internal/CreationListener.java
+++ b/core/src/com/google/inject/internal/CreationListener.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,4 +21,4 @@
 
   /** Notifies that creation should happen. */
   void notify(Errors errors);
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/CycleDetectingLock.java b/core/src/com/google/inject/internal/CycleDetectingLock.java
index 690b151..7b387b0 100644
--- a/core/src/com/google/inject/internal/CycleDetectingLock.java
+++ b/core/src/com/google/inject/internal/CycleDetectingLock.java
@@ -2,7 +2,6 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Supplier;
-import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableListMultimap;
 import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.ListMultimap;
@@ -10,7 +9,6 @@
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
-
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -21,166 +19,174 @@
 /**
  * Simplified version of {@link Lock} that is special due to how it handles deadlocks detection.
  *
- * <p>Is an inherent part of {@link SingletonScope}, moved into a upper level class due
- * to its size and complexity.
+ * <p>Is an inherent part of {@link SingletonScope}, moved into a upper level class due to its size
+ * and complexity.
  *
- * @param <ID> Lock identification provided by the client, is returned unmodified to the client
- *        when lock cycle is detected to identify it. Only toString() needs to be implemented.
- *        Lock references this object internally,
- *        for the purposes of Garbage Collection you should not use heavy IDs.
- *        Lock is referenced by a lock factory as long as it's owned by a thread.
- *
+ * @param <ID> Lock identification provided by the client, is returned unmodified to the client when
+ *     lock cycle is detected to identify it. Only toString() needs to be implemented. Lock
+ *     references this object internally, for the purposes of Garbage Collection you should not use
+ *     heavy IDs. Lock is referenced by a lock factory as long as it's owned by a thread.
  * @see SingletonScope
  * @see com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory
- *
  * @author timofeyb (Timothy Basanov)
  */
 interface CycleDetectingLock<ID> {
 
   /**
-   * Takes a lock in a blocking fashion in case no potential deadlocks are detected.
-   * If the lock was successfully owned, returns an empty map indicating no detected potential
-   * deadlocks.
+   * Takes a lock in a blocking fashion in case no potential deadlocks are detected. If the lock was
+   * successfully owned, returns an empty map indicating no detected potential deadlocks.
    *
-   * Otherwise, a map indicating threads involved in a potential deadlock are returned.
-   * Map is ordered by dependency cycle and lists locks for each thread that are part of
-   * the loop in order. Returned map is created atomically.
+   * <p>Otherwise, a map indicating threads involved in a potential deadlock are returned. Map is
+   * ordered by dependency cycle and lists locks for each thread that are part of the loop in order,
+   * the last lock in the list is the one that the thread is currently waiting for. Returned map is
+   * created atomically.
    *
-   * In case no cycle is detected performance is O(threads creating singletons),
-   * in case cycle is detected performance is O(singleton locks).
+   * <p>In case no cycle is detected performance is O(threads creating singletons), in case cycle is
+   * detected performance is O(singleton locks).
    */
-  ListMultimap<Long, ID> lockOrDetectPotentialLocksCycle();
+  ListMultimap<Thread, ID> lockOrDetectPotentialLocksCycle();
 
-  /**
-   * Unlocks previously locked lock.
-   */
+  /** Unlocks previously locked lock. */
   void unlock();
 
   /**
-   * Wraps locks so they would never cause a deadlock. On each
-   * {@link CycleDetectingLock#lockOrDetectPotentialLocksCycle} we check for dependency cycles
-   * within locks created by the same factory. Either we detect a cycle and return it
-   * or take it atomically.
+   * Wraps locks so they would never cause a deadlock. On each {@link
+   * CycleDetectingLock#lockOrDetectPotentialLocksCycle} we check for dependency cycles within locks
+   * created by the same factory. Either we detect a cycle and return it or take it atomically.
    *
-   * <p>Important to note that we do not prevent deadlocks in the client code. As an example:
-   * Thread A takes lock L and creates singleton class CA depending on the singleton class CB.
-   * Meanwhile thread B is creating class CB and is waiting on the lock L. Issue happens
-   * due to client code creating interdependent classes and using locks, where
-   * no guarantees on the creation order from Guice are provided.
+   * <p>Important to note that we do not prevent deadlocks in the client code. As an example: Thread
+   * A takes lock L and creates singleton class CA depending on the singleton class CB. Meanwhile
+   * thread B is creating class CB and is waiting on the lock L. Issue happens due to client code
+   * creating interdependent classes and using locks, where no guarantees on the creation order from
+   * Guice are provided.
    *
    * <p>Instances of these locks are not intended to be exposed outside of {@link SingletonScope}.
    */
   class CycleDetectingLockFactory<ID> {
 
     /**
-     * Specifies lock that thread is currently waiting on to own it.
-     * Used only for purposes of locks cycle detection.
+     * Specifies lock that thread is currently waiting on to own it. Used only for purposes of locks
+     * cycle detection.
      *
-     * Key: thread id
-     * Value: lock that is being waited on
+     * <ul>
+     * <li>Key: thread
+     * <li> Value: lock that is being waited on
+     * </ul>
      *
-     * Element is added inside {@link #lockOrDetectPotentialLocksCycle()} before {@link Lock#lock}
-     * is called. Element is removed inside {@link #lockOrDetectPotentialLocksCycle()} after
-     * {@link Lock#lock} and synchronously with adding it to {@link #locksOwnedByThread}.
+     * <p>Element is added inside {@link #lockOrDetectPotentialLocksCycle()} before {@link
+     * Lock#lock} is called. Element is removed inside {@link #lockOrDetectPotentialLocksCycle()}
+     * after {@link Lock#lock} and synchronously with adding it to {@link #locksOwnedByThread}.
      *
-     * Same lock can be added for several threads in case all of them are trying to
-     * take it.
+     * <p>Same lock can be added for several threads in case all of them are trying to take it.
      *
-     * Guarded by {@code this}.
+     * <p>Guarded by {@code CycleDetectingLockFactory.class}.
      */
-    private Map<Long, ReentrantCycleDetectingLock> lockThreadIsWaitingOn = Maps.newHashMap();
+    private static Map<Thread, ReentrantCycleDetectingLock<?>> lockThreadIsWaitingOn =
+        Maps.newHashMap();
 
     /**
-     * Lists locks that thread owns.
-     * Used only to populate locks in a potential cycle when it is detected.
+     * Lists locks that thread owns. Used only to populate locks in a potential cycle when it is
+     * detected.
      *
-     * Key: thread id
-     * Value: stack of locks that were owned.
+     * <ul>
+     * <li>Key: thread
+     * <li>Value: stack of locks that were owned.
+     * </ul>
      *
-     * Element is added inside {@link #lockOrDetectPotentialLocksCycle()} after {@link Lock#lock}
-     * is called. Element is removed inside {@link #unlock()} synchronously with
-     * {@link Lock#unlock()} call.
+     * <p>Element is added inside {@link #lockOrDetectPotentialLocksCycle()} after {@link Lock#lock}
+     * is called. Element is removed inside {@link #unlock()} synchronously with {@link
+     * Lock#unlock()} call.
      *
-     * Same lock can only be present several times for the same thread as locks are
-     * reentrant. Lock can not be owned by several different threads as the same time.
+     * <p>Same lock can only be present several times for the same thread as locks are reentrant.
+     * Lock can not be owned by several different threads as the same time.
      *
-     * Guarded by {@code this}.
+     * <p>Guarded by {@code CycleDetectingLockFactory.class}.
      */
-    private final Multimap<Long, ReentrantCycleDetectingLock> locksOwnedByThread =
+    private static final Multimap<Thread, ReentrantCycleDetectingLock<?>> locksOwnedByThread =
         LinkedHashMultimap.create();
 
     /**
-     * Creates new lock within this factory context. We can guarantee that locks created by
-     * the same factory would not deadlock.
+     * Creates new lock within this factory context. We can guarantee that locks created by the same
+     * factory would not deadlock.
      *
-     * @param newLockId lock id that would be used to report lock cycles if detected
+     * @param userLockId lock id that would be used to report lock cycles if detected
      */
-    CycleDetectingLock<ID> create(ID newLockId) {
-      return new ReentrantCycleDetectingLock(newLockId, new ReentrantLock());
+    CycleDetectingLock<ID> create(ID userLockId) {
+      return new ReentrantCycleDetectingLock<ID>(this, userLockId, new ReentrantLock());
     }
 
     /** The implementation for {@link CycleDetectingLock}. */
-    class ReentrantCycleDetectingLock implements CycleDetectingLock<ID> {
+    static class ReentrantCycleDetectingLock<ID> implements CycleDetectingLock<ID> {
 
       /** Underlying lock used for actual waiting when no potential deadlocks are detected. */
       private final Lock lockImplementation;
       /** User id for this lock. */
       private final ID userLockId;
+      /** Factory that was used to create this lock. */
+      private final CycleDetectingLockFactory<ID> lockFactory;
       /**
-       * Thread id for the thread that owned this lock. Nullable.
-       * Guarded by {@code CycleDetectingLockFactory.this}.
+       * Thread that owns this lock. Nullable. Guarded by {@code CycleDetectingLockFactory.this}.
        */
-      private Long lockOwnerThreadId = null;
+      private Thread lockOwnerThread = null;
+
       /**
-       * Number of times that thread owned this lock.
-       * Guarded by {@code CycleDetectingLockFactory.this}.
+       * Number of times that thread owned this lock. Guarded by {@code
+       * CycleDetectingLockFactory.this}.
        */
       private int lockReentranceCount = 0;
 
-      ReentrantCycleDetectingLock(ID userLockId, Lock lockImplementation) {
+      ReentrantCycleDetectingLock(
+          CycleDetectingLockFactory<ID> lockFactory, ID userLockId, Lock lockImplementation) {
+        this.lockFactory = lockFactory;
         this.userLockId = Preconditions.checkNotNull(userLockId, "userLockId");
-        this.lockImplementation = Preconditions.checkNotNull(
-            lockImplementation, "lockImplementation");
+        this.lockImplementation =
+            Preconditions.checkNotNull(lockImplementation, "lockImplementation");
       }
 
-      @Override public ListMultimap<Long, ID> lockOrDetectPotentialLocksCycle() {
-        final long currentThreadId = Thread.currentThread().getId();
-        synchronized (CycleDetectingLockFactory.this) {
+      @Override
+      public ListMultimap<Thread, ID> lockOrDetectPotentialLocksCycle() {
+        final Thread currentThread = Thread.currentThread();
+        synchronized (CycleDetectingLockFactory.class) {
           checkState();
-          ListMultimap<Long, ID> locksInCycle = detectPotentialLocksCycle();
+          // Add this lock to the waiting map to ensure it is included in any reported lock cycle.
+          lockThreadIsWaitingOn.put(currentThread, this);
+          ListMultimap<Thread, ID> locksInCycle = detectPotentialLocksCycle();
           if (!locksInCycle.isEmpty()) {
+            // We aren't actually going to wait for this lock, so remove it from the map.
+            lockThreadIsWaitingOn.remove(currentThread);
             // potential deadlock is found, we don't try to take this lock
             return locksInCycle;
           }
 
-          lockThreadIsWaitingOn.put(currentThreadId, this);
         }
 
         // this may be blocking, but we don't expect it to cause a deadlock
         lockImplementation.lock();
 
-        synchronized (CycleDetectingLockFactory.this) {
+        synchronized (CycleDetectingLockFactory.class) {
           // current thread is no longer waiting on this lock
-          lockThreadIsWaitingOn.remove(currentThreadId);
+          lockThreadIsWaitingOn.remove(currentThread);
           checkState();
 
           // mark it as owned by us
-          lockOwnerThreadId = currentThreadId;
+          lockOwnerThread = currentThread;
           lockReentranceCount++;
           // add this lock to the list of locks owned by a current thread
-          locksOwnedByThread.put(currentThreadId, this);
+          locksOwnedByThread.put(currentThread, this);
         }
         // no deadlock is found, locking successful
         return ImmutableListMultimap.of();
       }
 
-      @Override public void unlock() {
-        final long currentThreadId = Thread.currentThread().getId();
-        synchronized (CycleDetectingLockFactory.this) {
+      @Override
+      public void unlock() {
+        final Thread currentThread = Thread.currentThread();
+        synchronized (CycleDetectingLockFactory.class) {
           checkState();
-          Preconditions.checkState(lockOwnerThreadId != null,
-              "Thread is trying to unlock a lock that is not locked");
-          Preconditions.checkState(lockOwnerThreadId == currentThreadId,
+          Preconditions.checkState(
+              lockOwnerThread != null, "Thread is trying to unlock a lock that is not locked");
+          Preconditions.checkState(
+              lockOwnerThread == currentThread,
               "Thread is trying to unlock a lock owned by another thread");
 
           // releasing underlying lock
@@ -190,12 +196,13 @@
           lockReentranceCount--;
           if (lockReentranceCount == 0) {
             // we no longer own this lock
-            lockOwnerThreadId = null;
-            Preconditions.checkState(locksOwnedByThread.remove(currentThreadId, this),
+            lockOwnerThread = null;
+            Preconditions.checkState(
+                locksOwnedByThread.remove(currentThread, this),
                 "Internal error: Can not find this lock in locks owned by a current thread");
-            if (locksOwnedByThread.get(currentThreadId).isEmpty()) {
+            if (locksOwnedByThread.get(currentThread).isEmpty()) {
               // clearing memory
-              locksOwnedByThread.removeAll(currentThreadId);
+              locksOwnedByThread.removeAll(currentThread);
             }
           }
         }
@@ -203,21 +210,26 @@
 
       /** Check consistency of an internal state. */
       void checkState() throws IllegalStateException {
-        final long currentThreadId = Thread.currentThread().getId();
-        Preconditions.checkState(!lockThreadIsWaitingOn.containsKey(currentThreadId),
+        final Thread currentThread = Thread.currentThread();
+        Preconditions.checkState(
+            !lockThreadIsWaitingOn.containsKey(currentThread),
             "Internal error: Thread should not be in a waiting thread on a lock now");
-        if (lockOwnerThreadId != null) {
+        if (lockOwnerThread != null) {
           // check state of a locked lock
-          Preconditions.checkState(lockReentranceCount >= 0,
+          Preconditions.checkState(
+              lockReentranceCount >= 0,
               "Internal error: Lock ownership and reentrance count internal states do not match");
-          Preconditions.checkState(locksOwnedByThread.get(lockOwnerThreadId).contains(this),
+          Preconditions.checkState(
+              locksOwnedByThread.get(lockOwnerThread).contains(this),
               "Internal error: Set of locks owned by a current thread and lock "
                   + "ownership status do not match");
         } else {
           // check state of a non locked lock
-          Preconditions.checkState(lockReentranceCount == 0,
+          Preconditions.checkState(
+              lockReentranceCount == 0,
               "Internal error: Reentrance count of a non locked lock is expect to be zero");
-          Preconditions.checkState(!locksOwnedByThread.values().contains(this),
+          Preconditions.checkState(
+              !locksOwnedByThread.values().contains(this),
               "Internal error: Non locked lock should not be owned by any thread");
         }
       }
@@ -225,76 +237,93 @@
       /**
        * Algorithm to detect a potential lock cycle.
        *
-       * For lock's thread owner check which lock is it trying to take.
-       * Repeat recursively. When current thread is found a potential cycle is detected.
+       * <p>For lock's thread owner check which lock is it trying to take. Repeat recursively. When
+       * current thread is found a potential cycle is detected.
        *
        * @see CycleDetectingLock#lockOrDetectPotentialLocksCycle()
        */
-      private ListMultimap<Long, ID> detectPotentialLocksCycle() {
-        final long currentThreadId = Thread.currentThread().getId();
-        if (lockOwnerThreadId == null || lockOwnerThreadId == currentThreadId) {
+      private ListMultimap<Thread, ID> detectPotentialLocksCycle() {
+        final Thread currentThread = Thread.currentThread();
+        if (lockOwnerThread == null || lockOwnerThread == currentThread) {
           // if nobody owns this lock, lock cycle is impossible
           // if a current thread owns this lock, we let Guice to handle it
           return ImmutableListMultimap.of();
         }
 
-        ListMultimap<Long, ID> potentialLocksCycle = Multimaps.newListMultimap(
-            new LinkedHashMap<Long, Collection<ID>>(),
-            new Supplier<List<ID>>() {
-              @Override
-              public List<ID> get() {
-                return Lists.newArrayList();
-              }
-            });
+        ListMultimap<Thread, ID> potentialLocksCycle =
+            Multimaps.newListMultimap(
+                new LinkedHashMap<Thread, Collection<ID>>(),
+                new Supplier<List<ID>>() {
+                  @Override
+                  public List<ID> get() {
+                    return Lists.newArrayList();
+                  }
+                });
         // lock that is a part of a potential locks cycle, starts with current lock
-        ReentrantCycleDetectingLock lockOwnerWaitingOn = this;
+        ReentrantCycleDetectingLock<?> lockOwnerWaitingOn = this;
         // try to find a dependency path between lock's owner thread and a current thread
-        while (lockOwnerWaitingOn != null && lockOwnerWaitingOn.lockOwnerThreadId != null) {
-          Long threadOwnerThreadWaits = lockOwnerWaitingOn.lockOwnerThreadId;
+        while (lockOwnerWaitingOn != null && lockOwnerWaitingOn.lockOwnerThread != null) {
+          Thread threadOwnerThreadWaits = lockOwnerWaitingOn.lockOwnerThread;
           // in case locks cycle exists lock we're waiting for is part of it
-          potentialLocksCycle.putAll(threadOwnerThreadWaits,
-              getAllLockIdsAfter(threadOwnerThreadWaits, lockOwnerWaitingOn));
-
-          if (threadOwnerThreadWaits == currentThreadId) {
+          lockOwnerWaitingOn =
+              addAllLockIdsAfter(threadOwnerThreadWaits, lockOwnerWaitingOn, potentialLocksCycle);
+          if (threadOwnerThreadWaits == currentThread) {
             // owner thread depends on current thread, cycle detected
             return potentialLocksCycle;
           }
-          // going for the next thread we wait on indirectly
-          lockOwnerWaitingOn = lockThreadIsWaitingOn.get(threadOwnerThreadWaits);
         }
         // no dependency path from an owner thread to a current thread
         return ImmutableListMultimap.of();
       }
 
-      /** Return locks owned by a thread after a lock specified, inclusive. */
-      private List<ID> getAllLockIdsAfter(long threadId, ReentrantCycleDetectingLock lock) {
-        List<ID> ids = Lists.newArrayList();
+      /**
+       * Adds all locks held by the given thread that are after the given lock and then returns the
+       * lock the thread is currently waiting on, if any
+       */
+      private ReentrantCycleDetectingLock<?> addAllLockIdsAfter(
+          Thread thread,
+          ReentrantCycleDetectingLock<?> lock,
+          ListMultimap<Thread, ID> potentialLocksCycle) {
         boolean found = false;
-        Collection<ReentrantCycleDetectingLock> ownedLocks = locksOwnedByThread.get(threadId);
-        Preconditions.checkNotNull(ownedLocks,
-            "Internal error: No locks were found taken by a thread");
-        for (ReentrantCycleDetectingLock ownedLock : ownedLocks) {
+        Collection<ReentrantCycleDetectingLock<?>> ownedLocks = locksOwnedByThread.get(thread);
+        Preconditions.checkNotNull(
+            ownedLocks, "Internal error: No locks were found taken by a thread");
+        for (ReentrantCycleDetectingLock<?> ownedLock : ownedLocks) {
           if (ownedLock == lock) {
             found = true;
           }
-          if (found) {
-            ids.add(ownedLock.userLockId);
+          if (found && ownedLock.lockFactory == this.lockFactory) {
+            // All locks are stored in a shared map therefore there is no way to
+            // enforce type safety. We know that our cast is valid as we check for a lock's
+            // factory. If the lock was generated by the
+            // same factory it has to have same type as the current lock.
+            @SuppressWarnings("unchecked")
+            ID userLockId = (ID) ownedLock.userLockId;
+            potentialLocksCycle.put(thread, userLockId);
           }
         }
-        Preconditions.checkState(found, "Internal error: We can not find locks that "
-            + "created a cycle that we detected");
-        return ids;
+        Preconditions.checkState(
+            found,
+            "Internal error: We can not find locks that created a cycle that we detected");
+        ReentrantCycleDetectingLock<?> unownedLock = lockThreadIsWaitingOn.get(thread);
+        // If this thread is waiting for a lock add it to the cycle and return it
+        if (unownedLock != null && unownedLock.lockFactory == this.lockFactory) {
+          @SuppressWarnings("unchecked")
+          ID typed = (ID) unownedLock.userLockId;
+          potentialLocksCycle.put(thread, typed);
+        }
+        return unownedLock;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         // copy is made to prevent a data race
         // no synchronization is used, potentially stale data, should be good enough
-        Long localLockOwnerThreadId = this.lockOwnerThreadId;
-        if (localLockOwnerThreadId != null) {
-          return String.format("CycleDetectingLock[%s][locked by %s]",
-              userLockId, localLockOwnerThreadId);
+        Thread thread = this.lockOwnerThread;
+        if (thread != null) {
+          return String.format("%s[%s][locked by %s]", super.toString(), userLockId, thread);
         } else {
-          return String.format("CycleDetectingLock[%s][unlocked]", userLockId);
+          return String.format("%s[%s][unlocked]", super.toString(), userLockId);
         }
       }
     }
diff --git a/core/src/com/google/inject/internal/DefaultConstructionProxyFactory.java b/core/src/com/google/inject/internal/DefaultConstructionProxyFactory.java
index 947b49a..d8cfc18 100644
--- a/core/src/com/google/inject/internal/DefaultConstructionProxyFactory.java
+++ b/core/src/com/google/inject/internal/DefaultConstructionProxyFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,10 +16,9 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
-import com.google.inject.internal.BytecodeGen.Visibility;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -35,73 +34,119 @@
 
   private final InjectionPoint injectionPoint;
 
-  /**
-   * @param injectionPoint an injection point whose member is a constructor of {@code T}.
-   */
+  /** @param injectionPoint an injection point whose member is a constructor of {@code T}. */
   DefaultConstructionProxyFactory(InjectionPoint injectionPoint) {
     this.injectionPoint = injectionPoint;
   }
 
+  @Override
   public ConstructionProxy<T> create() {
     @SuppressWarnings("unchecked") // the injection point is for a constructor of T
     final Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
 
-    // Use FastConstructor if the constructor is public.
-    if (Modifier.isPublic(constructor.getModifiers())) {
-      Class<T> classToConstruct = constructor.getDeclaringClass();
-      /*if[AOP]*/
-      try {
-        final net.sf.cglib.reflect.FastConstructor fastConstructor
-            = BytecodeGen.newFastClass(classToConstruct, Visibility.forMember(constructor))
-                .getConstructor(constructor);
-
-      return new ConstructionProxy<T>() {
-        @SuppressWarnings("unchecked")
-        public T newInstance(Object... arguments) throws InvocationTargetException {
-          return (T) fastConstructor.newInstance(arguments);
-        }
-        public InjectionPoint getInjectionPoint() {
-          return injectionPoint;
-        }
-        public Constructor<T> getConstructor() {
-          return constructor;
-        }
-        public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
-            getMethodInterceptors() {
-          return ImmutableMap.of();
-        }
-      };
-      } catch (net.sf.cglib.core.CodeGenerationException e) {/* fall-through */}
-      /*end[AOP]*/
-      if (!Modifier.isPublic(classToConstruct.getModifiers())) {
-        constructor.setAccessible(true);
+    /*if[AOP]*/
+    try {
+      net.sf.cglib.reflect.FastClass fc = BytecodeGen.newFastClassForMember(constructor);
+      if (fc != null) {
+        int index = fc.getIndex(constructor.getParameterTypes());
+        // We could just fall back to reflection in this case but I believe this should actually
+        // be impossible.
+        Preconditions.checkArgument(
+            index >= 0, "Could not find constructor %s in fast class", constructor);
+        return new FastClassProxy<T>(injectionPoint, constructor, fc, index);
       }
-    } else {
-      constructor.setAccessible(true);
+    } catch (net.sf.cglib.core.CodeGenerationException e) {
+      /* fall-through */
+    }
+    /*end[AOP]*/
+
+    return new ReflectiveProxy<T>(injectionPoint, constructor);
+  }
+
+  /*if[AOP]*/
+  /** A {@link ConstructionProxy} that uses FastClass to invoke the constructor. */
+  private static final class FastClassProxy<T> implements ConstructionProxy<T> {
+    final InjectionPoint injectionPoint;
+    final Constructor<T> constructor;
+    final net.sf.cglib.reflect.FastClass fc;
+    final int index;
+
+    private FastClassProxy(
+        InjectionPoint injectionPoint,
+        Constructor<T> constructor,
+        net.sf.cglib.reflect.FastClass fc,
+        int index) {
+      this.injectionPoint = injectionPoint;
+      this.constructor = constructor;
+      this.fc = fc;
+      this.index = index;
     }
 
-    return new ConstructionProxy<T>() {
-      public T newInstance(Object... arguments) throws InvocationTargetException {
-        try {
-          return constructor.newInstance(arguments);
-        } catch (InstantiationException e) {
-          throw new AssertionError(e); // shouldn't happen, we know this is a concrete type
-        } catch (IllegalAccessException e) {
-          throw new AssertionError(e); // a security manager is blocking us, we're hosed
-        }
+    @Override
+    @SuppressWarnings("unchecked")
+    public T newInstance(Object... arguments) throws InvocationTargetException {
+      // Use this method instead of FastConstructor to save a stack frame
+      return (T) fc.newInstance(index, arguments);
+    }
+
+    @Override
+    public InjectionPoint getInjectionPoint() {
+      return injectionPoint;
+    }
+
+    @Override
+    public Constructor<T> getConstructor() {
+      return constructor;
+    }
+
+    @Override
+    public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
+        getMethodInterceptors() {
+      return ImmutableMap.of();
+    }
+  }
+  /*end[AOP]*/
+
+  private static final class ReflectiveProxy<T> implements ConstructionProxy<T> {
+    final Constructor<T> constructor;
+    final InjectionPoint injectionPoint;
+
+    ReflectiveProxy(InjectionPoint injectionPoint, Constructor<T> constructor) {
+      if (!Modifier.isPublic(constructor.getDeclaringClass().getModifiers())
+          || !Modifier.isPublic(constructor.getModifiers())) {
+        constructor.setAccessible(true);
       }
-      public InjectionPoint getInjectionPoint() {
-        return injectionPoint;
+      this.injectionPoint = injectionPoint;
+      this.constructor = constructor;
+    }
+
+    @Override
+    public T newInstance(Object... arguments) throws InvocationTargetException {
+      try {
+        return constructor.newInstance(arguments);
+      } catch (InstantiationException e) {
+        throw new AssertionError(e); // shouldn't happen, we know this is a concrete type
+      } catch (IllegalAccessException e) {
+        throw new AssertionError(e); // a security manager is blocking us, we're hosed
       }
-      public Constructor<T> getConstructor() {
-        return constructor;
-      }
-      /*if[AOP]*/
-      public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
-          getMethodInterceptors() {
-        return ImmutableMap.of();
-      }
-      /*end[AOP]*/
-    };
+    }
+
+    @Override
+    public InjectionPoint getInjectionPoint() {
+      return injectionPoint;
+    }
+
+    @Override
+    public Constructor<T> getConstructor() {
+      return constructor;
+    }
+
+    /*if[AOP]*/
+    @Override
+    public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
+        getMethodInterceptors() {
+      return ImmutableMap.of();
+    }
+    /*end[AOP]*/
   }
 }
diff --git a/core/src/com/google/inject/internal/DeferredLookups.java b/core/src/com/google/inject/internal/DeferredLookups.java
index 049c9a8..2c37406 100644
--- a/core/src/com/google/inject/internal/DeferredLookups.java
+++ b/core/src/com/google/inject/internal/DeferredLookups.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,6 @@
 import com.google.inject.spi.Element;
 import com.google.inject.spi.MembersInjectorLookup;
 import com.google.inject.spi.ProviderLookup;
-
 import java.util.List;
 
 /**
@@ -41,22 +40,22 @@
     this.injector = injector;
   }
 
-  /**
-   * Initialize the specified lookups, either immediately or when the injector is created.
-   */
+  /** Initialize the specified lookups, either immediately or when the injector is created. */
   void initialize(Errors errors) {
     injector.lookups = injector;
     new LookupProcessor(errors).process(injector, lookups);
   }
 
+  @Override
   public <T> Provider<T> getProvider(Key<T> key) {
-    ProviderLookup<T> lookup = new ProviderLookup<T>(key, key);
+    ProviderLookup<T> lookup = new ProviderLookup<>(key, key);
     lookups.add(lookup);
     return lookup.getProvider();
   }
 
+  @Override
   public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> type) {
-    MembersInjectorLookup<T> lookup = new MembersInjectorLookup<T>(type, type);
+    MembersInjectorLookup<T> lookup = new MembersInjectorLookup<>(type, type);
     lookups.add(lookup);
     return lookup.getMembersInjector();
   }
diff --git a/core/src/com/google/inject/internal/DelayedInitialize.java b/core/src/com/google/inject/internal/DelayedInitialize.java
index 82a8463..5534f50 100644
--- a/core/src/com/google/inject/internal/DelayedInitialize.java
+++ b/core/src/com/google/inject/internal/DelayedInitialize.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,15 +17,13 @@
 package com.google.inject.internal;
 
 /**
- * Something that needs some delayed initialization, typically
- * a binding or internal factory that needs to be created & put
- * into the bindings map & then initialized later.
- * 
+ * Something that needs some delayed initialization, typically a binding or internal factory that
+ * needs to be created & put into the bindings map & then initialized later.
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 interface DelayedInitialize {
-  
+
   /** Initializes this binding, throwing any errors if necessary. */
   void initialize(InjectorImpl injector, Errors errors) throws ErrorsException;
-
 }
diff --git a/core/src/com/google/inject/internal/DelegatingInvocationHandler.java b/core/src/com/google/inject/internal/DelegatingInvocationHandler.java
index 32441ff..f78262f 100644
--- a/core/src/com/google/inject/internal/DelegatingInvocationHandler.java
+++ b/core/src/com/google/inject/internal/DelegatingInvocationHandler.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +16,7 @@
 
 package com.google.inject.internal;
 
-
 import com.google.common.base.Preconditions;
-
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -29,16 +27,18 @@
 
   private T delegate;
 
-  public Object invoke(Object proxy, Method method, Object[] args)
-      throws Throwable {
+  @Override
+  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     try {
       // checking volatile field for synchronization
-      Preconditions.checkState(initialized,
+      Preconditions.checkState(
+          initialized,
           "This is a proxy used to support"
               + " circular references. The object we're"
               + " proxying is not constructed yet. Please wait until after"
               + " injection has completed to use this object.");
-      Preconditions.checkNotNull(delegate,
+      Preconditions.checkNotNull(
+          delegate,
           "This is a proxy used to support"
               + " circular references. The object we're "
               + " proxying is initialized to null."
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Element.java b/core/src/com/google/inject/internal/Element.java
similarity index 79%
rename from extensions/multibindings/src/com/google/inject/multibindings/Element.java
rename to core/src/com/google/inject/internal/Element.java
index c675551..5b738ef 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/Element.java
+++ b/core/src/com/google/inject/internal/Element.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,33 +14,34 @@
  * limitations under the License.
  */
 
-
-package com.google.inject.multibindings;
+package com.google.inject.internal;
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.Retention;
 
 /**
- * An internal binding annotation applied to each element in a multibinding.
- * All elements are assigned a globally-unique id to allow different modules
- * to contribute multibindings independently.
+ * An internal binding annotation applied to each element in a multibinding. All elements are
+ * assigned a globally-unique id to allow different modules to contribute multibindings
+ * independently.
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
-@Retention(RUNTIME) @BindingAnnotation
+@Retention(RUNTIME)
+@BindingAnnotation
 @interface Element {
 
   enum Type {
     MAPBINDER,
-    MULTIBINDER,
-    OPTIONALBINDER;
+    MULTIBINDER;
   }
 
   String setName();
+
   int uniqueId();
+
   Type type();
+
   String keyType();
 }
diff --git a/core/src/com/google/inject/internal/EncounterImpl.java b/core/src/com/google/inject/internal/EncounterImpl.java
index 8aa3e94..4fb8575 100644
--- a/core/src/com/google/inject/internal/EncounterImpl.java
+++ b/core/src/com/google/inject/internal/EncounterImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,13 +30,10 @@
 import com.google.inject.spi.InjectionListener;
 import com.google.inject.spi.Message;
 import com.google.inject.spi.TypeEncounter;
-
 import java.lang.reflect.Method;
 import java.util.List;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 final class EncounterImpl<T> implements TypeEncounter<T> {
 
   private final Errors errors;
@@ -59,12 +56,12 @@
 
   /*if[AOP]*/
   ImmutableList<MethodAspect> getAspects() {
-    return aspects == null
-        ? ImmutableList.<MethodAspect>of()
-        : ImmutableList.copyOf(aspects);
+    return aspects == null ? ImmutableList.<MethodAspect>of() : ImmutableList.copyOf(aspects);
   }
 
-  public void bindInterceptor(Matcher<? super Method> methodMatcher,
+  @Override
+  public void bindInterceptor(
+      Matcher<? super Method> methodMatcher,
       org.aopalliance.intercept.MethodInterceptor... interceptors) {
     checkState(valid, "Encounters may not be used after hear() returns.");
 
@@ -89,6 +86,7 @@
         : ImmutableSet.copyOf(injectionListeners);
   }
 
+  @Override
   public void register(MembersInjector<? super T> membersInjector) {
     checkState(valid, "Encounters may not be used after hear() returns.");
 
@@ -99,6 +97,7 @@
     membersInjectors.add(membersInjector);
   }
 
+  @Override
   public void register(InjectionListener<? super T> injectionListener) {
     checkState(valid, "Encounters may not be used after hear() returns.");
 
@@ -109,36 +108,43 @@
     injectionListeners.add(injectionListener);
   }
 
+  @Override
   public void addError(String message, Object... arguments) {
     checkState(valid, "Encounters may not be used after hear() returns.");
     errors.addMessage(message, arguments);
   }
 
+  @Override
   public void addError(Throwable t) {
     checkState(valid, "Encounters may not be used after hear() returns.");
     errors.errorInUserCode(t, "An exception was caught and reported. Message: %s", t.getMessage());
   }
 
+  @Override
   public void addError(Message message) {
     checkState(valid, "Encounters may not be used after hear() returns.");
     errors.addMessage(message);
   }
 
+  @Override
   public <T> Provider<T> getProvider(Key<T> key) {
     checkState(valid, "Encounters may not be used after hear() returns.");
     return lookups.getProvider(key);
   }
 
+  @Override
   public <T> Provider<T> getProvider(Class<T> type) {
     return getProvider(Key.get(type));
   }
 
+  @Override
   public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) {
     checkState(valid, "Encounters may not be used after hear() returns.");
     return lookups.getMembersInjector(typeLiteral);
   }
 
+  @Override
   public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
     return getMembersInjector(TypeLiteral.get(type));
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/ErrorHandler.java b/core/src/com/google/inject/internal/ErrorHandler.java
index b448eb7..c0ffd01 100644
--- a/core/src/com/google/inject/internal/ErrorHandler.java
+++ b/core/src/com/google/inject/internal/ErrorHandler.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,13 +25,9 @@
  */
 interface ErrorHandler {
 
-  /**
-   * Handles an error.
-   */
+  /** Handles an error. */
   void handle(Object source, Errors errors);
 
-  /**
-   * Handles a user-reported error.
-   */
+  /** Handles a user-reported error. */
   void handle(Message message);
 }
diff --git a/core/src/com/google/inject/internal/Errors.java b/core/src/com/google/inject/internal/Errors.java
index 7527e2a..7269f12 100644
--- a/core/src/com/google/inject/internal/Errors.java
+++ b/core/src/com/google/inject/internal/Errors.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,45 +20,34 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
+import com.google.common.primitives.Primitives;
+import com.google.inject.Binding;
 import com.google.inject.ConfigurationException;
 import com.google.inject.CreationException;
-import com.google.inject.Guice;
+import com.google.inject.Injector;
 import com.google.inject.Key;
-import com.google.inject.MembersInjector;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
 import com.google.inject.ProvisionException;
 import com.google.inject.Scope;
 import com.google.inject.TypeLiteral;
-import com.google.inject.internal.util.Classes;
 import com.google.inject.internal.util.SourceProvider;
-import com.google.inject.internal.util.StackTraceElements;
-import com.google.inject.spi.Dependency;
 import com.google.inject.spi.ElementSource;
-import com.google.inject.spi.InjectionListener;
-import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.Message;
 import com.google.inject.spi.ScopeBinding;
 import com.google.inject.spi.TypeConverterBinding;
 import com.google.inject.spi.TypeListenerBinding;
-
-import java.io.PrintWriter;
 import java.io.Serializable;
-import java.io.StringWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Formatter;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * A collection of error messages. If this type is passed as a method parameter, the method is
@@ -77,30 +66,58 @@
  */
 public final class Errors implements Serializable {
 
-  private static final Logger logger = Logger.getLogger(Guice.class.getName());
+  /** When a binding is not found, show at most this many bindings with the same type */
+  private static final int MAX_MATCHING_TYPES_REPORTED = 3;
 
-  private static final Set<Dependency<?>> warnedDependencies =
-      Sets.newSetFromMap(new ConcurrentHashMap<Dependency<?>, Boolean>());
-
+  /** When a binding is not found, show at most this many bindings that have some similarities */
+  private static final int MAX_RELATED_TYPES_REPORTED = 3;
 
   /**
-   * The root errors object. Used to access the list of error messages.
+   * Throws a ConfigurationException with an NullPointerExceptions as the cause if the given
+   * reference is {@code null}.
    */
+  static <T> T checkNotNull(T reference, String name) {
+    if (reference != null) {
+      return reference;
+    }
+
+    NullPointerException npe = new NullPointerException(name);
+    throw new ConfigurationException(ImmutableSet.of(new Message(npe.toString(), npe)));
+  }
+
+  /**
+   * Throws a ConfigurationException with a formatted {@link Message} if this condition is {@code
+   * false}.
+   */
+  static void checkConfiguration(boolean condition, String format, Object... args) {
+    if (condition) {
+      return;
+    }
+
+    throw new ConfigurationException(ImmutableSet.of(new Message(Errors.format(format, args))));
+  }
+
+  /**
+   * If the key is unknown and it is one of these types, it generally means there is a missing
+   * annotation.
+   */
+  private static final ImmutableSet<Class<?>> COMMON_AMBIGUOUS_TYPES =
+      ImmutableSet.<Class<?>>builder()
+          .add(Object.class)
+          .add(String.class)
+          .addAll(Primitives.allWrapperTypes())
+          .build();
+
+  /** The root errors object. Used to access the list of error messages. */
   private final Errors root;
 
-  /**
-   * The parent errors object. Used to obtain the chain of source objects.
-   */
+  /** The parent errors object. Used to obtain the chain of source objects. */
   private final Errors parent;
 
-  /**
-   * The leaf source for errors added here.
-   */
+  /** The leaf source for errors added here. */
   private final Object source;
 
-  /**
-   * null unless (root == this) and error messages exist. Never an empty list.
-   */
+  /** null unless (root == this) and error messages exist. Never an empty list. */
   private List<Message> errors; // lazy, use getErrorsForAdd()
 
   public Errors() {
@@ -121,9 +138,7 @@
     this.source = source;
   }
 
-  /**
-   * Returns an instance that uses {@code source} as a reference point for newly added errors.
-   */
+  /** Returns an instance that uses {@code source} as a reference point for newly added errors. */
   public Errors withSource(Object source) {
     return source == this.source || source == SourceProvider.UNKNOWN_SOURCE
         ? this
@@ -131,69 +146,166 @@
   }
 
   /**
-   * We use a fairly generic error message here. The motivation is to share the
-   * same message for both bind time errors:
+   * We use a fairly generic error message here. The motivation is to share the same message for
+   * both bind time errors:
+   *
    * <pre><code>Guice.createInjector(new AbstractModule() {
    *   public void configure() {
    *     bind(Runnable.class);
    *   }
    * }</code></pre>
+   *
    * ...and at provide-time errors:
+   *
    * <pre><code>Guice.createInjector().getInstance(Runnable.class);</code></pre>
-   * Otherwise we need to know who's calling when resolving a just-in-time
-   * binding, which makes things unnecessarily complex.
+   *
+   * Otherwise we need to know who's calling when resolving a just-in-time binding, which makes
+   * things unnecessarily complex.
    */
   public Errors missingImplementation(Key key) {
     return addMessage("No implementation for %s was bound.", key);
   }
 
-  public Errors jitDisabled(Key key) {
+  /** Within guice's core, allow for better missing binding messages */
+  <T> Errors missingImplementationWithHint(Key<T> key, Injector injector) {
+    StringBuilder sb = new StringBuilder();
+
+    sb.append(format("No implementation for %s was bound.", key));
+
+    // Keys which have similar strings as the desired key
+    List<String> possibleMatches = new ArrayList<>();
+
+    // Check for other keys that may have the same type,
+    // but not the same annotation
+    TypeLiteral<T> type = key.getTypeLiteral();
+    List<Binding<T>> sameTypes = injector.findBindingsByType(type);
+    if (!sameTypes.isEmpty()) {
+      sb.append(format("%n  Did you mean?"));
+      int howMany = Math.min(sameTypes.size(), MAX_MATCHING_TYPES_REPORTED);
+      for (int i = 0; i < howMany; ++i) {
+        // TODO: Look into a better way to prioritize suggestions. For example, possbily
+        // use levenshtein distance of the given annotation vs actual annotation.
+        sb.append(format("%n    * %s", sameTypes.get(i).getKey()));
+      }
+      int remaining = sameTypes.size() - MAX_MATCHING_TYPES_REPORTED;
+      if (remaining > 0) {
+        String plural = (remaining == 1) ? "" : "s";
+        sb.append(format("%n    %d more binding%s with other annotations.", remaining, plural));
+      }
+    } else {
+      // For now, do a simple substring search for possibilities. This can help spot
+      // issues when there are generics being used (such as a wrapper class) and the
+      // user has forgotten they need to bind based on the wrapper, not the underlying
+      // class. In the future, consider doing a strict in-depth type search.
+      // TODO: Look into a better way to prioritize suggestions. For example, possbily
+      // use levenshtein distance of the type literal strings.
+      String want = type.toString();
+      Map<Key<?>, Binding<?>> bindingMap = injector.getAllBindings();
+      for (Key<?> bindingKey : bindingMap.keySet()) {
+        String have = bindingKey.getTypeLiteral().toString();
+        if (have.contains(want) || want.contains(have)) {
+          Formatter fmt = new Formatter();
+          Messages.formatSource(fmt, bindingMap.get(bindingKey).getSource());
+          String match = String.format("%s bound%s", convert(bindingKey), fmt.toString());
+          possibleMatches.add(match);
+          // TODO: Consider a check that if there are more than some number of results,
+          // don't suggest any.
+          if (possibleMatches.size() > MAX_RELATED_TYPES_REPORTED) {
+            // Early exit if we have found more than we need.
+            break;
+          }
+        }
+      }
+
+      if ((possibleMatches.size() > 0) && (possibleMatches.size() <= MAX_RELATED_TYPES_REPORTED)) {
+        sb.append(format("%n  Did you mean?"));
+        for (String possibleMatch : possibleMatches) {
+          sb.append(format("%n    %s", possibleMatch));
+        }
+      }
+    }
+
+    // If where are no possibilities to suggest, then handle the case of missing
+    // annotations on simple types. This is usually a bad idea.
+    if (sameTypes.isEmpty()
+        && possibleMatches.isEmpty()
+        && key.getAnnotation() == null
+        && COMMON_AMBIGUOUS_TYPES.contains(key.getTypeLiteral().getRawType())) {
+      // We don't recommend using such simple types without annotations.
+      sb.append(format("%nThe key seems very generic, did you forget an annotation?"));
+    }
+
+    return addMessage(sb.toString());
+  }
+
+  public Errors jitDisabled(Key<?> key) {
     return addMessage("Explicit bindings are required and %s is not explicitly bound.", key);
   }
 
   public Errors jitDisabledInParent(Key<?> key) {
     return addMessage(
         "Explicit bindings are required and %s would be bound in a parent injector.%n"
-        + "Please add an explicit binding for it, either in the child or the parent.",
+            + "Please add an explicit binding for it, either in the child or the parent.",
         key);
   }
 
   public Errors atInjectRequired(Class clazz) {
     return addMessage(
         "Explicit @Inject annotations are required on constructors,"
-        + " but %s has no constructors annotated with @Inject.",
+            + " but %s has no constructors annotated with @Inject.",
         clazz);
   }
 
-  public Errors converterReturnedNull(String stringValue, Object source,
-      TypeLiteral<?> type, TypeConverterBinding typeConverterBinding) {
-    return addMessage("Received null converting '%s' (bound at %s) to %s%n"
-        + " using %s.",
+  public Errors converterReturnedNull(
+      String stringValue,
+      Object source,
+      TypeLiteral<?> type,
+      TypeConverterBinding typeConverterBinding) {
+    return addMessage(
+        "Received null converting '%s' (bound at %s) to %s%n using %s.",
         stringValue, convert(source), type, typeConverterBinding);
   }
 
-  public Errors conversionTypeError(String stringValue, Object source, TypeLiteral<?> type,
-      TypeConverterBinding typeConverterBinding, Object converted) {
-    return addMessage("Type mismatch converting '%s' (bound at %s) to %s%n"
-        + " using %s.%n"
-        + " Converter returned %s.",
+  public Errors conversionTypeError(
+      String stringValue,
+      Object source,
+      TypeLiteral<?> type,
+      TypeConverterBinding typeConverterBinding,
+      Object converted) {
+    return addMessage(
+        "Type mismatch converting '%s' (bound at %s) to %s%n"
+            + " using %s.%n"
+            + " Converter returned %s.",
         stringValue, convert(source), type, typeConverterBinding, converted);
   }
 
-  public Errors conversionError(String stringValue, Object source,
-      TypeLiteral<?> type, TypeConverterBinding typeConverterBinding, RuntimeException cause) {
-    return errorInUserCode(cause, "Error converting '%s' (bound at %s) to %s%n"
-        + " using %s.%n"
-        + " Reason: %s",
-        stringValue, convert(source), type, typeConverterBinding, cause);
+  public Errors conversionError(
+      String stringValue,
+      Object source,
+      TypeLiteral<?> type,
+      TypeConverterBinding typeConverterBinding,
+      RuntimeException cause) {
+    return errorInUserCode(
+        cause,
+        "Error converting '%s' (bound at %s) to %s%n using %s.%n Reason: %s",
+        stringValue,
+        convert(source),
+        type,
+        typeConverterBinding,
+        cause);
   }
 
-  public Errors ambiguousTypeConversion(String stringValue, Object source, TypeLiteral<?> type,
-      TypeConverterBinding a, TypeConverterBinding b) {
-    return addMessage("Multiple converters can convert '%s' (bound at %s) to %s:%n"
-        + " %s and%n"
-        + " %s.%n"
-        + " Please adjust your type converter configuration to avoid overlapping matches.",
+  public Errors ambiguousTypeConversion(
+      String stringValue,
+      Object source,
+      TypeLiteral<?> type,
+      TypeConverterBinding a,
+      TypeConverterBinding b) {
+    return addMessage(
+        "Multiple converters can convert '%s' (bound at %s) to %s:%n"
+            + " %s and%n"
+            + " %s.%n"
+            + " Please adjust your type converter configuration to avoid overlapping matches.",
         stringValue, convert(source), type, a, b);
   }
 
@@ -201,11 +313,6 @@
     return addMessage("Binding to Provider is not allowed.");
   }
 
-  public Errors subtypeNotProvided(Class<? extends Provider<?>> providerType,
-      Class<?> type) {
-    return addMessage("%s doesn't provide instances of %s.", providerType, type);
-  }
-
   public Errors notASubtype(Class<?> implementationType, Class<?> type) {
     return addMessage("%s doesn't extend %s.", implementationType, type);
   }
@@ -227,8 +334,9 @@
   }
 
   public Errors optionalConstructor(Constructor constructor) {
-    return addMessage("%s is annotated @Inject(optional=true), "
-        + "but constructors cannot be optional.", constructor);
+    return addMessage(
+        "%s is annotated @Inject(optional=true), but constructors cannot be optional.",
+        constructor);
   }
 
   public Errors cannotBindToGuiceType(String simpleName) {
@@ -241,13 +349,17 @@
 
   public Errors scopeAnnotationOnAbstractType(
       Class<? extends Annotation> scopeAnnotation, Class<?> type, Object source) {
-    return addMessage("%s is annotated with %s, but scope annotations are not supported "
-        + "for abstract types.%n Bound at %s.", type, scopeAnnotation, convert(source));
+    return addMessage(
+        "%s is annotated with %s, but scope annotations are not supported "
+            + "for abstract types.%n Bound at %s.",
+        type, scopeAnnotation, convert(source));
   }
 
   public Errors misplacedBindingAnnotation(Member member, Annotation bindingAnnotation) {
-    return addMessage("%s is annotated with %s, but binding annotations should be applied "
-        + "to its parameters instead.", member, bindingAnnotation);
+    return addMessage(
+        "%s is annotated with %s, but binding annotations should be applied "
+            + "to its parameters instead.",
+        member, bindingAnnotation);
   }
 
   private static final String CONSTRUCTOR_RULES =
@@ -255,22 +367,24 @@
           + "annotated with @Inject or a zero-argument constructor that is not private.";
 
   public Errors missingConstructor(Class<?> implementation) {
-    return addMessage("Could not find a suitable constructor in %s. " + CONSTRUCTOR_RULES,
-        implementation);
+    return addMessage(
+        "Could not find a suitable constructor in %s. " + CONSTRUCTOR_RULES, implementation);
   }
 
   public Errors tooManyConstructors(Class<?> implementation) {
-    return addMessage("%s has more than one constructor annotated with @Inject. "
-        + CONSTRUCTOR_RULES, implementation);
+    return addMessage(
+        "%s has more than one constructor annotated with @Inject. " + CONSTRUCTOR_RULES,
+        implementation);
   }
 
   public Errors constructorNotDefinedByType(Constructor<?> constructor, TypeLiteral<?> type) {
     return addMessage("%s does not define %s", type, constructor);
   }
 
-  public Errors duplicateScopes(ScopeBinding existing,
-      Class<? extends Annotation> annotationType, Scope scope) {
-    return addMessage("Scope %s is already bound to %s at %s.%n Cannot bind %s.",
+  public Errors duplicateScopes(
+      ScopeBinding existing, Class<? extends Annotation> annotationType, Scope scope) {
+    return addMessage(
+        "Scope %s is already bound to %s at %s.%n Cannot bind %s.",
         existing.getScope(), annotationType, existing.getSource(), scope);
   }
 
@@ -283,14 +397,17 @@
   }
 
   public Errors cannotInjectInnerClass(Class<?> type) {
-    return addMessage("Injecting into inner classes is not supported.  "
-        + "Please use a 'static' class (top-level or nested) instead of %s.", type);
+    return addMessage(
+        "Injecting into inner classes is not supported.  "
+            + "Please use a 'static' class (top-level or nested) instead of %s.",
+        type);
   }
 
-  public Errors duplicateBindingAnnotations(Member member,
-      Class<? extends Annotation> a, Class<? extends Annotation> b) {
-    return addMessage("%s has more than one annotation annotated with @BindingAnnotation: "
-        + "%s and %s", member, a, b);
+  public Errors duplicateBindingAnnotations(
+      Member member, Class<? extends Annotation> a, Class<? extends Annotation> b) {
+    return addMessage(
+        "%s has more than one annotation annotated with @BindingAnnotation: %s and %s",
+        member, a, b);
   }
 
   public Errors staticInjectionOnInterface(Class<?> clazz) {
@@ -327,7 +444,8 @@
   }
 
   public Errors jitBindingAlreadySet(Key<?> key) {
-    return addMessage("A just-in-time binding to %s was already configured on a parent injector.", key);
+    return addMessage(
+        "A just-in-time binding to %s was already configured on a parent injector.", key);
   }
 
   public Errors childBindingAlreadySet(Key<?> key, Set<Object> sources) {
@@ -339,53 +457,32 @@
         allSources.format("%n    bound at %s", source);
       }
     }
-    Errors errors = addMessage(
-        "Unable to create binding for %s."
-      + " It was already configured on one or more child injectors or private modules"
-      + "%s%n"
-      + "  If it was in a PrivateModule, did you forget to expose the binding?",
-        key, allSources.out());
+    Errors errors =
+        addMessage(
+            "Unable to create binding for %s."
+                + " It was already configured on one or more child injectors or private modules"
+                + "%s%n"
+                + "  If it was in a PrivateModule, did you forget to expose the binding?",
+            key, allSources.out());
     return errors;
   }
 
   public Errors errorCheckingDuplicateBinding(Key<?> key, Object source, Throwable t) {
     return addMessage(
         "A binding to %s was already configured at %s and an error was thrown "
-      + "while checking duplicate bindings.  Error: %s",
+            + "while checking duplicate bindings.  Error: %s",
         key, convert(source), t);
   }
 
-  public Errors errorInjectingMethod(Throwable cause) {
-    return errorInUserCode(cause, "Error injecting method, %s", cause);
-  }
-
-  public Errors errorNotifyingTypeListener(TypeListenerBinding listener,
-      TypeLiteral<?> type, Throwable cause) {
-    return errorInUserCode(cause,
-        "Error notifying TypeListener %s (bound at %s) of %s.%n"
-        + " Reason: %s",
-        listener.getListener(), convert(listener.getSource()), type, cause);
-  }
-
-  public Errors errorInjectingConstructor(Throwable cause) {
-    return errorInUserCode(cause, "Error injecting constructor, %s", cause);
-  }
-
-  public Errors errorInProvider(RuntimeException runtimeException) {
-    Throwable unwrapped = unwrap(runtimeException);
-    return errorInUserCode(unwrapped, "Error in custom provider, %s", unwrapped);
-  }
-
-  public Errors errorInUserInjector(
-      MembersInjector<?> listener, TypeLiteral<?> type, RuntimeException cause) {
-    return errorInUserCode(cause, "Error injecting %s using %s.%n"
-        + " Reason: %s", type, listener, cause);
-  }
-
-  public Errors errorNotifyingInjectionListener(
-      InjectionListener<?> listener, TypeLiteral<?> type, RuntimeException cause) {
-    return errorInUserCode(cause, "Error notifying InjectionListener %s of %s.%n"
-        + " Reason: %s", listener, type, cause);
+  public Errors errorNotifyingTypeListener(
+      TypeListenerBinding listener, TypeLiteral<?> type, Throwable cause) {
+    return errorInUserCode(
+        cause,
+        "Error notifying TypeListener %s (bound at %s) of %s.%n Reason: %s",
+        listener.getListener(),
+        convert(listener.getSource()),
+        type,
+        cause);
   }
 
   public Errors exposedButNotBound(Key<?> key) {
@@ -422,14 +519,6 @@
     }
   }
 
-  private Throwable unwrap(RuntimeException runtimeException) {
-   if(runtimeException instanceof Exceptions.UnhandledCheckedUserException) {
-     return runtimeException.getCause();
-   } else {
-     return runtimeException;
-   }
-  }
-
   public Errors cannotInjectRawProvider() {
     return addMessage("Cannot inject a Provider that has no type parameter");
   }
@@ -446,18 +535,6 @@
     return addMessage("Cannot inject a TypeLiteral that has no type parameter");
   }
 
-  public Errors cannotSatisfyCircularDependency(Class<?> expectedType) {
-    return addMessage(
-        "Tried proxying %s to support a circular dependency, but it is not an interface.",
-        expectedType);
-  }
-
-  public Errors circularProxiesDisabled(Class<?> expectedType) {
-    return addMessage(
-        "Tried proxying %s to support a circular dependency, but circular proxies are disabled.",
-        expectedType);
-  }
-
   public void throwCreationExceptionIfErrorsExist() {
     if (!hasErrors()) {
       return;
@@ -474,6 +551,7 @@
     throw new ConfigurationException(getMessages());
   }
 
+  // Guice no longer calls this, but external callers do
   public void throwProvisionExceptionIfErrorsExist() {
     if (!hasErrors()) {
       return;
@@ -482,16 +560,10 @@
     throw new ProvisionException(getMessages());
   }
 
-  private Message merge(Message message) {
-    List<Object> sources = Lists.newArrayList();
-    sources.addAll(getSources());
-    sources.addAll(message.getSources());
-    return new Message(sources, message.getMessage(), message.getCause());
-  }
-
   public Errors merge(Collection<Message> messages) {
+    List<Object> sources = getSources();
     for (Message message : messages) {
-      addMessage(merge(message));
+      addMessage(Messages.mergeSources(sources, message));
     }
     return this;
   }
@@ -505,7 +577,12 @@
     return this;
   }
 
-  public List<Object> getSources() {
+  public Errors merge(InternalProvisionException ipe) {
+    merge(ipe.getErrors());
+    return this;
+  }
+
+  private List<Object> getSources() {
     List<Object> sources = Lists.newArrayList();
     for (Errors e = this; e != null; e = e.parent) {
       if (e.source != SourceProvider.UNKNOWN_SOURCE) {
@@ -536,8 +613,7 @@
   }
 
   private Errors addMessage(Throwable cause, String messageFormat, Object... arguments) {
-    String message = format(messageFormat, arguments);
-    addMessage(new Message(getSources(), message, cause));
+    addMessage(Messages.create(cause, getSources(), messageFormat, arguments));
     return this;
   }
 
@@ -549,11 +625,9 @@
     return this;
   }
 
+  // TODO(lukes): inline into callers
   public static String format(String messageFormat, Object... arguments) {
-    for (int i = 0; i < arguments.length; i++) {
-      arguments[i] = Errors.convert(arguments[i]);
-    }
-    return String.format(messageFormat, arguments);
+    return Messages.format(messageFormat, arguments);
   }
 
   public List<Message> getMessages() {
@@ -569,274 +643,23 @@
     }.sortedCopy(root.errors);
   }
 
-  /** Returns the formatted message for an exception with the specified messages. */
-  public static String format(String heading, Collection<Message> errorMessages) {
-    Formatter fmt = new Formatter().format(heading).format(":%n%n");
-    int index = 1;
-    boolean displayCauses = getOnlyCause(errorMessages) == null;
-
-    for (Message errorMessage : errorMessages) {
-      fmt.format("%s) %s%n", index++, errorMessage.getMessage());
-
-      List<Object> dependencies = errorMessage.getSources();
-      for (int i = dependencies.size() - 1; i >= 0; i--) {
-        Object source = dependencies.get(i);
-        formatSource(fmt, source);
-      }
-
-      Throwable cause = errorMessage.getCause();
-      if (displayCauses && cause != null) {
-        StringWriter writer = new StringWriter();
-        cause.printStackTrace(new PrintWriter(writer));
-        fmt.format("Caused by: %s", writer.getBuffer());
-      }
-
-      fmt.format("%n");
-    }
-
-    if (errorMessages.size() == 1) {
-      fmt.format("1 error");
-    } else {
-      fmt.format("%s errors", errorMessages.size());
-    }
-
-    return fmt.toString();
-  }
-
-  /**
-   * Returns {@code value} if it is non-null allowed to be null. Otherwise a message is added and
-   * an {@code ErrorsException} is thrown.
-   */
-  public <T> T checkForNull(T value, Object source, Dependency<?> dependency)
-      throws ErrorsException {
-    if (value != null || dependency.isNullable() ) {
-      return value;
-    }
-
-    // Hack to allow null parameters to @Provides methods, for backwards compatibility.
-    if (dependency.getInjectionPoint().getMember() instanceof Method) {
-      Method annotated = (Method) dependency.getInjectionPoint().getMember();
-      if (annotated.isAnnotationPresent(Provides.class)) {
-        switch (InternalFlags.getNullableProvidesOption()) {
-          case ERROR:
-            break; // break out & let the below exception happen
-          case IGNORE:
-            return value; // user doesn't care about injecting nulls to non-@Nullables.
-          case WARN:
-            // Warn only once, otherwise we spam logs too much.
-            if (!warnedDependencies.add(dependency)) {
-              return value;
-            }
-            logger.log(Level.WARNING,
-                "Guice injected null into parameter {0} of {1} (a {2}), please mark it @Nullable."
-                    + " Use -Dguice_check_nullable_provides_params=ERROR to turn this into an"
-                    + " error.",
-                new Object[] {
-                    dependency.getParameterIndex(),
-                    convert(dependency.getInjectionPoint().getMember()),
-                    convert(dependency.getKey())});
-            return null; // log & exit.
-        }
-      }
-    }
-
-    int parameterIndex = dependency.getParameterIndex();
-    String parameterName = (parameterIndex != -1)
-        ? "parameter " + parameterIndex + " of "
-        : "";
-    addMessage("null returned by binding at %s%n but %s%s is not @Nullable",
-        source, parameterName, dependency.getInjectionPoint().getMember());
-
-    throw toException();
-  }
-
-  /**
-   * Returns the cause throwable if there is exactly one cause in {@code messages}. If there are
-   * zero or multiple messages with causes, null is returned.
-   */
-  public static Throwable getOnlyCause(Collection<Message> messages) {
-    Throwable onlyCause = null;
-    for (Message message : messages) {
-      Throwable messageCause = message.getCause();
-      if (messageCause == null) {
-        continue;
-      }
-
-      if (onlyCause != null) {
-        return null;
-      }
-
-      onlyCause = messageCause;
-    }
-
-    return onlyCause;
-  }
-
   public int size() {
     return root.errors == null ? 0 : root.errors.size();
   }
 
-  private static abstract class Converter<T> {
-
-    final Class<T> type;
-
-    Converter(Class<T> type) {
-      this.type = type;
-    }
-
-    boolean appliesTo(Object o) {
-      return o != null && type.isAssignableFrom(o.getClass());
-    }
-
-    String convert(Object o) {
-      return toString(type.cast(o));
-    }
-
-    abstract String toString(T t);
-  }
-
-  private static final Collection<Converter<?>> converters = ImmutableList.of(
-      new Converter<Class>(Class.class) {
-        @Override public String toString(Class c) {
-          return c.getName();
-        }
-      },
-      new Converter<Member>(Member.class) {
-        @Override public String toString(Member member) {
-          return Classes.toString(member);
-        }
-      },
-      new Converter<Key>(Key.class) {
-        @Override public String toString(Key key) {
-          if (key.getAnnotationType() != null) {
-            return key.getTypeLiteral() + " annotated with "
-                + (key.getAnnotation() != null ? key.getAnnotation() : key.getAnnotationType());
-          } else {
-            return key.getTypeLiteral().toString();
-          }
-        }
-      });
-
+  // TODO(lukes): inline in callers.  There are some callers outside of guice, so this is difficult
   public static Object convert(Object o) {
-    ElementSource source = null;
-    if (o instanceof ElementSource) {
-      source = (ElementSource)o;
-      o = source.getDeclaringSource();
-    }
-    return convert(o, source);
+    return Messages.convert(o);
   }
 
+  // TODO(lukes): inline in callers.  There are some callers outside of guice, so this is difficult
   public static Object convert(Object o, ElementSource source) {
-    for (Converter<?> converter : converters) {
-      if (converter.appliesTo(o)) {
-        return appendModules(converter.convert(o), source);
-      }
-    }
-    return appendModules(o, source);
+    return Messages.convert(o, source);
   }
 
-  private static Object appendModules(Object source, ElementSource elementSource) {
-    String modules = moduleSourceString(elementSource);
-    if (modules.length() == 0) {
-      return source;
-    } else {
-      return source + modules;
-    }
-  }
-
-  private static String moduleSourceString(ElementSource elementSource) {
-    // if we only have one module (or don't know what they are), then don't bother
-    // reporting it, because the source already is going to report exactly that module.
-    if (elementSource == null) {
-      return "";
-    }
-    List<String> modules = Lists.newArrayList(elementSource.getModuleClassNames());
-    // Insert any original element sources w/ module info into the path.
-    while(elementSource.getOriginalElementSource() != null) {
-      elementSource = elementSource.getOriginalElementSource();
-      modules.addAll(0, elementSource.getModuleClassNames());
-    }
-    if (modules.size() <= 1) {
-      return "";
-    }
-
-    // Ideally we'd do:
-    //    return Joiner.on(" -> ")
-    //        .appendTo(new StringBuilder(" (via modules: "), Lists.reverse(modules))
-    //        .append(")").toString();
-    // ... but for some reason we can't find Lists.reverse, so do it the boring way.
-    StringBuilder builder = new StringBuilder(" (via modules: ");
-    for (int i = modules.size() - 1; i >= 0; i--) {
-      builder.append(modules.get(i));
-      if (i != 0) {
-        builder.append(" -> ");
-      }
-    }
-    builder.append(")");
-    return builder.toString();
-  }
-
+  // TODO(lukes): inline in callers.  There are some callers outside of guice, so this is difficult
   public static void formatSource(Formatter formatter, Object source) {
-    ElementSource elementSource = null;
-    if (source instanceof ElementSource) {
-      elementSource = (ElementSource)source;
-      source = elementSource.getDeclaringSource();
-    }
-    formatSource(formatter, source, elementSource);
+    Messages.formatSource(formatter, source);
   }
 
-  public static void formatSource(Formatter formatter, Object source, ElementSource elementSource) {
-    String modules = moduleSourceString(elementSource);
-    if (source instanceof Dependency) {
-      Dependency<?> dependency = (Dependency<?>) source;
-      InjectionPoint injectionPoint = dependency.getInjectionPoint();
-      if (injectionPoint != null) {
-        formatInjectionPoint(formatter, dependency, injectionPoint, elementSource);
-      } else {
-        formatSource(formatter, dependency.getKey(), elementSource);
-      }
-
-    } else if (source instanceof InjectionPoint) {
-      formatInjectionPoint(formatter, null, (InjectionPoint) source, elementSource);
-
-    } else if (source instanceof Class) {
-      formatter.format("  at %s%s%n", StackTraceElements.forType((Class<?>) source), modules);
-
-    } else if (source instanceof Member) {
-      formatter.format("  at %s%s%n", StackTraceElements.forMember((Member) source), modules);
-
-    } else if (source instanceof TypeLiteral) {
-      formatter.format("  while locating %s%s%n", source, modules);
-
-    } else if (source instanceof Key) {
-      Key<?> key = (Key<?>) source;
-      formatter.format("  while locating %s%n", convert(key, elementSource));
-
-    } else if (source instanceof Thread) {
-      formatter.format("  in thread %s%n", source);
-
-    } else {
-      formatter.format("  at %s%s%n", source, modules);
-    }
-  }
-
-  public static void formatInjectionPoint(Formatter formatter, Dependency<?> dependency,
-      InjectionPoint injectionPoint, ElementSource elementSource) {
-    Member member = injectionPoint.getMember();
-    Class<? extends Member> memberType = Classes.memberType(member);
-
-    if (memberType == Field.class) {
-      dependency = injectionPoint.getDependencies().get(0);
-      formatter.format("  while locating %s%n", convert(dependency.getKey(), elementSource));
-      formatter.format("    for field at %s%n", StackTraceElements.forMember(member));
-
-    } else if (dependency != null) {
-      formatter.format("  while locating %s%n", convert(dependency.getKey(), elementSource));
-      formatter.format("    for parameter %s at %s%n",
-          dependency.getParameterIndex(), StackTraceElements.forMember(member));
-
-    } else {
-      formatSource(formatter, injectionPoint.getMember());
-    }
-  }
 }
diff --git a/core/src/com/google/inject/internal/ErrorsException.java b/core/src/com/google/inject/internal/ErrorsException.java
index 57f55c4..6e95dbc 100644
--- a/core/src/com/google/inject/internal/ErrorsException.java
+++ b/core/src/com/google/inject/internal/ErrorsException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.internal;
 
 /**
@@ -25,6 +24,8 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public class ErrorsException extends Exception {
+  // NOTE: this is used by Gin which is abandoned.  So changing this API will prevent Gin users from
+  // upgrading Guice version.
 
   private final Errors errors;
 
diff --git a/core/src/com/google/inject/internal/Exceptions.java b/core/src/com/google/inject/internal/Exceptions.java
deleted file mode 100644
index f9d1e21..0000000
--- a/core/src/com/google/inject/internal/Exceptions.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.internal;
-
-
-/**
- * Rethrows user-code exceptions in wrapped exceptions so that Errors can target the correct
- * exception.
- *
- * @author sameb@google.com (Sam Berlin)
- */
-class Exceptions {
-
-  /**
-   * Rethrows the exception (or it's cause, if it has one) directly if possible.
-   * If it was a checked exception, this wraps the exception in a stack trace
-   * with no frames, so that the exception is shown immediately with no frames
-   * above it.
-   */
-  public static RuntimeException rethrowCause(Throwable throwable) {
-    Throwable cause = throwable;
-    if(cause.getCause() != null) {
-      cause = cause.getCause();
-    }
-    return rethrow(cause);
-  }
-  
-  /** Rethrows the exception. */
-  public static RuntimeException rethrow(Throwable throwable) {    
-    if(throwable instanceof RuntimeException) {
-      throw (RuntimeException)throwable;
-    } else if(throwable instanceof Error) {
-      throw (Error)throwable;
-    } else {
-      throw new UnhandledCheckedUserException(throwable);
-    }
-  }
-
-  /**
-   * A marker exception class that we look for in order to unwrap the exception
-   * into the user exception, to provide a cleaner stack trace.
-   */
-  static class UnhandledCheckedUserException extends RuntimeException {
-    public UnhandledCheckedUserException(Throwable cause) {
-      super(cause);
-    }
-  }
-}
diff --git a/core/src/com/google/inject/internal/ExposedBindingImpl.java b/core/src/com/google/inject/internal/ExposedBindingImpl.java
index f17d5a6..1dfe408 100644
--- a/core/src/com/google/inject/internal/ExposedBindingImpl.java
+++ b/core/src/com/google/inject/internal/ExposedBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
 
 package com.google.inject.internal;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
 import com.google.inject.Injector;
@@ -25,43 +25,51 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.ExposedBinding;
 import com.google.inject.spi.PrivateElements;
-
 import java.util.Set;
 
 public final class ExposedBindingImpl<T> extends BindingImpl<T> implements ExposedBinding<T> {
 
   private final PrivateElements privateElements;
 
-  public ExposedBindingImpl(InjectorImpl injector, Object source, Key<T> key,
-      InternalFactory<T> factory, PrivateElements privateElements) {
+  public ExposedBindingImpl(
+      InjectorImpl injector,
+      Object source,
+      Key<T> key,
+      InternalFactory<T> factory,
+      PrivateElements privateElements) {
     super(injector, key, source, factory, Scoping.UNSCOPED);
     this.privateElements = privateElements;
   }
 
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
   }
 
+  @Override
   public PrivateElements getPrivateElements() {
     return privateElements;
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(ExposedBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(ExposedBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("privateElements", privateElements)
         .toString();
   }
 
+  @Override
   public void applyTo(Binder binder) {
     throw new UnsupportedOperationException("This element represents a synthetic binding.");
   }
-  
+
   // Purposely does not override equals/hashcode, because exposed bindings are only equal to
   // themselves right now -- that is, there cannot be "duplicate" exposed bindings.
 }
diff --git a/core/src/com/google/inject/internal/ExposedKeyFactory.java b/core/src/com/google/inject/internal/ExposedKeyFactory.java
index 52bf7cb..5de73aa 100644
--- a/core/src/com/google/inject/internal/ExposedKeyFactory.java
+++ b/core/src/com/google/inject/internal/ExposedKeyFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,6 +34,7 @@
     this.privateElements = privateElements;
   }
 
+  @Override
   public void notify(Errors errors) {
     InjectorImpl privateInjector = (InjectorImpl) privateElements.getInjector();
     BindingImpl<T> explicitBinding = privateInjector.state.getExplicitBinding(key);
@@ -49,8 +50,10 @@
     this.delegate = explicitBinding;
   }
 
-  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException {
-    return delegate.getInternalFactory().get(errors, context, dependency, linked);
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
+    // TODO(lukes): add a source to the thrown exception?
+    return delegate.getInternalFactory().get(context, dependency, linked);
   }
 }
diff --git a/core/src/com/google/inject/internal/ExposureBuilder.java b/core/src/com/google/inject/internal/ExposureBuilder.java
index 3b1c227..35dca16 100644
--- a/core/src/com/google/inject/internal/ExposureBuilder.java
+++ b/core/src/com/google/inject/internal/ExposureBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,12 +20,9 @@
 import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.binder.AnnotatedElementBuilder;
-
 import java.lang.annotation.Annotation;
 
-/**
- * For private binder's expose() method.
- */
+/** For private binder's expose() method. */
 public class ExposureBuilder<T> implements AnnotatedElementBuilder {
   private final Binder binder;
   private final Object source;
@@ -43,12 +40,14 @@
     }
   }
 
+  @Override
   public void annotatedWith(Class<? extends Annotation> annotationType) {
     Preconditions.checkNotNull(annotationType, "annotationType");
     checkNotAnnotated();
     key = Key.get(key.getTypeLiteral(), annotationType);
   }
 
+  @Override
   public void annotatedWith(Annotation annotation) {
     Preconditions.checkNotNull(annotation, "annotation");
     checkNotAnnotated();
@@ -63,7 +62,8 @@
     return source;
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "AnnotatedElementBuilder";
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/FactoryProxy.java b/core/src/com/google/inject/internal/FactoryProxy.java
index 6416d26..a3a2227 100644
--- a/core/src/com/google/inject/internal/FactoryProxy.java
+++ b/core/src/com/google/inject/internal/FactoryProxy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,14 +16,14 @@
 
 package com.google.inject.internal;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.Key;
 import com.google.inject.internal.InjectorImpl.JitLimitation;
 import com.google.inject.spi.Dependency;
 
 /**
- * A placeholder which enables us to swap in the real factory once the injector is created.
- * Used for a linked binding, so that getting the linked binding returns the link's factory.
+ * A placeholder which enables us to swap in the real factory once the injector is created. Used for
+ * a linked binding, so that getting the linked binding returns the link's factory.
  */
 final class FactoryProxy<T> implements InternalFactory<T>, CreationListener {
 
@@ -41,26 +41,36 @@
     this.source = source;
   }
 
+  @Override
   public void notify(final Errors errors) {
     try {
-      targetFactory = injector.getInternalFactory(targetKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT);
+      targetFactory =
+          injector.getInternalFactory(
+              targetKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT);
     } catch (ErrorsException e) {
       errors.merge(e.getErrors());
     }
   }
 
-  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException {
-    context.pushState(targetKey, source);
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
+    Key<? extends T> localTargetKey = targetKey;
+    context.pushState(localTargetKey, source);
+
     try {
-      return targetFactory.get(errors.withSource(targetKey), context, dependency, true);
-    } finally {
-      context.popState();
+      return targetFactory.get(context, dependency, true);
+    } catch (InternalProvisionException ipe) {
+      throw ipe.addSource(localTargetKey);
+      } finally {
+        context.popState();
+
     }
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(FactoryProxy.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(FactoryProxy.class)
         .add("key", key)
         .add("provider", targetFactory)
         .toString();
diff --git a/core/src/com/google/inject/internal/FailableCache.java b/core/src/com/google/inject/internal/FailableCache.java
index acd8be5..e1a461d 100644
--- a/core/src/com/google/inject/internal/FailableCache.java
+++ b/core/src/com/google/inject/internal/FailableCache.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,23 +27,26 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public abstract class FailableCache<K, V> {
-  
-  private final LoadingCache<K, Object> delegate = CacheBuilder.newBuilder().build(
-      new CacheLoader<K, Object>() {
-        public Object load(K key) {
-          Errors errors = new Errors();
-          V result = null;
-          try {
-            result = FailableCache.this.create(key, errors);
-          } catch (ErrorsException e) {
-            errors.merge(e.getErrors());
-          }
-          return errors.hasErrors() ? errors : result;
-        }
-      });
+
+  private final LoadingCache<K, Object> delegate =
+      CacheBuilder.newBuilder()
+          .build(
+              new CacheLoader<K, Object>() {
+                @Override
+                public Object load(K key) {
+                  Errors errors = new Errors();
+                  V result = null;
+                  try {
+                    result = FailableCache.this.create(key, errors);
+                  } catch (ErrorsException e) {
+                    errors.merge(e.getErrors());
+                  }
+                  return errors.hasErrors() ? errors : result;
+                }
+              });
 
   protected abstract V create(K key, Errors errors) throws ErrorsException;
-  
+
   public V get(K key, Errors errors) throws ErrorsException {
     Object resultOrError = delegate.getUnchecked(key);
     if (resultOrError instanceof Errors) {
@@ -55,7 +58,7 @@
       return result;
     }
   }
-  
+
   boolean remove(K key) {
     return delegate.asMap().remove(key) != null;
   }
diff --git a/core/src/com/google/inject/internal/Indexer.java b/core/src/com/google/inject/internal/Indexer.java
new file mode 100644
index 0000000..acbc163
--- /dev/null
+++ b/core/src/com/google/inject/internal/Indexer.java
@@ -0,0 +1,190 @@
+/*
+ * 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.google.inject.internal;
+
+import com.google.common.base.Objects;
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Scope;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.BindingScopingVisitor;
+import com.google.inject.spi.ConstructorBinding;
+import com.google.inject.spi.ConvertedConstantBinding;
+import com.google.inject.spi.DefaultBindingTargetVisitor;
+import com.google.inject.spi.ExposedBinding;
+import com.google.inject.spi.InstanceBinding;
+import com.google.inject.spi.LinkedKeyBinding;
+import com.google.inject.spi.ProviderBinding;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.spi.ProviderKeyBinding;
+import com.google.inject.spi.UntargettedBinding;
+import java.lang.annotation.Annotation;
+
+/**
+ * Visits bindings to return a {@code IndexedBinding} that can be used to emulate the binding
+ * deduplication that Guice internally performs.
+ *
+ * <p>Note: simply using equals/hashCode on the BindingImpls doesn't work because they all have
+ * unique annotations. This works around that by reimplementing equality semantics that ignores
+ * {@link Element#uniqueId()}. A better solution might be to introduce the idea of an 'anonymous'
+ * binding to guice, that might support this usecase directly.
+ */
+class Indexer extends DefaultBindingTargetVisitor<Object, Indexer.IndexedBinding>
+    implements BindingScopingVisitor<Object> {
+  enum BindingType {
+    INSTANCE,
+    PROVIDER_INSTANCE,
+    PROVIDER_KEY,
+    LINKED_KEY,
+    UNTARGETTED,
+    CONSTRUCTOR,
+    CONSTANT,
+    EXPOSED,
+    PROVIDED_BY,
+  }
+
+  static class IndexedBinding {
+    final String annotationName;
+    final Element.Type annotationType;
+    final TypeLiteral<?> typeLiteral;
+    final Object scope;
+    final BindingType type;
+    final Object extraEquality;
+
+    IndexedBinding(Binding<?> binding, BindingType type, Object scope, Object extraEquality) {
+      this.scope = scope;
+      this.type = type;
+      this.extraEquality = extraEquality;
+      this.typeLiteral = binding.getKey().getTypeLiteral();
+      Element annotation = (Element) binding.getKey().getAnnotation();
+      this.annotationName = annotation.setName();
+      this.annotationType = annotation.type();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!(obj instanceof IndexedBinding)) {
+        return false;
+      }
+      IndexedBinding o = (IndexedBinding) obj;
+      return type == o.type
+          && Objects.equal(scope, o.scope)
+          && typeLiteral.equals(o.typeLiteral)
+          && annotationType == o.annotationType
+          && annotationName.equals(o.annotationName)
+          && Objects.equal(extraEquality, o.extraEquality);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hashCode(
+          type, scope, typeLiteral, annotationType, annotationName, extraEquality);
+    }
+  }
+
+  final Injector injector;
+
+  Indexer(Injector injector) {
+    this.injector = injector;
+  }
+
+  boolean isIndexable(Binding<?> binding) {
+    return binding.getKey().getAnnotation() instanceof Element;
+  }
+
+  private Object scope(Binding<?> binding) {
+    return binding.acceptScopingVisitor(this);
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ConstructorBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.CONSTRUCTOR, scope(binding), binding.getConstructor());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ConvertedConstantBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.CONSTANT, scope(binding), binding.getValue());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ExposedBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(binding, BindingType.EXPOSED, scope(binding), binding);
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(InstanceBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.INSTANCE, scope(binding), binding.getInstance());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(LinkedKeyBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.LINKED_KEY, scope(binding), binding.getLinkedKey());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ProviderBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding,
+        BindingType.PROVIDED_BY,
+        scope(binding),
+        injector.getBinding(binding.getProvidedKey()));
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ProviderInstanceBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.PROVIDER_INSTANCE, scope(binding), binding.getUserSuppliedProvider());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(ProviderKeyBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(
+        binding, BindingType.PROVIDER_KEY, scope(binding), binding.getProviderKey());
+  }
+
+  @Override
+  public Indexer.IndexedBinding visit(UntargettedBinding<? extends Object> binding) {
+    return new Indexer.IndexedBinding(binding, BindingType.UNTARGETTED, scope(binding), null);
+  }
+
+  private static final Object EAGER_SINGLETON = new Object();
+
+  @Override
+  public Object visitEagerSingleton() {
+    return EAGER_SINGLETON;
+  }
+
+  @Override
+  public Object visitNoScoping() {
+    return Scopes.NO_SCOPE;
+  }
+
+  @Override
+  public Object visitScope(Scope scope) {
+    return scope;
+  }
+
+  @Override
+  public Object visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
+    return scopeAnnotation;
+  }
+}
diff --git a/core/src/com/google/inject/internal/InheritingState.java b/core/src/com/google/inject/internal/InheritingState.java
index 18363f4..7b739fc 100644
--- a/core/src/com/google/inject/internal/InheritingState.java
+++ b/core/src/com/google/inject/internal/InheritingState.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,25 +31,21 @@
 import com.google.inject.spi.ScopeBinding;
 import com.google.inject.spi.TypeConverterBinding;
 import com.google.inject.spi.TypeListenerBinding;
-
 import java.lang.annotation.Annotation;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 final class InheritingState implements State {
 
   private final State parent;
 
   // Must be a linked hashmap in order to preserve order of bindings in Modules.
   private final Map<Key<?>, Binding<?>> explicitBindingsMutable = Maps.newLinkedHashMap();
-  private final Map<Key<?>, Binding<?>> explicitBindings
-      = Collections.unmodifiableMap(explicitBindingsMutable);
+  private final Map<Key<?>, Binding<?>> explicitBindings =
+      Collections.unmodifiableMap(explicitBindingsMutable);
   private final Map<Class<? extends Annotation>, ScopeBinding> scopes = Maps.newHashMap();
   private final List<TypeConverterBinding> converters = Lists.newArrayList();
   /*if[AOP]*/
@@ -67,41 +63,50 @@
     this.blacklistedKeys = new WeakKeySet(lock);
   }
 
+  @Override
   public State parent() {
     return parent;
   }
 
+  @Override
   @SuppressWarnings("unchecked") // we only put in BindingImpls that match their key types
   public <T> BindingImpl<T> getExplicitBinding(Key<T> key) {
     Binding<?> binding = explicitBindings.get(key);
     return binding != null ? (BindingImpl<T>) binding : parent.getExplicitBinding(key);
   }
 
+  @Override
   public Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel() {
     return explicitBindings;
   }
 
+  @Override
   public void putBinding(Key<?> key, BindingImpl<?> binding) {
     explicitBindingsMutable.put(key, binding);
   }
 
+  @Override
   public ScopeBinding getScopeBinding(Class<? extends Annotation> annotationType) {
     ScopeBinding scopeBinding = scopes.get(annotationType);
     return scopeBinding != null ? scopeBinding : parent.getScopeBinding(annotationType);
   }
 
+  @Override
   public void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope) {
     scopes.put(annotationType, scope);
   }
 
+  @Override
   public Iterable<TypeConverterBinding> getConvertersThisLevel() {
     return converters;
   }
 
+  @Override
   public void addConverter(TypeConverterBinding typeConverterBinding) {
     converters.add(typeConverterBinding);
   }
 
+  @Override
   public TypeConverterBinding getConverter(
       String stringValue, TypeLiteral<?> type, Errors errors, Object source) {
     TypeConverterBinding matchingConverter = null;
@@ -119,10 +124,12 @@
   }
 
   /*if[AOP]*/
+  @Override
   public void addMethodAspect(MethodAspect methodAspect) {
     methodAspects.add(methodAspect);
   }
 
+  @Override
   public ImmutableList<MethodAspect> getMethodAspects() {
     return new ImmutableList.Builder<MethodAspect>()
         .addAll(parent.getMethodAspects())
@@ -131,10 +138,12 @@
   }
   /*end[AOP]*/
 
+  @Override
   public void addTypeListener(TypeListenerBinding listenerBinding) {
     typeListenerBindings.add(listenerBinding);
   }
 
+  @Override
   public List<TypeListenerBinding> getTypeListenerBindings() {
     List<TypeListenerBinding> parentBindings = parent.getTypeListenerBindings();
     List<TypeListenerBinding> result =
@@ -143,11 +152,13 @@
     result.addAll(typeListenerBindings);
     return result;
   }
-  
+
+  @Override
   public void addProvisionListener(ProvisionListenerBinding listenerBinding) {
     provisionListenerBindings.add(listenerBinding);
   }
 
+  @Override
   public List<ProvisionListenerBinding> getProvisionListenerBindings() {
     List<ProvisionListenerBinding> parentBindings = parent.getProvisionListenerBindings();
     List<ProvisionListenerBinding> result =
@@ -157,10 +168,12 @@
     return result;
   }
 
+  @Override
   public void addScanner(ModuleAnnotatedMethodScannerBinding scanner) {
     scannerBindings.add(scanner);
   }
 
+  @Override
   public List<ModuleAnnotatedMethodScannerBinding> getScannerBindings() {
     List<ModuleAnnotatedMethodScannerBinding> parentBindings = parent.getScannerBindings();
     List<ModuleAnnotatedMethodScannerBinding> result =
@@ -170,23 +183,28 @@
     return result;
   }
 
+  @Override
   public void blacklist(Key<?> key, State state, Object source) {
     parent.blacklist(key, state, source);
     blacklistedKeys.add(key, state, source);
   }
 
+  @Override
   public boolean isBlacklisted(Key<?> key) {
     return blacklistedKeys.contains(key);
   }
-  
+
+  @Override
   public Set<Object> getSourcesForBlacklistedKey(Key<?> key) {
     return blacklistedKeys.getSources(key);
   }
 
+  @Override
   public Object lock() {
     return lock;
   }
 
+  @Override
   public Map<Class<? extends Annotation>, Scope> getScopes() {
     ImmutableMap.Builder<Class<? extends Annotation>, Scope> builder = ImmutableMap.builder();
     for (Map.Entry<Class<? extends Annotation>, ScopeBinding> entry : scopes.entrySet()) {
diff --git a/core/src/com/google/inject/internal/Initializable.java b/core/src/com/google/inject/internal/Initializable.java
index 855dd8c..e3c9ed9 100644
--- a/core/src/com/google/inject/internal/Initializable.java
+++ b/core/src/com/google/inject/internal/Initializable.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,8 +23,6 @@
  */
 interface Initializable<T> {
 
-  /**
-   * Ensures the reference is initialized, then returns it.
-   */
-  T get(Errors errors) throws ErrorsException;
+  /** Ensures the reference is initialized, then returns it. */
+  T get() throws InternalProvisionException;
 }
diff --git a/core/src/com/google/inject/internal/Initializables.java b/core/src/com/google/inject/internal/Initializables.java
index 82e2868..36655f7 100644
--- a/core/src/com/google/inject/internal/Initializables.java
+++ b/core/src/com/google/inject/internal/Initializables.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,21 +16,19 @@
 
 package com.google.inject.internal;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 final class Initializables {
 
-  /**
-   * Returns an initializable for an instance that requires no initialization.
-   */
+  /** Returns an initializable for an instance that requires no initialization. */
   static <T> Initializable<T> of(final T instance) {
     return new Initializable<T>() {
-      public T get(Errors errors) throws ErrorsException {
+      @Override
+      public T get() {
         return instance;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return String.valueOf(instance);
       }
     };
diff --git a/core/src/com/google/inject/internal/Initializer.java b/core/src/com/google/inject/internal/Initializer.java
index ff83ea9..2ab4b0f 100644
--- a/core/src/com/google/inject/internal/Initializer.java
+++ b/core/src/com/google/inject/internal/Initializer.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,15 +21,16 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import com.google.inject.Binding;
 import com.google.inject.Key;
 import com.google.inject.Stage;
 import com.google.inject.TypeLiteral;
+import com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory;
 import com.google.inject.spi.InjectionPoint;
-
-import java.util.Map;
+import java.util.IdentityHashMap;
+import java.util.List;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * Manages and injects instances at injector-creation time. This is made more complicated by
@@ -39,46 +40,76 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 final class Initializer {
-  
-  /** the only thread that we'll use to inject members. */
-  private final Thread creatingThread = Thread.currentThread();
 
-  /** zero means everything is injected. */
-  private final CountDownLatch ready = new CountDownLatch(1);
-  
-  /** Maps from instances that need injection to the MembersInjector that will inject them. */
-  private final Map<Object, MembersInjectorImpl<?>> pendingMembersInjectors =
+  /** Is set to true once {@link #validateOustandingInjections} is called. */
+  private volatile boolean validationStarted = false;
+
+  /**
+   * Allows us to detect circular dependencies. It's only used during injectable reference
+   * initialization. After initialization direct access through volatile field is used.
+   */
+  private final CycleDetectingLockFactory<Class<?>> cycleDetectingLockFactory =
+      new CycleDetectingLockFactory<Class<?>>();
+
+  /**
+   * Instances that need injection during injector creation to a source that registered them. New
+   * references added before {@link #validateOustandingInjections}. Cleared up in {@link
+   * #injectAll}.
+   */
+  private final List<InjectableReference<?>> pendingInjections = Lists.newArrayList();
+
+  /**
+   * Map that guarantees that no instance would get two references. New references added before
+   * {@link #validateOustandingInjections}. Cleared up in {@link #validateOustandingInjections}.
+   */
+  private final IdentityHashMap<Object, InjectableReference<?>> initializablesCache =
       Maps.newIdentityHashMap();
 
-  /** Maps instances that need injection to a source that registered them */
-  private final Map<Object, InjectableReference<?>> pendingInjection = Maps.newIdentityHashMap();
-
   /**
    * Registers an instance for member injection when that step is performed.
    *
-   * @param instance an instance that optionally has members to be injected (each annotated with
-   *      @Inject).
+   * @param instance an instance that optionally has members to be injected (each annotated
+   *     with @Inject).
    * @param binding the binding that caused this initializable to be created, if it exists.
    * @param source the source location that this injection was requested
    */
-  <T> Initializable<T> requestInjection(InjectorImpl injector, T instance, Binding<T> binding,
-      Object source, Set<InjectionPoint> injectionPoints) {
+  <T> Initializable<T> requestInjection(
+      InjectorImpl injector,
+      T instance,
+      Binding<T> binding,
+      Object source,
+      Set<InjectionPoint> injectionPoints) {
     checkNotNull(source);
-    
+    Preconditions.checkState(
+        !validationStarted, "Member injection could not be requested after validation is started");
     ProvisionListenerStackCallback<T> provisionCallback =
         binding == null ? null : injector.provisionListenerStore.get(binding);
 
     // short circuit if the object has no injections or listeners.
-    if (instance == null || (injectionPoints.isEmpty()
-        && !injector.membersInjectorStore.hasTypeListeners()
-        && (provisionCallback == null || !provisionCallback.hasListeners()))) {
+    if (instance == null
+        || (injectionPoints.isEmpty()
+            && !injector.membersInjectorStore.hasTypeListeners()
+            && provisionCallback == null)) {
       return Initializables.of(instance);
     }
 
-    InjectableReference<T> initializable = new InjectableReference<T>(
-        injector, instance, binding == null ? null : binding.getKey(), provisionCallback, source);
-    pendingInjection.put(instance, initializable);
-    return initializable;
+    if (initializablesCache.containsKey(instance)) {
+      @SuppressWarnings("unchecked") // Map from T to InjectableReference<T>
+      Initializable<T> cached = (Initializable<T>) initializablesCache.get(instance);
+      return cached;
+    }
+
+    InjectableReference<T> injectableReference =
+        new InjectableReference<T>(
+            injector,
+            instance,
+            binding == null ? null : binding.getKey(),
+            provisionCallback,
+            source,
+            cycleDetectingLockFactory.create(instance.getClass()));
+    initializablesCache.put(instance, injectableReference);
+    pendingInjections.add(injectableReference);
+    return injectableReference;
   }
 
   /**
@@ -86,9 +117,11 @@
    * on the injected instances.
    */
   void validateOustandingInjections(Errors errors) {
-    for (InjectableReference<?> reference : pendingInjection.values()) {
+    validationStarted = true;
+    initializablesCache.clear();
+    for (InjectableReference<?> reference : pendingInjections) {
       try {
-        pendingMembersInjectors.put(reference.instance, reference.validate(errors));
+        reference.validate(errors);
       } catch (ErrorsException e) {
         errors.merge(e.getErrors());
       }
@@ -101,88 +134,130 @@
    * instances are codependent (directly or transitively), ordering of injection is arbitrary.
    */
   void injectAll(final Errors errors) {
-    // loop over a defensive copy since ensureInjected() mutates the set. Unfortunately, that copy
-    // is made complicated by a bug in IBM's JDK, wherein entrySet().toArray(Object[]) doesn't work
-    for (InjectableReference<?> reference : Lists.newArrayList(pendingInjection.values())) {
+    Preconditions.checkState(validationStarted, "Validation should be done before injection");
+    for (InjectableReference<?> reference : pendingInjections) {
       try {
-        reference.get(errors);
-      } catch (ErrorsException e) {
-        errors.merge(e.getErrors());
+        reference.get();
+      } catch (InternalProvisionException ipe) {
+        errors.merge(ipe);
       }
     }
-
-    if (!pendingInjection.isEmpty()) {
-      throw new AssertionError("Failed to satisfy " + pendingInjection);
-    }
-
-    ready.countDown();
+    pendingInjections.clear();
   }
 
-  private class InjectableReference<T> implements Initializable<T> {
+  private enum InjectableReferenceState {
+    NEW,
+    VALIDATED,
+    INJECTING,
+    READY
+  }
+
+  private static class InjectableReference<T> implements Initializable<T> {
+    private volatile InjectableReferenceState state = InjectableReferenceState.NEW;
+    private volatile MembersInjectorImpl<T> membersInjector = null;
+
     private final InjectorImpl injector;
     private final T instance;
     private final Object source;
     private final Key<T> key;
     private final ProvisionListenerStackCallback<T> provisionCallback;
+    private final CycleDetectingLock<?> lock;
 
-    public InjectableReference(InjectorImpl injector, T instance, Key<T> key,
-        ProvisionListenerStackCallback<T> provisionCallback, Object source) {
+    public InjectableReference(
+        InjectorImpl injector,
+        T instance,
+        Key<T> key,
+        ProvisionListenerStackCallback<T> provisionCallback,
+        Object source,
+        CycleDetectingLock<?> lock) {
       this.injector = injector;
       this.key = key; // possibly null!
       this.provisionCallback = provisionCallback; // possibly null!
       this.instance = checkNotNull(instance, "instance");
       this.source = checkNotNull(source, "source");
+      this.lock = checkNotNull(lock, "lock");
     }
 
-    public MembersInjectorImpl<T> validate(Errors errors) throws ErrorsException {
+    public void validate(Errors errors) throws ErrorsException {
       @SuppressWarnings("unchecked") // the type of 'T' is a TypeLiteral<T>
-          TypeLiteral<T> type = TypeLiteral.get((Class<T>) instance.getClass());
-      return injector.membersInjectorStore.get(type, errors.withSource(source));
+      TypeLiteral<T> type = TypeLiteral.get((Class<T>) instance.getClass());
+      membersInjector = injector.membersInjectorStore.get(type, errors.withSource(source));
+      Preconditions.checkNotNull(
+          membersInjector,
+          "No membersInjector available for instance: %s, from key: %s",
+          instance,
+          key);
+      state = InjectableReferenceState.VALIDATED;
     }
 
     /**
      * Reentrant. If {@code instance} was registered for injection at injector-creation time, this
      * method will ensure that all its members have been injected before returning.
      */
-    public T get(Errors errors) throws ErrorsException {
-      if (ready.getCount() == 0) {
+    @Override
+    public T get() throws InternalProvisionException {
+      // skipping acquiring lock if initialization is already finished
+      if (state == InjectableReferenceState.READY) {
         return instance;
       }
 
-      // just wait for everything to be injected by another thread
-      if (Thread.currentThread() != creatingThread) {
-        try {
-          ready.await();
-          return instance;
-        } catch (InterruptedException e) {
-          // Give up, since we don't know if our injection is ready
-          throw new RuntimeException(e);
-        }
-      }
+      // acquire lock for current binding to initialize an instance
+      Multimap<?, ?> lockCycle = lock.lockOrDetectPotentialLocksCycle();
+      if (!lockCycle.isEmpty()) {
+        // Potential deadlock detected and creation lock is not taken.
+        // According to injectAll()'s contract return non-initialized instance.
 
-      // toInject needs injection, do it right away. we only do this once, even if it fails
-      if (pendingInjection.remove(instance) != null) {
-        // safe because we only insert a members injector for the appropriate instance
-        @SuppressWarnings("unchecked")
-        MembersInjectorImpl<T> membersInjector =
-            (MembersInjectorImpl<T>)pendingMembersInjectors.remove(instance);
-        Preconditions.checkState(membersInjector != null,
-            "No membersInjector available for instance: %s, from key: %s", instance, key);
-        
+        // This condition should not be possible under the current Guice implementation.
+        // This clause exists for defensive programming purposes.
+
+        // Reasoning:
+        // get() is called either directly from injectAll(), holds no locks and can not create
+        // a cycle, or it is called through a singleton scope, which resolves deadlocks by itself.
+        // Before calling get() object has to be requested for injection.
+        // Initializer.requestInjection() is called either for constant object bindings, which wrap
+        // creation into a Singleton scope, or from Binder.requestInjection(), which
+        // has to use Singleton scope to reuse the same InjectableReference to potentially
+        // create a lock cycle.
+        return instance;
+      }
+      try {
+        // lock acquired, current thread owns this instance initialization
+        switch (state) {
+          case READY:
+            return instance;
+            // When instance depends on itself in the same thread potential dead lock
+            // is not detected. We have to prevent a stack overflow and we use
+            // an "injecting" stage to short-circuit a call.
+          case INJECTING:
+            return instance;
+          case VALIDATED:
+            state = InjectableReferenceState.INJECTING;
+            break;
+          case NEW:
+            throw new IllegalStateException("InjectableReference is not validated yet");
+          default:
+            throw new IllegalStateException("Unknown state: " + state);
+        }
+
         // if in Stage.TOOL, we only want to inject & notify toolable injection points.
         // (otherwise we'll inject all of them)
-        membersInjector.injectAndNotify(instance,
-            errors.withSource(source),
-            key,
-            provisionCallback,
-            source,
-            injector.options.stage == Stage.TOOL);
+        try {
+          membersInjector.injectAndNotify(
+              instance, key, provisionCallback, source, injector.options.stage == Stage.TOOL);
+        } catch (InternalProvisionException ipe) {
+          throw ipe.addSource(source);
+        }
+        // mark instance as ready to skip a lock on subsequent calls
+        state = InjectableReferenceState.READY;
+        return instance;
+      } finally {
+        // always release our creation lock, even on failures
+        lock.unlock();
       }
-
-      return instance;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return instance.toString();
     }
   }
diff --git a/core/src/com/google/inject/internal/InjectionRequestProcessor.java b/core/src/com/google/inject/internal/InjectionRequestProcessor.java
index 36ad261..dce78e8 100644
--- a/core/src/com/google/inject/internal/InjectionRequestProcessor.java
+++ b/core/src/com/google/inject/internal/InjectionRequestProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.InjectionRequest;
 import com.google.inject.spi.StaticInjectionRequest;
-
 import java.util.List;
 import java.util.Set;
 
@@ -44,12 +43,14 @@
     this.initializer = initializer;
   }
 
-  @Override public Boolean visit(StaticInjectionRequest request) {
+  @Override
+  public Boolean visit(StaticInjectionRequest request) {
     staticInjections.add(new StaticInjection(injector, request));
     return true;
   }
 
-  @Override public Boolean visit(InjectionRequest<?> request) {
+  @Override
+  public Boolean visit(InjectionRequest<?> request) {
     Set<InjectionPoint> injectionPoints;
     try {
       injectionPoints = request.getInjectionPoints();
@@ -103,31 +104,32 @@
         injectionPoints = e.getPartialValue();
       }
       if (injectionPoints != null) {
-        memberInjectors = injector.membersInjectorStore.getInjectors(
-            injectionPoints, errorsForMember);
+        memberInjectors =
+            injector.membersInjectorStore.getInjectors(injectionPoints, errorsForMember);
       } else {
         memberInjectors = ImmutableList.of();
       }
-      
+
       errors.merge(errorsForMember);
     }
 
     void injectMembers() {
+      InternalContext context = injector.enterContext();
       try {
-        injector.callInContext(new ContextualCallable<Void>() {
-          public Void call(InternalContext context) {
-            for (SingleMemberInjector memberInjector : memberInjectors) {
-              // Run injections if we're not in tool stage (ie, PRODUCTION or DEV),
-              // or if we are in tool stage and the injection point is toolable.
-              if(injector.options.stage != Stage.TOOL || memberInjector.getInjectionPoint().isToolable()) {
-                memberInjector.inject(errors, context, null);
-              }
+        boolean isStageTool = injector.options.stage == Stage.TOOL;
+        for (SingleMemberInjector memberInjector : memberInjectors) {
+          // Run injections if we're not in tool stage (ie, PRODUCTION or DEV),
+          // or if we are in tool stage and the injection point is toolable.
+          if (!isStageTool || memberInjector.getInjectionPoint().isToolable()) {
+            try {
+              memberInjector.inject(context, null);
+            } catch (InternalProvisionException e) {
+              errors.merge(e);
             }
-            return null;
           }
-        });
-      } catch (ErrorsException e) {
-        throw new AssertionError();
+        }
+      } finally {
+        context.close();
       }
     }
   }
diff --git a/core/src/com/google/inject/internal/InjectorImpl.java b/core/src/com/google/inject/internal/InjectorImpl.java
index 54ce8a3..321dbea 100644
--- a/core/src/com/google/inject/internal/InjectorImpl.java
+++ b/core/src/com/google/inject/internal/InjectorImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,11 +16,13 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
+import com.google.common.collect.ArrayListMultimap;
 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 com.google.common.collect.ListMultimap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.inject.Binder;
@@ -33,7 +35,6 @@
 import com.google.inject.Module;
 import com.google.inject.ProvidedBy;
 import com.google.inject.Provider;
-import com.google.inject.ProvisionException;
 import com.google.inject.Scope;
 import com.google.inject.Stage;
 import com.google.inject.TypeLiteral;
@@ -43,10 +44,10 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.InstanceBinding;
 import com.google.inject.spi.ProviderBinding;
 import com.google.inject.spi.TypeConverterBinding;
 import com.google.inject.util.Providers;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.InvocationTargetException;
@@ -57,7 +58,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
 
 /**
  * Default {@link Injector} implementation.
@@ -75,8 +75,12 @@
     final boolean atInjectRequired;
     final boolean exactBindingAnnotationsRequired;
 
-    InjectorOptions(Stage stage, boolean jitDisabled, boolean disableCircularProxies,
-        boolean atInjectRequired, boolean exactBindingAnnotationsRequired) {
+    InjectorOptions(
+        Stage stage,
+        boolean jitDisabled,
+        boolean disableCircularProxies,
+        boolean atInjectRequired,
+        boolean exactBindingAnnotationsRequired) {
       this.stage = stage;
       this.jitDisabled = jitDisabled;
       this.disableCircularProxies = disableCircularProxies;
@@ -86,7 +90,7 @@
 
     @Override
     public String toString() {
-      return Objects.toStringHelper(getClass())
+      return MoreObjects.toStringHelper(getClass())
           .add("stage", stage)
           .add("jitDisabled", jitDisabled)
           .add("disableCircularProxies", disableCircularProxies)
@@ -108,14 +112,14 @@
 
   final State state;
   final InjectorImpl parent;
-  final BindingsMultimap bindingsMultimap = new BindingsMultimap();
+  final ListMultimap<TypeLiteral<?>, Binding<?>> bindingsMultimap = ArrayListMultimap.create();
   final InjectorOptions options;
 
   /** Just-in-time binding cache. Guarded by state.lock() */
   final Map<Key<?>, BindingImpl<?>> jitBindings = Maps.newHashMap();
   /**
-   * Cache of Keys that we were unable to create JIT bindings for, so we don't
-   * keep trying.  Also guarded by state.lock().
+   * Cache of Keys that we were unable to create JIT bindings for, so we don't keep trying. Also
+   * guarded by state.lock().
    */
   final Set<Key<?>> failedJitBindings = Sets.newHashSet();
 
@@ -129,26 +133,29 @@
     if (parent != null) {
       localContext = parent.localContext;
     } else {
-      localContext = new ThreadLocal<Object[]>();
+      // No ThreadLocal.initialValue(), as that would cause classloader leaks. See
+      // https://github.com/google/guice/issues/288#issuecomment-48216933,
+      // https://github.com/google/guice/issues/288#issuecomment-48216944
+      localContext = new ThreadLocal<>();
     }
   }
 
   /** Indexes bindings by type. */
   void index() {
     for (Binding<?> binding : state.getExplicitBindingsThisLevel().values()) {
-      index(binding);
+      bindingsMultimap.put(binding.getKey().getTypeLiteral(), binding);
     }
   }
 
-  <T> void index(Binding<T> binding) {
-    bindingsMultimap.put(binding.getKey().getTypeLiteral(), binding);
-  }
-
+  @Override
   public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
-    return bindingsMultimap.getAll(type);
+    @SuppressWarnings("unchecked") // safe because we only put matching entries into the map
+    List<Binding<T>> list = (List<Binding<T>>) (List) bindingsMultimap.get(type);
+    return Collections.unmodifiableList(list);
   }
 
   /** Returns the binding for {@code key} */
+  @Override
   public <T> BindingImpl<T> getBinding(Key<T> key) {
     Errors errors = new Errors(key);
     try {
@@ -160,6 +167,7 @@
     }
   }
 
+  @Override
   public <T> BindingImpl<T> getExistingBinding(Key<T> key) {
     // Check explicit bindings, i.e. bindings created by modules.
     BindingImpl<T> explicitBinding = state.getExplicitBinding(key);
@@ -171,7 +179,7 @@
       for (InjectorImpl injector = this; injector != null; injector = injector.parent) {
         @SuppressWarnings("unchecked")
         BindingImpl<T> jitBinding = (BindingImpl<T>) injector.jitBindings.get(key);
-        if(jitBinding != null) {
+        if (jitBinding != null) {
           return jitBinding;
         }
       }
@@ -179,15 +187,15 @@
 
     // If Key is a Provider, we have to see if the type it is providing exists,
     // and, if so, we have to create the binding for the provider.
-    if(isProvider(key)) {
+    if (isProvider(key)) {
       try {
         // This is safe because isProvider above ensures that T is a Provider<?>
         @SuppressWarnings({"unchecked", "cast"})
-        Key<?> providedKey = (Key<?>)getProvidedKey((Key)key, new Errors());
-        if(getExistingBinding(providedKey) != null) {
+        Key<?> providedKey = (Key<?>) getProvidedKey((Key) key, new Errors());
+        if (getExistingBinding(providedKey) != null) {
           return getBinding(key);
         }
-      } catch(ErrorsException e) {
+      } catch (ErrorsException e) {
         throw new ConfigurationException(e.getErrors().getMessages());
       }
     }
@@ -197,8 +205,8 @@
   }
 
   /**
-   * Gets a binding implementation.  First, it check to see if the parent has a binding.  If the
-   * parent has a binding and the binding is scoped, it will use that binding.  Otherwise, this
+   * Gets a binding implementation. First, it check to see if the parent has a binding. If the
+   * parent has a binding and the binding is scoped, it will use that binding. Otherwise, this
    * checks for an explicit binding. If no explicit binding is found, it looks for a just-in-time
    * binding.
    */
@@ -214,21 +222,22 @@
     return getJustInTimeBinding(key, errors, jitType);
   }
 
+  @Override
   public <T> Binding<T> getBinding(Class<T> type) {
     return getBinding(Key.get(type));
   }
 
+  @Override
   public Injector getParent() {
     return parent;
   }
 
+  @Override
   public Injector createChildInjector(Iterable<? extends Module> modules) {
-    return new InternalInjectorCreator()
-        .parentInjector(this)
-        .addModules(modules)
-        .build();
+    return new InternalInjectorCreator().parentInjector(this).addModules(modules).build();
   }
 
+  @Override
   public Injector createChildInjector(Module... modules) {
     return createChildInjector(ImmutableList.copyOf(modules));
   }
@@ -292,7 +301,8 @@
     return key.getTypeLiteral().getRawType().equals(TypeLiteral.class);
   }
 
-  private static <T> Key<T> getProvidedKey(Key<Provider<T>> key, Errors errors) throws ErrorsException {
+  private static <T> Key<T> getProvidedKey(Key<Provider<T>> key, Errors errors)
+      throws ErrorsException {
     Type providerType = key.getTypeLiteral().getType();
 
     // If the Provider has no type parameter (raw Provider)...
@@ -321,21 +331,26 @@
     }
 
     @SuppressWarnings("unchecked") // safe because T came from Key<MembersInjector<T>>
-    TypeLiteral<T> instanceType = (TypeLiteral<T>) TypeLiteral.get(
-        ((ParameterizedType) membersInjectorType).getActualTypeArguments()[0]);
+    TypeLiteral<T> instanceType =
+        (TypeLiteral<T>)
+            TypeLiteral.get(((ParameterizedType) membersInjectorType).getActualTypeArguments()[0]);
     MembersInjector<T> membersInjector = membersInjectorStore.get(instanceType, errors);
 
-    InternalFactory<MembersInjector<T>> factory = new ConstantFactory<MembersInjector<T>>(
-        Initializables.of(membersInjector));
+    InternalFactory<MembersInjector<T>> factory =
+        new ConstantFactory<MembersInjector<T>>(Initializables.of(membersInjector));
 
-
-    return new InstanceBindingImpl<MembersInjector<T>>(this, key, SourceProvider.UNKNOWN_SOURCE,
-        factory, ImmutableSet.<InjectionPoint>of(), membersInjector);
+    return new InstanceBindingImpl<MembersInjector<T>>(
+        this,
+        key,
+        SourceProvider.UNKNOWN_SOURCE,
+        factory,
+        ImmutableSet.<InjectionPoint>of(),
+        membersInjector);
   }
 
   /**
-   * Creates a synthetic binding to {@code Provider<T>}, i.e. a binding to the provider from
-   * {@code Binding<T>}.
+   * Creates a synthetic binding to {@code Provider<T>}, i.e. a binding to the provider from {@code
+   * Binding<T>}.
    */
   private <T> BindingImpl<Provider<T>> createProviderBinding(Key<Provider<T>> key, Errors errors)
       throws ErrorsException {
@@ -349,7 +364,11 @@
     final BindingImpl<T> providedBinding;
 
     ProviderBindingImpl(InjectorImpl injector, Key<Provider<T>> key, Binding<T> providedBinding) {
-      super(injector, key, providedBinding.getSource(), createInternalFactory(providedBinding),
+      super(
+          injector,
+          key,
+          providedBinding.getSource(),
+          createInternalFactory(providedBinding),
           Scoping.UNSCOPED);
       this.providedBinding = (BindingImpl<T>) providedBinding;
     }
@@ -357,42 +376,48 @@
     static <T> InternalFactory<Provider<T>> createInternalFactory(Binding<T> providedBinding) {
       final Provider<T> provider = providedBinding.getProvider();
       return new InternalFactory<Provider<T>>() {
-        public Provider<T> get(Errors errors, InternalContext context, Dependency dependency, boolean linked) {
+        @Override
+        public Provider<T> get(InternalContext context, Dependency<?> dependency, boolean linked) {
           return provider;
         }
       };
     }
 
+    @Override
     public Key<? extends T> getProvidedKey() {
       return providedBinding.getKey();
     }
 
+    @Override
     public <V> V acceptTargetVisitor(BindingTargetVisitor<? super Provider<T>, V> visitor) {
       return visitor.visit(this);
     }
 
+    @Override
     public void applyTo(Binder binder) {
       throw new UnsupportedOperationException("This element represents a synthetic binding.");
     }
 
-    @Override public String toString() {
-      return Objects.toStringHelper(ProviderBinding.class)
+    @Override
+    public String toString() {
+      return MoreObjects.toStringHelper(ProviderBinding.class)
           .add("key", getKey())
           .add("providedKey", getProvidedKey())
           .toString();
     }
 
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return ImmutableSet.<Dependency<?>>of(Dependency.get(getProvidedKey()));
     }
 
     @Override
     public boolean equals(Object obj) {
-      if(obj instanceof ProviderBindingImpl) {
-        ProviderBindingImpl<?> o = (ProviderBindingImpl<?>)obj;
+      if (obj instanceof ProviderBindingImpl) {
+        ProviderBindingImpl<?> o = (ProviderBindingImpl<?>) obj;
         return getKey().equals(o.getKey())
-          && getScoping().equals(o.getScoping())
-          && Objects.equal(providedBinding, o.providedBinding);
+            && getScoping().equals(o.getScoping())
+            && Objects.equal(providedBinding, o.providedBinding);
       } else {
         return false;
       }
@@ -419,12 +444,17 @@
       return null;
     }
 
-    String stringValue = stringBinding.getProvider().get();
+    // We can't call getProvider().get() because this InstanceBinding may not have been inintialized
+    // yet (because we may have been called during InternalInjectorCreator.initializeStatically and
+    // instance binding validation hasn't happened yet.)
+    @SuppressWarnings("unchecked")
+    String stringValue = ((InstanceBinding<String>) stringBinding).getInstance();
     Object source = stringBinding.getSource();
 
     // Find a matching type converter.
     TypeLiteral<T> type = key.getTypeLiteral();
-    TypeConverterBinding typeConverterBinding = state.getConverter(stringValue, type, errors, source);
+    TypeConverterBinding typeConverterBinding =
+        state.getConverter(stringValue, type, errors, source);
 
     if (typeConverterBinding == null) {
       // No converter can handle the given type.
@@ -437,73 +467,91 @@
       T converted = (T) typeConverterBinding.getTypeConverter().convert(stringValue, type);
 
       if (converted == null) {
-        throw errors.converterReturnedNull(stringValue, source, type, typeConverterBinding)
+        throw errors
+            .converterReturnedNull(stringValue, source, type, typeConverterBinding)
             .toException();
       }
 
       if (!type.getRawType().isInstance(converted)) {
-        throw errors.conversionTypeError(stringValue, source, type, typeConverterBinding, converted)
+        throw errors
+            .conversionTypeError(stringValue, source, type, typeConverterBinding, converted)
             .toException();
       }
 
-      return new ConvertedConstantBindingImpl<T>(this, key, converted, stringBinding,
-          typeConverterBinding);
+      return new ConvertedConstantBindingImpl<T>(
+          this, key, converted, stringBinding, typeConverterBinding);
     } catch (ErrorsException e) {
       throw e;
     } catch (RuntimeException e) {
-      throw errors.conversionError(stringValue, source, type, typeConverterBinding, e)
+      throw errors
+          .conversionError(stringValue, source, type, typeConverterBinding, e)
           .toException();
     }
   }
 
-  private static class ConvertedConstantBindingImpl<T>
-      extends BindingImpl<T> implements ConvertedConstantBinding<T> {
+  private static class ConvertedConstantBindingImpl<T> extends BindingImpl<T>
+      implements ConvertedConstantBinding<T> {
     final T value;
     final Provider<T> provider;
     final Binding<String> originalBinding;
     final TypeConverterBinding typeConverterBinding;
 
     ConvertedConstantBindingImpl(
-        InjectorImpl injector, Key<T> key, T value, Binding<String> originalBinding,
+        InjectorImpl injector,
+        Key<T> key,
+        T value,
+        Binding<String> originalBinding,
         TypeConverterBinding typeConverterBinding) {
-      super(injector, key, originalBinding.getSource(),
-          new ConstantFactory<T>(Initializables.of(value)), Scoping.UNSCOPED);
+      super(
+          injector,
+          key,
+          originalBinding.getSource(),
+          new ConstantFactory<T>(Initializables.of(value)),
+          Scoping.UNSCOPED);
       this.value = value;
       provider = Providers.of(value);
       this.originalBinding = originalBinding;
       this.typeConverterBinding = typeConverterBinding;
     }
 
-    @Override public Provider<T> getProvider() {
+    @Override
+    public Provider<T> getProvider() {
       return provider;
     }
 
+    @Override
     public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
       return visitor.visit(this);
     }
 
+    @Override
     public T getValue() {
       return value;
     }
 
+    @Override
     public TypeConverterBinding getTypeConverterBinding() {
       return typeConverterBinding;
     }
 
+    @Override
     public Key<String> getSourceKey() {
       return originalBinding.getKey();
     }
 
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return ImmutableSet.<Dependency<?>>of(Dependency.get(getSourceKey()));
     }
 
+    @Override
     public void applyTo(Binder binder) {
       throw new UnsupportedOperationException("This element represents a synthetic binding.");
     }
 
-    @Override public String toString() {
-      return Objects.toStringHelper(ConvertedConstantBinding.class)
+    @Override
+    public String toString() {
+      return MoreObjects.toStringHelper(ConvertedConstantBinding.class)
           .add("key", getKey())
           .add("sourceKey", getSourceKey())
           .add("value", value)
@@ -512,11 +560,11 @@
 
     @Override
     public boolean equals(Object obj) {
-      if(obj instanceof ConvertedConstantBindingImpl) {
-        ConvertedConstantBindingImpl<?> o = (ConvertedConstantBindingImpl<?>)obj;
+      if (obj instanceof ConvertedConstantBindingImpl) {
+        ConvertedConstantBindingImpl<?> o = (ConvertedConstantBindingImpl<?>) obj;
         return getKey().equals(o.getKey())
-          && getScoping().equals(o.getScoping())
-          && Objects.equal(value, o.value);
+            && getScoping().equals(o.getScoping())
+            && Objects.equal(value, o.value);
       } else {
         return false;
       }
@@ -542,7 +590,7 @@
       Key<T> key = binding.getKey();
       jitBindings.put(key, binding);
       boolean successful = false;
-      DelayedInitialize delayed = (DelayedInitialize)binding;
+      DelayedInitialize delayed = (DelayedInitialize) binding;
       try {
         delayed.initialize(this, errors);
         successful = true;
@@ -560,32 +608,32 @@
 
   /**
    * Iterates through the binding's dependencies to clean up any stray bindings that were leftover
-   * from a failed JIT binding. This is required because the bindings are eagerly &
-   * optimistically added to allow circular dependency support, so dependencies may pass where they
-   * should have failed.
+   * from a failed JIT binding. This is required because the bindings are eagerly & optimistically
+   * added to allow circular dependency support, so dependencies may pass where they should have
+   * failed.
    */
   private boolean cleanup(BindingImpl<?> binding, Set<Key> encountered) {
     boolean bindingFailed = false;
     Set<Dependency<?>> deps = getInternalDependencies(binding);
-    for(Dependency dep : deps) {
+    for (Dependency dep : deps) {
       Key<?> depKey = dep.getKey();
       InjectionPoint ip = dep.getInjectionPoint();
-      if(encountered.add(depKey)) { // only check if we haven't looked at this key yet
+      if (encountered.add(depKey)) { // only check if we haven't looked at this key yet
         BindingImpl depBinding = jitBindings.get(depKey);
-        if(depBinding != null) { // if the binding still exists, validate
+        if (depBinding != null) { // if the binding still exists, validate
           boolean failed = cleanup(depBinding, encountered); // if children fail, we fail
-          if(depBinding instanceof ConstructorBindingImpl) {
-            ConstructorBindingImpl ctorBinding = (ConstructorBindingImpl)depBinding;
+          if (depBinding instanceof ConstructorBindingImpl) {
+            ConstructorBindingImpl ctorBinding = (ConstructorBindingImpl) depBinding;
             ip = ctorBinding.getInternalConstructor();
-            if(!ctorBinding.isInitialized()) {
+            if (!ctorBinding.isInitialized()) {
               failed = true;
             }
           }
-          if(failed) {
+          if (failed) {
             removeFailedJitBinding(depBinding, ip);
             bindingFailed = true;
           }
-        } else if(state.getExplicitBinding(depKey) == null) {
+        } else if (state.getExplicitBinding(depKey) == null) {
           // ignore keys if they were explicitly bound, but if neither JIT
           // nor explicit, it's also invalid & should let parent know.
           bindingFailed = true;
@@ -601,7 +649,7 @@
     jitBindings.remove(binding.getKey());
     membersInjectorStore.remove(binding.getKey().getTypeLiteral());
     provisionListenerStore.remove(binding);
-    if(ip != null) {
+    if (ip != null) {
       constructors.remove(ip);
     }
   }
@@ -609,10 +657,10 @@
   /** Safely gets the dependencies of possibly not initialized bindings. */
   @SuppressWarnings("unchecked")
   private Set<Dependency<?>> getInternalDependencies(BindingImpl<?> binding) {
-    if(binding instanceof ConstructorBindingImpl) {
-      return ((ConstructorBindingImpl)binding).getInternalDependencies();
-    } else if(binding instanceof HasDependencies) {
-      return ((HasDependencies)binding).getDependencies();
+    if (binding instanceof ConstructorBindingImpl) {
+      return ((ConstructorBindingImpl) binding).getInternalDependencies();
+    } else if (binding instanceof HasDependencies) {
+      return ((HasDependencies) binding).getDependencies();
     } else {
       return ImmutableSet.of();
     }
@@ -622,22 +670,23 @@
    * Creates a binding for an injectable type with the given scope. Looks for a scope on the type if
    * none is specified.
    */
-  <T> BindingImpl<T> createUninitializedBinding(Key<T> key, Scoping scoping, Object source,
-      Errors errors, boolean jitBinding) throws ErrorsException {
+  <T> BindingImpl<T> createUninitializedBinding(
+      Key<T> key, Scoping scoping, Object source, Errors errors, boolean jitBinding)
+      throws ErrorsException {
     Class<?> rawType = key.getTypeLiteral().getRawType();
 
     ImplementedBy implementedBy = rawType.getAnnotation(ImplementedBy.class);
 
     // Don't try to inject arrays or enums annotated with @ImplementedBy.
     if (rawType.isArray() || (rawType.isEnum() && implementedBy != null)) {
-      throw errors.missingImplementation(key).toException();
+      throw errors.missingImplementationWithHint(key, this).toException();
     }
 
     // Handle TypeLiteral<T> by binding the inner type
     if (rawType == TypeLiteral.class) {
       @SuppressWarnings("unchecked") // we have to fudge the inner type as Object
-      BindingImpl<T> binding = (BindingImpl<T>) createTypeLiteralBinding(
-          (Key<TypeLiteral<Object>>) key, errors);
+      BindingImpl<T> binding =
+          (BindingImpl<T>) createTypeLiteralBinding((Key<TypeLiteral<Object>>) key, errors);
       return binding;
     }
 
@@ -654,8 +703,8 @@
       return createProvidedByBinding(key, scoping, providedBy, errors);
     }
 
-
-    return ConstructorBindingImpl.create(this,
+    return ConstructorBindingImpl.create(
+        this,
         key,
         null, /* use default constructor */
         source,
@@ -689,17 +738,22 @@
 
     @SuppressWarnings("unchecked") // by definition, innerType == T, so this is safe
     TypeLiteral<T> value = (TypeLiteral<T>) TypeLiteral.get(innerType);
-    InternalFactory<TypeLiteral<T>> factory = new ConstantFactory<TypeLiteral<T>>(
-        Initializables.of(value));
-    return new InstanceBindingImpl<TypeLiteral<T>>(this, key, SourceProvider.UNKNOWN_SOURCE,
-        factory, ImmutableSet.<InjectionPoint>of(), value);
+    InternalFactory<TypeLiteral<T>> factory =
+        new ConstantFactory<TypeLiteral<T>>(Initializables.of(value));
+    return new InstanceBindingImpl<TypeLiteral<T>>(
+        this,
+        key,
+        SourceProvider.UNKNOWN_SOURCE,
+        factory,
+        ImmutableSet.<InjectionPoint>of(),
+        value);
   }
 
   /** Creates a binding for a type annotated with @ProvidedBy. */
-  <T> BindingImpl<T> createProvidedByBinding(Key<T> key, Scoping scoping,
-      ProvidedBy providedBy, Errors errors) throws ErrorsException {
+  <T> BindingImpl<T> createProvidedByBinding(
+      Key<T> key, Scoping scoping, ProvidedBy providedBy, Errors errors) throws ErrorsException {
     Class<?> rawType = key.getTypeLiteral().getRawType();
-    Class<? extends Provider<?>> providerType = providedBy.value();
+    Class<? extends javax.inject.Provider<?>> providerType = providedBy.value();
 
     // Make sure it's not the same type. TODO: Can we check for deeper loops?
     if (providerType == rawType) {
@@ -712,21 +766,22 @@
     ProvidedByInternalFactory<T> internalFactory =
         new ProvidedByInternalFactory<T>(rawType, providerType, providerKey);
     Object source = rawType;
-    BindingImpl<T> binding = LinkedProviderBindingImpl.createWithInitializer(
-        this,
-        key,
-        source,
-        Scoping.<T>scope(key, this, internalFactory, source, scoping),
-        scoping,
-        providerKey,
-        internalFactory);
+    BindingImpl<T> binding =
+        LinkedProviderBindingImpl.createWithInitializer(
+            this,
+            key,
+            source,
+            Scoping.<T>scope(key, this, internalFactory, source, scoping),
+            scoping,
+            providerKey,
+            internalFactory);
     internalFactory.setProvisionListenerCallback(provisionListenerStore.get(binding));
     return binding;
   }
 
   /** Creates a binding for a type annotated with @ImplementedBy. */
-  private <T> BindingImpl<T> createImplementedByBinding(Key<T> key, Scoping scoping,
-      ImplementedBy implementedBy, Errors errors)
+  private <T> BindingImpl<T> createImplementedByBinding(
+      Key<T> key, Scoping scoping, ImplementedBy implementedBy, Errors errors)
       throws ErrorsException {
     Class<?> rawType = key.getTypeLiteral().getRawType();
     Class<?> implementationType = implementedBy.value();
@@ -746,27 +801,14 @@
 
     // Look up the target binding.
     final Key<? extends T> targetKey = Key.get(subclass);
-    final BindingImpl<? extends T> targetBinding = getBindingOrThrow(targetKey, errors, JitLimitation.NEW_OR_EXISTING_JIT);
-
-    InternalFactory<T> internalFactory = new InternalFactory<T>() {
-      public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-          throws ErrorsException {
-        context.pushState(targetKey, targetBinding.getSource());
-        try {
-          return targetBinding.getInternalFactory().get(
-              errors.withSource(targetKey), context, dependency, true);
-        } finally {
-          context.popState();
-        }
-      }
-    };
-
     Object source = rawType;
+    FactoryProxy<T> factory = new FactoryProxy<>(this, key, targetKey, source);
+    factory.notify(errors); // causes the factory to initialize itself internally
     return new LinkedBindingImpl<T>(
         this,
         key,
         source,
-        Scoping.<T>scope(key, this, internalFactory, source, scoping),
+        Scoping.<T>scope(key, this, factory, source, scoping),
         scoping,
         targetKey);
   }
@@ -775,18 +817,23 @@
    * Attempts to create a just-in-time binding for {@code key} in the root injector, falling back to
    * other ancestor injectors until this injector is tried.
    */
-  private <T> BindingImpl<T> createJustInTimeBindingRecursive(Key<T> key, Errors errors,
-      boolean jitDisabled, JitLimitation jitType) throws ErrorsException {
+  private <T> BindingImpl<T> createJustInTimeBindingRecursive(
+      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
+      throws ErrorsException {
     // ask the parent to create the JIT binding
     if (parent != null) {
       if (jitType == JitLimitation.NEW_OR_EXISTING_JIT
-          && jitDisabled && !parent.options.jitDisabled) {
+          && jitDisabled
+          && !parent.options.jitDisabled) {
         // If the binding would be forbidden here but allowed in a parent, report an error instead
         throw errors.jitDisabledInParent(key).toException();
       }
 
       try {
-        return parent.createJustInTimeBindingRecursive(key, new Errors(), jitDisabled,
+        return parent.createJustInTimeBindingRecursive(
+            key,
+            new Errors(),
+            jitDisabled,
             parent.options.jitDisabled ? JitLimitation.NO_JIT : jitType);
       } catch (ErrorsException ignored) {
       }
@@ -811,18 +858,20 @@
   /**
    * Returns a new just-in-time binding created by resolving {@code key}. The strategies used to
    * create just-in-time bindings are:
+   *
    * <ol>
-   *   <li>Internalizing Providers. If the requested binding is for {@code Provider<T>}, we delegate
+   * <li>Internalizing Providers. If the requested binding is for {@code Provider<T>}, we delegate
    *     to the binding for {@code T}.
-   *   <li>Converting constants.
-   *   <li>ImplementedBy and ProvidedBy annotations. Only for unannotated keys.
-   *   <li>The constructor of the raw type. Only for unannotated keys.
+   * <li>Converting constants.
+   * <li>ImplementedBy and ProvidedBy annotations. Only for unannotated keys.
+   * <li>The constructor of the raw type. Only for unannotated keys.
    * </ol>
    *
    * @throws com.google.inject.internal.ErrorsException if the binding cannot be created.
    */
-  private <T> BindingImpl<T> createJustInTimeBinding(Key<T> key, Errors errors,
-      boolean jitDisabled, JitLimitation jitType) throws ErrorsException {
+  private <T> BindingImpl<T> createJustInTimeBinding(
+      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
+      throws ErrorsException {
     int numErrorsBefore = errors.size();
 
     // Retrieve the sources before checking for blacklisting to guard against sources becoming null
@@ -858,9 +907,7 @@
       return convertedBinding;
     }
 
-    if (!isTypeLiteral(key)
-        && jitDisabled
-        && jitType != JitLimitation.NEW_OR_EXISTING_JIT) {
+    if (!isTypeLiteral(key) && jitDisabled && jitType != JitLimitation.NEW_OR_EXISTING_JIT) {
       throw errors.jitDisabled(key).toException();
     }
 
@@ -875,25 +922,28 @@
           // throw with a more appropriate message below
         }
       }
-      throw errors.missingImplementation(key).toException();
+      throw errors.missingImplementationWithHint(key, this).toException();
     }
 
     Object source = key.getTypeLiteral().getRawType();
-    BindingImpl<T> binding = createUninitializedBinding(key, Scoping.UNSCOPED, source, errors, true);
+    BindingImpl<T> binding =
+        createUninitializedBinding(key, Scoping.UNSCOPED, source, errors, true);
     errors.throwIfNewErrors(numErrorsBefore);
     initializeJitBinding(binding, errors);
     return binding;
   }
 
-  <T> InternalFactory<? extends T> getInternalFactory(Key<T> key, Errors errors, JitLimitation jitType)
-      throws ErrorsException {
+  <T> InternalFactory<? extends T> getInternalFactory(
+      Key<T> key, Errors errors, JitLimitation jitType) throws ErrorsException {
     return getBindingOrThrow(key, errors, jitType).getInternalFactory();
   }
 
+  @Override
   public Map<Key<?>, Binding<?>> getBindings() {
     return state.getExplicitBindingsThisLevel();
   }
 
+  @Override
   public Map<Key<?>, Binding<?>> getAllBindings() {
     synchronized (state.lock()) {
       return new ImmutableMap.Builder<Key<?>, Binding<?>>()
@@ -903,41 +953,19 @@
     }
   }
 
+  @Override
   public Map<Class<? extends Annotation>, Scope> getScopeBindings() {
     return ImmutableMap.copyOf(state.getScopes());
   }
 
+  @Override
   public Set<TypeConverterBinding> getTypeConverterBindings() {
     return ImmutableSet.copyOf(state.getConvertersThisLevel());
   }
 
-  private static class BindingsMultimap {
-    final Map<TypeLiteral<?>, List<Binding<?>>> multimap = Maps.newHashMap();
-
-    <T> void put(TypeLiteral<T> type, Binding<T> binding) {
-      List<Binding<?>> bindingsForType = multimap.get(type);
-      if (bindingsForType == null) {
-        bindingsForType = Lists.newArrayList();
-        multimap.put(type, bindingsForType);
-      }
-      bindingsForType.add(binding);
-    }
-
-
-    @SuppressWarnings("unchecked") // safe because we only put matching entries into the map
-    <T> List<Binding<T>> getAll(TypeLiteral<T> type) {
-      List<Binding<?>> bindings = multimap.get(type);
-      return bindings != null
-          ? Collections.<Binding<T>>unmodifiableList((List) multimap.get(type))
-          : ImmutableList.<Binding<T>>of();
-    }
-  }
-
-  /**
-   * Returns parameter injectors, or {@code null} if there are no parameters.
-   */
-  SingleParameterInjector<?>[] getParametersInjectors(
-      List<Dependency<?>> parameters, Errors errors) throws ErrorsException {
+  /** Returns parameter injectors, or {@code null} if there are no parameters. */
+  SingleParameterInjector<?>[] getParametersInjectors(List<Dependency<?>> parameters, Errors errors)
+      throws ErrorsException {
     if (parameters.isEmpty()) {
       return null;
     }
@@ -957,9 +985,10 @@
     return result;
   }
 
-  <T> SingleParameterInjector<T> createParameterInjector(final Dependency<T> dependency,
-      final Errors errors) throws ErrorsException {
-    BindingImpl<? extends T> binding = getBindingOrThrow(dependency.getKey(), errors, JitLimitation.NO_JIT);
+  <T> SingleParameterInjector<T> createParameterInjector(
+      final Dependency<T> dependency, final Errors errors) throws ErrorsException {
+    BindingImpl<? extends T> binding =
+        getBindingOrThrow(dependency.getKey(), errors, JitLimitation.NO_JIT);
     return new SingleParameterInjector<T>(dependency, binding);
   }
 
@@ -978,12 +1007,14 @@
   /** Cached provision listener callbacks for each key. */
   ProvisionListenerCallbackStore provisionListenerStore;
 
+  @Override
   @SuppressWarnings("unchecked") // the members injector type is consistent with instance's type
   public void injectMembers(Object instance) {
     MembersInjector membersInjector = getMembersInjector(instance.getClass());
     membersInjector.injectMembers(instance);
   }
 
+  @Override
   public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) {
     Errors errors = new Errors(typeLiteral);
     try {
@@ -993,45 +1024,47 @@
     }
   }
 
+  @Override
   public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
     return getMembersInjector(TypeLiteral.get(type));
   }
 
+  @Override
   public <T> Provider<T> getProvider(Class<T> type) {
     return getProvider(Key.get(type));
   }
 
-  <T> Provider<T> getProviderOrThrow(final Dependency<T> dependency, Errors errors) throws ErrorsException {
-    final Key<T> key = dependency.getKey();
-    final BindingImpl<? extends T> binding = getBindingOrThrow(key, errors, JitLimitation.NO_JIT);
+  <T> Provider<T> getProviderOrThrow(final Dependency<T> dependency, Errors errors)
+      throws ErrorsException {
+    Key<T> key = dependency.getKey();
+    BindingImpl<? extends T> binding = getBindingOrThrow(key, errors, JitLimitation.NO_JIT);
+    final InternalFactory<? extends T> internalFactory = binding.getInternalFactory();
+    final Object source = binding.getSource();
 
     return new Provider<T>() {
+      @Override
       public T get() {
-        final Errors errors = new Errors(dependency);
+        InternalContext currentContext = enterContext();
+        Dependency previous = currentContext.pushDependency(dependency, source);
         try {
-          T t = callInContext(new ContextualCallable<T>() {
-            public T call(InternalContext context) throws ErrorsException {
-              Dependency previous = context.pushDependency(dependency, binding.getSource());
-              try {
-                return binding.getInternalFactory().get(errors, context, dependency, false);
-              } finally {
-                context.popStateAndSetDependency(previous);
-              }
-            }
-          });
-          errors.throwIfNewErrors(0);
+          T t = internalFactory.get(currentContext, dependency, false);
           return t;
-        } catch (ErrorsException e) {
-          throw new ProvisionException(errors.merge(e.getErrors()).getMessages());
+        } catch (InternalProvisionException e) {
+          throw e.addSource(dependency).toProvisionException();
+        } finally {
+          currentContext.popStateAndSetDependency(previous);
+          currentContext.close();
         }
       }
 
-      @Override public String toString() {
-        return binding.getInternalFactory().toString();
+      @Override
+      public String toString() {
+        return internalFactory.toString();
       }
     };
   }
 
+  @Override
   public <T> Provider<T> getProvider(final Key<T> key) {
     Errors errors = new Errors(key);
     try {
@@ -1043,77 +1076,68 @@
     }
   }
 
+  @Override
   public <T> T getInstance(Key<T> key) {
     return getProvider(key).get();
   }
 
+  @Override
   public <T> T getInstance(Class<T> type) {
     return getProvider(type).get();
   }
 
-  /** @see #getGlobalInternalContext */
+  /**
+   * Holds Object[] as a mutable wrapper, rather than InternalContext, since array operations are
+   * faster than ThreadLocal.set() / .get() operations.
+   *
+   * <p>Holds Object[] rather than InternalContext[], since localContext never gets cleaned up at
+   * any point. This could lead to problems when, for example, an OSGI application is reloaded, the
+   * InjectorImpl is destroyed, but the thread that the injector runs on is kept alive. In such a
+   * case, ThreadLocal itself would hold on to a reference to localContext, which would hold on to
+   * the old InternalContext.class object, which would hold on to the old classloader that loaded
+   * that class, and so on.
+   */
   private final ThreadLocal<Object[]> localContext;
-  /**
-   * Synchronization: map value is modified only for the current thread,
-   * it's ok to read map values of other threads. It can change between your
-   * calls.
-   *
-   * @see #getGlobalInternalContext
-   */
-  private static final ConcurrentMap<Thread, InternalContext> globalInternalContext =
-      Maps.newConcurrentMap();
 
-  /**
-   * Provides access to the internal context for the current injector of all threads.
-   * One does not need to use this from Guice source code as context could be passed on the stack.
-   * It is required for custom scopes which are called from Guice and sometimes do require
-   * access to current internal context, but it is not passed in. Contrary to {@link #localContext}
-   * it is not used to store injector-specific state, but to provide easy access to the current
-   * state.
-   *
-   * @return unmodifiable map
-   */
-  static Map<Thread, InternalContext> getGlobalInternalContext() {
-    return Collections.unmodifiableMap(globalInternalContext);
+  /** Only to be called by the {@link SingletonScope} provider. */
+  InternalContext getLocalContext() {
+    return (InternalContext) localContext.get()[0];
   }
 
-  /** Looks up thread local context. Creates (and removes) a new context if necessary. */
-  <T> T callInContext(ContextualCallable<T> callable) throws ErrorsException {
+  /**
+   * Looks up thread local context and {@link InternalContext#enter() enters} it or creates a new
+   * context if necessary.
+   *
+   * <p>All callers of this are responsible for calling {@link InternalContext#close()}. Typical
+   * usage should look like:
+   *
+   * <pre>{@code
+   * InternalContext ctx = injector.enterContext();
+   * try {
+   *   ... use ctx ...
+   * } finally {
+   *   ctx.close();
+   * }
+   * }</pre>
+   */
+  InternalContext enterContext() {
     Object[] reference = localContext.get();
     if (reference == null) {
       reference = new Object[1];
       localContext.set(reference);
     }
-    Thread currentThread = Thread.currentThread();
-    if (reference[0] == null) {
-      reference[0] = new InternalContext(options);
-      globalInternalContext.put(currentThread, (InternalContext) reference[0]);
-      try {
-        return callable.call((InternalContext) reference[0]);
-      } finally {
-        // Only clear contexts if this call created them.
-        reference[0] = null;
-        globalInternalContext.remove(currentThread);
-      }
+    InternalContext ctx = (InternalContext) reference[0];
+    if (ctx == null) {
+      reference[0] = ctx = new InternalContext(options, reference);
     } else {
-      Object previousGlobalInternalContext = globalInternalContext.get(currentThread);
-      globalInternalContext.put(currentThread, (InternalContext) reference[0]);
-      try {
-        // Someone else will clean up this local context.
-        return callable.call((InternalContext) reference[0]);
-      } finally {
-        if (previousGlobalInternalContext != null) {
-          globalInternalContext.put(currentThread, (InternalContext) previousGlobalInternalContext);
-        } else {
-          globalInternalContext.remove(currentThread);
-        }
-      }
+      ctx.enter();
     }
+    return ctx;
   }
 
   @Override
   public String toString() {
-    return Objects.toStringHelper(Injector.class)
+    return MoreObjects.toStringHelper(Injector.class)
         .add("bindings", state.getExplicitBindingsThisLevel().values())
         .toString();
   }
diff --git a/core/src/com/google/inject/internal/InjectorOptionsProcessor.java b/core/src/com/google/inject/internal/InjectorOptionsProcessor.java
index 61cc6ee..32bab00 100644
--- a/core/src/com/google/inject/internal/InjectorOptionsProcessor.java
+++ b/core/src/com/google/inject/internal/InjectorOptionsProcessor.java
@@ -53,11 +53,11 @@
     jitDisabled = true;
     return true;
   }
-  
+
   @Override
   public Boolean visit(RequireAtInjectOnConstructorsOption option) {
     atInjectRequired = true;
-    return true;    
+    return true;
   }
 
   @Override
@@ -68,7 +68,7 @@
 
   InjectorOptions getOptions(Stage stage, InjectorOptions parentOptions) {
     checkNotNull(stage, "stage must be set");
-    if(parentOptions == null) {
+    if (parentOptions == null) {
       return new InjectorOptions(
           stage,
           jitDisabled,
@@ -85,5 +85,4 @@
           exactBindingAnnotationsRequired || parentOptions.exactBindingAnnotationsRequired);
     }
   }
-
 }
diff --git a/core/src/com/google/inject/internal/InjectorShell.java b/core/src/com/google/inject/internal/InjectorShell.java
index 5982bb3..e2ddcd9 100644
--- a/core/src/com/google/inject/internal/InjectorShell.java
+++ b/core/src/com/google/inject/internal/InjectorShell.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,14 +39,13 @@
 import com.google.inject.spi.PrivateElements;
 import com.google.inject.spi.ProvisionListenerBinding;
 import com.google.inject.spi.TypeListenerBinding;
-
 import java.util.List;
 import java.util.logging.Logger;
 
 /**
- * A partially-initialized injector. See {@link InternalInjectorCreator}, which
- * uses this to build a tree of injectors in batch.
- * 
+ * A partially-initialized injector. See {@link InternalInjectorCreator}, which uses this to build a
+ * tree of injectors in batch.
+ *
  * @author jessewilson@google.com (Jesse Wilson)
  */
 final class InjectorShell {
@@ -54,7 +53,7 @@
   private final List<Element> elements;
   private final InjectorImpl injector;
 
-  private InjectorShell(Builder builder, List<Element> elements, InjectorImpl injector) {
+  private InjectorShell(List<Element> elements, InjectorImpl injector) {
     this.elements = elements;
     this.injector = injector;
   }
@@ -80,7 +79,7 @@
 
     /** null unless this exists in a {@link Binder#newPrivateBinder private environment} */
     private PrivateElementsImpl privateElements;
-    
+
     Builder stage(Stage stage) {
       this.stage = stage;
       return this;
@@ -105,7 +104,7 @@
         this.modules.add(module);
       }
     }
-    
+
     Stage getStage() {
       return options.stage;
     }
@@ -136,12 +135,12 @@
         modules.add(0, new InheritedScannersModule(parent.state));
       }
       elements.addAll(Elements.getElements(stage, modules));
-      
+
       // Look for injector-changing options
       InjectorOptionsProcessor optionsProcessor = new InjectorOptionsProcessor(errors);
       optionsProcessor.process(null, elements);
       options = optionsProcessor.getOptions(stage, options);
-      
+
       InjectorImpl injector = new InjectorImpl(parent, state, options);
       if (privateElements != null) {
         privateElements.initInjector(injector);
@@ -179,7 +178,7 @@
       bindStage(injector, stage);
       bindInjector(injector);
       bindLogger(injector);
-      
+
       // Process all normal bindings, then UntargettedBindings.
       // This is necessary because UntargettedBindings can create JIT bindings
       // and need all their other dependencies set up ahead of time.
@@ -191,7 +190,7 @@
       stopwatch.resetAndLog("Module annotated method scanners creation");
 
       List<InjectorShell> injectorShells = Lists.newArrayList();
-      injectorShells.add(new InjectorShell(this, elements, injector));
+      injectorShells.add(new InjectorShell(elements, injector));
 
       // recursively build child shells
       PrivateElementProcessor processor = new PrivateElementProcessor(errors);
@@ -213,15 +212,21 @@
   }
 
   /**
-   * The Injector is a special case because we allow both parent and child injectors to both have
-   * a binding for that key.
+   * The Injector is a special case because we allow both parent and child injectors to both have a
+   * binding for that key.
    */
   private static void bindInjector(InjectorImpl injector) {
     Key<Injector> key = Key.get(Injector.class);
     InjectorFactory injectorFactory = new InjectorFactory(injector);
-    injector.state.putBinding(key,
-        new ProviderInstanceBindingImpl<Injector>(injector, key, SourceProvider.UNKNOWN_SOURCE,
-            injectorFactory, Scoping.UNSCOPED, injectorFactory,
+    injector.state.putBinding(
+        key,
+        new ProviderInstanceBindingImpl<Injector>(
+            injector,
+            key,
+            SourceProvider.UNKNOWN_SOURCE,
+            injectorFactory,
+            Scoping.UNSCOPED,
+            injectorFactory,
             ImmutableSet.<InjectionPoint>of()));
   }
 
@@ -232,15 +237,17 @@
       this.injector = injector;
     }
 
-    public Injector get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-        throws ErrorsException {
+    @Override
+    public Injector get(InternalContext context, Dependency<?> dependency, boolean linked) {
       return injector;
     }
 
+    @Override
     public Injector get() {
       return injector;
     }
 
+    @Override
     public String toString() {
       return "Provider<Injector>";
     }
@@ -253,42 +260,53 @@
   private static void bindLogger(InjectorImpl injector) {
     Key<Logger> key = Key.get(Logger.class);
     LoggerFactory loggerFactory = new LoggerFactory();
-    injector.state.putBinding(key,
-        new ProviderInstanceBindingImpl<Logger>(injector, key,
-            SourceProvider.UNKNOWN_SOURCE, loggerFactory, Scoping.UNSCOPED,
-            loggerFactory, ImmutableSet.<InjectionPoint>of()));
+    injector.state.putBinding(
+        key,
+        new ProviderInstanceBindingImpl<Logger>(
+            injector,
+            key,
+            SourceProvider.UNKNOWN_SOURCE,
+            loggerFactory,
+            Scoping.UNSCOPED,
+            loggerFactory,
+            ImmutableSet.<InjectionPoint>of()));
   }
 
   private static class LoggerFactory implements InternalFactory<Logger>, Provider<Logger> {
-    public Logger get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked) {
+    @Override
+    public Logger get(InternalContext context, Dependency<?> dependency, boolean linked) {
       InjectionPoint injectionPoint = dependency.getInjectionPoint();
       return injectionPoint == null
           ? Logger.getAnonymousLogger()
           : Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
     }
 
+    @Override
     public Logger get() {
       return Logger.getAnonymousLogger();
     }
 
+    @Override
     public String toString() {
       return "Provider<Logger>";
     }
   }
-  
+
   private static void bindStage(InjectorImpl injector, Stage stage) {
     Key<Stage> key = Key.get(Stage.class);
-    InstanceBindingImpl<Stage> stageBinding = new InstanceBindingImpl<Stage>(
-        injector,
-        key,
-        SourceProvider.UNKNOWN_SOURCE,
-        new ConstantFactory<Stage>(Initializables.of(stage)),
-        ImmutableSet.<InjectionPoint>of(),
-        stage);
+    InstanceBindingImpl<Stage> stageBinding =
+        new InstanceBindingImpl<Stage>(
+            injector,
+            key,
+            SourceProvider.UNKNOWN_SOURCE,
+            new ConstantFactory<Stage>(Initializables.of(stage)),
+            ImmutableSet.<InjectionPoint>of(),
+            stage);
     injector.state.putBinding(key, stageBinding);
   }
 
   private static class RootModule implements Module {
+    @Override
     public void configure(Binder binder) {
       binder = binder.withSource(SourceProvider.UNKNOWN_SOURCE);
       binder.bindScope(Singleton.class, SINGLETON);
@@ -303,6 +321,7 @@
       this.state = state;
     }
 
+    @Override
     public void configure(Binder binder) {
       for (ModuleAnnotatedMethodScannerBinding binding : state.getScannerBindings()) {
         binding.applyTo(binder);
diff --git a/core/src/com/google/inject/internal/InstanceBindingImpl.java b/core/src/com/google/inject/internal/InstanceBindingImpl.java
index 9b7a483..44d53b4 100644
--- a/core/src/com/google/inject/internal/InstanceBindingImpl.java
+++ b/core/src/com/google/inject/internal/InstanceBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,80 +16,83 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
 import com.google.inject.Key;
-import com.google.inject.Provider;
 import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.InstanceBinding;
-import com.google.inject.util.Providers;
-
 import java.util.Set;
 
 final class InstanceBindingImpl<T> extends BindingImpl<T> implements InstanceBinding<T> {
 
   final T instance;
-  final Provider<T> provider;
   final ImmutableSet<InjectionPoint> injectionPoints;
 
-  public InstanceBindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Set<InjectionPoint> injectionPoints,
+  public InstanceBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Set<InjectionPoint> injectionPoints,
       T instance) {
     super(injector, key, source, internalFactory, Scoping.EAGER_SINGLETON);
     this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
     this.instance = instance;
-    this.provider = Providers.of(instance);
   }
 
-  public InstanceBindingImpl(Object source, Key<T> key, Scoping scoping,
-      Set<InjectionPoint> injectionPoints, T instance) {
+  public InstanceBindingImpl(
+      Object source, Key<T> key, Scoping scoping, Set<InjectionPoint> injectionPoints, T instance) {
     super(source, key, scoping);
     this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
     this.instance = instance;
-    this.provider = Providers.of(instance);
   }
 
-  @Override public Provider<T> getProvider() {
-    return this.provider;
-  }
-
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public T getInstance() {
     return instance;
   }
 
+  @Override
   public Set<InjectionPoint> getInjectionPoints() {
     return injectionPoints;
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return instance instanceof HasDependencies
         ? ImmutableSet.copyOf(((HasDependencies) instance).getDependencies())
         : Dependency.forInjectionPoints(injectionPoints);
   }
 
+  @Override
   public BindingImpl<T> withScoping(Scoping scoping) {
     return new InstanceBindingImpl<T>(getSource(), getKey(), scoping, injectionPoints, instance);
   }
 
+  @Override
   public BindingImpl<T> withKey(Key<T> key) {
     return new InstanceBindingImpl<T>(getSource(), key, getScoping(), injectionPoints, instance);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     // instance bindings aren't scoped
     binder.withSource(getSource()).bind(getKey()).toInstance(instance);
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(InstanceBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(InstanceBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("instance", instance)
@@ -98,11 +101,11 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof InstanceBindingImpl) {
-      InstanceBindingImpl<?> o = (InstanceBindingImpl<?>)obj;
+    if (obj instanceof InstanceBindingImpl) {
+      InstanceBindingImpl<?> o = (InstanceBindingImpl<?>) obj;
       return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping())
-        && Objects.equal(instance, o.instance);
+          && getScoping().equals(o.getScoping())
+          && Objects.equal(instance, o.instance);
     } else {
       return false;
     }
diff --git a/core/src/com/google/inject/internal/InterceptorBindingProcessor.java b/core/src/com/google/inject/internal/InterceptorBindingProcessor.java
index e352672..de2174a 100644
--- a/core/src/com/google/inject/internal/InterceptorBindingProcessor.java
+++ b/core/src/com/google/inject/internal/InterceptorBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,9 +30,11 @@
     super(errors);
   }
 
-  @Override public Boolean visit(InterceptorBinding command) {
-    injector.state.addMethodAspect(new MethodAspect(
-        command.getClassMatcher(), command.getMethodMatcher(), command.getInterceptors()));
+  @Override
+  public Boolean visit(InterceptorBinding command) {
+    injector.state.addMethodAspect(
+        new MethodAspect(
+            command.getClassMatcher(), command.getMethodMatcher(), command.getInterceptors()));
     return true;
   }
 }
diff --git a/core/src/com/google/inject/internal/InterceptorStackCallback.java b/core/src/com/google/inject/internal/InterceptorStackCallback.java
index f12ddaf..7ae22bb 100644
--- a/core/src/com/google/inject/internal/InterceptorStackCallback.java
+++ b/core/src/com/google/inject/internal/InterceptorStackCallback.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,18 +17,15 @@
 package com.google.inject.internal;
 
 import com.google.common.collect.Lists;
-
-import net.sf.cglib.proxy.MethodProxy;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import net.sf.cglib.proxy.MethodProxy;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
 /**
  * Intercepts a method with a stack of interceptors.
@@ -36,22 +33,24 @@
  * @author crazybob@google.com (Bob Lee)
  */
 final class InterceptorStackCallback implements net.sf.cglib.proxy.MethodInterceptor {
-  private static final Set<String> AOP_INTERNAL_CLASSES = new HashSet<String>(Arrays.asList(
-      InterceptorStackCallback.class.getName(),
-      InterceptedMethodInvocation.class.getName(),
-      MethodProxy.class.getName()));
+  private static final Set<String> AOP_INTERNAL_CLASSES =
+      new HashSet<String>(
+          Arrays.asList(
+              InterceptorStackCallback.class.getName(),
+              InterceptedMethodInvocation.class.getName(),
+              MethodProxy.class.getName()));
 
   final MethodInterceptor[] interceptors;
   final Method method;
 
-  public InterceptorStackCallback(Method method,
-      List<MethodInterceptor> interceptors) {
+  public InterceptorStackCallback(Method method, List<MethodInterceptor> interceptors) {
     this.method = method;
     this.interceptors = interceptors.toArray(new MethodInterceptor[interceptors.size()]);
   }
 
-  public Object intercept(Object proxy, Method method, Object[] arguments,
-      MethodProxy methodProxy) throws Throwable {
+  @Override
+  public Object intercept(Object proxy, Method method, Object[] arguments, MethodProxy methodProxy)
+      throws Throwable {
     return new InterceptedMethodInvocation(proxy, methodProxy, arguments, 0).proceed();
   }
 
@@ -62,49 +61,54 @@
     final MethodProxy methodProxy;
     final int index;
 
-    public InterceptedMethodInvocation(Object proxy, MethodProxy methodProxy,
-        Object[] arguments, int index) {
+    public InterceptedMethodInvocation(
+        Object proxy, MethodProxy methodProxy, Object[] arguments, int index) {
       this.proxy = proxy;
       this.methodProxy = methodProxy;
       this.arguments = arguments;
       this.index = index;
     }
 
+    @Override
     public Object proceed() throws Throwable {
       try {
         return index == interceptors.length
             ? methodProxy.invokeSuper(proxy, arguments)
-            : interceptors[index].invoke(
-                new InterceptedMethodInvocation(proxy, methodProxy, arguments, index + 1));
+            : interceptors[index]
+                .invoke(new InterceptedMethodInvocation(proxy, methodProxy, arguments, index + 1));
       } catch (Throwable t) {
         pruneStacktrace(t);
         throw t;
       }
     }
 
+    @Override
     public Method getMethod() {
       return method;
     }
 
+    @Override
     public Object[] getArguments() {
       return arguments;
     }
 
+    @Override
     public Object getThis() {
       return proxy;
     }
 
+    @Override
     public AccessibleObject getStaticPart() {
       return getMethod();
     }
   }
 
   /**
-   * Removes stacktrace elements related to AOP internal mechanics from the
-   * throwable's stack trace and any causes it may have.
+   * Removes stacktrace elements related to AOP internal mechanics from the throwable's stack trace
+   * and any causes it may have.
    */
   private void pruneStacktrace(Throwable throwable) {
-    for(Throwable t = throwable; t != null; t = t.getCause()) {
+    for (Throwable t = throwable; t != null; t = t.getCause()) {
       StackTraceElement[] stackTrace = t.getStackTrace();
       List<StackTraceElement> pruned = Lists.newArrayList();
       for (StackTraceElement element : stackTrace) {
diff --git a/core/src/com/google/inject/internal/InternalContext.java b/core/src/com/google/inject/internal/InternalContext.java
index 0af1969..59c77c5 100644
--- a/core/src/com/google/inject/internal/InternalContext.java
+++ b/core/src/com/google/inject/internal/InternalContext.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,99 +16,26 @@
 
 package com.google.inject.internal;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.inject.Key;
 import com.google.inject.internal.InjectorImpl.InjectorOptions;
 import com.google.inject.spi.Dependency;
-import com.google.inject.spi.DependencyAndSource;
-
-import java.util.Arrays;
-import java.util.List;
+import java.util.IdentityHashMap;
 import java.util.Map;
 
 /**
- * Internal context. Used to coordinate injections and support circular
- * dependencies.
+ * Internal context. Used to coordinate injections and support circular dependencies.
  *
  * @author crazybob@google.com (Bob Lee)
  */
-final class InternalContext {
+final class InternalContext implements AutoCloseable {
 
   private final InjectorOptions options;
 
-  private Map<Object, ConstructionContext<?>> constructionContexts = Maps.newHashMap();
+  private final Map<Object, ConstructionContext<?>> constructionContexts =
+      new IdentityHashMap<Object, ConstructionContext<?>>();
 
   /** Keeps track of the type that is currently being requested for injection. */
   private Dependency<?> dependency;
 
-  /** Keeps track of the hierarchy of types needed during injection. */
-  private final DependencyStack state = new DependencyStack();
-
-  InternalContext(InjectorOptions options) {
-    this.options = options;
-  }
-
-  public InjectorOptions getInjectorOptions() {
-    return options;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T> ConstructionContext<T> getConstructionContext(Object key) {
-    ConstructionContext<T> constructionContext
-        = (ConstructionContext<T>) constructionContexts.get(key);
-    if (constructionContext == null) {
-      constructionContext = new ConstructionContext<T>();
-      constructionContexts.put(key, constructionContext);
-    }
-    return constructionContext;
-  }
-
-  public Dependency<?> getDependency() {
-    return dependency;
-  }
-
-  /** Sets the new current dependency & adds it to the state. */
-  public Dependency<?> pushDependency(Dependency<?> dependency, Object source) {
-    Dependency<?> previous = this.dependency;
-    this.dependency = dependency;
-    state.add(dependency, source);
-    return previous;
-  }
-
-  /** Pops the current state & sets the new dependency. */
-  public void popStateAndSetDependency(Dependency<?> newDependency) {
-    state.pop();
-    this.dependency = newDependency;
-  }
-
-  /** Adds to the state without setting the dependency. */
-  public void pushState(Key<?> key, Object source) {
-    state.add(key, source);
-  }
-  
-  /** Pops from the state without setting a dependency. */
-  public void popState() {
-    state.pop();
-  }
-
-  /** Returns the current dependency chain (all the state). */
-  public List<DependencyAndSource> getDependencyChain() {
-    ImmutableList.Builder<DependencyAndSource> builder = ImmutableList.builder();
-    for (int i = 0; i < state.size(); i += 2) {
-      Object evenEntry = state.get(i);
-      Dependency<?> dependency;
-      if (evenEntry instanceof Key) {
-        dependency = Dependency.get((Key<?>) evenEntry);
-      } else {
-        dependency = (Dependency<?>) evenEntry;
-      }
-      builder.add(new DependencyAndSource(dependency, state.get(i + 1)));
-    }
-    return builder.build();
-  }
-
   /**
    * Keeps track of the hierarchy of types needed during injection.
    *
@@ -116,29 +43,126 @@
    * even indices, and sources on odd indices. This structure is to avoid the memory overhead of
    * DependencyAndSource objects, which can add to several tens of megabytes in large applications.
    */
-  private static final class DependencyStack {
-    private Object[] elements = new Object[16];
-    private int size = 0;
+  private Object[] dependencyStack = new Object[16];
 
-    public void add(Object dependencyOrKey, Object source) {
-      if (elements.length < size + 2) {
-        elements = Arrays.copyOf(elements, (elements.length*3)/2 + 2);
-      }
-      elements[size++] = dependencyOrKey;
-      elements[size++] = source;
+  private int dependencyStackSize = 0;
+
+
+  /**
+   * The number of times {@link #enter()} has been called + 1 for initial construction. This value
+   * is decremented when {@link #exit()} is called.
+   */
+  private int enterCount;
+
+  /**
+   * A single element array to clear when the {@link #enterCount} hits {@code 0}.
+   *
+   * <p>This is the value stored in the {@code InjectorImpl.localContext} thread local.
+   */
+  private final Object[] toClear;
+
+  InternalContext(InjectorOptions options, Object[] toClear) {
+    this.options = options;
+    this.toClear = toClear;
+    this.enterCount = 1;
+  }
+
+  /** Should only be called by InjectorImpl.enterContext(). */
+  void enter() {
+    enterCount++;
+  }
+
+  /** Should be called any any method that received an instance via InjectorImpl.enterContext(). */
+  @Override
+  public void close() {
+    int newCount = --enterCount;
+    if (newCount < 0) {
+      throw new IllegalStateException("Called close() too many times");
     }
-
-    public void pop() {
-      elements[--size] = null;
-      elements[--size] = null;
-    }
-
-    public Object get(int i) {
-      return elements[i];
-    }
-
-    public int size() {
-      return size;
+    if (newCount == 0) {
+      toClear[0] = null;
     }
   }
+
+  InjectorOptions getInjectorOptions() {
+    return options;
+  }
+
+  @SuppressWarnings("unchecked")
+  <T> ConstructionContext<T> getConstructionContext(Object key) {
+    ConstructionContext<T> constructionContext =
+        (ConstructionContext<T>) constructionContexts.get(key);
+    if (constructionContext == null) {
+      constructionContext = new ConstructionContext<>();
+      constructionContexts.put(key, constructionContext);
+    }
+    return constructionContext;
+  }
+
+  Dependency<?> getDependency() {
+    return dependency;
+  }
+
+  /** Sets the new current dependency & adds it to the state. */
+  Dependency<?> pushDependency(Dependency<?> dependency, Object source) {
+    Dependency<?> previous = this.dependency;
+    this.dependency = dependency;
+    doPushState(dependency, source);
+    return previous;
+  }
+
+
+  /** Pops the current state & sets the new dependency. */
+  void popStateAndSetDependency(Dependency<?> newDependency) {
+    popState();
+    this.dependency = newDependency;
+  }
+
+
+  /** Adds to the state without setting the dependency. */
+  void pushState(com.google.inject.Key<?> key, Object source) {
+    doPushState(key, source);
+  }
+
+
+  private void doPushState(Object dependencyOrKey, Object source) {
+    int localSize = dependencyStackSize;
+    Object[] localStack = dependencyStack;
+    if (localStack.length < localSize + 2) {
+      localStack = dependencyStack =
+        java.util.Arrays.copyOf(localStack, (localStack.length * 3) / 2 + 2);
+    }
+    localStack[localSize++] = dependencyOrKey;
+    localStack[localSize++] = source;
+    dependencyStackSize = localSize;
+  }
+
+
+  /** Pops from the state without setting a dependency. */
+  void popState() {
+    // N.B. we don't null out the array entries.  It isn't necessary since all the objects in the
+    // array (Key, Dependency, or Binding source objects) are all tied to the lifetime of the
+    // injector, which is greater than the lifetime of this object.  So removing them from the array
+    // doesn't matter.
+    dependencyStackSize -= 2;
+  }
+
+
+  /** Returns the current dependency chain (all the state stored in the dependencyStack). */
+  java.util.List<com.google.inject.spi.DependencyAndSource> getDependencyChain() {
+    com.google.common.collect.ImmutableList.Builder<com.google.inject.spi.DependencyAndSource>
+        builder = com.google.common.collect.ImmutableList.builder();
+    for (int i = 0; i < dependencyStackSize; i += 2) {
+      Object evenEntry = dependencyStack[i];
+      Dependency<?> dependency;
+      if (evenEntry instanceof com.google.inject.Key) {
+        dependency = Dependency.get((com.google.inject.Key<?>) evenEntry);
+      } else {
+        dependency = (Dependency<?>) evenEntry;
+      }
+      builder.add(new com.google.inject.spi.DependencyAndSource(dependency, dependencyStack[i + 1]));
+    }
+    return builder.build();
+  }
+
 }
diff --git a/core/src/com/google/inject/internal/InternalFactory.java b/core/src/com/google/inject/internal/InternalFactory.java
index 2267b12..00f0d11 100644
--- a/core/src/com/google/inject/internal/InternalFactory.java
+++ b/core/src/com/google/inject/internal/InternalFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,12 +27,12 @@
 
   /**
    * Creates an object to be injected.
+   *
    * @param context of this injection
    * @param linked true if getting as a result of a linked binding
-   *
-   * @throws com.google.inject.internal.ErrorsException if a value cannot be provided
-   * @return instance to be injected
+   * @throws com.google.inject.internal.InternalProvisionException if a value cannot be provided
+   * @return instance that was created
    */
-  T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException;
+  T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException;
 }
diff --git a/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java b/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
index c02c70e..218ce7c 100644
--- a/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
+++ b/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,11 +22,11 @@
 import com.google.inject.spi.ProviderInstanceBinding;
 
 /**
- * Adapts {@link ProviderInstanceBinding} providers, ensuring circular proxies
- * fail (or proxy) properly.
- * 
+ * Adapts {@link ProviderInstanceBinding} providers, ensuring circular proxies fail (or proxy)
+ * properly.
+ *
  * @author sameb@google.com (Sam Berlin)
-*/
+ */
 final class InternalFactoryToInitializableAdapter<T> extends ProviderInternalFactory<T> {
 
   private final ProvisionListenerStackCallback<T> provisionCallback;
@@ -34,29 +34,34 @@
 
   public InternalFactoryToInitializableAdapter(
       Initializable<? extends javax.inject.Provider<? extends T>> initializable,
-      Object source, ProvisionListenerStackCallback<T> provisionCallback) {
+      Object source,
+      ProvisionListenerStackCallback<T> provisionCallback) {
     super(source);
-    this.provisionCallback = checkNotNull(provisionCallback, "provisionCallback");
+    this.provisionCallback = provisionCallback;
     this.initializable = checkNotNull(initializable, "provider");
   }
 
-  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException {
-    return circularGet(initializable.get(errors), errors, context, dependency,
-        provisionCallback);
-  }
-  
   @Override
-  protected T provision(javax.inject.Provider<? extends T> provider, Errors errors,
-      Dependency<?> dependency, ConstructionContext<T> constructionContext) throws ErrorsException {
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
+    return circularGet(initializable.get(), context, dependency, provisionCallback);
+  }
+
+  @Override
+  protected T provision(
+      javax.inject.Provider<? extends T> provider,
+      Dependency<?> dependency,
+      ConstructionContext<T> constructionContext)
+      throws InternalProvisionException {
     try {
-      return super.provision(provider, errors, dependency, constructionContext);
-    } catch(RuntimeException userException) {
-      throw errors.withSource(source).errorInProvider(userException).toException();
+      return super.provision(provider, dependency, constructionContext);
+    } catch (RuntimeException userException) {
+      throw InternalProvisionException.errorInProvider(userException).addSource(source);
     }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return initializable.toString();
   }
 }
diff --git a/core/src/com/google/inject/internal/InternalFactoryToProviderAdapter.java b/core/src/com/google/inject/internal/InternalFactoryToProviderAdapter.java
index 4cd1b2e..690f683 100644
--- a/core/src/com/google/inject/internal/InternalFactoryToProviderAdapter.java
+++ b/core/src/com/google/inject/internal/InternalFactoryToProviderAdapter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,9 +21,7 @@
 import com.google.inject.Provider;
 import com.google.inject.spi.Dependency;
 
-/**
- * @author crazybob@google.com (Bob Lee)
-*/
+/** @author crazybob@google.com (Bob Lee) */
 final class InternalFactoryToProviderAdapter<T> implements InternalFactory<T> {
 
   private final Provider<? extends T> provider;
@@ -34,17 +32,22 @@
     this.source = checkNotNull(source, "source");
   }
 
-  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
-      throws ErrorsException {
-    // TODO(sameb): Does this need to push state into the context?
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
     try {
-      return errors.checkForNull(provider.get(), source, dependency);
+      T t = provider.get();
+      if (t == null && !dependency.isNullable()) {
+        InternalProvisionException.onNullInjectedIntoNonNullableDependency(source, dependency);
+      }
+      return t;
     } catch (RuntimeException userException) {
-      throw errors.withSource(source).errorInProvider(userException).toException();
+      throw InternalProvisionException.errorInProvider(userException).addSource(source);
     }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return provider.toString();
   }
 }
diff --git a/core/src/com/google/inject/internal/InternalFlags.java b/core/src/com/google/inject/internal/InternalFlags.java
index 85c07ac..4127ea6 100644
--- a/core/src/com/google/inject/internal/InternalFlags.java
+++ b/core/src/com/google/inject/internal/InternalFlags.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2013 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -121,11 +121,14 @@
     Class<T> enumType = defaultValue.getDeclaringClass();
     String value = null;
     try {
-      value = AccessController.doPrivileged(new PrivilegedAction<String>() {
-        public String run() {
-          return System.getProperty(name);
-        }
-      });
+      value =
+          AccessController.doPrivileged(
+              new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                  return System.getProperty(name);
+                }
+              });
       return (value != null && value.length() > 0) ? Enum.valueOf(enumType, value) : defaultValue;
     } catch (SecurityException e) {
       return secureValue;
diff --git a/core/src/com/google/inject/internal/InternalInjectorCreator.java b/core/src/com/google/inject/internal/InternalInjectorCreator.java
index d40bc83..64c4cf1 100644
--- a/core/src/com/google/inject/internal/InternalInjectorCreator.java
+++ b/core/src/com/google/inject/internal/InternalInjectorCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +16,6 @@
 
 package com.google.inject.internal;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import com.google.inject.Binding;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -30,8 +28,8 @@
 import com.google.inject.internal.util.Stopwatch;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.TypeConverterBinding;
-
 import java.lang.annotation.Annotation;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -43,14 +41,15 @@
  * top-level injector.
  *
  * <p>Injector construction happens in two phases.
+ *
  * <ol>
- *   <li>Static building. In this phase, we interpret commands, create bindings, and inspect 
+ * <li>Static building. In this phase, we interpret commands, create bindings, and inspect
  *     dependencies. During this phase, we hold a lock to ensure consistency with parent injectors.
- *     No user code is executed in this phase.</li>
- *   <li>Dynamic injection. In this phase, we call user code. We inject members that requested
+ *     No user code is executed in this phase.
+ * <li>Dynamic injection. In this phase, we call user code. We inject members that requested
  *     injection. This may require user's objects be created and their providers be called. And we
  *     create eager singletons. In this phase, user code may have started other threads. This phase
- *     is not executed for injectors created using {@link Stage#TOOL the tool stage}</li>
+ *     is not executed for injectors created using {@link Stage#TOOL the tool stage}
  * </ol>
  *
  * @author crazybob@google.com (Bob Lee)
@@ -67,12 +66,12 @@
 
   private final InjectorShell.Builder shellBuilder = new InjectorShell.Builder();
   private List<InjectorShell> shells;
-  
+
   public InternalInjectorCreator() {
     injectionRequestProcessor = new InjectionRequestProcessor(errors, initializer);
     bindingData = new ProcessedBindingData();
   }
-  
+
   public InternalInjectorCreator stage(Stage stage) {
     shellBuilder.stage(stage);
     return this;
@@ -146,6 +145,11 @@
     }
     stopwatch.resetAndLog("Provider verification");
 
+    // This needs to come late since some user bindings rely on requireBinding calls to create
+    // jit bindings during the LookupProcessor.
+    bindingData.initializeDelayedBindings();
+    stopwatch.resetAndLog("Delayed Binding initialization");
+
     for (InjectorShell shell : shells) {
       if (!shell.getElements().isEmpty()) {
         throw new AssertionError("Failed to execute " + shell.getElements());
@@ -155,9 +159,7 @@
     errors.throwCreationExceptionIfErrorsExist();
   }
 
-  /**
-   * Returns the injector being constructed. This is not necessarily the root injector.
-   */
+  /** Returns the injector being constructed. This is not necessarily the root injector. */
   private Injector primaryInjector() {
     return shells.get(0).getInjector();
   }
@@ -175,7 +177,7 @@
     stopwatch.resetAndLog("Instance injection");
     errors.throwCreationExceptionIfErrorsExist();
 
-    if(shellBuilder.getStage() != Stage.TOOL) {
+    if (shellBuilder.getStage() != Stage.TOOL) {
       for (InjectorShell shell : shells) {
         loadEagerSingletons(shell.getInjector(), shellBuilder.getStage(), errors);
       }
@@ -189,33 +191,33 @@
    * while we're binding these singletons are not be eager.
    */
   void loadEagerSingletons(InjectorImpl injector, Stage stage, final Errors errors) {
+    List<BindingImpl<?>> candidateBindings = new ArrayList<>();
     @SuppressWarnings("unchecked") // casting Collection<Binding> to Collection<BindingImpl> is safe
-    Iterable<BindingImpl<?>> candidateBindings = ImmutableList.copyOf(Iterables.concat(
-        (Collection) injector.state.getExplicitBindingsThisLevel().values(),
-        injector.jitBindings.values()));
-    for (final BindingImpl<?> binding : candidateBindings) {
-      if (isEagerSingleton(injector, binding, stage)) {
-        try {
-          injector.callInContext(new ContextualCallable<Void>() {
-            Dependency<?> dependency = Dependency.get(binding.getKey());
-            public Void call(InternalContext context) {
-              Dependency previous = context.pushDependency(dependency, binding.getSource());
-              Errors errorsForBinding = errors.withSource(dependency);
-              try {
-                binding.getInternalFactory().get(errorsForBinding, context, dependency, false);
-              } catch (ErrorsException e) {
-                errorsForBinding.merge(e.getErrors());
-              } finally {
-                context.popStateAndSetDependency(previous);
-              }
+    Collection<BindingImpl<?>> bindingsAtThisLevel =
+        (Collection) injector.state.getExplicitBindingsThisLevel().values();
+    candidateBindings.addAll(bindingsAtThisLevel);
+    synchronized (injector.state.lock()) {
+      // jit bindings must be accessed while holding the lock.
+      candidateBindings.addAll(injector.jitBindings.values());
+    }
+    InternalContext context = injector.enterContext();
+    try {
+      for (BindingImpl<?> binding : candidateBindings) {
+        if (isEagerSingleton(injector, binding, stage)) {
+          Dependency<?> dependency = Dependency.get(binding.getKey());
+          Dependency previous = context.pushDependency(dependency, binding.getSource());
 
-              return null;
+          try {
+            binding.getInternalFactory().get(context, dependency, false);
+          } catch (InternalProvisionException e) {
+            errors.withSource(dependency).merge(e);
+          } finally {
+              context.popStateAndSetDependency(previous);
             }
-          });
-        } catch (ErrorsException e) {
-          throw new AssertionError();
         }
       }
+    } finally {
+      context.close();
     }
   }
 
@@ -238,70 +240,106 @@
   /** {@link Injector} exposed to users in {@link Stage#TOOL}. */
   static class ToolStageInjector implements Injector {
     private final Injector delegateInjector;
-    
+
     ToolStageInjector(Injector delegateInjector) {
       this.delegateInjector = delegateInjector;
     }
+
+    @Override
     public void injectMembers(Object o) {
       throw new UnsupportedOperationException(
-        "Injector.injectMembers(Object) is not supported in Stage.TOOL");
+          "Injector.injectMembers(Object) is not supported in Stage.TOOL");
     }
+
+    @Override
     public Map<Key<?>, Binding<?>> getBindings() {
       return this.delegateInjector.getBindings();
     }
+
+    @Override
     public Map<Key<?>, Binding<?>> getAllBindings() {
       return this.delegateInjector.getAllBindings();
     }
+
+    @Override
     public <T> Binding<T> getBinding(Key<T> key) {
       return this.delegateInjector.getBinding(key);
     }
+
+    @Override
     public <T> Binding<T> getBinding(Class<T> type) {
       return this.delegateInjector.getBinding(type);
     }
+
+    @Override
     public <T> Binding<T> getExistingBinding(Key<T> key) {
       return this.delegateInjector.getExistingBinding(key);
     }
+
+    @Override
     public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
       return this.delegateInjector.findBindingsByType(type);
     }
+
+    @Override
     public Injector getParent() {
       return delegateInjector.getParent();
     }
+
+    @Override
     public Injector createChildInjector(Iterable<? extends Module> modules) {
       return delegateInjector.createChildInjector(modules);
     }
+
+    @Override
     public Injector createChildInjector(Module... modules) {
       return delegateInjector.createChildInjector(modules);
     }
+
+    @Override
     public Map<Class<? extends Annotation>, Scope> getScopeBindings() {
       return delegateInjector.getScopeBindings();
     }
+
+    @Override
     public Set<TypeConverterBinding> getTypeConverterBindings() {
       return delegateInjector.getTypeConverterBindings();
     }
+
+    @Override
     public <T> Provider<T> getProvider(Key<T> key) {
       throw new UnsupportedOperationException(
-        "Injector.getProvider(Key<T>) is not supported in Stage.TOOL");
+          "Injector.getProvider(Key<T>) is not supported in Stage.TOOL");
     }
+
+    @Override
     public <T> Provider<T> getProvider(Class<T> type) {
       throw new UnsupportedOperationException(
-        "Injector.getProvider(Class<T>) is not supported in Stage.TOOL");
+          "Injector.getProvider(Class<T>) is not supported in Stage.TOOL");
     }
+
+    @Override
     public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) {
       throw new UnsupportedOperationException(
-        "Injector.getMembersInjector(TypeLiteral<T>) is not supported in Stage.TOOL");
+          "Injector.getMembersInjector(TypeLiteral<T>) is not supported in Stage.TOOL");
     }
+
+    @Override
     public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
       throw new UnsupportedOperationException(
-        "Injector.getMembersInjector(Class<T>) is not supported in Stage.TOOL");
+          "Injector.getMembersInjector(Class<T>) is not supported in Stage.TOOL");
     }
+
+    @Override
     public <T> T getInstance(Key<T> key) {
       throw new UnsupportedOperationException(
-        "Injector.getInstance(Key<T>) is not supported in Stage.TOOL");
+          "Injector.getInstance(Key<T>) is not supported in Stage.TOOL");
     }
+
+    @Override
     public <T> T getInstance(Class<T> type) {
       throw new UnsupportedOperationException(
-        "Injector.getInstance(Class<T>) is not supported in Stage.TOOL");
+          "Injector.getInstance(Class<T>) is not supported in Stage.TOOL");
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/InternalProviderInstanceBindingImpl.java b/core/src/com/google/inject/internal/InternalProviderInstanceBindingImpl.java
new file mode 100644
index 0000000..dd941aa
--- /dev/null
+++ b/core/src/com/google/inject/internal/InternalProviderInstanceBindingImpl.java
@@ -0,0 +1,195 @@
+package com.google.inject.internal;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.ProviderWithExtensionVisitor;
+
+/**
+ * A {@link ProviderInstanceBindingImpl} for implementing 'native' guice extensions.
+ *
+ * <p>Beyond the normal binding contract that is mostly handled by our baseclass, this also
+ * implements {@link DelayedInitialize} in order to initialize factory state.
+ */
+final class InternalProviderInstanceBindingImpl<T> extends ProviderInstanceBindingImpl<T>
+    implements DelayedInitialize {
+  enum InitializationTiming {
+    /** This factory can be initialized eagerly. This should be the case for most things. */
+    EAGER,
+
+    /**
+     * Initialization of this factory should be delayed until after all other static initialization
+     * completes. This will be useful for factories that need to call {@link
+     * InjectorImpl#getExistingBinding(Key)} to not create jit bindings, but also want to be able to
+     * conditionally consume jit bindings created by other other bindings.
+     */
+    DELAYED;
+  }
+
+  private final Factory<T> originalFactory;
+
+  InternalProviderInstanceBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      Factory<T> originalFactory,
+      InternalFactory<? extends T> scopedFactory,
+      Scoping scoping) {
+    super(
+        injector,
+        key,
+        source,
+        scopedFactory,
+        scoping,
+        originalFactory,
+        ImmutableSet.<InjectionPoint>of());
+    this.originalFactory = originalFactory;
+  }
+
+  InitializationTiming getInitializationTiming() {
+    return originalFactory.initializationTiming;
+  }
+
+  @Override
+  public void initialize(final InjectorImpl injector, final Errors errors) throws ErrorsException {
+    originalFactory.source = getSource();
+    originalFactory.provisionCallback = injector.provisionListenerStore.get(this);
+    // For these kinds of providers, the 'user supplied provider' is really 'guice supplied'
+    // So make our user supplied provider just delegate to the guice supplied one.
+    originalFactory.delegateProvider = getProvider();
+    originalFactory.initialize(injector, errors);
+  }
+
+  /**
+   * A base factory implementation. Any Factories that delegate to other bindings should use the
+   * {@code CyclicFactory} subclass, but trivial factories can use this one.
+   */
+  abstract static class Factory<T> implements InternalFactory<T>, Provider<T>, HasDependencies {
+    private final InitializationTiming initializationTiming;
+    private Object source;
+    private Provider<T> delegateProvider;
+    ProvisionListenerStackCallback<T> provisionCallback;
+
+    Factory(InitializationTiming initializationTiming) {
+      this.initializationTiming = initializationTiming;
+    }
+    /**
+     * The binding source.
+     *
+     * <p>May be useful for augmenting runtime error messages.
+     *
+     * <p>Note: this will return {#code null} until {@link #initialize(InjectorImpl, Errors)} has
+     * already been called.
+     */
+    final Object getSource() {
+      return source;
+    }
+
+    /**
+     * A callback that allows for implementations to fetch dependencies on other bindings.
+     *
+     * <p>Will be called exactly once, prior to any call to {@link #doProvision}.
+     */
+    abstract void initialize(InjectorImpl injector, Errors errors) throws ErrorsException;
+
+    @Override
+    public final T get() {
+      Provider<T> local = delegateProvider;
+      if (local == null) {
+        throw new IllegalStateException(
+            "This Provider cannot be used until the Injector has been created.");
+      }
+      return local.get();
+    }
+
+    @Override
+    public T get(final InternalContext context, final Dependency<?> dependency, boolean linked)
+        throws InternalProvisionException {
+      if (provisionCallback == null) {
+        return doProvision(context, dependency);
+      } else {
+        return provisionCallback.provision(
+            context,
+            new ProvisionCallback<T>() {
+              @Override
+              public T call() throws InternalProvisionException {
+                return doProvision(context, dependency);
+              }
+            });
+      }
+    }
+    /**
+     * Creates an object to be injected.
+     *
+     * @throws com.google.inject.internal.InternalProvisionException if a value cannot be provided
+     * @return instance to be injected
+     */
+    protected abstract T doProvision(InternalContext context, Dependency<?> dependency)
+        throws InternalProvisionException;
+  }
+
+  /**
+   * An base factory implementation that can be extended to provide a specialized implementation of
+   * a {@link ProviderWithExtensionVisitor} and also implements {@link InternalFactory}
+   */
+  abstract static class CyclicFactory<T> extends Factory<T> {
+
+    CyclicFactory(InitializationTiming initializationTiming) {
+      super(initializationTiming);
+    }
+
+    @Override
+    public final T get(
+        final InternalContext context, final Dependency<?> dependency, boolean linked)
+        throws InternalProvisionException {
+      final ConstructionContext<T> constructionContext = context.getConstructionContext(this);
+      // We have a circular reference between bindings. Return a proxy.
+      if (constructionContext.isConstructing()) {
+        Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType();
+        @SuppressWarnings("unchecked")
+        T proxyType =
+            (T) constructionContext.createProxy(context.getInjectorOptions(), expectedType);
+        return proxyType;
+      }
+      // Optimization: Don't go through the callback stack if no one's listening.
+      constructionContext.startConstruction();
+      try {
+        if (provisionCallback == null) {
+          return provision(dependency, context, constructionContext);
+        } else {
+          return provisionCallback.provision(
+              context,
+              new ProvisionCallback<T>() {
+                @Override
+                public T call() throws InternalProvisionException {
+                  return provision(dependency, context, constructionContext);
+                }
+              });
+        }
+      } finally {
+        constructionContext.removeCurrentReference();
+        constructionContext.finishConstruction();
+      }
+    }
+
+    private T provision(
+        Dependency<?> dependency,
+        InternalContext context,
+        ConstructionContext<T> constructionContext)
+        throws InternalProvisionException {
+      try {
+        T t = doProvision(context, dependency);
+        constructionContext.setProxyDelegates(t);
+        return t;
+      } catch (InternalProvisionException ipe) {
+        throw ipe.addSource(getSource());
+      } catch (Throwable t) {
+        throw InternalProvisionException.errorInProvider(t).addSource(getSource());
+      }
+    }
+  }
+}
diff --git a/core/src/com/google/inject/internal/InternalProvisionException.java b/core/src/com/google/inject/internal/InternalProvisionException.java
new file mode 100644
index 0000000..4a49d92
--- /dev/null
+++ b/core/src/com/google/inject/internal/InternalProvisionException.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.inject.Guice;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Provides;
+import com.google.inject.ProvisionException;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.util.SourceProvider;
+import com.google.inject.internal.util.StackTraceElements;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.InjectionListener;
+import com.google.inject.spi.Message;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A checked exception for provisioning errors.
+ *
+ * <p>This is the internal dual of {@link ProvisionException}, similar to the relationship between
+ * {@link com.google.inject.ConfigurationException} and {@link ErrorsException}. This is useful for
+ * several reasons:
+ *
+ * <ul>
+ *   <li>Since it is a checked exception, we get some assistance from the java compiler in ensuring
+ *       that we correctly handle it everywhere. ProvisionException is unchecked.
+ *   <li>Since this is an internal package, we can add useful construction and mutation APIs that
+ *       would be undesirable in a public supported API.
+ * </ul>
+ *
+ * <p>This exception will be thrown when errors are encountered during provisioning, ErrorsException
+ * will continue to be used for errors that are encountered during provisioning and both make use of
+ * the {@link Message} as the core model.
+ *
+ * <p>NOTE: this object stores a list of messages but in the most common case the cardinality will
+ * be 1. The only time that multiple errors might be reported via this mechanism is when {@link
+ * #errorInUserCode} is called with an exception that holds multiple errors (like
+ * ProvisionException).
+ */
+public final class InternalProvisionException extends Exception {
+  private static final Logger logger = Logger.getLogger(Guice.class.getName());
+  private static final Set<Dependency<?>> warnedDependencies =
+      Collections.newSetFromMap(new ConcurrentHashMap<Dependency<?>, Boolean>());
+
+
+  public static InternalProvisionException circularDependenciesDisabled(Class<?> expectedType) {
+    return create(
+        "Found a circular dependency involving %s, and circular dependencies are disabled.",
+        expectedType);
+  }
+
+  public static InternalProvisionException cannotProxyClass(Class<?> expectedType) {
+    return create(
+        "Tried proxying %s to support a circular dependency, but it is not an interface.",
+        expectedType);
+  }
+
+  public static InternalProvisionException create(String format, Object... arguments) {
+    return new InternalProvisionException(Messages.create(format, arguments));
+  }
+
+  public static InternalProvisionException errorInUserCode(
+      Throwable cause, String messageFormat, Object... arguments) {
+    Collection<Message> messages = Errors.getMessagesFromThrowable(cause);
+    if (!messages.isEmpty()) {
+      // TODO(lukes): it seems like we are dropping some valuable context here..
+      // consider eliminating this special case
+      return new InternalProvisionException(messages);
+    } else {
+      return new InternalProvisionException(Messages.create(cause, messageFormat, arguments));
+    }
+  }
+
+  public static InternalProvisionException subtypeNotProvided(
+      Class<? extends javax.inject.Provider<?>> providerType, Class<?> type) {
+    return create("%s doesn't provide instances of %s.", providerType, type);
+  }
+
+  public static InternalProvisionException errorInProvider(Throwable cause) {
+    return errorInUserCode(cause, "Error in custom provider, %s", cause);
+  }
+
+  public static InternalProvisionException errorInjectingMethod(Throwable cause) {
+    return errorInUserCode(cause, "Error injecting method, %s", cause);
+  }
+
+  public static InternalProvisionException errorInjectingConstructor(Throwable cause) {
+    return errorInUserCode(cause, "Error injecting constructor, %s", cause);
+  }
+
+  public static InternalProvisionException errorInUserInjector(
+      MembersInjector<?> listener, TypeLiteral<?> type, RuntimeException cause) {
+    return errorInUserCode(
+        cause, "Error injecting %s using %s.%n Reason: %s", type, listener, cause);
+  }
+
+  public static InternalProvisionException jitDisabled(Key<?> key) {
+    return create("Explicit bindings are required and %s is not explicitly bound.", key);
+  }
+
+  public static InternalProvisionException errorNotifyingInjectionListener(
+      InjectionListener<?> listener, TypeLiteral<?> type, RuntimeException cause) {
+    return errorInUserCode(
+        cause, "Error notifying InjectionListener %s of %s.%n Reason: %s", listener, type, cause);
+  }
+
+  /**
+   * Returns {@code value} if it is non-null or allowed to be null. Otherwise a message is added and
+   * an {@code InternalProvisionException} is thrown.
+   */
+  static void onNullInjectedIntoNonNullableDependency(Object source, Dependency<?> dependency)
+      throws InternalProvisionException {
+    // Hack to allow null parameters to @Provides methods, for backwards compatibility.
+    if (dependency.getInjectionPoint().getMember() instanceof Method) {
+      Method annotated = (Method) dependency.getInjectionPoint().getMember();
+      if (annotated.isAnnotationPresent(Provides.class)) {
+        switch (InternalFlags.getNullableProvidesOption()) {
+          case ERROR:
+            break; // break out & let the below exception happen
+          case IGNORE:
+            return; // user doesn't care about injecting nulls to non-@Nullables.
+          case WARN:
+            // Warn only once, otherwise we spam logs too much.
+            if (warnedDependencies.add(dependency)) {
+              logger.log(
+                  Level.WARNING,
+                  "Guice injected null into {0} (a {1}), please mark it @Nullable."
+                      + " Use -Dguice_check_nullable_provides_params=ERROR to turn this into an"
+                      + " error.",
+                  new Object[] {
+                    Messages.formatParameter(dependency), Messages.convert(dependency.getKey())
+                  });
+            }
+            return;
+        }
+      }
+    }
+
+    Object formattedDependency =
+        (dependency.getParameterIndex() != -1)
+            ? Messages.formatParameter(dependency)
+            : StackTraceElements.forMember(dependency.getInjectionPoint().getMember());
+
+    throw InternalProvisionException.create(
+            "null returned by binding at %s%n but %s is not @Nullable", source, formattedDependency)
+        .addSource(source);
+  }
+
+  private final List<Object> sourcesToPrepend = new ArrayList<>();
+  private final ImmutableList<Message> errors;
+
+  private InternalProvisionException(Message error) {
+    this(ImmutableList.of(error));
+  }
+
+  private InternalProvisionException(Iterable<Message> errors) {
+    this.errors = ImmutableList.copyOf(errors);
+    checkArgument(!this.errors.isEmpty(), "Can't create a provision exception with no errors");
+  }
+
+  /**
+   * Prepends the given {@code source} to the stack of binding sources for the errors reported in
+   * this exception.
+   *
+   * <p>See {@link Errors#withSource(Object)}
+   *
+   * <p>It is expected that this method is called as the exception propagates up the stack.
+   *
+   * @param source
+   * @return {@code this}
+   */
+  InternalProvisionException addSource(Object source) {
+    if (source == SourceProvider.UNKNOWN_SOURCE) {
+      return this;
+    }
+    int sz = sourcesToPrepend.size();
+    if (sz > 0 && sourcesToPrepend.get(sz - 1) == source) {
+      // This is for when there are two identical sources added in a row.  This behavior is copied
+      // from Errors.withSource where it can happen when an constructor/provider method throws an
+      // exception
+      return this;
+    }
+    sourcesToPrepend.add(source);
+    return this;
+  }
+
+  ImmutableList<Message> getErrors() {
+    ImmutableList.Builder<Message> builder = ImmutableList.builder();
+    // reverse them since sources are added as the exception propagates (so the first source is the
+    // last one added)
+    List<Object> newSources = Lists.reverse(sourcesToPrepend);
+    for (Message error : errors) {
+      builder.add(Messages.mergeSources(newSources, error));
+    }
+    return builder.build();
+  }
+
+  /** Returns this exception convered to a ProvisionException. */
+  public ProvisionException toProvisionException() {
+    return new ProvisionException(getErrors());
+  }
+}
diff --git a/core/src/com/google/inject/internal/LinkedBindingImpl.java b/core/src/com/google/inject/internal/LinkedBindingImpl.java
index 8f83324..f2e1a03 100644
--- a/core/src/com/google/inject/internal/LinkedBindingImpl.java
+++ b/core/src/com/google/inject/internal/LinkedBindingImpl.java
@@ -16,6 +16,7 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
@@ -24,15 +25,19 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.LinkedKeyBinding;
-
 import java.util.Set;
 
-public final class LinkedBindingImpl<T> extends BindingImpl<T> implements LinkedKeyBinding<T>, HasDependencies {
+public final class LinkedBindingImpl<T> extends BindingImpl<T>
+    implements LinkedKeyBinding<T>, HasDependencies {
 
   final Key<? extends T> targetKey;
 
-  public LinkedBindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Scoping scoping,
+  public LinkedBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping,
       Key<? extends T> targetKey) {
     super(injector, key, source, internalFactory, scoping);
     this.targetKey = targetKey;
@@ -43,32 +48,39 @@
     this.targetKey = targetKey;
   }
 
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public Key<? extends T> getLinkedKey() {
     return targetKey;
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return ImmutableSet.<Dependency<?>>of(Dependency.get(targetKey));
   }
 
+  @Override
   public BindingImpl<T> withScoping(Scoping scoping) {
     return new LinkedBindingImpl<T>(getSource(), getKey(), scoping, targetKey);
   }
 
+  @Override
   public BindingImpl<T> withKey(Key<T> key) {
     return new LinkedBindingImpl<T>(getSource(), key, getScoping(), targetKey);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     getScoping().applyTo(binder.withSource(getSource()).bind(getKey()).to(getLinkedKey()));
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(LinkedKeyBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(LinkedKeyBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("scope", getScoping())
@@ -78,11 +90,11 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof LinkedBindingImpl) {
-      LinkedBindingImpl<?> o = (LinkedBindingImpl<?>)obj;
+    if (obj instanceof LinkedBindingImpl) {
+      LinkedBindingImpl<?> o = (LinkedBindingImpl<?>) obj;
       return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping())
-        && Objects.equal(targetKey, o.targetKey);
+          && getScoping().equals(o.getScoping())
+          && Objects.equal(targetKey, o.targetKey);
     } else {
       return false;
     }
diff --git a/core/src/com/google/inject/internal/LinkedProviderBindingImpl.java b/core/src/com/google/inject/internal/LinkedProviderBindingImpl.java
index a4a78a5..fa9d792 100644
--- a/core/src/com/google/inject/internal/LinkedProviderBindingImpl.java
+++ b/core/src/com/google/inject/internal/LinkedProviderBindingImpl.java
@@ -16,6 +16,7 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
@@ -24,17 +25,20 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.ProviderKeyBinding;
-
 import java.util.Set;
 
-final class LinkedProviderBindingImpl<T>
-    extends BindingImpl<T> implements ProviderKeyBinding<T>, HasDependencies, DelayedInitialize {
+final class LinkedProviderBindingImpl<T> extends BindingImpl<T>
+    implements ProviderKeyBinding<T>, HasDependencies, DelayedInitialize {
 
   final Key<? extends javax.inject.Provider<? extends T>> providerKey;
   final DelayedInitialize delayedInitializer;
 
-  private LinkedProviderBindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Scoping scoping,
+  private LinkedProviderBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping,
       Key<? extends javax.inject.Provider<? extends T>> providerKey,
       DelayedInitialize delayedInitializer) {
     super(injector, key, source, internalFactory, scoping);
@@ -42,60 +46,79 @@
     this.delayedInitializer = delayedInitializer;
   }
 
-  public LinkedProviderBindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Scoping scoping,
+  public LinkedProviderBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping,
       Key<? extends javax.inject.Provider<? extends T>> providerKey) {
     this(injector, key, source, internalFactory, scoping, providerKey, null);
   }
 
-  LinkedProviderBindingImpl(Object source, Key<T> key, Scoping scoping,
+  LinkedProviderBindingImpl(
+      Object source,
+      Key<T> key,
+      Scoping scoping,
       Key<? extends javax.inject.Provider<? extends T>> providerKey) {
     super(source, key, scoping);
     this.providerKey = providerKey;
     this.delayedInitializer = null;
   }
 
-  static <T> LinkedProviderBindingImpl<T> createWithInitializer(InjectorImpl injector, Key<T> key,
-      Object source, InternalFactory<? extends T> internalFactory, Scoping scoping,
+  static <T> LinkedProviderBindingImpl<T> createWithInitializer(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping,
       Key<? extends javax.inject.Provider<? extends T>> providerKey,
       DelayedInitialize delayedInitializer) {
-    return new LinkedProviderBindingImpl<T>(injector, key, source, internalFactory, scoping,
-        providerKey, delayedInitializer);
+    return new LinkedProviderBindingImpl<T>(
+        injector, key, source, internalFactory, scoping, providerKey, delayedInitializer);
   }
 
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public Key<? extends javax.inject.Provider<? extends T>> getProviderKey() {
     return providerKey;
   }
 
+  @Override
   public void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
     if (delayedInitializer != null) {
       delayedInitializer.initialize(injector, errors);
     }
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return ImmutableSet.<Dependency<?>>of(Dependency.get(providerKey));
   }
 
+  @Override
   public BindingImpl<T> withScoping(Scoping scoping) {
     return new LinkedProviderBindingImpl<T>(getSource(), getKey(), scoping, providerKey);
   }
 
+  @Override
   public BindingImpl<T> withKey(Key<T> key) {
     return new LinkedProviderBindingImpl<T>(getSource(), key, getScoping(), providerKey);
   }
 
+  @Override
   public void applyTo(Binder binder) {
-    getScoping().applyTo(binder.withSource(getSource())
-        .bind(getKey()).toProvider(getProviderKey()));
+    getScoping()
+        .applyTo(binder.withSource(getSource()).bind(getKey()).toProvider(getProviderKey()));
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(ProviderKeyBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(ProviderKeyBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("scope", getScoping())
@@ -105,11 +128,11 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof LinkedProviderBindingImpl) {
-      LinkedProviderBindingImpl<?> o = (LinkedProviderBindingImpl<?>)obj;
+    if (obj instanceof LinkedProviderBindingImpl) {
+      LinkedProviderBindingImpl<?> o = (LinkedProviderBindingImpl<?>) obj;
       return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping())
-        && Objects.equal(providerKey, o.providerKey);
+          && getScoping().equals(o.getScoping())
+          && Objects.equal(providerKey, o.providerKey);
     } else {
       return false;
     }
diff --git a/core/src/com/google/inject/internal/ListenerBindingProcessor.java b/core/src/com/google/inject/internal/ListenerBindingProcessor.java
index e8ebed2..e70acb5 100644
--- a/core/src/com/google/inject/internal/ListenerBindingProcessor.java
+++ b/core/src/com/google/inject/internal/ListenerBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,13 +30,15 @@
     super(errors);
   }
 
-  @Override public Boolean visit(TypeListenerBinding binding) {
+  @Override
+  public Boolean visit(TypeListenerBinding binding) {
     injector.state.addTypeListener(binding);
     return true;
   }
-  
-  @Override public Boolean visit(ProvisionListenerBinding binding) {
+
+  @Override
+  public Boolean visit(ProvisionListenerBinding binding) {
     injector.state.addProvisionListener(binding);
     return true;
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/LookupProcessor.java b/core/src/com/google/inject/internal/LookupProcessor.java
index bf11b83..5e68505 100644
--- a/core/src/com/google/inject/internal/LookupProcessor.java
+++ b/core/src/com/google/inject/internal/LookupProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,10 +33,11 @@
     super(errors);
   }
 
-  @Override public <T> Boolean visit(MembersInjectorLookup<T> lookup) {
+  @Override
+  public <T> Boolean visit(MembersInjectorLookup<T> lookup) {
     try {
-      MembersInjector<T> membersInjector
-          = injector.membersInjectorStore.get(lookup.getType(), errors);
+      MembersInjector<T> membersInjector =
+          injector.membersInjectorStore.get(lookup.getType(), errors);
       lookup.initializeDelegate(membersInjector);
     } catch (ErrorsException e) {
       errors.merge(e.getErrors()); // TODO: source
@@ -45,7 +46,8 @@
     return true;
   }
 
-  @Override public <T> Boolean visit(ProviderLookup<T> lookup) {
+  @Override
+  public <T> Boolean visit(ProviderLookup<T> lookup) {
     // ensure the provider can be created
     try {
       Provider<T> provider = injector.getProviderOrThrow(lookup.getDependency(), errors);
diff --git a/core/src/com/google/inject/internal/Lookups.java b/core/src/com/google/inject/internal/Lookups.java
index 2b32c7a..d3e64d8 100644
--- a/core/src/com/google/inject/internal/Lookups.java
+++ b/core/src/com/google/inject/internal/Lookups.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/core/src/com/google/inject/internal/MembersInjectorImpl.java b/core/src/com/google/inject/internal/MembersInjectorImpl.java
index 498b441..c1503ea 100644
--- a/core/src/com/google/inject/internal/MembersInjectorImpl.java
+++ b/core/src/com/google/inject/internal/MembersInjectorImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,71 +33,77 @@
 final class MembersInjectorImpl<T> implements MembersInjector<T> {
   private final TypeLiteral<T> typeLiteral;
   private final InjectorImpl injector;
-  private final ImmutableList<SingleMemberInjector> memberInjectors;
-  private final ImmutableSet<MembersInjector<? super T>> userMembersInjectors;
-  private final ImmutableSet<InjectionListener<? super T>> injectionListeners;
-  /*if[AOP]*/
-  private final ImmutableList<MethodAspect> addedAspects;
+  // a null list means empty. Since it is common for many of these lists to be empty we can save
+  // some memory lookups by representing empty as null.
+  /* @Nullable */ private final ImmutableList<SingleMemberInjector> memberInjectors;
+  /* @Nullable */ private final ImmutableList<MembersInjector<? super T>> userMembersInjectors;
+  /* @Nullable */ private final ImmutableList<InjectionListener<? super T>> injectionListeners;
+  /*if[AOP]*//* @Nullable */ private final ImmutableList<MethodAspect> addedAspects;
   /*end[AOP]*/
 
-  MembersInjectorImpl(InjectorImpl injector, TypeLiteral<T> typeLiteral,
-      EncounterImpl<T> encounter, ImmutableList<SingleMemberInjector> memberInjectors) {
+  MembersInjectorImpl(
+      InjectorImpl injector,
+      TypeLiteral<T> typeLiteral,
+      EncounterImpl<T> encounter,
+      ImmutableList<SingleMemberInjector> memberInjectors) {
     this.injector = injector;
     this.typeLiteral = typeLiteral;
-    this.memberInjectors = memberInjectors;
-    this.userMembersInjectors = encounter.getMembersInjectors();
-    this.injectionListeners = encounter.getInjectionListeners();
+    this.memberInjectors = memberInjectors.isEmpty() ? null : memberInjectors;
+    this.userMembersInjectors =
+        encounter.getMembersInjectors().isEmpty() ? null : encounter.getMembersInjectors().asList();
+    this.injectionListeners =
+        encounter.getInjectionListeners().isEmpty()
+            ? null
+            : encounter.getInjectionListeners().asList();
     /*if[AOP]*/
-    this.addedAspects = encounter.getAspects();
+    this.addedAspects = encounter.getAspects().isEmpty() ? null : encounter.getAspects();
     /*end[AOP]*/
   }
 
   public ImmutableList<SingleMemberInjector> getMemberInjectors() {
-    return memberInjectors;
+    return memberInjectors == null ? ImmutableList.<SingleMemberInjector>of() : memberInjectors;
   }
 
+  @Override
   public void injectMembers(T instance) {
-    Errors errors = new Errors(typeLiteral);
+    TypeLiteral<T> localTypeLiteral = typeLiteral;
     try {
-      injectAndNotify(instance, errors, null, null, typeLiteral, false);
-    } catch (ErrorsException e) {
-      errors.merge(e.getErrors());
+      injectAndNotify(instance, null, null, localTypeLiteral, false);
+    } catch (InternalProvisionException ipe) {
+      throw ipe.addSource(localTypeLiteral).toProvisionException();
     }
-
-    errors.throwProvisionExceptionIfErrorsExist();
   }
 
-  void injectAndNotify(final T instance,
-      final Errors errors,
+  void injectAndNotify(
+      final T instance,
       final Key<T> key, // possibly null!
       final ProvisionListenerStackCallback<T> provisionCallback, // possibly null!
       final Object source,
-      final boolean toolableOnly) throws ErrorsException {
+      final boolean toolableOnly)
+      throws InternalProvisionException {
     if (instance == null) {
       return;
     }
-
-    injector.callInContext(new ContextualCallable<Void>() {
-      @Override
-      public Void call(final InternalContext context) throws ErrorsException {
-        context.pushState(key, source);
-        try {
-          if (provisionCallback != null && provisionCallback.hasListeners()) {
-            provisionCallback.provision(errors, context, new ProvisionCallback<T>() {
-              @Override public T call() {
-                injectMembers(instance, errors, context, toolableOnly);
+    final InternalContext context = injector.enterContext();
+    context.pushState(key, source);
+    try {
+      if (provisionCallback != null && provisionCallback.hasListeners()) {
+        provisionCallback.provision(
+            context,
+            new ProvisionCallback<T>() {
+              @Override
+              public T call() throws InternalProvisionException {
+                injectMembers(instance, context, toolableOnly);
                 return instance;
               }
             });
-          } else {
-            injectMembers(instance, errors, context, toolableOnly);
-          }
-        } finally {
-          context.popState();
-        }
-        return null;
+      } else {
+        injectMembers(instance, context, toolableOnly);
       }
-    });
+    } finally {
+      context.popState();
+      context.close();
+    }
 
     // TODO: We *could* notify listeners too here,
     // but it's not clear if we want to.  There's no way to know
@@ -107,59 +113,80 @@
     // if atleast one InjectionPoint was toolable, in which case
     // the above callInContext could return 'true' if it injected
     // anything.)
-    if(!toolableOnly) {
-      notifyListeners(instance, errors);
+    if (!toolableOnly) {
+      notifyListeners(instance);
     }
   }
 
-  void notifyListeners(T instance, Errors errors) throws ErrorsException {
-    int numErrorsBefore = errors.size();
-    for (InjectionListener<? super T> injectionListener : injectionListeners) {
+  void notifyListeners(T instance) throws InternalProvisionException {
+    ImmutableList<InjectionListener<? super T>> localInjectionListeners = injectionListeners;
+    if (localInjectionListeners == null) {
+      // no listeners
+      return;
+    }
+    // optimization: use manual for/each to save allocating an iterator here
+    for (int i = 0; i < localInjectionListeners.size(); i++) {
+      InjectionListener<? super T> injectionListener = localInjectionListeners.get(i);
       try {
         injectionListener.afterInjection(instance);
       } catch (RuntimeException e) {
-        errors.errorNotifyingInjectionListener(injectionListener, typeLiteral, e);
+        throw InternalProvisionException.errorNotifyingInjectionListener(
+            injectionListener, typeLiteral, e);
       }
     }
-    errors.throwIfNewErrors(numErrorsBefore);
   }
 
-  void injectMembers(T t, Errors errors, InternalContext context, boolean toolableOnly) {
-    // optimization: use manual for/each to save allocating an iterator here
-    for (int i = 0, size = memberInjectors.size(); i < size; i++) {
-      SingleMemberInjector injector = memberInjectors.get(i);
-      if(!toolableOnly || injector.getInjectionPoint().isToolable()) {
-        injector.inject(errors, context, t);
+  void injectMembers(T t, InternalContext context, boolean toolableOnly)
+      throws InternalProvisionException {
+    ImmutableList<SingleMemberInjector> localMembersInjectors = memberInjectors;
+    if (localMembersInjectors != null) {
+      // optimization: use manual for/each to save allocating an iterator here
+      for (int i = 0, size = localMembersInjectors.size(); i < size; i++) {
+        SingleMemberInjector injector = localMembersInjectors.get(i);
+        if (!toolableOnly || injector.getInjectionPoint().isToolable()) {
+          injector.inject(context, t);
+        }
       }
     }
 
     // TODO: There's no way to know if a user's MembersInjector wants toolable injections.
-    if(!toolableOnly) {
-      for (MembersInjector<? super T> userMembersInjector : userMembersInjectors) {
-        try {
-          userMembersInjector.injectMembers(t);
-        } catch (RuntimeException e) {
-          errors.errorInUserInjector(userMembersInjector, typeLiteral, e);
+    if (!toolableOnly) {
+      ImmutableList<MembersInjector<? super T>> localUsersMembersInjectors = userMembersInjectors;
+      if (localUsersMembersInjectors != null) {
+        // optimization: use manual for/each to save allocating an iterator here
+        for (int i = 0; i < localUsersMembersInjectors.size(); i++) {
+          MembersInjector<? super T> userMembersInjector = localUsersMembersInjectors.get(i);
+          try {
+            userMembersInjector.injectMembers(t);
+          } catch (RuntimeException e) {
+            throw InternalProvisionException.errorInUserInjector(
+                userMembersInjector, typeLiteral, e);
+          }
         }
       }
     }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "MembersInjector<" + typeLiteral + ">";
   }
 
   public ImmutableSet<InjectionPoint> getInjectionPoints() {
-    ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
-    for (SingleMemberInjector memberInjector : memberInjectors) {
-      builder.add(memberInjector.getInjectionPoint());
+    ImmutableList<SingleMemberInjector> localMemberInjectors = memberInjectors;
+    if (localMemberInjectors != null) {
+      ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
+      for (SingleMemberInjector memberInjector : localMemberInjectors) {
+        builder.add(memberInjector.getInjectionPoint());
+      }
+      return builder.build();
     }
-    return builder.build();
+    return ImmutableSet.of();
   }
 
   /*if[AOP]*/
   public ImmutableList<MethodAspect> getAddedAspects() {
-    return addedAspects;
+    return addedAspects == null ? ImmutableList.<MethodAspect>of() : addedAspects;
   }
   /*end[AOP]*/
 }
diff --git a/core/src/com/google/inject/internal/MembersInjectorStore.java b/core/src/com/google/inject/internal/MembersInjectorStore.java
index 8e2acdd..6328902 100644
--- a/core/src/com/google/inject/internal/MembersInjectorStore.java
+++ b/core/src/com/google/inject/internal/MembersInjectorStore.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,6 @@
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.TypeListener;
 import com.google.inject.spi.TypeListenerBinding;
-
 import java.lang.reflect.Field;
 import java.util.List;
 import java.util.Set;
@@ -38,16 +37,16 @@
   private final InjectorImpl injector;
   private final ImmutableList<TypeListenerBinding> typeListenerBindings;
 
-  private final FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>> cache
-      = new FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>>() {
-    @Override protected MembersInjectorImpl<?> create(TypeLiteral<?> type, Errors errors)
-        throws ErrorsException {
-      return createWithListeners(type, errors);
-    }
-  };
+  private final FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>> cache =
+      new FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>>() {
+        @Override
+        protected MembersInjectorImpl<?> create(TypeLiteral<?> type, Errors errors)
+            throws ErrorsException {
+          return createWithListeners(type, errors);
+        }
+      };
 
-  MembersInjectorStore(InjectorImpl injector,
-      List<TypeListenerBinding> typeListenerBindings) {
+  MembersInjectorStore(InjectorImpl injector, List<TypeListenerBinding> typeListenerBindings) {
     this.injector = injector;
     this.typeListenerBindings = ImmutableList.copyOf(typeListenerBindings);
   }
@@ -60,9 +59,7 @@
     return !typeListenerBindings.isEmpty();
   }
 
-  /**
-   * Returns a new complete members injector with injection listeners registered.
-   */
+  /** Returns a new complete members injector with injection listeners registered. */
   @SuppressWarnings("unchecked") // the MembersInjector type always agrees with the passed type
   public <T> MembersInjectorImpl<T> get(TypeLiteral<T> key, Errors errors) throws ErrorsException {
     return (MembersInjectorImpl<T>) cache.get(key, errors);
@@ -74,16 +71,14 @@
    * ImplicitBindingTest#testCircularJitBindingsLeaveNoResidue and
    * #testInstancesRequestingProvidersForThemselvesWithChildInjectors for examples of when this is
    * necessary.)
-   * 
-   * Returns true if the type was stored in the cache, false otherwise.
+   *
+   * <p>Returns true if the type was stored in the cache, false otherwise.
    */
   boolean remove(TypeLiteral<?> type) {
     return cache.remove(type);
   }
 
-  /**
-   * Creates a new members injector and attaches both injection listeners and method aspects.
-   */
+  /** Creates a new members injector and attaches both injection listeners and method aspects. */
   private <T> MembersInjectorImpl<T> createWithListeners(TypeLiteral<T> type, Errors errors)
       throws ErrorsException {
     int numErrorsBefore = errors.size();
@@ -98,7 +93,7 @@
     ImmutableList<SingleMemberInjector> injectors = getInjectors(injectionPoints, errors);
     errors.throwIfNewErrors(numErrorsBefore);
 
-    EncounterImpl<T> encounter = new EncounterImpl<T>(errors, injector.lookups);
+    EncounterImpl<T> encounter = new EncounterImpl<>(errors, injector.lookups);
     Set<TypeListener> alreadySeenListeners = Sets.newHashSet();
     for (TypeListenerBinding binding : typeListenerBindings) {
       TypeListener typeListener = binding.getListener();
@@ -117,20 +112,20 @@
     return new MembersInjectorImpl<T>(injector, type, encounter, injectors);
   }
 
-  /**
-   * Returns the injectors for the specified injection points.
-   */
+  /** Returns the injectors for the specified injection points. */
   ImmutableList<SingleMemberInjector> getInjectors(
       Set<InjectionPoint> injectionPoints, Errors errors) {
     List<SingleMemberInjector> injectors = Lists.newArrayList();
     for (InjectionPoint injectionPoint : injectionPoints) {
       try {
-        Errors errorsForMember = injectionPoint.isOptional()
-            ? new Errors(injectionPoint)
-            : errors.withSource(injectionPoint);
-        SingleMemberInjector injector = injectionPoint.getMember() instanceof Field
-            ? new SingleFieldInjector(this.injector, injectionPoint, errorsForMember)
-            : new SingleMethodInjector(this.injector, injectionPoint, errorsForMember);
+        Errors errorsForMember =
+            injectionPoint.isOptional()
+                ? new Errors(injectionPoint)
+                : errors.withSource(injectionPoint);
+        SingleMemberInjector injector =
+            injectionPoint.getMember() instanceof Field
+                ? new SingleFieldInjector(this.injector, injectionPoint, errorsForMember)
+                : new SingleMethodInjector(this.injector, injectionPoint, errorsForMember);
         injectors.add(injector);
       } catch (ErrorsException ignoredForNow) {
         // ignored for now
diff --git a/core/src/com/google/inject/internal/MessageProcessor.java b/core/src/com/google/inject/internal/MessageProcessor.java
index d7c607b..cb9be02 100644
--- a/core/src/com/google/inject/internal/MessageProcessor.java
+++ b/core/src/com/google/inject/internal/MessageProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Guice;
 import com.google.inject.spi.Message;
-
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -36,10 +35,12 @@
     super(errors);
   }
 
-  @Override public Boolean visit(Message message) {
+  @Override
+  public Boolean visit(Message message) {
     if (message.getCause() != null) {
       String rootMessage = getRootMessage(message.getCause());
-      logger.log(Level.INFO,
+      logger.log(
+          Level.INFO,
           "An exception was caught and reported. Message: " + rootMessage,
           message.getCause());
     }
diff --git a/core/src/com/google/inject/internal/Messages.java b/core/src/com/google/inject/internal/Messages.java
new file mode 100644
index 0000000..2c80ab2
--- /dev/null
+++ b/core/src/com/google/inject/internal/Messages.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Equivalence;
+import com.google.common.base.Objects;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.util.Classes;
+import com.google.inject.internal.util.StackTraceElements;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.ElementSource;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.Message;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Formatter;
+import java.util.List;
+import java.util.Map;
+
+/** Utility methods for {@link Message} objects */
+public final class Messages {
+  private Messages() {}
+
+  /** Prepends the list of sources to the given {@link Message} */
+  static Message mergeSources(List<Object> sources, Message message) {
+    List<Object> messageSources = message.getSources();
+    // It is possible that the end of getSources() and the beginning of message.getSources() are
+    // equivalent, in this case we should drop the repeated source when joining the lists.  The
+    // most likely scenario where this would happen is when a scoped binding throws an exception,
+    // due to the fact that InternalFactoryToProviderAdapter applies the binding source when
+    // merging errors.
+    if (!sources.isEmpty()
+        && !messageSources.isEmpty()
+        && Objects.equal(messageSources.get(0), sources.get(sources.size() - 1))) {
+      messageSources = messageSources.subList(1, messageSources.size());
+    }
+    return new Message(
+        ImmutableList.builder().addAll(sources).addAll(messageSources).build(),
+        message.getMessage(),
+        message.getCause());
+  }
+
+  /**
+   * Calls {@link String#format} after converting the arguments using some standard guice formatting
+   * for {@link Key}, {@link Class} and {@link Member} objects.
+   */
+  public static String format(String messageFormat, Object... arguments) {
+    for (int i = 0; i < arguments.length; i++) {
+      arguments[i] = convert(arguments[i]);
+    }
+    return String.format(messageFormat, arguments);
+  }
+
+  /** Returns the formatted message for an exception with the specified messages. */
+  public static String formatMessages(String heading, Collection<Message> errorMessages) {
+    Formatter fmt = new Formatter().format(heading).format(":%n%n");
+    int index = 1;
+    boolean displayCauses = getOnlyCause(errorMessages) == null;
+
+    Map<Equivalence.Wrapper<Throwable>, Integer> causes = Maps.newHashMap();
+    for (Message errorMessage : errorMessages) {
+      int thisIdx = index++;
+      fmt.format("%s) %s%n", thisIdx, errorMessage.getMessage());
+
+      List<Object> dependencies = errorMessage.getSources();
+      for (int i = dependencies.size() - 1; i >= 0; i--) {
+        Object source = dependencies.get(i);
+        formatSource(fmt, source);
+      }
+
+      Throwable cause = errorMessage.getCause();
+      if (displayCauses && cause != null) {
+        Equivalence.Wrapper<Throwable> causeEquivalence = ThrowableEquivalence.INSTANCE.wrap(cause);
+        if (!causes.containsKey(causeEquivalence)) {
+          causes.put(causeEquivalence, thisIdx);
+          fmt.format("Caused by: %s", Throwables.getStackTraceAsString(cause));
+        } else {
+          int causeIdx = causes.get(causeEquivalence);
+          fmt.format(
+              "Caused by: %s (same stack trace as error #%s)",
+              cause.getClass().getName(), causeIdx);
+        }
+      }
+
+      fmt.format("%n");
+    }
+
+    if (errorMessages.size() == 1) {
+      fmt.format("1 error");
+    } else {
+      fmt.format("%s errors", errorMessages.size());
+    }
+
+    return fmt.toString();
+  }
+
+  /**
+   * Creates a new Message without a cause.
+   *
+   * @param messageFormat Format string
+   * @param arguments format string arguments
+   */
+  public static Message create(String messageFormat, Object... arguments) {
+    return create(null, messageFormat, arguments);
+  }
+
+  /**
+   * Creates a new Message with the given cause.
+   *
+   * @param cause The exception that caused the error
+   * @param messageFormat Format string
+   * @param arguments format string arguments
+   */
+  public static Message create(Throwable cause, String messageFormat, Object... arguments) {
+    return create(cause, ImmutableList.of(), messageFormat, arguments);
+  }
+
+  /**
+   * Creates a new Message with the given cause and a binding source stack.
+   *
+   * @param cause The exception that caused the error
+   * @param sources The binding sources for the source stack
+   * @param messageFormat Format string
+   * @param arguments format string arguments
+   */
+  public static Message create(
+      Throwable cause, List<Object> sources, String messageFormat, Object... arguments) {
+    String message = format(messageFormat, arguments);
+    return new Message(sources, message, cause);
+  }
+
+  /** Formats an object in a user friendly way. */
+  static Object convert(Object o) {
+    ElementSource source = null;
+    if (o instanceof ElementSource) {
+      source = (ElementSource) o;
+      o = source.getDeclaringSource();
+    }
+    return convert(o, source);
+  }
+
+  static Object convert(Object o, ElementSource source) {
+    for (Converter<?> converter : converters) {
+      if (converter.appliesTo(o)) {
+        return appendModules(converter.convert(o), source);
+      }
+    }
+    return appendModules(o, source);
+  }
+
+  private static Object appendModules(Object source, ElementSource elementSource) {
+    String modules = moduleSourceString(elementSource);
+    if (modules.length() == 0) {
+      return source;
+    } else {
+      return source + modules;
+    }
+  }
+
+  private static String moduleSourceString(ElementSource elementSource) {
+    // if we only have one module (or don't know what they are), then don't bother
+    // reporting it, because the source already is going to report exactly that module.
+    if (elementSource == null) {
+      return "";
+    }
+    List<String> modules = Lists.newArrayList(elementSource.getModuleClassNames());
+    // Insert any original element sources w/ module info into the path.
+    while (elementSource.getOriginalElementSource() != null) {
+      elementSource = elementSource.getOriginalElementSource();
+      modules.addAll(0, elementSource.getModuleClassNames());
+    }
+    if (modules.size() <= 1) {
+      return "";
+    }
+
+    // Ideally we'd do:
+    //    return Joiner.on(" -> ")
+    //        .appendTo(new StringBuilder(" (via modules: "), Lists.reverse(modules))
+    //        .append(")").toString();
+    // ... but for some reason we can't find Lists.reverse, so do it the boring way.
+    StringBuilder builder = new StringBuilder(" (via modules: ");
+    for (int i = modules.size() - 1; i >= 0; i--) {
+      builder.append(modules.get(i));
+      if (i != 0) {
+        builder.append(" -> ");
+      }
+    }
+    builder.append(")");
+    return builder.toString();
+  }
+
+  static void formatSource(Formatter formatter, Object source) {
+    ElementSource elementSource = null;
+    if (source instanceof ElementSource) {
+      elementSource = (ElementSource) source;
+      source = elementSource.getDeclaringSource();
+    }
+    formatSource(formatter, source, elementSource);
+  }
+
+  static void formatSource(Formatter formatter, Object source, ElementSource elementSource) {
+    String modules = moduleSourceString(elementSource);
+    if (source instanceof Dependency) {
+      Dependency<?> dependency = (Dependency<?>) source;
+      InjectionPoint injectionPoint = dependency.getInjectionPoint();
+      if (injectionPoint != null) {
+        formatInjectionPoint(formatter, dependency, injectionPoint, elementSource);
+      } else {
+        formatSource(formatter, dependency.getKey(), elementSource);
+      }
+
+    } else if (source instanceof InjectionPoint) {
+      formatInjectionPoint(formatter, null, (InjectionPoint) source, elementSource);
+
+    } else if (source instanceof Class) {
+      formatter.format("  at %s%s%n", StackTraceElements.forType((Class<?>) source), modules);
+
+    } else if (source instanceof Member) {
+      formatter.format("  at %s%s%n", StackTraceElements.forMember((Member) source), modules);
+
+    } else if (source instanceof TypeLiteral) {
+      formatter.format("  while locating %s%s%n", source, modules);
+
+    } else if (source instanceof Key) {
+      Key<?> key = (Key<?>) source;
+      formatter.format("  while locating %s%n", convert(key, elementSource));
+
+    } else if (source instanceof Thread) {
+      formatter.format("  in thread %s%n", source);
+
+    } else {
+      formatter.format("  at %s%s%n", source, modules);
+    }
+  }
+
+  private static void formatInjectionPoint(
+      Formatter formatter,
+      Dependency<?> dependency,
+      InjectionPoint injectionPoint,
+      ElementSource elementSource) {
+    Member member = injectionPoint.getMember();
+    Class<? extends Member> memberType = Classes.memberType(member);
+
+    if (memberType == Field.class) {
+      dependency = injectionPoint.getDependencies().get(0);
+      formatter.format("  while locating %s%n", convert(dependency.getKey(), elementSource));
+      formatter.format("    for field at %s%n", StackTraceElements.forMember(member));
+
+    } else if (dependency != null) {
+      formatter.format("  while locating %s%n", convert(dependency.getKey(), elementSource));
+      formatter.format("    for %s%n", formatParameter(dependency));
+
+    } else {
+      formatSource(formatter, injectionPoint.getMember());
+    }
+  }
+
+  static String formatParameter(Dependency<?> dependency) {
+    int ordinal = dependency.getParameterIndex() + 1;
+    return String.format(
+        "the %s%s parameter of %s",
+        ordinal,
+        getOrdinalSuffix(ordinal),
+        StackTraceElements.forMember(dependency.getInjectionPoint().getMember()));
+  }
+
+  /**
+   * Maps {@code 1} to the string {@code "1st"} ditto for all non-negative numbers
+   *
+   * @see <a href="https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers">
+   *     https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers</a>
+   */
+  private static String getOrdinalSuffix(int ordinal) {
+    // negative ordinals don't make sense, we allow zero though because we are programmers
+    checkArgument(ordinal >= 0);
+    if ((ordinal / 10) % 10 == 1) {
+      // all the 'teens' are weird
+      return "th";
+    } else {
+      // could use a lookup table? any better?
+      switch (ordinal % 10) {
+        case 1:
+          return "st";
+        case 2:
+          return "nd";
+        case 3:
+          return "rd";
+        default:
+          return "th";
+      }
+    }
+  }
+
+  private abstract static class Converter<T> {
+
+    final Class<T> type;
+
+    Converter(Class<T> type) {
+      this.type = type;
+    }
+
+    boolean appliesTo(Object o) {
+      return o != null && type.isAssignableFrom(o.getClass());
+    }
+
+    String convert(Object o) {
+      return toString(type.cast(o));
+    }
+
+    abstract String toString(T t);
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"}) // rawtypes aren't avoidable
+  private static final Collection<Converter<?>> converters =
+      ImmutableList.of(
+          new Converter<Class>(Class.class) {
+            @Override
+            public String toString(Class c) {
+              return c.getName();
+            }
+          },
+          new Converter<Member>(Member.class) {
+            @Override
+            public String toString(Member member) {
+              return Classes.toString(member);
+            }
+          },
+          new Converter<Key>(Key.class) {
+            @Override
+            public String toString(Key key) {
+              if (key.getAnnotationType() != null) {
+                return key.getTypeLiteral()
+                    + " annotated with "
+                    + (key.getAnnotation() != null ? key.getAnnotation() : key.getAnnotationType());
+              } else {
+                return key.getTypeLiteral().toString();
+              }
+            }
+          });
+
+  /**
+   * Returns the cause throwable if there is exactly one cause in {@code messages}. If there are
+   * zero or multiple messages with causes, null is returned.
+   */
+  public static Throwable getOnlyCause(Collection<Message> messages) {
+    Throwable onlyCause = null;
+    for (Message message : messages) {
+      Throwable messageCause = message.getCause();
+      if (messageCause == null) {
+        continue;
+      }
+
+      if (onlyCause != null && !ThrowableEquivalence.INSTANCE.equivalent(onlyCause, messageCause)) {
+        return null;
+      }
+
+      onlyCause = messageCause;
+    }
+
+    return onlyCause;
+  }
+
+  private static final class ThrowableEquivalence extends Equivalence<Throwable> {
+    static final ThrowableEquivalence INSTANCE = new ThrowableEquivalence();
+
+    @Override
+    protected boolean doEquivalent(Throwable a, Throwable b) {
+      return a.getClass().equals(b.getClass())
+          && Objects.equal(a.getMessage(), b.getMessage())
+          && Arrays.equals(a.getStackTrace(), b.getStackTrace())
+          && equivalent(a.getCause(), b.getCause());
+    }
+
+    @Override
+    protected int doHash(Throwable t) {
+      return Objects.hashCode(t.getClass().hashCode(), t.getMessage(), hash(t.getCause()));
+    }
+  }
+}
diff --git a/core/src/com/google/inject/internal/MethodAspect.java b/core/src/com/google/inject/internal/MethodAspect.java
index 7bdf193..d04175f 100644
--- a/core/src/com/google/inject/internal/MethodAspect.java
+++ b/core/src/com/google/inject/internal/MethodAspect.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,10 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.inject.matcher.Matcher;
-
-import org.aopalliance.intercept.MethodInterceptor;
-
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
+import org.aopalliance.intercept.MethodInterceptor;
 
 /**
  * Ties a matcher to a method interceptor.
@@ -44,15 +42,19 @@
    *     annotatedWith(Transactional.class)}.
    * @param interceptors to apply
    */
-  MethodAspect(Matcher<? super Class<?>> classMatcher,
-      Matcher<? super Method> methodMatcher, List<MethodInterceptor> interceptors) {
+  MethodAspect(
+      Matcher<? super Class<?>> classMatcher,
+      Matcher<? super Method> methodMatcher,
+      List<MethodInterceptor> interceptors) {
     this.classMatcher = checkNotNull(classMatcher, "class matcher");
     this.methodMatcher = checkNotNull(methodMatcher, "method matcher");
     this.interceptors = checkNotNull(interceptors, "interceptors");
   }
 
-  MethodAspect(Matcher<? super Class<?>> classMatcher,
-      Matcher<? super Method> methodMatcher, MethodInterceptor... interceptors) {
+  MethodAspect(
+      Matcher<? super Class<?>> classMatcher,
+      Matcher<? super Method> methodMatcher,
+      MethodInterceptor... interceptors) {
     this(classMatcher, methodMatcher, Arrays.asList(interceptors));
   }
 
diff --git a/core/src/com/google/inject/internal/ModuleAnnotatedMethodScannerProcessor.java b/core/src/com/google/inject/internal/ModuleAnnotatedMethodScannerProcessor.java
index 85c721d..74c64b0 100644
--- a/core/src/com/google/inject/internal/ModuleAnnotatedMethodScannerProcessor.java
+++ b/core/src/com/google/inject/internal/ModuleAnnotatedMethodScannerProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,7 +29,8 @@
     super(errors);
   }
 
-  @Override public Boolean visit(ModuleAnnotatedMethodScannerBinding command) {
+  @Override
+  public Boolean visit(ModuleAnnotatedMethodScannerBinding command) {
     injector.state.addScanner(command);
     return true;
   }
diff --git a/core/src/com/google/inject/internal/MoreTypes.java b/core/src/com/google/inject/internal/MoreTypes.java
index bdf6029..11e6ab3 100644
--- a/core/src/com/google/inject/internal/MoreTypes.java
+++ b/core/src/com/google/inject/internal/MoreTypes.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.internal;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -26,7 +25,6 @@
 import com.google.inject.Key;
 import com.google.inject.TypeLiteral;
 import com.google.inject.util.Types;
-
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.lang.reflect.GenericArrayType;
@@ -36,12 +34,10 @@
 import java.lang.reflect.TypeVariable;
 import java.lang.reflect.WildcardType;
 import java.util.Arrays;
-import java.util.Map;
 import java.util.NoSuchElementException;
 
 /**
- * Static methods for working with types that we aren't publishing in the
- * public {@code Types} API.
+ * Static methods for working with types that we aren't publishing in the public {@code Types} API.
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
@@ -51,8 +47,8 @@
 
   private MoreTypes() {}
 
-  private static final Map<TypeLiteral<?>, TypeLiteral<?>> PRIMITIVE_TO_WRAPPER
-      = new ImmutableMap.Builder<TypeLiteral<?>, TypeLiteral<?>>()
+  private static final ImmutableMap<TypeLiteral<?>, TypeLiteral<?>> PRIMITIVE_TO_WRAPPER =
+      new ImmutableMap.Builder<TypeLiteral<?>, TypeLiteral<?>>()
           .put(TypeLiteral.get(boolean.class), TypeLiteral.get(Boolean.class))
           .put(TypeLiteral.get(byte.class), TypeLiteral.get(Byte.class))
           .put(TypeLiteral.get(short.class), TypeLiteral.get(Short.class))
@@ -65,13 +61,12 @@
           .build();
 
   /**
-   * Returns a key that doesn't hold any references to parent classes.
-   * This is necessary for anonymous keys, so ensure we don't hold a ref
-   * to the containing module (or class) forever.
+   * Returns a key that doesn't hold any references to parent classes. This is necessary for
+   * anonymous keys, so ensure we don't hold a ref to the containing module (or class) forever.
    */
   public static <T> Key<T> canonicalizeKey(Key<T> key) {
     // If we know this isn't a subclass, return as-is.
-    // Otherwise, recreate the key to avoid the subclass 
+    // Otherwise, recreate the key to avoid the subclass
     if (key.getClass() == Key.class) {
       return key;
     } else if (key.getAnnotation() != null) {
@@ -106,8 +101,9 @@
       // the following casts are generally unsafe, but com.google.inject.Provider extends
       // javax.inject.Provider and is covariant
       @SuppressWarnings("unchecked")
-      TypeLiteral<T> guiceProviderType = (TypeLiteral<T>) TypeLiteral.get(
-          Types.providerOf(parameterizedType.getActualTypeArguments()[0]));
+      TypeLiteral<T> guiceProviderType =
+          (TypeLiteral<T>)
+              TypeLiteral.get(Types.providerOf(parameterizedType.getActualTypeArguments()[0]));
       return guiceProviderType;
     }
 
@@ -129,9 +125,7 @@
     return recreated;
   }
 
-  /**
-   * Returns true if {@code type} is free from type variables.
-   */
+  /** Returns true if {@code type} is free from type variables. */
   private static boolean isFullySpecified(Type type) {
     if (type instanceof Class) {
       return true;
@@ -139,7 +133,7 @@
     } else if (type instanceof CompositeType) {
       return ((CompositeType) type).isFullySpecified();
 
-    } else if (type instanceof TypeVariable){
+    } else if (type instanceof TypeVariable) {
       return false;
 
     } else {
@@ -148,9 +142,8 @@
   }
 
   /**
-   * Returns a type that is functionally equal but not necessarily equal
-   * according to {@link Object#equals(Object) Object.equals()}. The returned
-   * type is {@link Serializable}.
+   * Returns a type that is functionally equal but not necessarily equal according to {@link
+   * Object#equals(Object) Object.equals()}. The returned type is {@link Serializable}.
    */
   public static Type canonicalize(Type type) {
     if (type instanceof Class) {
@@ -162,8 +155,8 @@
 
     } else if (type instanceof ParameterizedType) {
       ParameterizedType p = (ParameterizedType) type;
-      return new ParameterizedTypeImpl(p.getOwnerType(),
-          p.getRawType(), p.getActualTypeArguments());
+      return new ParameterizedTypeImpl(
+          p.getOwnerType(), p.getRawType(), p.getActualTypeArguments());
 
     } else if (type instanceof GenericArrayType) {
       GenericArrayType g = (GenericArrayType) type;
@@ -191,28 +184,33 @@
       // Neal isn't either but suspects some pathological case related
       // to nested classes exists.
       Type rawType = parameterizedType.getRawType();
-      checkArgument(rawType instanceof Class,
-          "Expected a Class, but <%s> is of type %s", type, type.getClass().getName());
+      checkArgument(
+          rawType instanceof Class,
+          "Expected a Class, but <%s> is of type %s",
+          type,
+          type.getClass().getName());
       return (Class<?>) rawType;
 
     } else if (type instanceof GenericArrayType) {
-      Type componentType = ((GenericArrayType)type).getGenericComponentType();
+      Type componentType = ((GenericArrayType) type).getGenericComponentType();
       return Array.newInstance(getRawType(componentType), 0).getClass();
 
-    } else if (type instanceof TypeVariable) {
+    } else if (type instanceof TypeVariable || type instanceof WildcardType) {
       // we could use the variable's bounds, but that'll won't work if there are multiple.
-      // having a raw type that's more general than necessary is okay  
+      // having a raw type that's more general than necessary is okay
       return Object.class;
 
     } else {
-      throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
-          + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
+      throw new IllegalArgumentException(
+          "Expected a Class, ParameterizedType, or "
+              + "GenericArrayType, but <"
+              + type
+              + "> is of type "
+              + type.getClass().getName());
     }
   }
 
-  /**
-   * Returns true if {@code a} and {@code b} are equal.
-   */
+  /** Returns true if {@code a} and {@code b} are equal. */
   public static boolean equals(Type a, Type b) {
     if (a == b) {
       // also handles (a == null && b == null)
@@ -278,8 +276,8 @@
 
   /**
    * Returns the generic supertype for {@code type}. For example, given a class {@code IntegerSet},
-   * the result for when supertype is {@code Set.class} is {@code Set<Integer>} and the result
-   * when the supertype is {@code Collection.class} is {@code Collection<Integer>}.
+   * the result for when supertype is {@code Set.class} is {@code Set<Integer>} and the result when
+   * the supertype is {@code Collection.class} is {@code Collection<Integer>}.
    */
   public static Type getGenericSupertype(Type type, Class<?> rawType, Class<?> toResolve) {
     if (toResolve == rawType) {
@@ -347,9 +345,7 @@
    */
   private static Class<?> declaringClassOf(TypeVariable typeVariable) {
     GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
-    return genericDeclaration instanceof Class
-        ? (Class<?>) genericDeclaration
-        : null;
+    return genericDeclaration instanceof Class ? (Class<?>) genericDeclaration : null;
   }
 
   public static class ParameterizedTypeImpl
@@ -372,18 +368,22 @@
       }
     }
 
+    @Override
     public Type[] getActualTypeArguments() {
       return typeArguments.clone();
     }
 
+    @Override
     public Type getRawType() {
       return rawType;
     }
 
+    @Override
     public Type getOwnerType() {
       return ownerType;
     }
 
+    @Override
     public boolean isFullySpecified() {
       if (ownerType != null && !MoreTypes.isFullySpecified(ownerType)) {
         return false;
@@ -402,18 +402,19 @@
       return true;
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof ParameterizedType
           && MoreTypes.equals(this, (ParameterizedType) other);
     }
 
-    @Override public int hashCode() {
-      return Arrays.hashCode(typeArguments)
-          ^ rawType.hashCode()
-          ^ hashCodeOrZero(ownerType);
+    @Override
+    public int hashCode() {
+      return Arrays.hashCode(typeArguments) ^ rawType.hashCode() ^ hashCodeOrZero(ownerType);
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       StringBuilder stringBuilder = new StringBuilder(30 * (typeArguments.length + 1));
       stringBuilder.append(typeToString(rawType));
 
@@ -431,10 +432,14 @@
     private static void ensureOwnerType(Type ownerType, Type rawType) {
       if (rawType instanceof Class<?>) {
         Class rawTypeAsClass = (Class) rawType;
-        checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null,
-            "No owner type for enclosed %s", rawType);
-        checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null,
-            "Owner type for unenclosed %s", rawType);
+        checkArgument(
+            ownerType != null || rawTypeAsClass.getEnclosingClass() == null,
+            "No owner type for enclosed %s",
+            rawType);
+        checkArgument(
+            ownerType == null || rawTypeAsClass.getEnclosingClass() != null,
+            "Owner type for unenclosed %s",
+            rawType);
       }
     }
 
@@ -449,24 +454,28 @@
       this.componentType = canonicalize(componentType);
     }
 
+    @Override
     public Type getGenericComponentType() {
       return componentType;
     }
 
+    @Override
     public boolean isFullySpecified() {
       return MoreTypes.isFullySpecified(componentType);
     }
 
-    @Override public boolean equals(Object o) {
-      return o instanceof GenericArrayType
-          && MoreTypes.equals(this, (GenericArrayType) o);
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof GenericArrayType && MoreTypes.equals(this, (GenericArrayType) o);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return componentType.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return typeToString(componentType) + "[]";
     }
 
@@ -474,9 +483,9 @@
   }
 
   /**
-   * The WildcardType interface supports multiple upper bounds and multiple
-   * lower bounds. We only support what the Java 6 language needs - at most one
-   * bound. If a lower bound is set, the upper bound must be Object.class.
+   * The WildcardType interface supports multiple upper bounds and multiple lower bounds. We only
+   * support what the Java 6 language needs - at most one bound. If a lower bound is set, the upper
+   * bound must be Object.class.
    */
   public static class WildcardTypeImpl implements WildcardType, Serializable, CompositeType {
     private final Type upperBound;
@@ -501,31 +510,35 @@
       }
     }
 
+    @Override
     public Type[] getUpperBounds() {
-      return new Type[] { upperBound };
+      return new Type[] {upperBound};
     }
 
+    @Override
     public Type[] getLowerBounds() {
-      return lowerBound != null ? new Type[] { lowerBound } : EMPTY_TYPE_ARRAY;
+      return lowerBound != null ? new Type[] {lowerBound} : EMPTY_TYPE_ARRAY;
     }
 
+    @Override
     public boolean isFullySpecified() {
       return MoreTypes.isFullySpecified(upperBound)
           && (lowerBound == null || MoreTypes.isFullySpecified(lowerBound));
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof WildcardType
-          && MoreTypes.equals(this, (WildcardType) other);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof WildcardType && MoreTypes.equals(this, (WildcardType) other);
     }
 
-    @Override public int hashCode() {
-      // this equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds());  
-      return (lowerBound != null ? 31 + lowerBound.hashCode() : 1)
-          ^ (31 + upperBound.hashCode());
+    @Override
+    public int hashCode() {
+      // this equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds());
+      return (lowerBound != null ? 31 + lowerBound.hashCode() : 1) ^ (31 + upperBound.hashCode());
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       if (lowerBound != null) {
         return "? super " + typeToString(lowerBound);
       } else if (upperBound == Object.class) {
@@ -539,8 +552,11 @@
   }
 
   private static void checkNotPrimitive(Type type, String use) {
-    checkArgument(!(type instanceof Class<?>) || !((Class) type).isPrimitive(),
-        "Primitive types are not allowed in %s: %s", use, type);
+    checkArgument(
+        !(type instanceof Class<?>) || !((Class) type).isPrimitive(),
+        "Primitive types are not allowed in %s: %s",
+        use,
+        type);
   }
 
   /** A type formed from other types, such as arrays, parameterized types or wildcard types */
diff --git a/core/src/com/google/inject/internal/Nullability.java b/core/src/com/google/inject/internal/Nullability.java
index 76f7e76..c8da51d 100644
--- a/core/src/com/google/inject/internal/Nullability.java
+++ b/core/src/com/google/inject/internal/Nullability.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,14 +21,13 @@
 /**
  * Whether a member supports null values injected.
  *
- * <p>Support for {@code Nullable} annotations in Guice is loose.
- * Any annotation type whose simplename is "Nullable" is sufficient to indicate
- * support for null values injected.
+ * <p>Support for {@code Nullable} annotations in Guice is loose. Any annotation type whose
+ * simplename is "Nullable" is sufficient to indicate support for null values injected.
  *
- * <p>This allows support for JSR-305's
- * <a href="http://groups.google.com/group/jsr-305/web/proposed-annotations">
- * javax.annotation.meta.Nullable</a> annotation and IntelliJ IDEA's
- * <a href="http://www.jetbrains.com/idea/documentation/howto.html">
+ * <p>This allows support for JSR-305's <a
+ * href="http://groups.google.com/group/jsr-305/web/proposed-annotations">
+ * javax.annotation.meta.Nullable</a> annotation and IntelliJ IDEA's <a
+ * href="http://www.jetbrains.com/idea/documentation/howto.html">
  * org.jetbrains.annotations.Nullable</a>.
  *
  * @author jessewilson@google.com (Jesse Wilson)
@@ -37,7 +36,7 @@
   private Nullability() {}
 
   public static boolean allowsNull(Annotation[] annotations) {
-    for(Annotation a : annotations) {
+    for (Annotation a : annotations) {
       Class<? extends Annotation> type = a.annotationType();
       if ("Nullable".equals(type.getSimpleName())) {
         return true;
diff --git a/core/src/com/google/inject/internal/PrivateElementProcessor.java b/core/src/com/google/inject/internal/PrivateElementProcessor.java
index 4a641a9..7d45a7d 100644
--- a/core/src/com/google/inject/internal/PrivateElementProcessor.java
+++ b/core/src/com/google/inject/internal/PrivateElementProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.common.collect.Lists;
 import com.google.inject.spi.PrivateElements;
-
 import java.util.List;
 
 /**
@@ -34,10 +33,10 @@
     super(errors);
   }
 
-  @Override public Boolean visit(PrivateElements privateElements) {
-    InjectorShell.Builder builder = new InjectorShell.Builder()
-        .parent(injector)
-        .privateElements(privateElements);
+  @Override
+  public Boolean visit(PrivateElements privateElements) {
+    InjectorShell.Builder builder =
+        new InjectorShell.Builder().parent(injector).privateElements(privateElements);
     injectorShellBuilders.add(builder);
     return true;
   }
diff --git a/core/src/com/google/inject/internal/PrivateElementsImpl.java b/core/src/com/google/inject/internal/PrivateElementsImpl.java
index 6a3d915..3ae71cc 100644
--- a/core/src/com/google/inject/internal/PrivateElementsImpl.java
+++ b/core/src/com/google/inject/internal/PrivateElementsImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,7 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
@@ -32,14 +32,11 @@
 import com.google.inject.spi.Element;
 import com.google.inject.spi.ElementVisitor;
 import com.google.inject.spi.PrivateElements;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public final class PrivateElementsImpl implements PrivateElements {
 
   /*
@@ -58,16 +55,19 @@
 
   /** lazily instantiated */
   private ImmutableMap<Key<?>, Object> exposedKeysToSources;
+
   private Injector injector;
 
   public PrivateElementsImpl(Object source) {
     this.source = checkNotNull(source, "source");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public List<Element> getElements() {
     if (elements == null) {
       elements = ImmutableList.copyOf(elementsMutable);
@@ -77,6 +77,7 @@
     return elements;
   }
 
+  @Override
   public Injector getInjector() {
     return injector;
   }
@@ -86,6 +87,7 @@
     this.injector = checkNotNull(injector, "injector");
   }
 
+  @Override
   public Set<Key<?>> getExposedKeys() {
     if (exposedKeysToSources == null) {
       Map<Key<?>, Object> exposedKeysToSourcesMutable = Maps.newLinkedHashMap();
@@ -99,6 +101,7 @@
     return exposedKeysToSources.keySet();
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
@@ -111,6 +114,7 @@
     exposureBuilders.add(exposureBuilder);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     PrivateBinder privateBinder = binder.withSource(source).newPrivateBinder();
 
@@ -124,6 +128,7 @@
     }
   }
 
+  @Override
   public Object getExposedSource(Key<?> key) {
     getExposedKeys(); // ensure exposedKeysToSources is populated
     Object source = exposedKeysToSources.get(key);
@@ -131,8 +136,9 @@
     return source;
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(PrivateElements.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(PrivateElements.class)
         .add("exposedKeys", getExposedKeys())
         .add("source", getSource())
         .toString();
diff --git a/core/src/com/google/inject/internal/ProcessedBindingData.java b/core/src/com/google/inject/internal/ProcessedBindingData.java
index 8cd2602..86a26c6 100644
--- a/core/src/com/google/inject/internal/ProcessedBindingData.java
+++ b/core/src/com/google/inject/internal/ProcessedBindingData.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,38 +17,58 @@
 package com.google.inject.internal;
 
 import com.google.common.collect.Lists;
-
 import java.util.List;
 
 /**
- * Keeps track of creation listeners & uninitialized bindings,
- * so they can be processed after bindings are recorded.
- * 
+ * Keeps track of creation listeners & uninitialized bindings, so they can be processed after
+ * bindings are recorded.
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 class ProcessedBindingData {
-  
+
   private final List<CreationListener> creationListeners = Lists.newArrayList();
   private final List<Runnable> uninitializedBindings = Lists.newArrayList();
-  
+  private final List<Runnable> delayedUninitializedBindings = Lists.newArrayList();
+
   void addCreationListener(CreationListener listener) {
     creationListeners.add(listener);
   }
-  
+
   void addUninitializedBinding(Runnable runnable) {
     uninitializedBindings.add(runnable);
   }
-  
+
+  void addDelayedUninitializedBinding(Runnable runnable) {
+    delayedUninitializedBindings.add(runnable);
+  }
+
+  /** Initialize bindings. This may be done eagerly */
   void initializeBindings() {
     for (Runnable initializer : uninitializedBindings) {
       initializer.run();
     }
   }
 
+  /**
+   * Runs creation listeners.
+   *
+   * <p>TODO(lukes): figure out exactly why this case exists.
+   */
   void runCreationListeners(Errors errors) {
     for (CreationListener creationListener : creationListeners) {
       creationListener.notify(errors);
     }
   }
 
+  /**
+   * Initialized bindings that need to be delayed until after all injection points and other
+   * bindings are processed. The main current usecase for this is resolving Optional dependencies
+   * for OptionalBinder bindings.
+   */
+  void initializeDelayedBindings() {
+    for (Runnable initializer : delayedUninitializedBindings) {
+      initializer.run();
+    }
+  }
 }
diff --git a/core/src/com/google/inject/internal/ProvidedByInternalFactory.java b/core/src/com/google/inject/internal/ProvidedByInternalFactory.java
index 1591c50..9d67374 100644
--- a/core/src/com/google/inject/internal/ProvidedByInternalFactory.java
+++ b/core/src/com/google/inject/internal/ProvidedByInternalFactory.java
@@ -14,79 +14,85 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.internal;
 
-import static com.google.common.base.Preconditions.checkState;
-
 import com.google.inject.Key;
 import com.google.inject.ProvidedBy;
-import com.google.inject.Provider;
 import com.google.inject.internal.InjectorImpl.JitLimitation;
 import com.google.inject.spi.Dependency;
+import javax.inject.Provider;
 
 /**
  * An {@link InternalFactory} for {@literal @}{@link ProvidedBy} bindings.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
-class ProvidedByInternalFactory<T> extends ProviderInternalFactory<T>
-    implements DelayedInitialize {
-  
+class ProvidedByInternalFactory<T> extends ProviderInternalFactory<T> implements DelayedInitialize {
+
   private final Class<?> rawType;
   private final Class<? extends Provider<?>> providerType;
   private final Key<? extends Provider<T>> providerKey;
   private BindingImpl<? extends Provider<T>> providerBinding;
   private ProvisionListenerStackCallback<T> provisionCallback;
-  
+
   ProvidedByInternalFactory(
       Class<?> rawType,
       Class<? extends Provider<?>> providerType,
       Key<? extends Provider<T>> providerKey) {
     super(providerKey);
     this.rawType = rawType;
-    this.providerType = providerType; 
+    this.providerType = providerType;
     this.providerKey = providerKey;
   }
-  
+
   void setProvisionListenerCallback(ProvisionListenerStackCallback<T> listener) {
     provisionCallback = listener;
   }
-  
+
+  @Override
   public void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
     providerBinding =
         injector.getBindingOrThrow(providerKey, errors, JitLimitation.NEW_OR_EXISTING_JIT);
   }
 
-  public T get(Errors errors, InternalContext context, Dependency dependency, boolean linked)
-      throws ErrorsException {
-    checkState(providerBinding != null, "not initialized");
-    
-    context.pushState(providerKey, providerBinding.getSource());
+  @Override
+  public T get(InternalContext context, Dependency<?> dependency, boolean linked)
+      throws InternalProvisionException {
+    BindingImpl<? extends Provider<T>> localProviderBinding = providerBinding;
+    if (localProviderBinding == null) {
+      throw new IllegalStateException("not initialized");
+    }
+    Key<? extends Provider<T>> localProviderKey = providerKey;
+    context.pushState(localProviderKey, localProviderBinding.getSource());
+
     try {
-      errors = errors.withSource(providerKey);
-      Provider<? extends T> provider = providerBinding.getInternalFactory().get(
-          errors, context, dependency, true);
-      return circularGet(provider, errors, context, dependency, provisionCallback);
-    } finally {
-      context.popState();
+      Provider<? extends T> provider =
+          localProviderBinding.getInternalFactory().get(context, dependency, true);
+      return circularGet(provider, context, dependency, provisionCallback);
+    } catch (InternalProvisionException ipe) {
+      throw ipe.addSource(localProviderKey);
+      } finally {
+        context.popState();
+
     }
   }
-  
+
   @Override
-  protected T provision(javax.inject.Provider<? extends T> provider, Errors errors,
-      Dependency<?> dependency, ConstructionContext<T> constructionContext)
-      throws ErrorsException {
+  protected T provision(
+      javax.inject.Provider<? extends T> provider,
+      Dependency<?> dependency,
+      ConstructionContext<T> constructionContext)
+      throws InternalProvisionException {
     try {
-      Object o = super.provision(provider, errors, dependency, constructionContext);
+      Object o = super.provision(provider, dependency, constructionContext);
       if (o != null && !rawType.isInstance(o)) {
-        throw errors.subtypeNotProvided(providerType, rawType).toException();
+        throw InternalProvisionException.subtypeNotProvided(providerType, rawType);
       }
       @SuppressWarnings("unchecked") // protected by isInstance() check above
       T t = (T) o;
       return t;
     } catch (RuntimeException e) {
-      throw errors.errorInProvider(e).toException();
+      throw InternalProvisionException.errorInProvider(e).addSource(source);
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
index f254b41..8db5a3e 100644
--- a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
+++ b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,7 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
@@ -28,17 +29,19 @@
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderWithExtensionVisitor;
 import com.google.inject.util.Providers;
-
 import java.util.Set;
 
-final class ProviderInstanceBindingImpl<T> extends BindingImpl<T>
-    implements ProviderInstanceBinding<T> {
+class ProviderInstanceBindingImpl<T> extends BindingImpl<T> implements ProviderInstanceBinding<T> {
 
   final javax.inject.Provider<? extends T> providerInstance;
   final ImmutableSet<InjectionPoint> injectionPoints;
 
-  public ProviderInstanceBindingImpl(InjectorImpl injector, Key<T> key,
-      Object source, InternalFactory<? extends T> internalFactory, Scoping scoping,
+  public ProviderInstanceBindingImpl(
+      InjectorImpl injector,
+      Key<T> key,
+      Object source,
+      InternalFactory<? extends T> internalFactory,
+      Scoping scoping,
       javax.inject.Provider<? extends T> providerInstance,
       Set<InjectionPoint> injectionPoints) {
     super(injector, key, source, internalFactory, scoping);
@@ -46,16 +49,21 @@
     this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
   }
 
-  public ProviderInstanceBindingImpl(Object source, Key<T> key, Scoping scoping,
-      Set<InjectionPoint> injectionPoints, javax.inject.Provider<? extends T> providerInstance) {
+  public ProviderInstanceBindingImpl(
+      Object source,
+      Key<T> key,
+      Scoping scoping,
+      Set<InjectionPoint> injectionPoints,
+      javax.inject.Provider<? extends T> providerInstance) {
     super(source, key, scoping);
     this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
     this.providerInstance = providerInstance;
   }
 
+  @Override
   @SuppressWarnings("unchecked") // the extension type is always consistent with the provider type
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
-    if(providerInstance instanceof ProviderWithExtensionVisitor) {
+    if (providerInstance instanceof ProviderWithExtensionVisitor) {
       return ((ProviderWithExtensionVisitor<? extends T>) providerInstance)
           .acceptExtensionVisitor(visitor, this);
     } else {
@@ -66,39 +74,46 @@
   public Provider<? extends T> getProviderInstance() {
     return Providers.guicify(providerInstance);
   }
-  
+
+  @Override
   public javax.inject.Provider<? extends T> getUserSuppliedProvider() {
     return providerInstance;
   }
 
+  @Override
   public Set<InjectionPoint> getInjectionPoints() {
     return injectionPoints;
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return providerInstance instanceof HasDependencies
         ? ImmutableSet.copyOf(((HasDependencies) providerInstance).getDependencies())
         : Dependency.forInjectionPoints(injectionPoints);
   }
 
+  @Override
   public BindingImpl<T> withScoping(Scoping scoping) {
     return new ProviderInstanceBindingImpl<T>(
         getSource(), getKey(), scoping, injectionPoints, providerInstance);
   }
 
+  @Override
   public BindingImpl<T> withKey(Key<T> key) {
     return new ProviderInstanceBindingImpl<T>(
         getSource(), key, getScoping(), injectionPoints, providerInstance);
   }
 
+  @Override
   public void applyTo(Binder binder) {
-    getScoping().applyTo(
-        binder.withSource(getSource()).bind(getKey()).toProvider(getUserSuppliedProvider()));
+    getScoping()
+        .applyTo(
+            binder.withSource(getSource()).bind(getKey()).toProvider(getUserSuppliedProvider()));
   }
 
   @Override
   public String toString() {
-    return Objects.toStringHelper(ProviderInstanceBinding.class)
+    return MoreObjects.toStringHelper(ProviderInstanceBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .add("scope", getScoping())
@@ -108,11 +123,11 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof ProviderInstanceBindingImpl) {
-      ProviderInstanceBindingImpl<?> o = (ProviderInstanceBindingImpl<?>)obj;
+    if (obj instanceof ProviderInstanceBindingImpl) {
+      ProviderInstanceBindingImpl<?> o = (ProviderInstanceBindingImpl<?>) obj;
       return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping())
-        && Objects.equal(providerInstance, o.providerInstance);
+          && getScoping().equals(o.getScoping())
+          && Objects.equal(providerInstance, o.providerInstance);
     } else {
       return false;
     }
diff --git a/core/src/com/google/inject/internal/ProviderInternalFactory.java b/core/src/com/google/inject/internal/ProviderInternalFactory.java
index 8574535..0cd6fc2 100644
--- a/core/src/com/google/inject/internal/ProviderInternalFactory.java
+++ b/core/src/com/google/inject/internal/ProviderInternalFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,57 +14,58 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.internal;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
 import com.google.inject.spi.Dependency;
-
 import javax.inject.Provider;
 
 /**
- * Base class for InternalFactories that are used by Providers, to handle
- * circular dependencies.
+ * Base class for InternalFactories that are used by Providers, to handle circular dependencies.
  *
  * @author sameb@google.com (Sam Berlin)
  */
 abstract class ProviderInternalFactory<T> implements InternalFactory<T> {
-  
+
   protected final Object source;
-  
+
   ProviderInternalFactory(Object source) {
     this.source = checkNotNull(source, "source");
   }
-  
-  protected T circularGet(final Provider<? extends T> provider, final Errors errors,
-      InternalContext context, final Dependency<?> dependency,
-      ProvisionListenerStackCallback<T> provisionCallback)
-      throws ErrorsException {    
+
+  protected T circularGet(
+      final Provider<? extends T> provider,
+      InternalContext context,
+      final Dependency<?> dependency,
+      /* @Nullable */ ProvisionListenerStackCallback<T> provisionCallback)
+      throws InternalProvisionException {
     final ConstructionContext<T> constructionContext = context.getConstructionContext(this);
 
     // We have a circular reference between constructors. Return a proxy.
     if (constructionContext.isConstructing()) {
-        Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType();
-        // TODO: if we can't proxy this object, can we proxy the other object?
-        @SuppressWarnings("unchecked")
-        T proxyType = (T) constructionContext.createProxy(
-            errors, context.getInjectorOptions(), expectedType);
-        return proxyType;
+      Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType();
+      // TODO: if we can't proxy this object, can we proxy the other object?
+      @SuppressWarnings("unchecked")
+      T proxyType = (T) constructionContext.createProxy(context.getInjectorOptions(), expectedType);
+      return proxyType;
     }
 
     // Optimization: Don't go through the callback stack if no one's listening.
     constructionContext.startConstruction();
     try {
-      if (!provisionCallback.hasListeners()) {
-        return provision(provider, errors, dependency, constructionContext);
+      if (provisionCallback == null) {
+        return provision(provider, dependency, constructionContext);
       } else {
-        return provisionCallback.provision(errors, context, new ProvisionCallback<T>() {
-          public T call() throws ErrorsException {
-            return provision(provider, errors, dependency, constructionContext);
-          }
-        });
+        return provisionCallback.provision(
+            context,
+            new ProvisionCallback<T>() {
+              @Override
+              public T call() throws InternalProvisionException {
+                return provision(provider, dependency, constructionContext);
+              }
+            });
       }
     } finally {
       constructionContext.removeCurrentReference();
@@ -73,12 +74,18 @@
   }
 
   /**
-   * Provisions a new instance. Subclasses should override this to catch
-   * exceptions & rethrow as ErrorsExceptions.
+   * Provisions a new instance. Subclasses should override this to catch exceptions & rethrow as
+   * ErrorsExceptions.
    */
-  protected T provision(Provider<? extends T> provider, Errors errors, Dependency<?> dependency,
-      ConstructionContext<T> constructionContext) throws ErrorsException {
-    T t = errors.checkForNull(provider.get(), source, dependency);
+  protected T provision(
+      Provider<? extends T> provider,
+      Dependency<?> dependency,
+      ConstructionContext<T> constructionContext)
+      throws InternalProvisionException {
+    T t = provider.get();
+    if (t == null && !dependency.isNullable()) {
+      InternalProvisionException.onNullInjectedIntoNonNullableDependency(source, dependency);
+    }
     constructionContext.setProxyDelegates(t);
     return t;
   }
diff --git a/core/src/com/google/inject/internal/ProviderMethod.java b/core/src/com/google/inject/internal/ProviderMethod.java
index beaf406..0723252 100644
--- a/core/src/com/google/inject/internal/ProviderMethod.java
+++ b/core/src/com/google/inject/internal/ProviderMethod.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,15 +17,13 @@
 package com.google.inject.internal;
 
 import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
 import com.google.inject.Exposed;
 import com.google.inject.Key;
 import com.google.inject.PrivateBinder;
-import com.google.inject.Provider;
 import com.google.inject.Provides;
-import com.google.inject.internal.BytecodeGen.Visibility;
+import com.google.inject.internal.InternalProviderInstanceBindingImpl.InitializationTiming;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.Dependency;
@@ -34,12 +32,10 @@
 import com.google.inject.spi.ProviderWithExtensionVisitor;
 import com.google.inject.spi.ProvidesMethodBinding;
 import com.google.inject.spi.ProvidesMethodTargetVisitor;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -47,50 +43,47 @@
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
-public abstract class ProviderMethod<T> implements ProviderWithExtensionVisitor<T>, HasDependencies,
-    ProvidesMethodBinding<T> {
+public abstract class ProviderMethod<T> extends InternalProviderInstanceBindingImpl.CyclicFactory<T>
+    implements HasDependencies, ProvidesMethodBinding<T>, ProviderWithExtensionVisitor<T> {
 
   /**
    * Creates a {@link ProviderMethod}.
    *
-   * <p>Unless {@code skipFastClassGeneration} is set, this will use
-   * {@link net.sf.cglib.reflect.FastClass} to invoke the actual method, since it is significantly
-   * faster. However, this will fail if the method is {@code private} or {@code protected}, since
-   * fastclass is subject to java access policies.
+   * <p>Unless {@code skipFastClassGeneration} is set, this will use {@link
+   * net.sf.cglib.reflect.FastClass} to invoke the actual method, since it is significantly faster.
+   * However, this will fail if the method is {@code private} or {@code protected}, since fastclass
+   * is subject to java access policies.
    */
-  static <T> ProviderMethod<T> create(Key<T> key, Method method, Object instance,
-      ImmutableSet<Dependency<?>> dependencies, List<Provider<?>> parameterProviders,
-      Class<? extends Annotation> scopeAnnotation, boolean skipFastClassGeneration,
+  static <T> ProviderMethod<T> create(
+      Key<T> key,
+      Method method,
+      Object instance,
+      ImmutableSet<Dependency<?>> dependencies,
+      Class<? extends Annotation> scopeAnnotation,
+      boolean skipFastClassGeneration,
       Annotation annotation) {
     int modifiers = method.getModifiers();
     /*if[AOP]*/
-    if (!skipFastClassGeneration && !Modifier.isPrivate(modifiers)
-        && !Modifier.isProtected(modifiers)) {
+    if (!skipFastClassGeneration) {
       try {
-        // We use an index instead of FastMethod to save a stack frame.
-        return new FastClassProviderMethod<T>(key,
-            method,
-            instance,
-            dependencies,
-            parameterProviders,
-            scopeAnnotation,
-            annotation);
-      } catch (net.sf.cglib.core.CodeGenerationException e) {/* fall-through */}
+        net.sf.cglib.reflect.FastClass fc = BytecodeGen.newFastClassForMember(method);
+        if (fc != null) {
+          return new FastClassProviderMethod<T>(
+              key, fc, method, instance, dependencies, scopeAnnotation, annotation);
+        }
+      } catch (net.sf.cglib.core.CodeGenerationException e) {
+        /* fall-through */
+      }
     }
     /*end[AOP]*/
 
-    if (!Modifier.isPublic(modifiers) ||
-        !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
+    if (!Modifier.isPublic(modifiers)
+        || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
       method.setAccessible(true);
     }
 
-    return new ReflectionProviderMethod<T>(key,
-        method,
-        instance,
-        dependencies,
-        parameterProviders,
-        scopeAnnotation,
-        annotation);
+    return new ReflectionProviderMethod<T>(
+        key, method, instance, dependencies, scopeAnnotation, annotation);
   }
 
   protected final Object instance;
@@ -99,22 +92,30 @@
   private final Key<T> key;
   private final Class<? extends Annotation> scopeAnnotation;
   private final ImmutableSet<Dependency<?>> dependencies;
-  private final List<Provider<?>> parameterProviders;
   private final boolean exposed;
   private final Annotation annotation;
 
   /**
-   * @param method the method to invoke. It's return type must be the same type as {@code key}.
+   * Set by {@link #initialize(InjectorImpl, Errors)} so it is always available prior to injection.
    */
-  private ProviderMethod(Key<T> key, Method method, Object instance,
-      ImmutableSet<Dependency<?>> dependencies, List<Provider<?>> parameterProviders,
-      Class<? extends Annotation> scopeAnnotation, Annotation annotation) {
+  private SingleParameterInjector<?>[] parameterInjectors;
+
+  /** @param method the method to invoke. It's return type must be the same type as {@code key}. */
+  private ProviderMethod(
+      Key<T> key,
+      Method method,
+      Object instance,
+      ImmutableSet<Dependency<?>> dependencies,
+      Class<? extends Annotation> scopeAnnotation,
+      Annotation annotation) {
+    // We can be safely initialized eagerly since our bindings must exist statically and it is an
+    // error for them not to.
+    super(InitializationTiming.EAGER);
     this.key = key;
     this.scopeAnnotation = scopeAnnotation;
     this.instance = instance;
     this.dependencies = dependencies;
     this.method = method;
-    this.parameterProviders = parameterProviders;
     this.exposed = method.isAnnotationPresent(Exposed.class);
     this.annotation = annotation;
   }
@@ -133,12 +134,12 @@
   public Object getInstance() {
     return instance;
   }
-  
+
   @Override
   public Object getEnclosingInstance() {
     return instance;
   }
-  
+
   @Override
   public Annotation getAnnotation() {
     return annotation;
@@ -161,43 +162,48 @@
   }
 
   @Override
-  public T get() {
-    Object[] parameters = new Object[parameterProviders.size()];
-    for (int i = 0; i < parameters.length; i++) {
-      parameters[i] = parameterProviders.get(i).get();
-    }
+  void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+    parameterInjectors = injector.getParametersInjectors(dependencies.asList(), errors);
+  }
 
+  @Override
+  protected T doProvision(InternalContext context, Dependency<?> dependency)
+      throws InternalProvisionException {
     try {
-      @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
-      T result = (T) doProvision(parameters);
-      return result;
+      T t = doProvision(SingleParameterInjector.getAll(context, parameterInjectors));
+      if (t == null && !dependency.isNullable()) {
+        InternalProvisionException.onNullInjectedIntoNonNullableDependency(getMethod(), dependency);
+      }
+      return t;
     } catch (IllegalAccessException e) {
       throw new AssertionError(e);
-    } catch (InvocationTargetException e) {
-      throw Exceptions.rethrowCause(e);
+    } catch (InvocationTargetException userException) {
+      Throwable cause = userException.getCause() != null ? userException.getCause() : userException;
+      throw InternalProvisionException.errorInProvider(cause).addSource(getSource());
     }
   }
 
   /** Extension point for our subclasses to implement the provisioning strategy. */
-  abstract Object doProvision(Object[] parameters)
+  abstract T doProvision(Object[] parameters)
       throws IllegalAccessException, InvocationTargetException;
 
   @Override
   public Set<Dependency<?>> getDependencies() {
     return dependencies;
   }
-  
+
   @Override
   @SuppressWarnings("unchecked")
-  public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
-      ProviderInstanceBinding<? extends B> binding) {
+  public <B, V> V acceptExtensionVisitor(
+      BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding) {
     if (visitor instanceof ProvidesMethodTargetVisitor) {
-      return ((ProvidesMethodTargetVisitor<T, V>)visitor).visit(this);
+      return ((ProvidesMethodTargetVisitor<T, V>) visitor).visit(this);
     }
     return visitor.visit(binding);
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     String annotationString = annotation.toString();
     // Show @Provides w/o the com.google.inject prefix.
     if (annotation.annotationType() == Provides.class) {
@@ -208,19 +214,19 @@
     }
     return annotationString + " " + StackTraceElements.forMember(method);
   }
-  
+
   @Override
   public boolean equals(Object obj) {
     if (obj instanceof ProviderMethod) {
       ProviderMethod<?> o = (ProviderMethod<?>) obj;
       return method.equals(o.method)
-         && instance.equals(o.instance)
-         && annotation.equals(o.annotation);
+          && instance.equals(o.instance)
+          && annotation.equals(o.annotation);
     } else {
       return false;
     }
   }
-  
+
   @Override
   public int hashCode() {
     // Avoid calling hashCode on 'instance', which is a user-object
@@ -238,65 +244,46 @@
     final net.sf.cglib.reflect.FastClass fastClass;
     final int methodIndex;
 
-    FastClassProviderMethod(Key<T> key,
+    FastClassProviderMethod(
+        Key<T> key,
+        net.sf.cglib.reflect.FastClass fc,
         Method method,
         Object instance,
         ImmutableSet<Dependency<?>> dependencies,
-        List<Provider<?>> parameterProviders,
         Class<? extends Annotation> scopeAnnotation,
         Annotation annotation) {
-      super(key,
-          method,
-          instance,
-          dependencies,
-          parameterProviders,
-          scopeAnnotation,
-          annotation);
-      // We need to generate a FastClass for the method's class, not the object's class.
-      this.fastClass =
-          BytecodeGen.newFastClass(method.getDeclaringClass(), Visibility.forMember(method));
-      // Use the Signature overload of getIndex because it properly uses return types to identify
-      // particular methods.  This is normally irrelevant, except in the case of covariant overrides
-      // which java implements with a compiler generated bridge method to implement the override.
-      this.methodIndex = fastClass.getIndex(
-          new net.sf.cglib.core.Signature(
-              method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
-      Preconditions.checkArgument(this.methodIndex >= 0, 
-          "Could not find method %s in fast class for class %s", 
-          method, 
-          method.getDeclaringClass());
+      super(key, method, instance, dependencies, scopeAnnotation, annotation);
+      this.fastClass = fc;
+      this.methodIndex = fc.getMethod(method).getIndex();
     }
 
-    @Override public Object doProvision(Object[] parameters)
+    @SuppressWarnings("unchecked")
+    @Override
+    public T doProvision(Object[] parameters)
         throws IllegalAccessException, InvocationTargetException {
-      return fastClass.invoke(methodIndex, instance, parameters);
+      return (T) fastClass.invoke(methodIndex, instance, parameters);
     }
   }
   /*end[AOP]*/
 
   /**
-   * A {@link ProviderMethod} implementation that invokes the method using normal java reflection. 
+   * A {@link ProviderMethod} implementation that invokes the method using normal java reflection.
    */
   private static final class ReflectionProviderMethod<T> extends ProviderMethod<T> {
-    ReflectionProviderMethod(Key<T> key,
+    ReflectionProviderMethod(
+        Key<T> key,
         Method method,
         Object instance,
         ImmutableSet<Dependency<?>> dependencies,
-        List<Provider<?>> parameterProviders,
         Class<? extends Annotation> scopeAnnotation,
         Annotation annotation) {
-      super(key,
-          method,
-          instance,
-          dependencies,
-          parameterProviders,
-          scopeAnnotation,
-          annotation);
+      super(key, method, instance, dependencies, scopeAnnotation, annotation);
     }
 
-    @Override Object doProvision(Object[] parameters) throws IllegalAccessException,
-        InvocationTargetException {
-      return method.invoke(instance, parameters);
+    @SuppressWarnings("unchecked")
+    @Override
+    T doProvision(Object[] parameters) throws IllegalAccessException, InvocationTargetException {
+      return (T) method.invoke(instance, parameters);
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/ProviderMethodsModule.java b/core/src/com/google/inject/internal/ProviderMethodsModule.java
index 7682dab..a854f73 100644
--- a/core/src/com/google/inject/internal/ProviderMethodsModule.java
+++ b/core/src/com/google/inject/internal/ProviderMethodsModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,30 +18,26 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Optional;
 import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Multimap;
 import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.Module;
-import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
-import com.google.inject.spi.Dependency;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.Message;
 import com.google.inject.spi.ModuleAnnotatedMethodScanner;
 import com.google.inject.util.Modules;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Set;
 
 /**
  * Creates bindings to methods annotated with {@literal @}{@link Provides}. Use the scope and
@@ -51,61 +47,42 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public final class ProviderMethodsModule implements Module {
-
-  private static ModuleAnnotatedMethodScanner PROVIDES_BUILDER =
-      new ModuleAnnotatedMethodScanner() {
-        @Override
-        public <T> Key<T> prepareMethod(
-            Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
-          return key;
-        }
-
-        @Override
-        public Set<? extends Class<? extends Annotation>> annotationClasses() {
-          return ImmutableSet.of(Provides.class);
-        }
-      };
-
   private final Object delegate;
   private final TypeLiteral<?> typeLiteral;
   private final boolean skipFastClassGeneration;
   private final ModuleAnnotatedMethodScanner scanner;
 
-  private ProviderMethodsModule(Object delegate, boolean skipFastClassGeneration,
-      ModuleAnnotatedMethodScanner scanner) {
+  private ProviderMethodsModule(
+      Object delegate, boolean skipFastClassGeneration, ModuleAnnotatedMethodScanner scanner) {
     this.delegate = checkNotNull(delegate, "delegate");
     this.typeLiteral = TypeLiteral.get(this.delegate.getClass());
     this.skipFastClassGeneration = skipFastClassGeneration;
     this.scanner = scanner;
   }
 
-  /**
-   * Returns a module which creates bindings for provider methods from the given module.
-   */
+  /** Returns a module which creates bindings for provider methods from the given module. */
   public static Module forModule(Module module) {
-    return forObject(module, false, PROVIDES_BUILDER);
+    return forObject(module, false, ProvidesMethodScanner.INSTANCE);
   }
 
-  /**
-   * Returns a module which creates bindings methods in the module that match the scanner.
-   */
+  /** Returns a module which creates bindings methods in the module that match the scanner. */
   public static Module forModule(Object module, ModuleAnnotatedMethodScanner scanner) {
     return forObject(module, false, scanner);
   }
 
   /**
-   * Returns a module which creates bindings for provider methods from the given object.
-   * This is useful notably for <a href="http://code.google.com/p/google-gin/">GIN</a>
+   * Returns a module which creates bindings for provider methods from the given object. This is
+   * useful notably for <a href="http://code.google.com/p/google-gin/">GIN</a>
    *
    * <p>This will skip bytecode generation for provider methods, since it is assumed that callers
    * are only interested in Module metadata.
    */
   public static Module forObject(Object object) {
-    return forObject(object, true, PROVIDES_BUILDER);
+    return forObject(object, true, ProvidesMethodScanner.INSTANCE);
   }
 
-  private static Module forObject(Object object, boolean skipFastClassGeneration,
-      ModuleAnnotatedMethodScanner scanner) {
+  private static Module forObject(
+      Object object, boolean skipFastClassGeneration, ModuleAnnotatedMethodScanner scanner) {
     // avoid infinite recursion, since installing a module always installs itself
     if (object instanceof ProviderMethodsModule) {
       return Modules.EMPTY_MODULE;
@@ -119,91 +96,115 @@
   }
 
   @Override
-  public synchronized void configure(Binder binder) {
+  public void configure(Binder binder) {
     for (ProviderMethod<?> providerMethod : getProviderMethods(binder)) {
       providerMethod.configure(binder);
     }
   }
 
   public List<ProviderMethod<?>> getProviderMethods(Binder binder) {
-    List<ProviderMethod<?>> result = Lists.newArrayList();
-    Multimap<Signature, Method> methodsBySignature = HashMultimap.create();
+    List<ProviderMethod<?>> result = null;
+    // The highest class in the type hierarchy that contained a provider method definition.
+    Class<?> superMostClass = delegate.getClass();
     for (Class<?> c = delegate.getClass(); c != Object.class; c = c.getSuperclass()) {
       for (Method method : c.getDeclaredMethods()) {
-        // private/static methods cannot override or be overridden by other methods, so there is no
-        // point in indexing them.
-        // Skip synthetic methods and bridge methods since java will automatically generate
-        // synthetic overrides in some cases where we don't want to generate an error (e.g.
-        // increasing visibility of a subclass).
-        if (((method.getModifiers() & (Modifier.PRIVATE | Modifier.STATIC)) == 0)
-            && !method.isBridge() && !method.isSynthetic()) {
-          methodsBySignature.put(new Signature(method), method);
-        }
-        Optional<Annotation> annotation = isProvider(binder, method);
-        if (annotation.isPresent()) {
-          result.add(createProviderMethod(binder, method, annotation.get()));
+        Annotation annotation = getAnnotation(binder, method);
+        if (annotation != null) {
+          if (result == null) {
+            result = Lists.newArrayList();
+          }
+          result.add(createProviderMethod(binder, method, annotation));
+          superMostClass = c;
         }
       }
     }
-    // we have found all the providers and now need to identify if any were overridden
-    // In the worst case this will have O(n^2) in the number of @Provides methods, but that is only
-    // assuming that every method is an override, in general it should be very quick.
-    for (ProviderMethod<?> provider : result) {
-      Method method = provider.getMethod();
-      for (Method matchingSignature : methodsBySignature.get(new Signature(method))) {
-        // matching signature is in the same class or a super class, therefore method cannot be
-        // overridding it.
-        if (matchingSignature.getDeclaringClass().isAssignableFrom(method.getDeclaringClass())) {
-          continue;
+    if (result == null) {
+      // We didn't find anything
+      return ImmutableList.of();
+    }
+    // We have found some provider methods, now we need to check if any were overridden.
+    // We do this as a separate pass to avoid calculating all the signatures when there are no
+    // provides methods, or when all provides methods are defined in a single class.
+    Multimap<Signature, Method> methodsBySignature = null;
+    // We can stop scanning when we see superMostClass, since no superclass method can override
+    // a method in a subclass.  Corrollary, if superMostClass == delegate.getClass(), there can be
+    // no overrides of a provides method.
+    for (Class<?> c = delegate.getClass(); c != superMostClass; c = c.getSuperclass()) {
+      for (Method method : c.getDeclaredMethods()) {
+        if (((method.getModifiers() & (Modifier.PRIVATE | Modifier.STATIC)) == 0)
+            && !method.isBridge()
+            && !method.isSynthetic()) {
+          if (methodsBySignature == null) {
+            methodsBySignature = HashMultimap.create();
+          }
+          methodsBySignature.put(new Signature(typeLiteral, method), method);
         }
-        // now we know matching signature is in a subtype of method.getDeclaringClass()
-        if (overrides(matchingSignature, method)) {
-          String annotationString = provider.getAnnotation().annotationType() == Provides.class
-              ? "@Provides" : "@" + provider.getAnnotation().annotationType().getCanonicalName();
-          binder.addError(
-              "Overriding " + annotationString + " methods is not allowed."
-                  + "\n\t" + annotationString + " method: %s\n\toverridden by: %s",
-              method,
-              matchingSignature);
-          break;
+      }
+    }
+    if (methodsBySignature != null) {
+      // we have found all the signatures and now need to identify if any were overridden
+      // In the worst case this will have O(n^2) in the number of @Provides methods, but that is
+      // only assuming that every method is an override, in general it should be very quick.
+      for (ProviderMethod<?> provider : result) {
+        Method method = provider.getMethod();
+        for (Method matchingSignature :
+            methodsBySignature.get(new Signature(typeLiteral, method))) {
+          // matching signature is in the same class or a super class, therefore method cannot be
+          // overridding it.
+          if (matchingSignature.getDeclaringClass().isAssignableFrom(method.getDeclaringClass())) {
+            continue;
+          }
+          // now we know matching signature is in a subtype of method.getDeclaringClass()
+          if (overrides(matchingSignature, method)) {
+            String annotationString =
+                provider.getAnnotation().annotationType() == Provides.class
+                    ? "@Provides"
+                    : "@" + provider.getAnnotation().annotationType().getCanonicalName();
+            binder.addError(
+                "Overriding "
+                    + annotationString
+                    + " methods is not allowed."
+                    + "\n\t"
+                    + annotationString
+                    + " method: %s\n\toverridden by: %s",
+                method,
+                matchingSignature);
+            break;
+          }
         }
       }
     }
     return result;
   }
 
-  /**
-   * Returns true if the method is a provider.
-   *
-   * Synthetic bridge methods are excluded. Starting with JDK 8, javac copies annotations onto
-   * bridge methods (which always have erased signatures).
-   */
-  private Optional<Annotation> isProvider(Binder binder, Method method) {
+  /** Returns the annotation that is claimed by the scanner, or null if there is none. */
+  private Annotation getAnnotation(Binder binder, Method method) {
     if (method.isBridge() || method.isSynthetic()) {
-      return Optional.absent();
+      return null;
     }
     Annotation annotation = null;
     for (Class<? extends Annotation> annotationClass : scanner.annotationClasses()) {
       Annotation foundAnnotation = method.getAnnotation(annotationClass);
       if (foundAnnotation != null) {
         if (annotation != null) {
-          binder.addError("More than one annotation claimed by %s on method %s."
-              + " Methods can only have one annotation claimed per scanner.",
+          binder.addError(
+              "More than one annotation claimed by %s on method %s."
+                  + " Methods can only have one annotation claimed per scanner.",
               scanner, method);
-          return Optional.absent();
+          return null;
         }
         annotation = foundAnnotation;
       }
     }
-    return Optional.fromNullable(annotation);
+    return annotation;
   }
 
-  private final class Signature {
+  private static final class Signature {
     final Class<?>[] parameters;
     final String name;
     final int hashCode;
 
-    Signature(Method method) {
+    Signature(TypeLiteral<?> typeLiteral, Method method) {
       this.name = method.getName();
       // We need to 'resolve' the parameters against the actual class type in case this method uses
       // type parameters.  This is so we can detect overrides of generic superclass methods where
@@ -219,7 +220,8 @@
       this.hashCode = name.hashCode() + 31 * Arrays.hashCode(parameters);
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
       if (obj instanceof Signature) {
         Signature other = (Signature) obj;
         return other.name.equals(name) && Arrays.equals(parameters, other.parameters);
@@ -227,7 +229,8 @@
       return false;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return hashCode;
     }
   }
@@ -246,34 +249,34 @@
     return a.getDeclaringClass().getPackage().equals(b.getDeclaringClass().getPackage());
   }
 
-  private <T> ProviderMethod<T> createProviderMethod(Binder binder, Method method,
-      Annotation annotation) {
+  private <T> ProviderMethod<T> createProviderMethod(
+      Binder binder, Method method, Annotation annotation) {
     binder = binder.withSource(method);
     Errors errors = new Errors(method);
 
     // prepare the parameter providers
     InjectionPoint point = InjectionPoint.forMethod(method, typeLiteral);
-    List<Dependency<?>> dependencies = point.getDependencies();
-    List<Provider<?>> parameterProviders = Lists.newArrayList();
-    for (Dependency<?> dependency : point.getDependencies()) {
-      parameterProviders.add(binder.getProvider(dependency));
-    }
-
     @SuppressWarnings("unchecked") // Define T as the method's return type.
     TypeLiteral<T> returnType = (TypeLiteral<T>) typeLiteral.getReturnType(method);
     Key<T> key = getKey(errors, returnType, method, method.getAnnotations());
     try {
       key = scanner.prepareMethod(binder, annotation, key, point);
-    } catch(Throwable t) {
+    } catch (Throwable t) {
       binder.addError(t);
     }
-    Class<? extends Annotation> scopeAnnotation
-        = Annotations.findScopeAnnotation(errors, method.getAnnotations());
+    Class<? extends Annotation> scopeAnnotation =
+        Annotations.findScopeAnnotation(errors, method.getAnnotations());
     for (Message message : errors.getMessages()) {
       binder.addError(message);
     }
-    return ProviderMethod.create(key, method, delegate, ImmutableSet.copyOf(dependencies),
-        parameterProviders, scopeAnnotation, skipFastClassGeneration, annotation);
+    return ProviderMethod.create(
+        key,
+        method,
+        delegate,
+        ImmutableSet.copyOf(point.getDependencies()),
+        scopeAnnotation,
+        skipFastClassGeneration,
+        annotation);
   }
 
   <T> Key<T> getKey(Errors errors, TypeLiteral<T> type, Member member, Annotation[] annotations) {
@@ -281,13 +284,15 @@
     return bindingAnnotation == null ? Key.get(type) : Key.get(type, bindingAnnotation);
   }
 
-  @Override public boolean equals(Object o) {
+  @Override
+  public boolean equals(Object o) {
     return o instanceof ProviderMethodsModule
         && ((ProviderMethodsModule) o).delegate == delegate
         && ((ProviderMethodsModule) o).scanner == scanner;
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return delegate.hashCode();
   }
 }
diff --git a/core/src/com/google/inject/internal/ProviderToInternalFactoryAdapter.java b/core/src/com/google/inject/internal/ProviderToInternalFactoryAdapter.java
index 672cf25..490684d 100644
--- a/core/src/com/google/inject/internal/ProviderToInternalFactoryAdapter.java
+++ b/core/src/com/google/inject/internal/ProviderToInternalFactoryAdapter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,43 +17,42 @@
 package com.google.inject.internal;
 
 import com.google.inject.Provider;
-import com.google.inject.ProvisionException;
-import com.google.inject.spi.Dependency;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 final class ProviderToInternalFactoryAdapter<T> implements Provider<T> {
 
   private final InjectorImpl injector;
   private final InternalFactory<? extends T> internalFactory;
 
-  public ProviderToInternalFactoryAdapter(InjectorImpl injector,
-      InternalFactory<? extends T> internalFactory) {
+  public ProviderToInternalFactoryAdapter(
+      InjectorImpl injector, InternalFactory<? extends T> internalFactory) {
     this.injector = injector;
     this.internalFactory = internalFactory;
   }
 
+  @Override
   public T get() {
-    final Errors errors = new Errors();
+    InternalContext context = injector.enterContext();
     try {
-      T t = injector.callInContext(new ContextualCallable<T>() {
-        public T call(InternalContext context) throws ErrorsException {
-          Dependency dependency = context.getDependency();
-          // Always pretend that we are a linked binding, to support
-          // scoping implicit bindings.  If we are not actually a linked
-          // binding, we'll fail properly elsewhere in the chain.
-          return internalFactory.get(errors, context, dependency, true);
-        }
-      });
-      errors.throwIfNewErrors(0);
+      // Always pretend that we are a linked binding, to support
+      // scoping implicit bindings.  If we are not actually a linked
+      // binding, we'll fail properly elsewhere in the chain.
+      T t = internalFactory.get(context, context.getDependency(), true);
       return t;
-    } catch (ErrorsException e) {
-      throw new ProvisionException(errors.merge(e.getErrors()).getMessages());
+    } catch (InternalProvisionException e) {
+      throw e.toProvisionException();
+    } finally {
+      context.close();
     }
   }
 
-  @Override public String toString() {
+  /** Exposed for SingletonScope. */
+  InjectorImpl getInjector() {
+    return injector;
+  }
+
+  @Override
+  public String toString() {
     return internalFactory.toString();
   }
 }
diff --git a/core/src/com/google/inject/internal/ProvidesMethodScanner.java b/core/src/com/google/inject/internal/ProvidesMethodScanner.java
new file mode 100644
index 0000000..f7709b2
--- /dev/null
+++ b/core/src/com/google/inject/internal/ProvidesMethodScanner.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
+import com.google.inject.multibindings.MapKey;
+import com.google.inject.multibindings.ProvidesIntoMap;
+import com.google.inject.multibindings.ProvidesIntoOptional;
+import com.google.inject.multibindings.ProvidesIntoSet;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.ModuleAnnotatedMethodScanner;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+/**
+ * A {@link ModuleAnnotatedMethodScanner} that handles the {@Provides}, {@link ProvidesIntoSet},
+ * {@link ProvidesIntoMap} and {@link ProvidesIntoOptional} annotations.
+ *
+ * <p>This is the default scanner used by ProviderMethodsModule and handles all the built in
+ * annotations.
+ */
+final class ProvidesMethodScanner extends ModuleAnnotatedMethodScanner {
+  static final ProvidesMethodScanner INSTANCE = new ProvidesMethodScanner();
+  private static final ImmutableSet<Class<? extends Annotation>> ANNOTATIONS =
+      ImmutableSet.of(
+          Provides.class, ProvidesIntoSet.class, ProvidesIntoMap.class, ProvidesIntoOptional.class);
+
+  private ProvidesMethodScanner() {}
+
+  @Override
+  public Set<? extends Class<? extends Annotation>> annotationClasses() {
+    return ANNOTATIONS;
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"}) // mapKey doesn't know its key type
+  @Override
+  public <T> Key<T> prepareMethod(
+      Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
+    Method method = (Method) injectionPoint.getMember();
+    AnnotationOrError mapKey = findMapKeyAnnotation(binder, method);
+    if (annotation instanceof Provides) {
+      if (mapKey.annotation != null) {
+        binder.addError("Found a MapKey annotation on non map binding at %s.", method);
+      }
+      // no key rewriting for plain old @Provides
+      return key;
+    }
+    if (annotation instanceof ProvidesIntoSet) {
+      if (mapKey.annotation != null) {
+        binder.addError("Found a MapKey annotation on non map binding at %s.", method);
+      }
+      return RealMultibinder.newRealSetBinder(binder, key).getKeyForNewItem();
+    } else if (annotation instanceof ProvidesIntoMap) {
+      if (mapKey.error) {
+        // Already failed on the MapKey, don't bother doing more work.
+        return key;
+      }
+      if (mapKey.annotation == null) {
+        // If no MapKey, make an error and abort.
+        binder.addError("No MapKey found for map binding at %s.", method);
+        return key;
+      }
+      TypeAndValue typeAndValue = typeAndValueOfMapKey(mapKey.annotation);
+      return RealMapBinder.newRealMapBinder(binder, typeAndValue.type, key)
+          .getKeyForNewValue(typeAndValue.value);
+    } else if (annotation instanceof ProvidesIntoOptional) {
+      if (mapKey.annotation != null) {
+        binder.addError("Found a MapKey annotation on non map binding at %s.", method);
+      }
+      switch (((ProvidesIntoOptional) annotation).value()) {
+        case DEFAULT:
+          return RealOptionalBinder.newRealOptionalBinder(binder, key).getKeyForDefaultBinding();
+        case ACTUAL:
+          return RealOptionalBinder.newRealOptionalBinder(binder, key).getKeyForActualBinding();
+      }
+    }
+    throw new IllegalStateException("Invalid annotation: " + annotation);
+  }
+
+  private static class AnnotationOrError {
+    final Annotation annotation;
+    final boolean error;
+
+    AnnotationOrError(Annotation annotation, boolean error) {
+      this.annotation = annotation;
+      this.error = error;
+    }
+
+    static AnnotationOrError forPossiblyNullAnnotation(Annotation annotation) {
+      return new AnnotationOrError(annotation, false);
+    }
+
+    static AnnotationOrError forError() {
+      return new AnnotationOrError(null, true);
+    }
+  }
+
+  private static AnnotationOrError findMapKeyAnnotation(Binder binder, Method method) {
+    Annotation foundAnnotation = null;
+    for (Annotation annotation : method.getAnnotations()) {
+      MapKey mapKey = annotation.annotationType().getAnnotation(MapKey.class);
+      if (mapKey != null) {
+        if (foundAnnotation != null) {
+          binder.addError("Found more than one MapKey annotations on %s.", method);
+          return AnnotationOrError.forError();
+        }
+        if (mapKey.unwrapValue()) {
+          try {
+            // validate there's a declared method called "value"
+            Method valueMethod = annotation.annotationType().getDeclaredMethod("value");
+            if (valueMethod.getReturnType().isArray()) {
+              binder.addError(
+                  "Array types are not allowed in a MapKey with unwrapValue=true: %s",
+                  annotation.annotationType());
+              return AnnotationOrError.forError();
+            }
+          } catch (NoSuchMethodException invalid) {
+            binder.addError(
+                "No 'value' method in MapKey with unwrapValue=true: %s",
+                annotation.annotationType());
+            return AnnotationOrError.forError();
+          }
+        }
+        foundAnnotation = annotation;
+      }
+    }
+    return AnnotationOrError.forPossiblyNullAnnotation(foundAnnotation);
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  static TypeAndValue<?> typeAndValueOfMapKey(Annotation mapKeyAnnotation) {
+    if (!mapKeyAnnotation.annotationType().getAnnotation(MapKey.class).unwrapValue()) {
+      return new TypeAndValue(TypeLiteral.get(mapKeyAnnotation.annotationType()), mapKeyAnnotation);
+    } else {
+      try {
+        Method valueMethod = mapKeyAnnotation.annotationType().getDeclaredMethod("value");
+        valueMethod.setAccessible(true);
+        TypeLiteral<?> returnType =
+            TypeLiteral.get(mapKeyAnnotation.annotationType()).getReturnType(valueMethod);
+        return new TypeAndValue(returnType, valueMethod.invoke(mapKeyAnnotation));
+      } catch (NoSuchMethodException e) {
+        throw new IllegalStateException(e);
+      } catch (SecurityException e) {
+        throw new IllegalStateException(e);
+      } catch (IllegalAccessException e) {
+        throw new IllegalStateException(e);
+      } catch (InvocationTargetException e) {
+        throw new IllegalStateException(e);
+      }
+    }
+  }
+
+  private static class TypeAndValue<T> {
+    final TypeLiteral<T> type;
+    final T value;
+
+    TypeAndValue(TypeLiteral<T> type, T value) {
+      this.type = type;
+      this.value = value;
+    }
+  }
+}
diff --git a/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java b/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
index 1074628..0e000dd 100644
--- a/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
+++ b/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,9 +28,7 @@
 import com.google.inject.Stage;
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.spi.ProvisionListenerBinding;
-
 import java.util.List;
-import java.util.Set;
 import java.util.logging.Logger;
 
 /**
@@ -42,51 +40,57 @@
 
   // TODO(sameb): Consider exposing this in the API somehow?  Maybe?
   // Lots of code often want to skip over the internal stuffs.
-  private static final Set<Key<?>> INTERNAL_BINDINGS =
+  private static final ImmutableSet<Key<?>> INTERNAL_BINDINGS =
       ImmutableSet.of(Key.get(Injector.class), Key.get(Stage.class), Key.get(Logger.class));
-  
+
   private final ImmutableList<ProvisionListenerBinding> listenerBindings;
 
-  private final LoadingCache<KeyBinding, ProvisionListenerStackCallback<?>> cache
-      = CacheBuilder.newBuilder().build(
-          new CacheLoader<KeyBinding, ProvisionListenerStackCallback<?>>() {
-            public ProvisionListenerStackCallback<?> load(KeyBinding key) {
-              return create(key.binding);
-            }
-          });
+  private final LoadingCache<KeyBinding, ProvisionListenerStackCallback<?>> cache =
+      CacheBuilder.newBuilder()
+          .build(
+              new CacheLoader<KeyBinding, ProvisionListenerStackCallback<?>>() {
+                @Override
+                public ProvisionListenerStackCallback<?> load(KeyBinding key) {
+                  return create(key.binding);
+                }
+              });
 
   ProvisionListenerCallbackStore(List<ProvisionListenerBinding> listenerBindings) {
     this.listenerBindings = ImmutableList.copyOf(listenerBindings);
   }
 
-  /** Returns a new {@link ProvisionListenerStackCallback} for the key.
+  /**
+   * Returns a new {@link ProvisionListenerStackCallback} for the key or {@code null} if there are
+   * no listeners
    */
-  @SuppressWarnings("unchecked") // the ProvisionListenerStackCallback type always agrees with the passed type
+  @SuppressWarnings(
+      "unchecked") // the ProvisionListenerStackCallback type always agrees with the passed type
   public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
     // Never notify any listeners for internal bindings.
     if (!INTERNAL_BINDINGS.contains(binding.getKey())) {
-      return (ProvisionListenerStackCallback<T>) cache.getUnchecked(
-          new KeyBinding(binding.getKey(), binding));
+      ProvisionListenerStackCallback<T> callback =
+          (ProvisionListenerStackCallback<T>)
+              cache.getUnchecked(new KeyBinding(binding.getKey(), binding));
+      return callback.hasListeners() ? callback : null;
     }
-    return ProvisionListenerStackCallback.emptyListener();
+    return null;
   }
 
   /**
-   * Purges a key from the cache. Use this only if the type is not actually valid for
-   * binding and needs to be purged. (See issue 319 and
+   * Purges a key from the cache. Use this only if the type is not actually valid for binding and
+   * needs to be purged. (See issue 319 and
    * ImplicitBindingTest#testCircularJitBindingsLeaveNoResidue and
    * #testInstancesRequestingProvidersForThemselvesWithChildInjectors for examples of when this is
    * necessary.)
-   * 
-   * Returns true if the type was stored in the cache, false otherwise.
+   *
+   * <p>Returns true if the type was stored in the cache, false otherwise.
    */
   boolean remove(Binding<?> type) {
     return cache.asMap().remove(type) != null;
   }
 
   /**
-   * Creates a new {@link ProvisionListenerStackCallback} with the correct listeners
-   * for the key.
+   * Creates a new {@link ProvisionListenerStackCallback} with the correct listeners for the key.
    */
   private <T> ProvisionListenerStackCallback<T> create(Binding<T> binding) {
     List<ProvisionListener> listeners = null;
@@ -105,21 +109,22 @@
     }
     return new ProvisionListenerStackCallback<T>(binding, listeners);
   }
-  
+
   /** A struct that holds key & binding but uses just key for equality/hashcode. */
   private static class KeyBinding {
     final Key<?> key;
     final Binding<?> binding;
-    
+
     KeyBinding(Key<?> key, Binding<?> binding) {
       this.key = key;
       this.binding = binding;
     }
-    
+
     @Override
     public boolean equals(Object obj) {
-      return obj instanceof KeyBinding && key.equals(((KeyBinding)obj).key);
+      return obj instanceof KeyBinding && key.equals(((KeyBinding) obj).key);
     }
+
     @Override
     public int hashCode() {
       return key.hashCode();
diff --git a/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java b/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
index f72da25..01a3d2d 100644
--- a/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
+++ b/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,10 +19,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
 import com.google.inject.Binding;
-import com.google.inject.ProvisionException;
-import com.google.inject.spi.DependencyAndSource;
 import com.google.inject.spi.ProvisionListener;
-
 import java.util.List;
 import java.util.Set;
 
@@ -32,15 +29,16 @@
  * @author sameb@google.com (Sam Berlin)
  */
 final class ProvisionListenerStackCallback<T> {
-  
-  private static final ProvisionListener EMPTY_LISTENER[] = new ProvisionListener[0];
-  @SuppressWarnings("rawtypes")
+
+  private static final ProvisionListener[] EMPTY_LISTENER = new ProvisionListener[0];
+
+  @SuppressWarnings({"rawtypes", "unchecked"})
   private static final ProvisionListenerStackCallback<?> EMPTY_CALLBACK =
       new ProvisionListenerStackCallback(null /* unused, so ok */, ImmutableList.of());
 
   private final ProvisionListener[] listeners;
   private final Binding<T> binding;
-  
+
   @SuppressWarnings("unchecked")
   public static <T> ProvisionListenerStackCallback<T> emptyListener() {
     return (ProvisionListenerStackCallback<T>) EMPTY_CALLBACK;
@@ -55,30 +53,32 @@
       this.listeners = deDuplicated.toArray(new ProvisionListener[deDuplicated.size()]);
     }
   }
-  
+
   public boolean hasListeners() {
     return listeners.length > 0;
   }
 
-  public T provision(Errors errors, InternalContext context, ProvisionCallback<T> callable)
-      throws ErrorsException {
-    Provision provision = new Provision(errors, context, callable);
+  public T provision(InternalContext context, ProvisionCallback<T> callable)
+      throws InternalProvisionException {
+    Provision provision = new Provision(context, callable);
     RuntimeException caught = null;
     try {
       provision.provision();
-    } catch(RuntimeException t) {
+    } catch (RuntimeException t) {
       caught = t;
     }
-    
+
     if (provision.exceptionDuringProvision != null) {
       throw provision.exceptionDuringProvision;
     } else if (caught != null) {
-      Object listener = provision.erredListener != null ?
-          provision.erredListener.getClass() : "(unknown)";
-      throw errors
-          .errorInUserCode(caught, "Error notifying ProvisionListener %s of %s.%n"
-              + " Reason: %s", listener, binding.getKey(), caught)
-          .toException();
+      Object listener =
+          provision.erredListener != null ? provision.erredListener.getClass() : "(unknown)";
+      throw InternalProvisionException.errorInUserCode(
+          caught,
+          "Error notifying ProvisionListener %s of %s.%n Reason: %s",
+          listener,
+          binding.getKey(),
+          caught);
     } else {
       return provision.result;
     }
@@ -86,25 +86,22 @@
 
   // TODO(sameb): Can this be more InternalFactory-like?
   public interface ProvisionCallback<T> {
-    public T call() throws ErrorsException;
+    public T call() throws InternalProvisionException;
   }
 
   private class Provision extends ProvisionListener.ProvisionInvocation<T> {
 
-    final Errors errors;
-    final int numErrorsBefore;
     final InternalContext context;
+
     final ProvisionCallback<T> callable;
     int index = -1;
     T result;
-    ErrorsException exceptionDuringProvision;
+    InternalProvisionException exceptionDuringProvision;
     ProvisionListener erredListener;
 
-    public Provision(Errors errors, InternalContext context, ProvisionCallback<T> callable) {
+    public Provision(InternalContext context, ProvisionCallback<T> callable) {
       this.callable = callable;
       this.context = context;
-      this.errors = errors;
-      this.numErrorsBefore = errors.size();
     }
 
     @Override
@@ -113,18 +110,15 @@
       if (index == listeners.length) {
         try {
           result = callable.call();
-          // Make sure we don't return the provisioned object if there were any errors
-          // injecting its field/method dependencies.
-          errors.throwIfNewErrors(numErrorsBefore);
-        } catch(ErrorsException ee) {
-          exceptionDuringProvision = ee;
-          throw new ProvisionException(errors.merge(ee.getErrors()).getMessages());
+        } catch (InternalProvisionException ipe) {
+          exceptionDuringProvision = ipe;
+          throw ipe.toProvisionException();
         }
       } else if (index < listeners.length) {
         int currentIdx = index;
         try {
           listeners[index].onProvision(this);
-        } catch(RuntimeException re) {
+        } catch (RuntimeException re) {
           erredListener = listeners[currentIdx];
           throw re;
         }
@@ -137,7 +131,7 @@
       }
       return result;
     }
-    
+
     @Override
     public Binding<T> getBinding() {
       // TODO(sameb): Because so many places cast directly to BindingImpl & subclasses,
@@ -145,10 +139,12 @@
       // if someone calls that they'll get strange errors.
       return binding;
     }
-    
+
+    @Deprecated
     @Override
-    public List<DependencyAndSource> getDependencyChain() {
+    public List<com.google.inject.spi.DependencyAndSource> getDependencyChain() {
       return context.getDependencyChain();
     }
+
   }
 }
diff --git a/core/src/com/google/inject/internal/ProxyFactory.java b/core/src/com/google/inject/internal/ProxyFactory.java
index 13aff81..156a5c8 100644
--- a/core/src/com/google/inject/internal/ProxyFactory.java
+++ b/core/src/com/google/inject/internal/ProxyFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
 
 package com.google.inject.internal;
 
-import static com.google.inject.internal.BytecodeGen.newFastClass;
+import static com.google.inject.internal.BytecodeGen.newFastClassForMember;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -24,16 +24,6 @@
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.inject.spi.InjectionPoint;
-
-import net.sf.cglib.core.MethodWrapper;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.reflect.FastClass;
-import net.sf.cglib.reflect.FastConstructor;
-
-import org.aopalliance.intercept.MethodInterceptor;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -41,6 +31,12 @@
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import net.sf.cglib.core.MethodWrapper;
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.reflect.FastClass;
+import org.aopalliance.intercept.MethodInterceptor;
 
 /**
  * Builds a construction proxy that can participate in AOP. This class manages applying type and
@@ -49,7 +45,7 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 final class ProxyFactory<T> implements ConstructionProxyFactory<T> {
-  
+
   private static final Logger logger = Logger.getLogger(ProxyFactory.class.getName());
 
   private final InjectionPoint injectionPoint;
@@ -68,7 +64,7 @@
     this.injectionPoint = injectionPoint;
 
     @SuppressWarnings("unchecked") // the member of injectionPoint is always a Constructor<T>
-        Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
+    Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
     declaringClass = constructor.getDeclaringClass();
 
     // Find applicable aspects. Bow out if none are applicable to this class.
@@ -101,12 +97,13 @@
     for (MethodAspect methodAspect : applicableAspects) {
       for (MethodInterceptorsPair pair : methodInterceptorsPairs) {
         if (methodAspect.matches(pair.method)) {
-          if(pair.method.isSynthetic()) {
-            logger.log(Level.WARNING,
+          if (pair.method.isSynthetic()) {
+            logger.log(
+                Level.WARNING,
                 "Method [{0}] is synthetic and is being intercepted by {1}."
-              + " This could indicate a bug.  The method may be intercepted twice,"
-              + " or may not be intercepted at all.",
-                new Object[] { pair.method, methodAspect.interceptors() });
+                    + " This could indicate a bug.  The method may be intercepted twice,"
+                    + " or may not be intercepted at all.",
+                new Object[] {pair.method, methodAspect.interceptors()});
           }
           visibility = visibility.and(BytecodeGen.Visibility.forMember(pair.method));
           pair.addAll(methodAspect.interceptors());
@@ -142,18 +139,18 @@
       callbacks[i] = new InterceptorStackCallback(pair.method, deDuplicated);
     }
 
-    interceptors = interceptorsMapBuilder != null
-        ? interceptorsMapBuilder.build()
-        : ImmutableMap.<Method, List<MethodInterceptor>>of();
+    interceptors =
+        interceptorsMapBuilder != null
+            ? interceptorsMapBuilder.build()
+            : ImmutableMap.<Method, List<MethodInterceptor>>of();
   }
 
-  /**
-   * Returns the interceptors that apply to the constructed type.
-   */
+  /** Returns the interceptors that apply to the constructed type. */
   public ImmutableMap<Method, List<MethodInterceptor>> getInterceptors() {
     return interceptors;
   }
 
+  @Override
   public ConstructionProxy<T> create() throws ErrorsException {
     if (interceptors.isEmpty()) {
       return new DefaultConstructionProxyFactory<T>(injectionPoint).create();
@@ -172,10 +169,10 @@
     // Create the proxied class. We're careful to ensure that all enhancer state is not-specific
     // to this injector. Otherwise, the proxies for each injector will waste PermGen memory
     try {
-    Enhancer enhancer = BytecodeGen.newEnhancer(declaringClass, visibility);
-    enhancer.setCallbackFilter(new IndicesCallbackFilter(methods));
-    enhancer.setCallbackTypes(callbackTypes);
-    return new ProxyConstructor<T>(enhancer, injectionPoint, callbacks, interceptors);
+      Enhancer enhancer = BytecodeGen.newEnhancer(declaringClass, visibility);
+      enhancer.setCallbackFilter(new IndicesCallbackFilter(methods));
+      enhancer.setCallbackTypes(callbackTypes);
+      return new ProxyConstructor<T>(enhancer, injectionPoint, callbacks, interceptors);
     } catch (Throwable e) {
       throw new Errors().errorEnhancingClass(declaringClass, e).toException();
     }
@@ -202,10 +199,9 @@
   }
 
   /**
-   * A callback filter that maps methods to unique IDs. We define equals and
-   * hashCode without using any state related to the injector so that enhanced
-   * classes intercepting the same methods can be shared between injectors (and
-   * child injectors, etc).
+   * A callback filter that maps methods to unique IDs. We define equals and hashCode without using
+   * any state related to the injector so that enhanced classes intercepting the same methods can be
+   * shared between injectors (and child injectors, etc).
    */
   private static class IndicesCallbackFilter implements CallbackFilter {
     final Map<Object, Integer> indices;
@@ -220,63 +216,71 @@
       this.hashCode = indices.hashCode();
     }
 
+    @Override
     public int accept(Method method) {
       return indices.get(MethodWrapper.create(method));
     }
 
-    @Override public boolean equals(Object o) {
-      return o instanceof IndicesCallbackFilter &&
-          ((IndicesCallbackFilter) o).indices.equals(indices);
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof IndicesCallbackFilter
+          && ((IndicesCallbackFilter) o).indices.equals(indices);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return hashCode;
     }
   }
 
-  /**
-   * Constructs instances that participate in AOP.
-   */
+  /** Constructs instances that participate in AOP. */
   private static class ProxyConstructor<T> implements ConstructionProxy<T> {
     final Class<?> enhanced;
     final InjectionPoint injectionPoint;
     final Constructor<T> constructor;
     final Callback[] callbacks;
 
-    final FastConstructor fastConstructor;
+    final int constructorIndex;
     final ImmutableMap<Method, List<MethodInterceptor>> methodInterceptors;
+    final FastClass fastClass;
 
     @SuppressWarnings("unchecked") // the constructor promises to construct 'T's
-    ProxyConstructor(Enhancer enhancer, InjectionPoint injectionPoint, Callback[] callbacks,
+    ProxyConstructor(
+        Enhancer enhancer,
+        InjectionPoint injectionPoint,
+        Callback[] callbacks,
         ImmutableMap<Method, List<MethodInterceptor>> methodInterceptors) {
       this.enhanced = enhancer.createClass(); // this returns a cached class if possible
       this.injectionPoint = injectionPoint;
       this.constructor = (Constructor<T>) injectionPoint.getMember();
       this.callbacks = callbacks;
       this.methodInterceptors = methodInterceptors;
-
-      FastClass fastClass = newFastClass(enhanced, BytecodeGen.Visibility.forMember(constructor));
-      this.fastConstructor = fastClass.getConstructor(constructor.getParameterTypes());
+      this.fastClass = newFastClassForMember(enhanced, constructor);
+      this.constructorIndex = fastClass.getIndex(constructor.getParameterTypes());
     }
 
+    @Override
     @SuppressWarnings("unchecked") // the constructor promises to produce 'T's
     public T newInstance(Object... arguments) throws InvocationTargetException {
       Enhancer.registerCallbacks(enhanced, callbacks);
       try {
-        return (T) fastConstructor.newInstance(arguments);
+        return (T) fastClass.newInstance(constructorIndex, arguments);
       } finally {
         Enhancer.registerCallbacks(enhanced, null);
       }
     }
 
+    @Override
     public InjectionPoint getInjectionPoint() {
       return injectionPoint;
     }
 
+    @Override
     public Constructor<T> getConstructor() {
       return constructor;
     }
 
+    @Override
     public ImmutableMap<Method, List<MethodInterceptor>> getMethodInterceptors() {
       return methodInterceptors;
     }
diff --git a/core/src/com/google/inject/internal/RealElement.java b/core/src/com/google/inject/internal/RealElement.java
new file mode 100644
index 0000000..8f984a6
--- /dev/null
+++ b/core/src/com/google/inject/internal/RealElement.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import com.google.inject.internal.Element.Type;
+import java.lang.annotation.Annotation;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** An implementation of Element. */
+// TODO(cgruber): Use AutoAnnotation when available, here & wherever else is makes sense.
+class RealElement implements Element {
+  private static final AtomicInteger nextUniqueId = new AtomicInteger(1);
+
+  private final int uniqueId;
+  private final String setName;
+  private final Element.Type type;
+  private final String keyType;
+
+  RealElement(String setName, Element.Type type, String keyType) {
+    this(setName, type, keyType, nextUniqueId.incrementAndGet());
+  }
+
+  RealElement(String setName, Element.Type type, String keyType, int uniqueId) {
+    this.uniqueId = uniqueId;
+    this.setName = setName;
+    this.type = type;
+    this.keyType = keyType;
+  }
+
+  @Override
+  public String setName() {
+    return setName;
+  }
+
+  @Override
+  public int uniqueId() {
+    return uniqueId;
+  }
+
+  @Override
+  public Element.Type type() {
+    return type;
+  }
+
+  @Override
+  public String keyType() {
+    return keyType;
+  }
+
+  @Override
+  public Class<? extends Annotation> annotationType() {
+    return Element.class;
+  }
+
+  @Override
+  public String toString() {
+    return "@"
+        + Element.class.getName()
+        + "(setName="
+        + setName
+        + ",uniqueId="
+        + uniqueId
+        + ", type="
+        + type
+        + ", keyType="
+        + keyType
+        + ")";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof Element
+        && ((Element) o).setName().equals(setName())
+        && ((Element) o).uniqueId() == uniqueId()
+        && ((Element) o).type() == type()
+        && ((Element) o).keyType().equals(keyType());
+  }
+
+  @Override
+  public int hashCode() {
+    return ((127 * "setName".hashCode()) ^ setName.hashCode())
+        + ((127 * "uniqueId".hashCode()) ^ uniqueId)
+        + ((127 * "type".hashCode()) ^ type.hashCode())
+        + ((127 * "keyType".hashCode()) ^ keyType.hashCode());
+  }
+}
diff --git a/core/src/com/google/inject/internal/RealMapBinder.java b/core/src/com/google/inject/internal/RealMapBinder.java
new file mode 100644
index 0000000..1e28fb2
--- /dev/null
+++ b/core/src/com/google/inject/internal/RealMapBinder.java
@@ -0,0 +1,1344 @@
+
+package com.google.inject.internal;
+
+import static com.google.inject.internal.Element.Type.MAPBINDER;
+import static com.google.inject.internal.Errors.checkConfiguration;
+import static com.google.inject.internal.Errors.checkNotNull;
+import static com.google.inject.internal.RealMultibinder.setOf;
+import static com.google.inject.util.Types.newParameterizedType;
+import static com.google.inject.util.Types.newParameterizedTypeWithOwner;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.inject.Binder;
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.InternalProviderInstanceBindingImpl.InitializationTiming;
+import com.google.inject.multibindings.MapBinderBinding;
+import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.MultibindingsTargetVisitor;
+import com.google.inject.spi.BindingTargetVisitor;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.spi.ProviderWithExtensionVisitor;
+import com.google.inject.util.Types;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The actual mapbinder plays several roles:
+ *
+ * <p>As a MapBinder, it acts as a factory for LinkedBindingBuilders for each of the map's values.
+ * It delegates to a {@link Multibinder} of entries (keys to value providers).
+ *
+ * <p>As a Module, it installs the binding to the map itself, as well as to a corresponding map
+ * whose values are providers.
+ *
+ * <p>As a module, this implements equals() and hashcode() in order to trick Guice into executing
+ * its configure() method only once. That makes it so that multiple mapbinders can be created for
+ * the same target map, but only one is bound. Since the list of bindings is retrieved from the
+ * injector itself (and not the mapbinder), each mapbinder has access to all contributions from all
+ * equivalent mapbinders.
+ *
+ * <p>Rather than binding a single Map.Entry&lt;K, V&gt;, the map binder binds keys and values
+ * independently. This allows the values to be properly scoped.
+ */
+public final class RealMapBinder<K, V> implements Module {
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with no binding annotation.
+   */
+  public static <K, V> RealMapBinder<K, V> newMapRealBinder(
+      Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    binder = binder.skipSources(RealMapBinder.class);
+    return newRealMapBinder(
+        binder,
+        keyType,
+        valueType,
+        Key.get(mapOf(keyType, valueType)),
+        RealMultibinder.newRealSetBinder(binder, Key.get(entryOfProviderOf(keyType, valueType))));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotation}.
+   */
+  public static <K, V> RealMapBinder<K, V> newRealMapBinder(
+      Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType, Annotation annotation) {
+    binder = binder.skipSources(RealMapBinder.class);
+    return newRealMapBinder(
+        binder,
+        keyType,
+        valueType,
+        Key.get(mapOf(keyType, valueType), annotation),
+        RealMultibinder.newRealSetBinder(
+            binder, Key.get(entryOfProviderOf(keyType, valueType), annotation)));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotationType}.
+   */
+  public static <K, V> RealMapBinder<K, V> newRealMapBinder(
+      Binder binder,
+      TypeLiteral<K> keyType,
+      TypeLiteral<V> valueType,
+      Class<? extends Annotation> annotationType) {
+    binder = binder.skipSources(RealMapBinder.class);
+    return newRealMapBinder(
+        binder,
+        keyType,
+        valueType,
+        Key.get(mapOf(keyType, valueType), annotationType),
+        RealMultibinder.newRealSetBinder(
+            binder, Key.get(entryOfProviderOf(keyType, valueType), annotationType)));
+  }
+
+  @SuppressWarnings("unchecked") // a map of <K, V> is safely a Map<K, V>
+  static <K, V> TypeLiteral<Map<K, V>> mapOf(TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, V>>)
+        TypeLiteral.get(Types.mapOf(keyType.getType(), valueType.getType()));
+  }
+
+  @SuppressWarnings("unchecked") // a provider map <K, V> is safely a Map<K, Provider<V>>
+  static <K, V> TypeLiteral<Map<K, Provider<V>>> mapOfProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, Provider<V>>>)
+        TypeLiteral.get(Types.mapOf(keyType.getType(), Types.providerOf(valueType.getType())));
+  }
+
+  // provider map <K, V> is safely a Map<K, javax.inject.Provider<V>>>
+  @SuppressWarnings("unchecked")
+  static <K, V> TypeLiteral<Map<K, javax.inject.Provider<V>>> mapOfJavaxProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, javax.inject.Provider<V>>>)
+        TypeLiteral.get(
+            Types.mapOf(
+                keyType.getType(),
+                newParameterizedType(javax.inject.Provider.class, valueType.getType())));
+  }
+
+  @SuppressWarnings("unchecked") // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
+  static <K, V> TypeLiteral<Map<K, Set<Provider<V>>>> mapOfSetOfProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, Set<Provider<V>>>>)
+        TypeLiteral.get(
+            Types.mapOf(keyType.getType(), Types.setOf(Types.providerOf(valueType.getType()))));
+  }
+
+  @SuppressWarnings("unchecked") // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
+  static <K, V> TypeLiteral<Map<K, Set<javax.inject.Provider<V>>>> mapOfSetOfJavaxProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, Set<javax.inject.Provider<V>>>>)
+        TypeLiteral.get(
+            Types.mapOf(
+                keyType.getType(), Types.setOf(Types.javaxProviderOf(valueType.getType()))));
+  }
+
+  @SuppressWarnings("unchecked") // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
+  static <K, V> TypeLiteral<Map<K, Collection<Provider<V>>>> mapOfCollectionOfProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, Collection<Provider<V>>>>)
+        TypeLiteral.get(
+            Types.mapOf(
+                keyType.getType(), Types.collectionOf(Types.providerOf(valueType.getType()))));
+  }
+
+  @SuppressWarnings("unchecked") // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
+  static <K, V>
+      TypeLiteral<Map<K, Collection<javax.inject.Provider<V>>>> mapOfCollectionOfJavaxProviderOf(
+          TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map<K, Collection<javax.inject.Provider<V>>>>)
+        TypeLiteral.get(
+            Types.mapOf(
+                keyType.getType(), Types.collectionOf(Types.javaxProviderOf(valueType.getType()))));
+  }
+
+  @SuppressWarnings("unchecked") // a provider entry <K, V> is safely a Map.Entry<K, Provider<V>>
+  static <K, V> TypeLiteral<Map.Entry<K, Provider<V>>> entryOfProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map.Entry<K, Provider<V>>>)
+        TypeLiteral.get(
+            newParameterizedTypeWithOwner(
+                Map.class,
+                Map.Entry.class,
+                keyType.getType(),
+                Types.providerOf(valueType.getType())));
+  }
+
+  @SuppressWarnings("unchecked") // a provider entry <K, V> is safely a Map.Entry<K, Provider<V>>
+  static <K, V> TypeLiteral<Map.Entry<K, Provider<V>>> entryOfJavaxProviderOf(
+      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Map.Entry<K, Provider<V>>>)
+        TypeLiteral.get(
+            newParameterizedTypeWithOwner(
+                Map.class,
+                Map.Entry.class,
+                keyType.getType(),
+                Types.javaxProviderOf(valueType.getType())));
+  }
+
+  @SuppressWarnings("unchecked") // a provider entry <K, V> is safely a Map.Entry<K, Provider<V>>
+  static <K, V>
+      TypeLiteral<Set<Map.Entry<K, javax.inject.Provider<V>>>> setOfEntryOfJavaxProviderOf(
+          TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return (TypeLiteral<Set<Map.Entry<K, javax.inject.Provider<V>>>>)
+        TypeLiteral.get(Types.setOf(entryOfJavaxProviderOf(keyType, valueType).getType()));
+  }
+
+  /** Given a Key<T> will return a Key<Provider<T>> */
+  @SuppressWarnings("unchecked")
+  private static <T> Key<Provider<T>> getKeyOfProvider(Key<T> valueKey) {
+    return (Key<Provider<T>>)
+        valueKey.ofType(Types.providerOf(valueKey.getTypeLiteral().getType()));
+  }
+
+  // Note: We use valueTypeAndAnnotation effectively as a Pair<TypeLiteral, Annotation|Class>
+  // since it's an easy way to group a type and an optional annotation type or instance.
+  static <K, V> RealMapBinder<K, V> newRealMapBinder(
+      Binder binder, TypeLiteral<K> keyType, Key<V> valueTypeAndAnnotation) {
+    binder = binder.skipSources(RealMapBinder.class);
+    TypeLiteral<V> valueType = valueTypeAndAnnotation.getTypeLiteral();
+    return newRealMapBinder(
+        binder,
+        keyType,
+        valueType,
+        valueTypeAndAnnotation.ofType(mapOf(keyType, valueType)),
+        RealMultibinder.newRealSetBinder(
+            binder, valueTypeAndAnnotation.ofType(entryOfProviderOf(keyType, valueType))));
+  }
+
+  private static <K, V> RealMapBinder<K, V> newRealMapBinder(
+      Binder binder,
+      TypeLiteral<K> keyType,
+      TypeLiteral<V> valueType,
+      Key<Map<K, V>> mapKey,
+      RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder) {
+    RealMapBinder<K, V> mapBinder =
+        new RealMapBinder<K, V>(binder, keyType, valueType, mapKey, entrySetBinder);
+    binder.install(mapBinder);
+    return mapBinder;
+  }
+
+  // Until the injector initializes us, we don't know what our dependencies are,
+  // so initialize to the whole Injector.
+  private static final ImmutableSet<Dependency<?>> MODULE_DEPENDENCIES =
+      ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
+
+  private final BindingSelection<K, V> bindingSelection;
+  private final Binder binder;
+
+  private final RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder;
+
+  private RealMapBinder(
+      Binder binder,
+      TypeLiteral<K> keyType,
+      TypeLiteral<V> valueType,
+      Key<Map<K, V>> mapKey,
+      RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder) {
+    this.bindingSelection = new BindingSelection<>(keyType, valueType, mapKey, entrySetBinder);
+    this.binder = binder;
+    this.entrySetBinder = entrySetBinder;
+  }
+
+  public void permitDuplicates() {
+    checkConfiguration(!bindingSelection.isInitialized(), "MapBinder was already initialized");
+    entrySetBinder.permitDuplicates();
+    binder.install(new MultimapBinder<K, V>(bindingSelection));
+  }
+
+  /** Adds a binding to the map for the given key. */
+  Key<V> getKeyForNewValue(K key) {
+    checkNotNull(key, "key");
+    checkConfiguration(!bindingSelection.isInitialized(), "MapBinder was already initialized");
+    RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder =
+        bindingSelection.getEntrySetBinder();
+
+    Key<V> valueKey =
+        Key.get(
+            bindingSelection.getValueType(),
+            new RealElement(
+                entrySetBinder.getSetName(), MAPBINDER, bindingSelection.getKeyType().toString()));
+    entrySetBinder.addBinding().toProvider(new ProviderMapEntry<K, V>(key, valueKey));
+    return valueKey;
+  }
+
+  /**
+   * This creates two bindings. One for the {@code Map.Entry<K, Provider<V>>} and another for {@code
+   * V}.
+   */
+  public LinkedBindingBuilder<V> addBinding(K key) {
+    return binder.bind(getKeyForNewValue(key));
+  }
+
+  @Override
+  public void configure(Binder binder) {
+    checkConfiguration(!bindingSelection.isInitialized(), "MapBinder was already initialized");
+
+    // Binds a Map<K, Provider<V>>
+    RealProviderMapProvider<K, V> providerMapProvider =
+        new RealProviderMapProvider<K, V>(bindingSelection);
+    binder.bind(bindingSelection.getProviderMapKey()).toProvider(providerMapProvider);
+
+    // The map this exposes is internally an ImmutableMap, so it's OK to massage
+    // the guice Provider to javax Provider in the value (since Guice provider
+    // implements javax Provider).
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    Provider<Map<K, javax.inject.Provider<V>>> javaxProviderMapProvider =
+        (Provider) providerMapProvider;
+    binder.bind(bindingSelection.getJavaxProviderMapKey()).toProvider(javaxProviderMapProvider);
+
+    RealMapProvider<K, V> mapProvider = new RealMapProvider<>(bindingSelection);
+    binder.bind(bindingSelection.getMapKey()).toProvider(mapProvider);
+
+    // The Map.Entries are all ProviderMapEntry instances which do not allow setValue, so it is
+    // safe to massage the return type like this
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    Key<Set<Map.Entry<K, javax.inject.Provider<V>>>> massagedEntrySetProviderKey =
+        (Key) bindingSelection.getEntrySetBinder().getSetKey();
+    binder.bind(bindingSelection.getEntrySetJavaxProviderKey()).to(massagedEntrySetProviderKey);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof RealMapBinder
+        && ((RealMapBinder<?, ?>) o).bindingSelection.equals(bindingSelection);
+  }
+
+  @Override
+  public int hashCode() {
+    return bindingSelection.hashCode();
+  }
+
+  /**
+   * The BindingSelection contains some of the core state and logic for the MapBinder.
+   *
+   * <p>It lazily computes the value for keys for various permutations of Maps that are provided by
+   * this module. It also builds up maps from {@code K} to {@code Binding<V>}, which is used by all
+   * of the internal factories to actually provide the desired maps.
+   *
+   * <p>During initialization time there is only one BindingSelection. It is possible that multiple
+   * different BindingSelections are constructed. Specifically, in the case of two different modules
+   * each adding bindings to the same MapBinder. If that happens, we define the BindingSelection
+   * held by the {@link RealMapProvider} to be the authoritative one. The logic for this exists in
+   * {@link RealMultimapBinderProviderWithDependencies}. This is done to avoid confusion because the
+   * BindingSelection contains mutable state.
+   */
+  private static final class BindingSelection<K, V> {
+    private enum InitializationState {
+      UNINITIALIZED,
+      INITIALIZED,
+      HAS_ERRORS;
+    }
+
+    private final TypeLiteral<K> keyType;
+    private final TypeLiteral<V> valueType;
+    private final Key<Map<K, V>> mapKey;
+
+    // Lazily computed
+    private Key<Map<K, javax.inject.Provider<V>>> javaxProviderMapKey;
+    private Key<Map<K, Provider<V>>> providerMapKey;
+    private Key<Map<K, Set<V>>> multimapKey;
+    private Key<Map<K, Set<Provider<V>>>> providerSetMultimapKey;
+    private Key<Map<K, Set<javax.inject.Provider<V>>>> javaxProviderSetMultimapKey;
+    private Key<Map<K, Collection<Provider<V>>>> providerCollectionMultimapKey;
+    private Key<Map<K, Collection<javax.inject.Provider<V>>>> javaxProviderCollectionMultimapKey;
+    private Key<Set<Map.Entry<K, javax.inject.Provider<V>>>> entrySetJavaxProviderKey;
+
+    private final RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder;
+
+    private InitializationState initializationState;
+
+    /**
+     * These are built during initialization and used by all factories to actually provide the
+     * relevant maps. These contain all of the necessary information about the map binder.
+     */
+    private ImmutableMap<K, Binding<V>> mapBindings;
+
+    private ImmutableMap<K, Set<Binding<V>>> multimapBindings;
+    private ImmutableList<Map.Entry<K, Binding<V>>> entries;
+
+    /**
+     * Indicates if this Map permits duplicates. It is initialized during initialization by querying
+     * the injector. This is done because multiple different modules can contribute to a MapBinder,
+     * and any one could set permitDuplicates.
+     */
+    private boolean permitsDuplicates;
+
+    private BindingSelection(
+        TypeLiteral<K> keyType,
+        TypeLiteral<V> valueType,
+        Key<Map<K, V>> mapKey,
+        RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder) {
+      this.keyType = keyType;
+      this.valueType = valueType;
+      this.mapKey = mapKey;
+      this.entrySetBinder = entrySetBinder;
+      this.initializationState = InitializationState.UNINITIALIZED;
+    }
+
+    /**
+     * Will initialize internal data structures.
+     *
+     * @return {@code true} if initialization was successful, {@code false} if there were errors
+     */
+    private boolean tryInitialize(InjectorImpl injector, Errors errors) {
+      // Every one of our providers will call this method, so only execute the logic once.
+      if (initializationState != InitializationState.UNINITIALIZED) {
+        return initializationState != InitializationState.HAS_ERRORS;
+      }
+
+      // Multiple different modules can all contribute to the same MapBinder, and if any
+      // one of them permits duplicates, then the map binder as a whole will permit duplicates.
+      // Since permitDuplicates() may not have been called on this instance, we need to go
+      // to the injector to see if permitDuplicates was set.
+      permitsDuplicates = entrySetBinder.permitsDuplicates(injector);
+
+      // We now build the Map<K, Set<Binding<V>>> from the entrySetBinder.
+      // The entrySetBinder contains all of the ProviderMapEntrys, and once
+      // we have those, it's easy to iterate through them to organize them by K.
+      Map<K, ImmutableSet.Builder<Binding<V>>> bindingMultimapMutable =
+          new LinkedHashMap<K, ImmutableSet.Builder<Binding<V>>>();
+      Map<K, Binding<V>> bindingMapMutable = new LinkedHashMap<>();
+      Multimap<K, Indexer.IndexedBinding> index = HashMultimap.create();
+      Indexer indexer = new Indexer(injector);
+      Multimap<K, Binding<V>> duplicates = null;
+
+      ImmutableList.Builder<Map.Entry<K, Binding<V>>> entriesBuilder = ImmutableList.builder();
+
+      // We get all of the Bindings that were put into the entrySetBinder
+      for (Binding<Map.Entry<K, Provider<V>>> binding :
+          injector.findBindingsByType(entrySetBinder.getElementTypeLiteral())) {
+        if (entrySetBinder.containsElement(binding)) {
+
+          // Protected by findBindingByType() and the fact that all providers are added by us
+          // in addBinding(). It would theoretically be possible for someone to directly
+          // add their own binding to the entrySetBinder, but they shouldn't do that.
+          @SuppressWarnings({"unchecked", "rawtypes"})
+          ProviderInstanceBinding<ProviderMapEntry<K, V>> entryBinding =
+              (ProviderInstanceBinding) binding;
+
+          // We added all these bindings initially, so we know they are ProviderMapEntrys
+          @SuppressWarnings({"unchecked", "rawtypes"})
+          ProviderMapEntry<K, V> entry = (ProviderMapEntry) entryBinding.getUserSuppliedProvider();
+          K key = entry.getKey();
+
+          Key<V> valueKey = entry.getValueKey();
+          Binding<V> valueBinding = injector.getExistingBinding(valueKey);
+
+          // Use the indexer to de-dupe user bindings. This is needed because of the
+          // uniqueId in RealElement. The uniqueId intentionally circumvents the regular
+          // Guice deduplication, so we need to re-implement our own here, ignoring
+          // uniqueId.
+          if (index.put(key, valueBinding.acceptTargetVisitor(indexer))) {
+
+            entriesBuilder.add(Maps.immutableEntry(key, valueBinding));
+
+            Binding<V> previous = bindingMapMutable.put(key, valueBinding);
+            // Check if this is a duplicate binding
+            if (previous != null && !permitsDuplicates) {
+              if (duplicates == null) {
+                // This is linked for both keys and values to maintain order
+                duplicates = LinkedHashMultimap.create();
+              }
+
+              // We add both the previous and the current value to the duplicates map.
+              // This is because if there are three duplicates, we will only execute this code
+              // for the second and third, but we want all three values to display a helpful
+              // error message. We rely on the multimap to dedupe repeated values.
+              duplicates.put(key, previous);
+              duplicates.put(key, valueBinding);
+            }
+
+            // Don't do extra work unless we need to
+            if (permitsDuplicates) {
+              // Create a set builder for this key if it's the first time we've seen it
+              if (!bindingMultimapMutable.containsKey(key)) {
+                bindingMultimapMutable.put(key, ImmutableSet.<Binding<V>>builder());
+              }
+
+              // Add the Binding<V>
+              bindingMultimapMutable.get(key).add(valueBinding);
+            }
+          }
+        }
+      }
+
+      // It is safe to check if duplicates is non-null because if duplicates are allowed,
+      // we don't build up this data structure
+      if (duplicates != null) {
+        initializationState = InitializationState.HAS_ERRORS;
+        reportDuplicateKeysError(duplicates, errors);
+
+        return false;
+      }
+
+      // Build all of the ImmutableSet.Builders,
+      // transforming from Map<K, ImmutableSet.Builder<Binding<V>>> to
+      // ImmutableMap<K, Set<Binding<V>>>
+      ImmutableMap.Builder<K, Set<Binding<V>>> bindingsMultimapBuilder = ImmutableMap.builder();
+      for (Map.Entry<K, ImmutableSet.Builder<Binding<V>>> entry :
+          bindingMultimapMutable.entrySet()) {
+        bindingsMultimapBuilder.put(entry.getKey(), entry.getValue().build());
+      }
+      mapBindings = ImmutableMap.copyOf(bindingMapMutable);
+      multimapBindings = bindingsMultimapBuilder.build();
+
+      entries = entriesBuilder.build();
+
+      initializationState = InitializationState.INITIALIZED;
+
+      return true;
+    }
+
+    private static <K, V> void reportDuplicateKeysError(
+        Multimap<K, Binding<V>> duplicates, Errors errors) {
+      StringBuilder sb = new StringBuilder("Map injection failed due to duplicated key ");
+      boolean first = true;
+      for (Map.Entry<K, Collection<Binding<V>>> entry : duplicates.asMap().entrySet()) {
+        K dupKey = entry.getKey();
+
+        if (first) {
+          first = false;
+          sb.append("\"" + dupKey + "\", from bindings:\n");
+        } else {
+          sb.append("\n and key: \"" + dupKey + "\", from bindings:\n");
+        }
+
+        for (Binding<V> dup : entry.getValue()) {
+          sb.append("\t at " + Errors.convert(dup.getSource()) + "\n");
+        }
+      }
+
+      // TODO(user): Add a different error for every duplicated key
+      errors.addMessage(sb.toString());
+    }
+
+    private boolean containsElement(Element element) {
+      if (entrySetBinder.containsElement(element)) {
+        return true;
+      }
+
+      Key<?> key;
+      if (element instanceof Binding) {
+        key = ((Binding<?>) element).getKey();
+      } else {
+        return false; // cannot match;
+      }
+
+      return key.equals(getMapKey())
+          || key.equals(getProviderMapKey())
+          || key.equals(getJavaxProviderMapKey())
+          || key.equals(getMultimapKey())
+          || key.equals(getProviderSetMultimapKey())
+          || key.equals(getJavaxProviderSetMultimapKey())
+          || key.equals(getProviderCollectionMultimapKey())
+          || key.equals(getJavaxProviderCollectionMultimapKey())
+          || key.equals(entrySetBinder.getSetKey())
+          || key.equals(getEntrySetJavaxProviderKey())
+          || matchesValueKey(key);
+    }
+
+    /** Returns true if the key indicates this is a value in the map. */
+    private boolean matchesValueKey(Key<?> key) {
+      return key.getAnnotation() instanceof RealElement
+          && ((RealElement) key.getAnnotation()).setName().equals(entrySetBinder.getSetName())
+          && ((RealElement) key.getAnnotation()).type() == MAPBINDER
+          && ((RealElement) key.getAnnotation()).keyType().equals(keyType.toString())
+          && key.getTypeLiteral().equals(valueType);
+    }
+
+    private Key<Map<K, Provider<V>>> getProviderMapKey() {
+      Key<Map<K, Provider<V>>> local = providerMapKey;
+      if (local == null) {
+        local = providerMapKey = mapKey.ofType(mapOfProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Map<K, javax.inject.Provider<V>>> getJavaxProviderMapKey() {
+      Key<Map<K, javax.inject.Provider<V>>> local = javaxProviderMapKey;
+      if (local == null) {
+        local = javaxProviderMapKey = mapKey.ofType(mapOfJavaxProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Map<K, Set<V>>> getMultimapKey() {
+      Key<Map<K, Set<V>>> local = multimapKey;
+      if (local == null) {
+        local = multimapKey = mapKey.ofType(mapOf(keyType, setOf(valueType)));
+      }
+      return local;
+    }
+
+    private Key<Map<K, Set<Provider<V>>>> getProviderSetMultimapKey() {
+      Key<Map<K, Set<Provider<V>>>> local = providerSetMultimapKey;
+      if (local == null) {
+        local = providerSetMultimapKey = mapKey.ofType(mapOfSetOfProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Map<K, Set<javax.inject.Provider<V>>>> getJavaxProviderSetMultimapKey() {
+      Key<Map<K, Set<javax.inject.Provider<V>>>> local = javaxProviderSetMultimapKey;
+      if (local == null) {
+        local =
+            javaxProviderSetMultimapKey =
+                mapKey.ofType(mapOfSetOfJavaxProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Map<K, Collection<Provider<V>>>> getProviderCollectionMultimapKey() {
+      Key<Map<K, Collection<Provider<V>>>> local = providerCollectionMultimapKey;
+      if (local == null) {
+        local =
+            providerCollectionMultimapKey =
+                mapKey.ofType(mapOfCollectionOfProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Map<K, Collection<javax.inject.Provider<V>>>>
+        getJavaxProviderCollectionMultimapKey() {
+      Key<Map<K, Collection<javax.inject.Provider<V>>>> local = javaxProviderCollectionMultimapKey;
+      if (local == null) {
+        local =
+            javaxProviderCollectionMultimapKey =
+                mapKey.ofType(mapOfCollectionOfJavaxProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private Key<Set<Map.Entry<K, javax.inject.Provider<V>>>> getEntrySetJavaxProviderKey() {
+      Key<Set<Map.Entry<K, javax.inject.Provider<V>>>> local = entrySetJavaxProviderKey;
+      if (local == null) {
+        local =
+            entrySetJavaxProviderKey =
+                mapKey.ofType(setOfEntryOfJavaxProviderOf(keyType, valueType));
+      }
+      return local;
+    }
+
+    private ImmutableMap<K, Binding<V>> getMapBindings() {
+      checkConfiguration(isInitialized(), "MapBinder has not yet been initialized");
+      return mapBindings;
+    }
+
+    private ImmutableMap<K, Set<Binding<V>>> getMultimapBindings() {
+      checkConfiguration(isInitialized(), "MapBinder has not yet been initialized");
+      return multimapBindings;
+    }
+
+    private ImmutableList<Map.Entry<K, Binding<V>>> getEntries() {
+      checkConfiguration(isInitialized(), "MapBinder has not yet been initialized");
+      return entries;
+    }
+
+    private boolean isInitialized() {
+      return initializationState == InitializationState.INITIALIZED;
+    }
+
+    private TypeLiteral<K> getKeyType() {
+      return keyType;
+    }
+
+    private TypeLiteral<V> getValueType() {
+      return valueType;
+    }
+
+    private Key<Map<K, V>> getMapKey() {
+      return mapKey;
+    }
+
+    private RealMultibinder<Map.Entry<K, Provider<V>>> getEntrySetBinder() {
+      return entrySetBinder;
+    }
+
+    private boolean permitsDuplicates() {
+      if (isInitialized()) {
+        return permitsDuplicates;
+      } else {
+        throw new UnsupportedOperationException(
+            "permitsDuplicates() not supported for module bindings");
+      }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof BindingSelection && ((BindingSelection<?, ?>) o).mapKey.equals(mapKey);
+    }
+
+    @Override
+    public int hashCode() {
+      return mapKey.hashCode();
+    }
+  }
+
+  private static final class RealProviderMapProvider<K, V>
+      extends RealMapBinderProviderWithDependencies<K, V, Map<K, Provider<V>>> {
+    private Map<K, Provider<V>> mapOfProviders;
+    private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
+
+    private RealProviderMapProvider(BindingSelection<K, V> bindingSelection) {
+      super(bindingSelection);
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return dependencies;
+    }
+
+    @Override
+    protected void doInitialize(InjectorImpl injector, Errors errors) {
+      ImmutableMap.Builder<K, Provider<V>> mapOfProvidersBuilder = ImmutableMap.builder();
+      ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
+      for (Map.Entry<K, Binding<V>> entry : bindingSelection.getMapBindings().entrySet()) {
+        mapOfProvidersBuilder.put(entry.getKey(), entry.getValue().getProvider());
+        dependenciesBuilder.add(Dependency.get(getKeyOfProvider(entry.getValue().getKey())));
+      }
+
+      mapOfProviders = mapOfProvidersBuilder.build();
+      dependencies = dependenciesBuilder.build();
+    }
+
+    @Override
+    protected Map<K, Provider<V>> doProvision(InternalContext context, Dependency<?> dependency) {
+      return mapOfProviders;
+    }
+  }
+
+  private static final class RealMapProvider<K, V>
+      extends RealMapBinderProviderWithDependencies<K, V, Map<K, V>>
+      implements ProviderWithExtensionVisitor<Map<K, V>>, MapBinderBinding<Map<K, V>> {
+    private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
+
+    /**
+     * An array of all the injectors.
+     *
+     * <p>This is parallel to array of keys below
+     */
+    private SingleParameterInjector<V>[] injectors;
+
+    private K[] keys;
+
+    private RealMapProvider(BindingSelection<K, V> bindingSelection) {
+      super(bindingSelection);
+    }
+
+    private BindingSelection<K, V> getBindingSelection() {
+      return bindingSelection;
+    }
+
+    @Override
+    protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      @SuppressWarnings("unchecked")
+      K[] keysArray = (K[]) new Object[bindingSelection.getMapBindings().size()];
+      keys = keysArray;
+      ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
+      int i = 0;
+      for (Map.Entry<K, Binding<V>> entry : bindingSelection.getMapBindings().entrySet()) {
+        dependenciesBuilder.add(Dependency.get(entry.getValue().getKey()));
+        keys[i] = entry.getKey();
+        i++;
+      }
+
+      ImmutableSet<Dependency<?>> localDependencies = dependenciesBuilder.build();
+      dependencies = localDependencies;
+
+      List<Dependency<?>> dependenciesList = localDependencies.asList();
+
+      // We know the type because we built up our own sets of dependencies, it's just
+      // that the interface uses a "?" generic
+      @SuppressWarnings("unchecked")
+      SingleParameterInjector<V>[] typedInjectors =
+          (SingleParameterInjector<V>[]) injector.getParametersInjectors(dependenciesList, errors);
+      injectors = typedInjectors;
+    }
+
+    @Override
+    protected Map<K, V> doProvision(InternalContext context, Dependency<?> dependency)
+        throws InternalProvisionException {
+      SingleParameterInjector<V>[] localInjectors = injectors;
+      if (localInjectors == null) {
+        // if injectors == null, then we have no bindings so return the empty map.
+        return ImmutableMap.of();
+      }
+
+      ImmutableMap.Builder<K, V> resultBuilder = ImmutableMap.builder();
+      K[] localKeys = keys;
+      for (int i = 0; i < localInjectors.length; i++) {
+        SingleParameterInjector<V> injector = localInjectors[i];
+        K key = localKeys[i];
+
+        V value = injector.inject(context);
+
+        if (value == null) {
+          throw createNullValueException(key, bindingSelection.getMapBindings().get(key));
+        }
+
+        resultBuilder.put(key, value);
+      }
+
+      return resultBuilder.build();
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return dependencies;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <B, W> W acceptExtensionVisitor(
+        BindingTargetVisitor<B, W> visitor, ProviderInstanceBinding<? extends B> binding) {
+      if (visitor instanceof MultibindingsTargetVisitor) {
+        return ((MultibindingsTargetVisitor<Map<K, V>, W>) visitor).visit(this);
+      } else {
+        return visitor.visit(binding);
+      }
+    }
+
+    @Override
+    public Key<Map<K, V>> getMapKey() {
+      return bindingSelection.getMapKey();
+    }
+
+    @Override
+    public TypeLiteral<K> getKeyTypeLiteral() {
+      return bindingSelection.getKeyType();
+    }
+
+    @Override
+    public TypeLiteral<V> getValueTypeLiteral() {
+      return bindingSelection.getValueType();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<Map.Entry<?, Binding<?>>> getEntries() {
+      if (bindingSelection.isInitialized()) {
+        return (List<Map.Entry<?, Binding<?>>>) (List<?>) bindingSelection.getEntries();
+      } else {
+        throw new UnsupportedOperationException("getEntries() not supported for module bindings");
+      }
+    }
+
+    @Override
+    public List<Map.Entry<?, Binding<?>>> getEntries(Iterable<? extends Element> elements) {
+      // Iterate over the elements, building up the below maps
+      // This is a preprocessing step allowing us to only iterate over elements
+      // once and have O(n) runtime
+      ImmutableMultimap.Builder<K, Key<V>> keyToValueKeyBuilder = ImmutableMultimap.builder();
+      ImmutableMap.Builder<Key<V>, Binding<V>> valueKeyToBindingBuilder = ImmutableMap.builder();
+      ImmutableMap.Builder<Key<V>, K> valueKeyToKeyBuilder = ImmutableMap.builder();
+      ImmutableMap.Builder<Key<V>, Binding<Map.Entry<K, Provider<V>>>>
+          valueKeyToEntryBindingBuilder = ImmutableMap.builder();
+      for (Element element : elements) {
+        if (element instanceof Binding) {
+          Binding<?> binding = (Binding<?>) element;
+          if (bindingSelection.matchesValueKey(binding.getKey())
+              && binding.getKey().getTypeLiteral().equals(bindingSelection.valueType)) {
+            // Safe because of the check on the type literal above
+            @SuppressWarnings("unchecked")
+            Binding<V> typedBinding = (Binding<V>) binding;
+            Key<V> typedKey = typedBinding.getKey();
+            valueKeyToBindingBuilder.put(typedKey, typedBinding);
+          }
+        }
+
+        if (element instanceof ProviderInstanceBinding
+            && bindingSelection.getEntrySetBinder().containsElement(element)) {
+          // Safe because of the instanceof check, and containsElement() check
+          @SuppressWarnings({"unchecked", "rawtypes"})
+          ProviderInstanceBinding<Map.Entry<K, Provider<V>>> entryBinding =
+              (ProviderInstanceBinding) element;
+
+          // Safe because of the check for containsElement() above
+          @SuppressWarnings("unchecked")
+          Provider<Map.Entry<K, Provider<V>>> typedProvider =
+              (Provider<Map.Entry<K, Provider<V>>>) entryBinding.getUserSuppliedProvider();
+          Provider<Map.Entry<K, Provider<V>>> userSuppliedProvider = typedProvider;
+
+          if (userSuppliedProvider instanceof ProviderMapEntry) {
+            // Safe because of the instanceof check
+            @SuppressWarnings("unchecked")
+            ProviderMapEntry<K, V> typedUserSuppliedProvider =
+                (ProviderMapEntry<K, V>) userSuppliedProvider;
+            ProviderMapEntry<K, V> entry = typedUserSuppliedProvider;
+
+            keyToValueKeyBuilder.put(entry.getKey(), entry.getValueKey());
+            valueKeyToEntryBindingBuilder.put(entry.getValueKey(), entryBinding);
+            valueKeyToKeyBuilder.put(entry.getValueKey(), entry.getKey());
+          }
+        }
+      }
+
+      ImmutableMultimap<K, Key<V>> keyToValueKey = keyToValueKeyBuilder.build();
+      ImmutableMap<Key<V>, K> valueKeyToKey = valueKeyToKeyBuilder.build();
+      ImmutableMap<Key<V>, Binding<V>> valueKeyToBinding = valueKeyToBindingBuilder.build();
+      ImmutableMap<Key<V>, Binding<Map.Entry<K, Provider<V>>>> valueKeyToEntryBinding =
+          valueKeyToEntryBindingBuilder.build();
+
+      // Check that there is a 1:1 mapping from keys from the ProviderMapEntrys to the
+      // keys from the Bindings.
+      Set<Key<V>> keysFromProviderMapEntrys = Sets.newHashSet(keyToValueKey.values());
+      Set<Key<V>> keysFromBindings = valueKeyToBinding.keySet();
+
+      if (!keysFromProviderMapEntrys.equals(keysFromBindings)) {
+        Set<Key<V>> keysOnlyFromProviderMapEntrys =
+            Sets.difference(keysFromProviderMapEntrys, keysFromBindings);
+        Set<Key<V>> keysOnlyFromBindings =
+            Sets.difference(keysFromBindings, keysFromProviderMapEntrys);
+
+        StringBuilder sb = new StringBuilder("Expected a 1:1 mapping from map keys to values.");
+
+        if (!keysOnlyFromBindings.isEmpty()) {
+          sb.append(
+              Errors.format("%nFound these Bindings that were missing an associated entry:%n"));
+          for (Key<V> key : keysOnlyFromBindings) {
+            sb.append(
+                Errors.format("  %s bound at: %s%n", key, valueKeyToBinding.get(key).getSource()));
+          }
+        }
+
+        if (!keysOnlyFromProviderMapEntrys.isEmpty()) {
+          sb.append(Errors.format("%nFound these map keys without a corresponding value:%n"));
+          for (Key<V> key : keysOnlyFromProviderMapEntrys) {
+            sb.append(
+                Errors.format(
+                    "  '%s' bound at: %s%n",
+                    valueKeyToKey.get(key), valueKeyToEntryBinding.get(key).getSource()));
+          }
+        }
+
+        throw new IllegalArgumentException(sb.toString());
+      }
+
+      // Now that we have the two maps, generate the result map
+      ImmutableList.Builder<Map.Entry<?, Binding<?>>> resultBuilder = ImmutableList.builder();
+      for (Map.Entry<K, Key<V>> entry : keyToValueKey.entries()) {
+        Binding<?> binding = valueKeyToBinding.get(entry.getValue());
+        // No null check for binding needed because of the above check to make sure all the
+        // values in keyToValueKey are present as keys in valueKeyToBinding
+
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        Map.Entry<?, Binding<?>> newEntry =
+            (Map.Entry) Maps.immutableEntry(entry.getKey(), binding);
+        resultBuilder.add(newEntry);
+      }
+      return resultBuilder.build();
+    }
+
+    @Override
+    public boolean permitsDuplicates() {
+      if (bindingSelection.isInitialized()) {
+        return bindingSelection.permitsDuplicates();
+      } else {
+        throw new UnsupportedOperationException(
+            "permitsDuplicates() not supported for module bindings");
+      }
+    }
+
+    @Override
+    public boolean containsElement(Element element) {
+      return bindingSelection.containsElement(element);
+    }
+  }
+
+  /**
+   * Binds {@code Map<K, Set<V>>} and {{@code Map<K, Set<Provider<V>>>}.
+   *
+   * <p>This will only exist if permitDuplicates() is called.
+   */
+  private static final class MultimapBinder<K, V> implements Module {
+    private final BindingSelection<K, V> bindingSelection;
+
+    private MultimapBinder(BindingSelection<K, V> bindingSelection) {
+      this.bindingSelection = bindingSelection;
+    }
+
+    @Override
+    public void configure(Binder binder) {
+      // Binds a Map<K, Set<Provider<V>>>
+      Provider<Map<K, Set<Provider<V>>>> multimapProvider =
+          new RealProviderMultimapProvider<K, V>(bindingSelection.getMapKey());
+      binder.bind(bindingSelection.getProviderSetMultimapKey()).toProvider(multimapProvider);
+
+      // Provide links from a few different public keys to the providerMultimapKey.
+      // The collection this exposes is internally an ImmutableMap, so it's OK to massage
+      // the guice Provider to javax Provider in the value (since the guice Provider implements
+      // javax Provider).
+      @SuppressWarnings({"unchecked", "rawtypes"})
+      Provider<Map<K, Set<javax.inject.Provider<V>>>> javaxProvider = (Provider) multimapProvider;
+      binder.bind(bindingSelection.getJavaxProviderSetMultimapKey()).toProvider(javaxProvider);
+
+      @SuppressWarnings({"unchecked", "rawtypes"})
+      Provider<Map<K, Collection<Provider<V>>>> collectionProvider = (Provider) multimapProvider;
+      binder
+          .bind(bindingSelection.getProviderCollectionMultimapKey())
+          .toProvider(collectionProvider);
+
+      @SuppressWarnings({"unchecked", "rawtypes"})
+      Provider<Map<K, Collection<javax.inject.Provider<V>>>> collectionJavaxProvider =
+          (Provider) multimapProvider;
+      binder
+          .bind(bindingSelection.getJavaxProviderCollectionMultimapKey())
+          .toProvider(collectionJavaxProvider);
+
+      // Binds a Map<K, Set<V>>
+      @SuppressWarnings({"unchecked", "rawtypes"})
+      Provider<Map<K, Set<V>>> realMultimapProvider =
+          new RealMultimapProvider(bindingSelection.getMapKey());
+      binder.bind(bindingSelection.getMultimapKey()).toProvider(realMultimapProvider);
+    }
+
+    @Override
+    public int hashCode() {
+      return bindingSelection.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof MultimapBinder
+          && ((MultimapBinder<?, ?>) o).bindingSelection.equals(bindingSelection);
+    }
+
+    private static final class RealProviderMultimapProvider<K, V>
+        extends RealMultimapBinderProviderWithDependencies<K, V, Map<K, Set<Provider<V>>>> {
+      private Map<K, Set<Provider<V>>> multimapOfProviders;
+      private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
+
+      private RealProviderMultimapProvider(Key<Map<K, V>> mapKey) {
+        super(mapKey);
+      }
+
+      @Override
+      public Set<Dependency<?>> getDependencies() {
+        return dependencies;
+      }
+
+      @Override
+      protected void doInitialize(InjectorImpl injector, Errors errors) {
+        ImmutableMap.Builder<K, Set<Provider<V>>> multimapOfProvidersBuilder =
+            ImmutableMap.builder();
+        ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
+        for (Map.Entry<K, Set<Binding<V>>> entry :
+            bindingSelection.getMultimapBindings().entrySet()) {
+          ImmutableSet.Builder<Provider<V>> providersBuilder = ImmutableSet.builder();
+          for (Binding<V> binding : entry.getValue()) {
+            providersBuilder.add(binding.getProvider());
+            dependenciesBuilder.add(Dependency.get(getKeyOfProvider(binding.getKey())));
+          }
+
+          multimapOfProvidersBuilder.put(entry.getKey(), providersBuilder.build());
+        }
+        multimapOfProviders = multimapOfProvidersBuilder.build();
+        dependencies = dependenciesBuilder.build();
+      }
+
+      @Override
+      protected Map<K, Set<Provider<V>>> doProvision(
+          InternalContext context, Dependency<?> dependency) {
+        return multimapOfProviders;
+      }
+    }
+
+    private static final class RealMultimapProvider<K, V>
+        extends RealMultimapBinderProviderWithDependencies<K, V, Map<K, Set<V>>> {
+
+      /**
+       * A simple class to hold a key and the associated bindings as an array.
+       *
+       * <p>Arrays are used for performance.
+       */
+      private static final class PerKeyData<K, V> {
+        private final K key;
+        private final Binding<V>[] bindings;
+        private final SingleParameterInjector<V>[] injectors;
+
+        private PerKeyData(K key, Binding<V>[] bindings, SingleParameterInjector<V>[] injectors) {
+          Preconditions.checkArgument(bindings.length == injectors.length);
+
+          this.key = key;
+          this.bindings = bindings;
+          this.injectors = injectors;
+        }
+      }
+
+      private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
+
+      private PerKeyData<K, V>[] perKeyDatas;
+
+      private RealMultimapProvider(Key<Map<K, V>> mapKey) {
+        super(mapKey);
+      }
+
+      @Override
+      public Set<Dependency<?>> getDependencies() {
+        return dependencies;
+      }
+
+      @Override
+      protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        PerKeyData<K, V>[] typedPerKeyData =
+            new PerKeyData[bindingSelection.getMapBindings().size()];
+        perKeyDatas = typedPerKeyData;
+        ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
+        List<Dependency<?>> dependenciesForKey = Lists.newArrayList();
+        int i = 0;
+        for (Map.Entry<K, Set<Binding<V>>> entry :
+            bindingSelection.getMultimapBindings().entrySet()) {
+          // Clear the list of dependencies because we're reusing it for each different key
+          dependenciesForKey.clear();
+
+          Set<Binding<V>> bindings = entry.getValue();
+          @SuppressWarnings({"unchecked", "rawtypes"})
+          Binding<V>[] typedBindings = new Binding[bindings.size()];
+          Binding<V>[] bindingsArray = typedBindings;
+          int j = 0;
+          for (Binding<V> binding : bindings) {
+            Dependency<V> dependency = Dependency.get(binding.getKey());
+            dependenciesBuilder.add(dependency);
+            dependenciesForKey.add(dependency);
+            bindingsArray[j] = binding;
+            j++;
+          }
+
+          @SuppressWarnings("unchecked")
+          SingleParameterInjector<V>[] injectors =
+              (SingleParameterInjector<V>[])
+                  injector.getParametersInjectors(dependenciesForKey, errors);
+
+          perKeyDatas[i] = new PerKeyData<>(entry.getKey(), bindingsArray, injectors);
+          i++;
+        }
+
+        dependencies = dependenciesBuilder.build();
+      }
+
+      @Override
+      protected Map<K, Set<V>> doProvision(InternalContext context, Dependency<?> dependency)
+          throws InternalProvisionException {
+        ImmutableMap.Builder<K, Set<V>> resultBuilder = ImmutableMap.builder();
+
+        for (PerKeyData<K, V> perKeyData : perKeyDatas) {
+          ImmutableSet.Builder<V> bindingsBuilder = ImmutableSet.builder();
+          SingleParameterInjector<V>[] injectors = perKeyData.injectors;
+          for (int i = 0; i < injectors.length; i++) {
+            SingleParameterInjector<V> injector = injectors[i];
+            V value = injector.inject(context);
+
+            if (value == null) {
+              throw createNullValueException(perKeyData.key, perKeyData.bindings[i]);
+            }
+
+            bindingsBuilder.add(value);
+          }
+
+          resultBuilder.put(perKeyData.key, bindingsBuilder.build());
+        }
+
+        return resultBuilder.build();
+      }
+    }
+  }
+
+  /** A factory for a {@code Map.Entry<K, Provider<V>>}. */
+  //VisibleForTesting
+  static final class ProviderMapEntry<K, V>
+      extends InternalProviderInstanceBindingImpl.Factory<Map.Entry<K, Provider<V>>> {
+    private final K key;
+    private final Key<V> valueKey;
+    private Map.Entry<K, Provider<V>> entry;
+
+    ProviderMapEntry(K key, Key<V> valueKey) {
+      super(InitializationTiming.EAGER);
+      this.key = key;
+      this.valueKey = valueKey;
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      // The dependencies are Key<Provider<V>>
+      return ImmutableSet.<Dependency<?>>of(Dependency.get(getKeyOfProvider(valueKey)));
+    }
+
+    @Override
+    void initialize(InjectorImpl injector, Errors errors) {
+      Binding<V> valueBinding = injector.getExistingBinding(valueKey);
+      entry = Maps.immutableEntry(key, valueBinding.getProvider());
+    }
+
+    @Override
+    protected Map.Entry<K, Provider<V>> doProvision(
+        InternalContext context, Dependency<?> dependency) {
+      return entry;
+    }
+
+    K getKey() {
+      return key;
+    }
+
+    Key<V> getValueKey() {
+      return valueKey;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (obj instanceof ProviderMapEntry) {
+        ProviderMapEntry<?, ?> o = (ProviderMapEntry<?, ?>) obj;
+        return key.equals(o.key) && valueKey.equals(o.valueKey);
+      }
+      return false;
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hashCode(key, valueKey);
+    }
+
+    @Override
+    public String toString() {
+      return "ProviderMapEntry(" + key + ", " + valueKey + ")";
+    }
+  }
+
+  /** A base class for ProviderWithDependencies that need equality based on a specific object. */
+  private abstract static class RealMapBinderProviderWithDependencies<K, V, P>
+      extends InternalProviderInstanceBindingImpl.Factory<P> {
+    final BindingSelection<K, V> bindingSelection;
+
+    private RealMapBinderProviderWithDependencies(BindingSelection<K, V> bindingSelection) {
+      // While MapBinders only depend on bindings created in modules so we could theoretically
+      // initialize eagerly, they also depend on
+      // 1. findBindingsByType returning results
+      // 2. being able to call BindingImpl.acceptTargetVisitor
+      // neither of those is available during eager initialization, so we use DELAYED
+      super(InitializationTiming.DELAYED);
+
+      this.bindingSelection = bindingSelection;
+    }
+
+    @Override
+    final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      if (bindingSelection.tryInitialize(injector, errors)) {
+        doInitialize(injector, errors);
+      }
+    }
+
+    /**
+     * Initialize the factory. BindingSelection is guaranteed to be initialized at this point and
+     * this will be called prior to any provisioning.
+     */
+    protected abstract void doInitialize(InjectorImpl injector, Errors errors)
+        throws ErrorsException;
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj != null
+          && this.getClass() == obj.getClass()
+          && bindingSelection.equals(
+              ((RealMapBinderProviderWithDependencies<?, ?, ?>) obj).bindingSelection);
+    }
+
+    @Override
+    public int hashCode() {
+      return bindingSelection.hashCode();
+    }
+  }
+
+  /**
+   * A base class for ProviderWithDependencies that need equality based on a specific object.
+   *
+   * <p>This differs from {@link RealMapBinderProviderWithDependencies} in that it gets the {@code
+   * bindingSelection} from the injector at initialization time, rather than in the constructor.
+   * This is done to allow all the providers to operate on the same instance of the {@link
+   * BindingSelection}.
+   */
+  private abstract static class RealMultimapBinderProviderWithDependencies<K, V, P>
+      extends InternalProviderInstanceBindingImpl.Factory<P> {
+    final Key<Map<K, V>> mapKey;
+    BindingSelection<K, V> bindingSelection;
+
+    private RealMultimapBinderProviderWithDependencies(Key<Map<K, V>> mapKey) {
+      // While MapBinders only depend on bindings created in modules so we could theoretically
+      // initialize eagerly, they also depend on
+      // 1. findBindingsByType returning results
+      // 2. being able to call BindingImpl.acceptTargetVisitor
+      // neither of those is available during eager initialization, so we use DELAYED
+      super(InitializationTiming.DELAYED);
+
+      this.mapKey = mapKey;
+    }
+
+    /**
+     * This will get the authoritative {@link BindingSelection} from the map provider. This
+     * guarantees that everyone has the same instance of the bindingSelection and sees consistent
+     * state.
+     */
+    @Override
+    final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      Binding<Map<K, V>> mapBinding = injector.getExistingBinding(mapKey);
+      ProviderInstanceBinding<Map<K, V>> providerInstanceBinding =
+          (ProviderInstanceBinding<Map<K, V>>) mapBinding;
+      @SuppressWarnings("unchecked")
+      RealMapProvider<K, V> mapProvider =
+          (RealMapProvider<K, V>) providerInstanceBinding.getUserSuppliedProvider();
+
+      this.bindingSelection = mapProvider.getBindingSelection();
+
+      if (bindingSelection.tryInitialize(injector, errors)) {
+        doInitialize(injector, errors);
+      }
+    }
+
+    /**
+     * Initialize the factory. BindingSelection is guaranteed to be initialized at this point and
+     * this will be called prior to any provisioning.
+     */
+    abstract void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException;
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj != null
+          && this.getClass() == obj.getClass()
+          && mapKey.equals(((RealMultimapBinderProviderWithDependencies<?, ?, ?>) obj).mapKey);
+    }
+
+    @Override
+    public int hashCode() {
+      return mapKey.hashCode();
+    }
+  }
+
+  private static <K, V> InternalProvisionException createNullValueException(
+      K key, Binding<V> binding) {
+    return InternalProvisionException.create(
+        "Map injection failed due to null value for key \"%s\", bound at: %s",
+        key, binding.getSource());
+  }
+}
diff --git a/core/src/com/google/inject/internal/RealMultibinder.java b/core/src/com/google/inject/internal/RealMultibinder.java
new file mode 100644
index 0000000..aa887f4
--- /dev/null
+++ b/core/src/com/google/inject/internal/RealMultibinder.java
@@ -0,0 +1,604 @@
+package com.google.inject.internal;
+
+import static com.google.inject.internal.Element.Type.MULTIBINDER;
+import static com.google.inject.internal.Errors.checkConfiguration;
+import static com.google.inject.internal.Errors.checkNotNull;
+import static com.google.inject.name.Names.named;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.inject.AbstractModule;
+import com.google.inject.Binder;
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.InternalProviderInstanceBindingImpl.InitializationTiming;
+import com.google.inject.multibindings.MultibinderBinding;
+import com.google.inject.multibindings.MultibindingsTargetVisitor;
+import com.google.inject.spi.BindingTargetVisitor;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.spi.ProviderWithExtensionVisitor;
+import com.google.inject.util.Types;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The actual multibinder plays several roles:
+ *
+ * <p>As a Multibinder, it acts as a factory for LinkedBindingBuilders for each of the set's
+ * elements. Each binding is given an annotation that identifies it as a part of this set.
+ *
+ * <p>As a Module, it installs the binding to the set itself. As a module, this implements equals()
+ * and hashcode() in order to trick Guice into executing its configure() method only once. That
+ * makes it so that multiple multibinders can be created for the same target collection, but only
+ * one is bound. Since the list of bindings is retrieved from the injector itself (and not the
+ * multibinder), each multibinder has access to all contributions from all multibinders.
+ *
+ * <p>As a Provider, this constructs the set instances.
+ *
+ * <p>We use a subclass to hide 'implements Module, Provider' from the public API.
+ */
+public final class RealMultibinder<T> implements Module {
+
+  /** Implementation of newSetBinder. */
+  public static <T> RealMultibinder<T> newRealSetBinder(Binder binder, Key<T> key) {
+    binder = binder.skipSources(RealMultibinder.class);
+    RealMultibinder<T> result = new RealMultibinder<>(binder, key);
+    binder.install(result);
+    return result;
+  }
+
+  @SuppressWarnings("unchecked") // wrapping a T in a Set safely returns a Set<T>
+  static <T> TypeLiteral<Set<T>> setOf(TypeLiteral<T> elementType) {
+    Type type = Types.setOf(elementType.getType());
+    return (TypeLiteral<Set<T>>) TypeLiteral.get(type);
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> TypeLiteral<Collection<Provider<T>>> collectionOfProvidersOf(
+      TypeLiteral<T> elementType) {
+    Type providerType = Types.providerOf(elementType.getType());
+    Type type = Types.collectionOf(providerType);
+    return (TypeLiteral<Collection<Provider<T>>>) TypeLiteral.get(type);
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> TypeLiteral<Collection<javax.inject.Provider<T>>> collectionOfJavaxProvidersOf(
+      TypeLiteral<T> elementType) {
+    Type providerType =
+        Types.newParameterizedType(javax.inject.Provider.class, elementType.getType());
+    Type type = Types.collectionOf(providerType);
+    return (TypeLiteral<Collection<javax.inject.Provider<T>>>) TypeLiteral.get(type);
+  }
+
+  private final BindingSelection<T> bindingSelection;
+  private final Binder binder;
+
+  RealMultibinder(Binder binder, Key<T> key) {
+    this.binder = checkNotNull(binder, "binder");
+    this.bindingSelection = new BindingSelection<>(key);
+  }
+
+  @Override
+  public void configure(Binder binder) {
+    checkConfiguration(!bindingSelection.isInitialized(), "Multibinder was already initialized");
+    binder
+        .bind(bindingSelection.getSetKey())
+        .toProvider(new RealMultibinderProvider<T>(bindingSelection));
+    Provider<Collection<Provider<T>>> collectionOfProvidersProvider =
+        new RealMultibinderCollectionOfProvidersProvider<T>(bindingSelection);
+    binder
+        .bind(bindingSelection.getCollectionOfProvidersKey())
+        .toProvider(collectionOfProvidersProvider);
+
+    // The collection this exposes is internally an ImmutableList, so it's OK to massage
+    // the guice Provider to javax Provider in the value (since the guice Provider implements
+    // javax Provider).
+    @SuppressWarnings("unchecked")
+    Provider<Collection<javax.inject.Provider<T>>> javaxProvider =
+        (Provider) collectionOfProvidersProvider;
+    binder.bind(bindingSelection.getCollectionOfJavaxProvidersKey()).toProvider(javaxProvider);
+  }
+
+  public void permitDuplicates() {
+    binder.install(new PermitDuplicatesModule(bindingSelection.getPermitDuplicatesKey()));
+  }
+
+  /** Adds a new entry to the set and returns the key for it. */
+  Key<T> getKeyForNewItem() {
+    checkConfiguration(!bindingSelection.isInitialized(), "Multibinder was already initialized");
+    return Key.get(
+        bindingSelection.getElementTypeLiteral(),
+        new RealElement(bindingSelection.getSetName(), MULTIBINDER, ""));
+  }
+
+  public LinkedBindingBuilder<T> addBinding() {
+    return binder.bind(getKeyForNewItem());
+  }
+
+  // These methods are used by RealMapBinder
+
+  Key<Set<T>> getSetKey() {
+    return bindingSelection.getSetKey();
+  }
+
+  TypeLiteral<T> getElementTypeLiteral() {
+    return bindingSelection.getElementTypeLiteral();
+  }
+
+  String getSetName() {
+    return bindingSelection.getSetName();
+  }
+
+  boolean permitsDuplicates(Injector injector) {
+    return bindingSelection.permitsDuplicates(injector);
+  }
+
+  boolean containsElement(com.google.inject.spi.Element element) {
+    return bindingSelection.containsElement(element);
+  }
+
+  private static final class RealMultibinderProvider<T>
+      extends InternalProviderInstanceBindingImpl.Factory<Set<T>>
+      implements ProviderWithExtensionVisitor<Set<T>>, MultibinderBinding<Set<T>> {
+    private final BindingSelection<T> bindingSelection;
+    private List<Binding<T>> bindings;
+    private SingleParameterInjector<T>[] injectors;
+    private boolean permitDuplicates;
+
+    RealMultibinderProvider(BindingSelection<T> bindingSelection) {
+      // While Multibinders only depend on bindings created in modules so we could theoretically
+      // initialize eagerly, they also depend on
+      // 1. findBindingsByType returning results
+      // 2. being able to call BindingImpl.acceptTargetVisitor
+      // neither of those is available during eager initialization, so we use DELAYED
+      super(InitializationTiming.DELAYED);
+      this.bindingSelection = bindingSelection;
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.getDependencies();
+    }
+
+    @Override
+    void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      bindingSelection.initialize(injector, errors);
+      this.bindings = bindingSelection.getBindings();
+      this.injectors = bindingSelection.getParameterInjectors();
+      this.permitDuplicates = bindingSelection.permitsDuplicates();
+    }
+
+    @Override
+    protected Set<T> doProvision(InternalContext context, Dependency<?> dependency)
+        throws InternalProvisionException {
+      SingleParameterInjector<T>[] localInjectors = injectors;
+      if (localInjectors == null) {
+        // if localInjectors == null, then we have no bindings so return the empty set.
+        return ImmutableSet.of();
+      }
+      // Ideally we would just add to an ImmutableSet.Builder, but if we did that and there were
+      // duplicates we wouldn't be able to tell which one was the duplicate.  So to manage this we
+      // first put everything into an array and then construct the set.  This way if something gets
+      // dropped we can figure out what it is.
+      @SuppressWarnings("unchecked")
+      T[] values = (T[]) new Object[localInjectors.length];
+      for (int i = 0; i < localInjectors.length; i++) {
+        SingleParameterInjector<T> parameterInjector = localInjectors[i];
+        T newValue = parameterInjector.inject(context);
+        if (newValue == null) {
+          throw newNullEntryException(i);
+        }
+        values[i] = newValue;
+      }
+      ImmutableSet<T> set = ImmutableSet.copyOf(values);
+      // There are fewer items in the set than the array.  Figure out which one got dropped.
+      if (!permitDuplicates && set.size() < values.length) {
+        throw newDuplicateValuesException(set, values);
+      }
+      return set;
+    }
+
+    private InternalProvisionException newNullEntryException(int i) {
+      return InternalProvisionException.create(
+          "Set injection failed due to null element bound at: %s", bindings.get(i).getSource());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <B, V> V acceptExtensionVisitor(
+        BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding) {
+      if (visitor instanceof MultibindingsTargetVisitor) {
+        return ((MultibindingsTargetVisitor<Set<T>, V>) visitor).visit(this);
+      } else {
+        return visitor.visit(binding);
+      }
+    }
+
+    private InternalProvisionException newDuplicateValuesException(
+        ImmutableSet<T> set, T[] values) {
+      // TODO(lukes): consider reporting all duplicate values, the easiest way would be to rebuild
+      // a new set and detect dupes as we go
+      // Find the duplicate binding
+      // To do this we take advantage of the fact that set, values and bindings all have the same
+      // ordering for a non-empty prefix of the set.
+      // First we scan for the first item dropped from the set.
+      int newBindingIndex = 0;
+      for (T item : set) {
+        if (item != values[newBindingIndex]) {
+          break;
+        }
+        newBindingIndex++;
+      }
+      // once we exit the loop newBindingIndex will point at the first item in values that was
+      // dropped.
+
+      Binding<T> newBinding = bindings.get(newBindingIndex);
+      T newValue = values[newBindingIndex];
+      // Now we scan again to find the index of the value, we are guaranteed to find it.
+      int oldBindingIndex = set.asList().indexOf(newValue);
+      T oldValue = values[oldBindingIndex];
+      Binding<T> duplicateBinding = bindings.get(oldBindingIndex);
+      String oldString = oldValue.toString();
+      String newString = newValue.toString();
+      if (Objects.equal(oldString, newString)) {
+        // When the value strings match, just show the source of the bindings
+        return InternalProvisionException.create(
+            "Set injection failed due to duplicated element \"%s\""
+                + "\n    Bound at %s\n    Bound at %s",
+            newValue, duplicateBinding.getSource(), newBinding.getSource());
+      } else {
+        // When the value strings don't match, include them both as they may be useful for debugging
+        return InternalProvisionException.create(
+            "Set injection failed due to multiple elements comparing equal:"
+                + "\n    \"%s\"\n        bound at %s"
+                + "\n    \"%s\"\n        bound at %s",
+            oldValue, duplicateBinding.getSource(), newValue, newBinding.getSource());
+      }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj instanceof RealMultibinderProvider
+          && bindingSelection.equals(((RealMultibinderProvider<?>) obj).bindingSelection);
+    }
+
+    @Override
+    public int hashCode() {
+      return bindingSelection.hashCode();
+    }
+
+    @Override
+    public Key<Set<T>> getSetKey() {
+      return bindingSelection.getSetKey();
+    }
+
+    @Override
+    public TypeLiteral<?> getElementTypeLiteral() {
+      return bindingSelection.getElementTypeLiteral();
+    }
+
+    @Override
+    public List<Binding<?>> getElements() {
+      return bindingSelection.getElements();
+    }
+
+    @Override
+    public boolean permitsDuplicates() {
+      return bindingSelection.permitsDuplicates();
+    }
+
+    @Override
+    public boolean containsElement(com.google.inject.spi.Element element) {
+      return bindingSelection.containsElement(element);
+    }
+  }
+
+  private static final class BindingSelection<T> {
+    // prior to initialization we declare just a dependency on the injector, but as soon as we are
+    // initialized we swap to dependencies on the elements.
+    private static final ImmutableSet<Dependency<?>> MODULE_DEPENDENCIES =
+        ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
+    private final TypeLiteral<T> elementType;
+    private final Key<Set<T>> setKey;
+
+    // these are all lazily allocated
+    private String setName;
+    private Key<Collection<Provider<T>>> collectionOfProvidersKey;
+    private Key<Collection<javax.inject.Provider<T>>> collectionOfJavaxProvidersKey;
+    private Key<Boolean> permitDuplicatesKey;
+
+    private boolean isInitialized;
+    /* a binding for each element in the set. null until initialization, non-null afterwards */
+    private ImmutableList<Binding<T>> bindings;
+
+    // Starts out as Injector and gets set up properly after initialization
+    private ImmutableSet<Dependency<?>> dependencies = MODULE_DEPENDENCIES;
+    private ImmutableSet<Dependency<?>> providerDependencies = MODULE_DEPENDENCIES;
+
+    /** whether duplicates are allowed. Possibly configured by a different instance */
+    private boolean permitDuplicates;
+
+    private SingleParameterInjector<T>[] parameterinjectors;
+
+    BindingSelection(Key<T> key) {
+      this.setKey = key.ofType(setOf(key.getTypeLiteral()));
+      this.elementType = key.getTypeLiteral();
+    }
+
+    void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      // This will be called multiple times, once by each Factory. We only want
+      // to do the work to initialize everything once, so guard this code with
+      // isInitialized.
+      if (isInitialized) {
+        return;
+      }
+      List<Binding<T>> bindings = Lists.newArrayList();
+      Set<Indexer.IndexedBinding> index = Sets.newHashSet();
+      Indexer indexer = new Indexer(injector);
+      List<Dependency<?>> dependencies = Lists.newArrayList();
+      List<Dependency<?>> providerDependencies = Lists.newArrayList();
+      for (Binding<?> entry : injector.findBindingsByType(elementType)) {
+        if (keyMatches(entry.getKey())) {
+          @SuppressWarnings("unchecked") // protected by findBindingsByType()
+          Binding<T> binding = (Binding<T>) entry;
+          if (index.add(binding.acceptTargetVisitor(indexer))) {
+            // TODO(lukes): most of these are linked bindings since user bindings are linked to
+            // a user binding through the @Element annotation.  Since this is an implementation
+            // detail we could 'dereference' the @Element if it is a LinkedBinding and avoid
+            // provisioning through the FactoryProxy at runtime.
+            // Ditto for OptionalBinder/MapBinder
+            bindings.add(binding);
+            Key<T> key = binding.getKey();
+            // TODO(lukes): we should mark this as a non-nullable dependency since we don't accept
+            // null.
+            // Add a dependency on Key<T>
+            dependencies.add(Dependency.get(key));
+            // and add a dependency on Key<Provider<T>>
+            providerDependencies.add(
+                Dependency.get(key.ofType(Types.providerOf(key.getTypeLiteral().getType()))));
+          }
+        }
+      }
+
+      this.bindings = ImmutableList.copyOf(bindings);
+      this.dependencies = ImmutableSet.copyOf(dependencies);
+      this.providerDependencies = ImmutableSet.copyOf(providerDependencies);
+      this.permitDuplicates = permitsDuplicates(injector);
+      // This is safe because all our dependencies are assignable to T and we never assign to
+      // elements of this array.
+      @SuppressWarnings("unchecked")
+      SingleParameterInjector<T>[] typed =
+          (SingleParameterInjector<T>[]) injector.getParametersInjectors(dependencies, errors);
+      this.parameterinjectors = typed;
+      isInitialized = true;
+    }
+
+    boolean permitsDuplicates(Injector injector) {
+      return injector.getBindings().containsKey(getPermitDuplicatesKey());
+    }
+
+    ImmutableList<Binding<T>> getBindings() {
+      checkConfiguration(isInitialized, "not initialized");
+      return bindings;
+    }
+
+    SingleParameterInjector<T>[] getParameterInjectors() {
+      checkConfiguration(isInitialized, "not initialized");
+      return parameterinjectors;
+    }
+
+    ImmutableSet<Dependency<?>> getDependencies() {
+      return dependencies;
+    }
+
+    ImmutableSet<Dependency<?>> getProviderDependencies() {
+      return providerDependencies;
+    }
+
+    String getSetName() {
+      // lazily initialized since most selectors don't survive module installation.
+      if (setName == null) {
+        setName = Annotations.nameOf(setKey);
+      }
+      return setName;
+    }
+
+    Key<Boolean> getPermitDuplicatesKey() {
+      Key<Boolean> local = permitDuplicatesKey;
+      if (local == null) {
+        local =
+            permitDuplicatesKey = Key.get(Boolean.class, named(toString() + " permits duplicates"));
+      }
+      return local;
+    }
+
+    Key<Collection<Provider<T>>> getCollectionOfProvidersKey() {
+      Key<Collection<Provider<T>>> local = collectionOfProvidersKey;
+      if (local == null) {
+        local = collectionOfProvidersKey = setKey.ofType(collectionOfProvidersOf(elementType));
+      }
+      return local;
+    }
+
+    Key<Collection<javax.inject.Provider<T>>> getCollectionOfJavaxProvidersKey() {
+      Key<Collection<javax.inject.Provider<T>>> local = collectionOfJavaxProvidersKey;
+      if (local == null) {
+        local =
+            collectionOfJavaxProvidersKey =
+                setKey.ofType(collectionOfJavaxProvidersOf(elementType));
+      }
+      return local;
+    }
+
+    boolean isInitialized() {
+      return isInitialized;
+    }
+
+    // MultibinderBinding API methods
+
+    TypeLiteral<T> getElementTypeLiteral() {
+      return elementType;
+    }
+
+    Key<Set<T>> getSetKey() {
+      return setKey;
+    }
+
+    @SuppressWarnings("unchecked")
+    List<Binding<?>> getElements() {
+      if (isInitialized()) {
+        return (List<Binding<?>>) (List<?>) bindings; // safe because bindings is immutable.
+      } else {
+        throw new UnsupportedOperationException("getElements() not supported for module bindings");
+      }
+    }
+
+    boolean permitsDuplicates() {
+      if (isInitialized()) {
+        return permitDuplicates;
+      } else {
+        throw new UnsupportedOperationException(
+            "permitsDuplicates() not supported for module bindings");
+      }
+    }
+
+    boolean containsElement(com.google.inject.spi.Element element) {
+      if (element instanceof Binding) {
+        Binding<?> binding = (Binding<?>) element;
+        return keyMatches(binding.getKey())
+            || binding.getKey().equals(getPermitDuplicatesKey())
+            || binding.getKey().equals(setKey)
+            || binding.getKey().equals(collectionOfProvidersKey)
+            || binding.getKey().equals(collectionOfJavaxProvidersKey);
+      } else {
+        return false;
+      }
+    }
+
+    private boolean keyMatches(Key<?> key) {
+      return key.getTypeLiteral().equals(elementType)
+          && key.getAnnotation() instanceof Element
+          && ((Element) key.getAnnotation()).setName().equals(getSetName())
+          && ((Element) key.getAnnotation()).type() == MULTIBINDER;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (obj instanceof BindingSelection) {
+        return setKey.equals(((BindingSelection<?>) obj).setKey);
+      }
+      return false;
+    }
+
+    @Override
+    public int hashCode() {
+      return setKey.hashCode();
+    }
+
+    @Override
+    public String toString() {
+      return (getSetName().isEmpty() ? "" : getSetName() + " ")
+          + "Multibinder<"
+          + elementType
+          + ">";
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof RealMultibinder
+        && ((RealMultibinder<?>) o).bindingSelection.equals(bindingSelection);
+  }
+
+  @Override
+  public int hashCode() {
+    return bindingSelection.hashCode();
+  }
+
+  private static final class RealMultibinderCollectionOfProvidersProvider<T>
+      extends InternalProviderInstanceBindingImpl.Factory<Collection<Provider<T>>> {
+
+    private final BindingSelection<T> bindingSelection;
+    private ImmutableList<Provider<T>> collectionOfProviders;
+
+    RealMultibinderCollectionOfProvidersProvider(BindingSelection<T> bindingSelection) {
+      super(InitializationTiming.DELAYED); // See comment in RealMultibinderProvider
+      this.bindingSelection = bindingSelection;
+    }
+
+    @Override
+    void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      bindingSelection.initialize(injector, errors);
+      ImmutableList.Builder<Provider<T>> providers = ImmutableList.builder();
+      for (Binding<T> binding : bindingSelection.getBindings()) {
+        providers.add(binding.getProvider());
+      }
+      this.collectionOfProviders = providers.build();
+    }
+
+    @Override
+    protected Collection<Provider<T>> doProvision(
+        InternalContext context, Dependency<?> dependency) {
+      return collectionOfProviders;
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.getProviderDependencies();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj instanceof RealMultibinderCollectionOfProvidersProvider
+          && bindingSelection.equals(
+              ((RealMultibinderCollectionOfProvidersProvider<?>) obj).bindingSelection);
+    }
+
+    @Override
+    public int hashCode() {
+      return bindingSelection.hashCode();
+    }
+  }
+
+  /**
+   * We install the permit duplicates configuration as its own binding, all by itself. This way, if
+   * only one of a multibinder's users remember to call permitDuplicates(), they're still permitted.
+   *
+   * <p>This is like setting a global variable in the injector so that each instance of the
+   * multibinder will have the same value for permitDuplicates, even if it is only set on one of
+   * them.
+   */
+  private static class PermitDuplicatesModule extends AbstractModule {
+    private final Key<Boolean> key;
+
+    PermitDuplicatesModule(Key<Boolean> key) {
+      this.key = key;
+    }
+
+    @Override
+    protected void configure() {
+      bind(key).toInstance(true);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof PermitDuplicatesModule && ((PermitDuplicatesModule) o).key.equals(key);
+    }
+
+    @Override
+    public int hashCode() {
+      return getClass().hashCode() ^ key.hashCode();
+    }
+  }
+}
diff --git a/core/src/com/google/inject/internal/RealOptionalBinder.java b/core/src/com/google/inject/internal/RealOptionalBinder.java
new file mode 100644
index 0000000..7072d2e
--- /dev/null
+++ b/core/src/com/google/inject/internal/RealOptionalBinder.java
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.inject.internal.Errors.checkConfiguration;
+import static com.google.inject.util.Types.newParameterizedType;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.inject.Binder;
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.InternalProviderInstanceBindingImpl.InitializationTiming;
+import com.google.inject.multibindings.MultibindingsTargetVisitor;
+import com.google.inject.multibindings.OptionalBinderBinding;
+import com.google.inject.spi.BindingTargetVisitor;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.spi.ProviderWithExtensionVisitor;
+import com.google.inject.util.Types;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Set;
+import javax.inject.Qualifier;
+
+/**
+ * The actual OptionalBinder plays several roles. It implements Module to hide that fact from the
+ * public API, and installs the various bindings that are exposed to the user.
+ */
+public final class RealOptionalBinder<T> implements Module {
+  public static <T> RealOptionalBinder<T> newRealOptionalBinder(Binder binder, Key<T> type) {
+    binder = binder.skipSources(RealOptionalBinder.class);
+    RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<>(binder, type);
+    binder.install(optionalBinder);
+    return optionalBinder;
+  }
+
+  /* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */
+  private static final Class<?> JAVA_OPTIONAL_CLASS;
+  private static final Object JAVA_OPTIONAL_EMPTY;
+  private static final Method JAVA_OPTIONAL_OF_METHOD;
+
+  static {
+    Class<?> optional = null;
+    Object emptyObject = null;
+    Method of = null;
+    boolean useJavaOptional = false;
+    try {
+      optional = Class.forName("java.util.Optional");
+      emptyObject = optional.getDeclaredMethod("empty").invoke(null);
+      of = optional.getDeclaredMethod("of", Object.class);
+      // only use optional support if all our reflection succeeded
+      useJavaOptional = true;
+    } catch (ClassNotFoundException ignored) {
+    } catch (NoSuchMethodException ignored) {
+    } catch (SecurityException ignored) {
+    } catch (IllegalAccessException ignored) {
+    } catch (InvocationTargetException ignored) {
+    }
+    JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null;
+    JAVA_OPTIONAL_EMPTY = useJavaOptional ? emptyObject : null;
+    JAVA_OPTIONAL_OF_METHOD = useJavaOptional ? of : null;
+  }
+
+  /**
+   * Returns java.util.Optional.empty() if the parameter is null, calls {@link
+   * #invokeJavaOptionalOf} otherwise.
+   */
+  private static Object invokeJavaOptionalOfNullable(Object o) {
+    if (o == null) {
+      return JAVA_OPTIONAL_EMPTY;
+    }
+    return invokeJavaOptionalOf(o);
+  }
+
+  /** Invokes java.util.Optional.of. */
+  private static Object invokeJavaOptionalOf(Object o) {
+    try {
+      return JAVA_OPTIONAL_OF_METHOD.invoke(null, o);
+    } catch (IllegalAccessException e) {
+      throw new SecurityException(e);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalStateException(e);
+    } catch (InvocationTargetException e) {
+      throw Throwables.propagate(e.getCause());
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> TypeLiteral<Optional<T>> optionalOf(TypeLiteral<T> type) {
+    return (TypeLiteral<Optional<T>>)
+        TypeLiteral.get(Types.newParameterizedType(Optional.class, type.getType()));
+  }
+
+  static <T> TypeLiteral<?> javaOptionalOf(TypeLiteral<T> type) {
+    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
+    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType()));
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider(
+      TypeLiteral<T> type) {
+    return (TypeLiteral<Optional<javax.inject.Provider<T>>>)
+        TypeLiteral.get(
+            Types.newParameterizedType(
+                Optional.class, newParameterizedType(javax.inject.Provider.class, type.getType())));
+  }
+
+  static <T> TypeLiteral<?> javaOptionalOfJavaxProvider(TypeLiteral<T> type) {
+    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
+    return TypeLiteral.get(
+        Types.newParameterizedType(
+            JAVA_OPTIONAL_CLASS,
+            newParameterizedType(javax.inject.Provider.class, type.getType())));
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) {
+    return (TypeLiteral<Optional<Provider<T>>>)
+        TypeLiteral.get(
+            Types.newParameterizedType(
+                Optional.class, newParameterizedType(Provider.class, type.getType())));
+  }
+
+  static <T> TypeLiteral<?> javaOptionalOfProvider(TypeLiteral<T> type) {
+    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
+    return TypeLiteral.get(
+        Types.newParameterizedType(
+            JAVA_OPTIONAL_CLASS, newParameterizedType(Provider.class, type.getType())));
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> Key<Provider<T>> providerOf(Key<T> key) {
+    Type providerT = Types.providerOf(key.getTypeLiteral().getType());
+    return (Key<Provider<T>>) key.ofType(providerT);
+  }
+
+  enum Source {
+    DEFAULT,
+    ACTUAL
+  }
+
+  @Retention(RUNTIME)
+  @Qualifier
+  @interface Default {
+    String value();
+  }
+
+  @Retention(RUNTIME)
+  @Qualifier
+  @interface Actual {
+    String value();
+  }
+
+  private final BindingSelection<T> bindingSelection;
+  private final Binder binder;
+
+  private RealOptionalBinder(Binder binder, Key<T> typeKey) {
+    this.bindingSelection = new BindingSelection<>(typeKey);
+    this.binder = binder;
+  }
+
+  /**
+   * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
+   * bindings.
+   */
+  private void addDirectTypeBinding(Binder binder) {
+    binder
+        .bind(bindingSelection.getDirectKey())
+        .toProvider(new RealDirectTypeProvider<T>(bindingSelection));
+  }
+
+  /**
+   * Returns the key to use for the default binding.
+   *
+   * <p>As a side effect this installs support for the 'direct type', so a binding for {@code T}
+   * will be made available.
+   */
+  Key<T> getKeyForDefaultBinding() {
+    bindingSelection.checkNotInitialized();
+    addDirectTypeBinding(binder);
+    return bindingSelection.getKeyForDefaultBinding();
+  }
+
+  public LinkedBindingBuilder<T> setDefault() {
+    return binder.bind(getKeyForDefaultBinding());
+  }
+
+  /**
+   * Returns the key to use for the actual binding, overrides the default if set.
+   *
+   * <p>As a side effect this installs support for the 'direct type', so a binding for {@code T}
+   * will be made available.
+   */
+  Key<T> getKeyForActualBinding() {
+    bindingSelection.checkNotInitialized();
+    addDirectTypeBinding(binder);
+    return bindingSelection.getKeyForActualBinding();
+  }
+
+  public LinkedBindingBuilder<T> setBinding() {
+    return binder.bind(getKeyForActualBinding());
+  }
+
+  @Override
+  public void configure(Binder binder) {
+    bindingSelection.checkNotInitialized();
+    Key<T> key = bindingSelection.getDirectKey();
+    // Every OptionalBinder get's the following types bound
+    // * Optional<Provider<T>>
+    // * Optional<javax.inject.Provider<T>>
+    // * Optional<T>
+    // If setDefault() or setBinding() is called then also
+    // * T is bound
+    // If java.util.Optional is on the classpath (because this is a jdk8+ vm), then you also get
+    // * java.util.Optional<Provider<T>>
+    // * java.util.Optional<javax.inject.Provider<T>>
+    // * java.util.Optional<T>
+    InternalProviderInstanceBindingImpl.Factory<Optional<Provider<T>>> optionalProviderFactory =
+        new RealOptionalProviderProvider<T>(bindingSelection);
+    binder
+        .bind(key.ofType(optionalOfProvider(key.getTypeLiteral())))
+        .toProvider(optionalProviderFactory);
+
+    // Provider is assignable to javax.inject.Provider and the provider that the factory contains
+    // cannot be modified so we can use some rawtypes hackery to share the same implementation.
+    @SuppressWarnings("unchecked")
+    InternalProviderInstanceBindingImpl.Factory<Optional<javax.inject.Provider<T>>>
+        optionalJavaxProviderFactory =
+            (InternalProviderInstanceBindingImpl.Factory) optionalProviderFactory;
+    binder
+        .bind(key.ofType(optionalOfJavaxProvider(key.getTypeLiteral())))
+        .toProvider(optionalJavaxProviderFactory);
+
+    Key<Optional<T>> optionalKey = key.ofType(optionalOf(key.getTypeLiteral()));
+    binder
+        .bind(optionalKey)
+        .toProvider(new RealOptionalKeyProvider<T>(bindingSelection, optionalKey));
+
+    // Bind the java-8 types if we know them.
+    bindJava8Optional(binder);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void bindJava8Optional(Binder binder) {
+    if (JAVA_OPTIONAL_CLASS != null) {
+      Key<?> key = bindingSelection.getDirectKey();
+      TypeLiteral<?> typeLiteral = key.getTypeLiteral();
+      InternalProviderInstanceBindingImpl.Factory<Object> javaOptionalProviderFactory =
+          new JavaOptionalProviderProvider(bindingSelection);
+      binder
+          .bind(key.ofType(javaOptionalOfProvider(typeLiteral)))
+          .toProvider((Provider) javaOptionalProviderFactory);
+      // Provider is assignable to javax.inject.Provider and the provider that the factory contains
+      // cannot be modified so we can use some rawtypes hackery to share the same implementation.
+      binder
+          .bind(key.ofType(javaOptionalOfJavaxProvider(typeLiteral)))
+          .toProvider((Provider) javaOptionalProviderFactory);
+      Key<?> javaOptionalKey = key.ofType(javaOptionalOf(typeLiteral));
+      binder
+          .bind(javaOptionalKey)
+          .toProvider(new JavaOptionalProvider(bindingSelection, javaOptionalKey));
+    }
+  }
+
+  /** Provides the binding for java.util.Optional<T>. */
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private static final class JavaOptionalProvider extends RealOptionalBinderProviderWithDependencies
+      implements ProviderWithExtensionVisitor, OptionalBinderBinding {
+
+    private final Key<?> optionalKey;
+
+    private Dependency<?> targetDependency;
+    private InternalFactory<?> target;
+
+    JavaOptionalProvider(BindingSelection<?> bindingSelection, Key<?> optionalKey) {
+      super(bindingSelection);
+      this.optionalKey = optionalKey;
+    }
+
+    @Override
+    void doInitialize() {
+      if (bindingSelection.getBinding() != null) {
+        target = bindingSelection.getBinding().getInternalFactory();
+        targetDependency = bindingSelection.getDependency();
+      }
+    }
+
+    @Override
+    protected Object doProvision(InternalContext context, Dependency dependency)
+        throws InternalProvisionException {
+      InternalFactory<?> local = target;
+      if (local == null) {
+        return JAVA_OPTIONAL_EMPTY;
+      }
+      Dependency<?> localDependency = targetDependency;
+      Object result;
+      Dependency previous = context.pushDependency(localDependency, getSource());
+
+      try {
+        // See comments in RealOptionalKeyProvider, about how localDependency may be more specific
+        // than what we actually need.
+        result = local.get(context, localDependency, false);
+      } catch (InternalProvisionException ipe) {
+        throw ipe.addSource(localDependency);
+        } finally {
+          context.popStateAndSetDependency(previous);
+
+      }
+      return invokeJavaOptionalOfNullable(result);
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.dependencies;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object acceptExtensionVisitor(
+        BindingTargetVisitor visitor, ProviderInstanceBinding binding) {
+      if (visitor instanceof MultibindingsTargetVisitor) {
+        return ((MultibindingsTargetVisitor) visitor).visit(this);
+      } else {
+        return visitor.visit(binding);
+      }
+    }
+
+    @Override
+    public boolean containsElement(Element element) {
+      return bindingSelection.containsElement(element);
+    }
+
+    @Override
+    public Binding<?> getActualBinding() {
+      return bindingSelection.getActualBinding();
+    }
+
+    @Override
+    public Binding<?> getDefaultBinding() {
+      return bindingSelection.getDefaultBinding();
+    }
+
+    @Override
+    public Key getKey() {
+      return optionalKey;
+    }
+  }
+
+  /** Provides the binding for java.util.Optional<Provider<T>>. */
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private static final class JavaOptionalProviderProvider
+      extends RealOptionalBinderProviderWithDependencies {
+    private Object value;
+
+    JavaOptionalProviderProvider(BindingSelection<?> bindingSelection) {
+      super(bindingSelection);
+    }
+
+    @Override
+    void doInitialize() {
+      if (bindingSelection.getBinding() == null) {
+        value = JAVA_OPTIONAL_EMPTY;
+      } else {
+        value = invokeJavaOptionalOf(bindingSelection.getBinding().getProvider());
+      }
+    }
+
+    @Override
+    protected Object doProvision(InternalContext context, Dependency dependency) {
+      return value;
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.providerDependencies();
+    }
+  }
+
+  /** Provides the binding for T, conditionally installed by calling setBinding/setDefault. */
+  private static final class RealDirectTypeProvider<T>
+      extends RealOptionalBinderProviderWithDependencies<T, T> {
+    private Key<? extends T> targetKey;
+
+    private Object targetSource;
+
+    private InternalFactory<? extends T> targetFactory;
+
+    RealDirectTypeProvider(BindingSelection<T> bindingSelection) {
+      super(bindingSelection);
+    }
+
+    @Override
+    void doInitialize() {
+      BindingImpl<T> targetBinding = bindingSelection.getBinding();
+      // we only install this factory if they call setBinding()/setDefault() so we know that
+      // targetBinding will be non-null.
+      this.targetKey = targetBinding.getKey();
+      this.targetSource = targetBinding.getSource();
+      this.targetFactory = targetBinding.getInternalFactory();
+    }
+
+    @Override
+    protected T doProvision(InternalContext context, Dependency<?> dependency)
+        throws InternalProvisionException {
+      // This is what linked bindings do (see FactoryProxy), and we are pretty similar.
+      context.pushState(targetKey, targetSource);
+
+      try {
+        return targetFactory.get(context, dependency, true);
+      } catch (InternalProvisionException ipe) {
+        throw ipe.addSource(targetKey);
+        } finally {
+          context.popState();
+
+      }
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.dependencies;
+    }
+  }
+
+  /** Provides the binding for Optional<Provider<T>>. */
+  private static final class RealOptionalProviderProvider<T>
+      extends RealOptionalBinderProviderWithDependencies<T, Optional<Provider<T>>> {
+    private Optional<Provider<T>> value;
+
+    RealOptionalProviderProvider(BindingSelection<T> bindingSelection) {
+      super(bindingSelection);
+    }
+
+    @Override
+    void doInitialize() {
+      if (bindingSelection.getBinding() == null) {
+        value = Optional.absent();
+      } else {
+        value = Optional.of(bindingSelection.getBinding().getProvider());
+      }
+    }
+
+    @Override
+    protected Optional<Provider<T>> doProvision(InternalContext context, Dependency<?> dependency) {
+      return value;
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.providerDependencies();
+    }
+  }
+
+  /** Provides the binding for Optional<T>. */
+  private static final class RealOptionalKeyProvider<T>
+      extends RealOptionalBinderProviderWithDependencies<T, Optional<T>>
+      implements ProviderWithExtensionVisitor<Optional<T>>, OptionalBinderBinding<Optional<T>> {
+
+    private final Key<Optional<T>> optionalKey;
+
+    // These are assigned to non-null values during initialization if and only if we have a binding
+    // to delegate to.
+    private Dependency<?> targetDependency;
+    private InternalFactory<? extends T> delegate;
+
+    RealOptionalKeyProvider(BindingSelection<T> bindingSelection, Key<Optional<T>> optionalKey) {
+      super(bindingSelection);
+      this.optionalKey = optionalKey;
+    }
+
+    @Override
+    void doInitialize() {
+      if (bindingSelection.getBinding() != null) {
+        delegate = bindingSelection.getBinding().getInternalFactory();
+        targetDependency = bindingSelection.getDependency();
+      }
+    }
+
+    @Override
+    protected Optional<T> doProvision(InternalContext context, Dependency<?> currentDependency)
+        throws InternalProvisionException {
+      InternalFactory<? extends T> local = delegate;
+      if (local == null) {
+        return Optional.absent();
+      }
+      Dependency<?> localDependency = targetDependency;
+      T result;
+      Dependency previous = context.pushDependency(localDependency, getSource());
+
+      try {
+        // currentDependency is Optional<? super T>, so we really just need to set the target
+        // dependency to ? super T, but we are currently setting it to T.  We could hypothetically
+        // make it easier for our delegate to generate proxies by modifying the dependency, but that
+        // would also require us to rewrite the key on each call.  So for now we don't do it.
+        result = local.get(context, localDependency, false);
+      } catch (InternalProvisionException ipe) {
+        throw ipe.addSource(localDependency);
+        } finally {
+          context.popStateAndSetDependency(previous);
+
+      }
+      return Optional.fromNullable(result);
+    }
+
+    @Override
+    public Set<Dependency<?>> getDependencies() {
+      return bindingSelection.dependencies();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <B, R> R acceptExtensionVisitor(
+        BindingTargetVisitor<B, R> visitor, ProviderInstanceBinding<? extends B> binding) {
+      if (visitor instanceof MultibindingsTargetVisitor) {
+        return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this);
+      } else {
+        return visitor.visit(binding);
+      }
+    }
+
+    @Override
+    public Key<Optional<T>> getKey() {
+      return optionalKey;
+    }
+
+    @Override
+    public Binding<?> getActualBinding() {
+      return bindingSelection.getActualBinding();
+    }
+
+    @Override
+    public Binding<?> getDefaultBinding() {
+      return bindingSelection.getDefaultBinding();
+    }
+
+    @Override
+    public boolean containsElement(Element element) {
+      return bindingSelection.containsElement(element);
+    }
+  }
+
+  /**
+   * A helper object that implements the core logic for deciding what the implementation of the
+   * binding will be.
+   *
+   * <p>This also implements the main OptionalBinderBinding logic.
+   */
+  private static final class BindingSelection<T> {
+    private static final ImmutableSet<Dependency<?>> MODULE_DEPENDENCIES =
+        ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
+
+    /*@Nullable */ BindingImpl<T> actualBinding;
+    /*@Nullable */ BindingImpl<T> defaultBinding;
+    /*@Nullable */ BindingImpl<T> binding;
+    private boolean initialized;
+    private final Key<T> key;
+
+    // Until the injector initializes us, we don't know what our dependencies are,
+    // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly).
+    private ImmutableSet<Dependency<?>> dependencies = MODULE_DEPENDENCIES;
+    private ImmutableSet<Dependency<?>> providerDependencies = MODULE_DEPENDENCIES;
+
+    /** lazily allocated, by {@link #getBindingName}. */
+    private String bindingName;
+
+    /** lazily allocated, by {@link #getKeyForDefaultBinding}. */
+    private Key<T> defaultBindingKey;
+
+    /** lazily allocated, by {@link #getKeyForActualBinding}. */
+    private Key<T> actualBindingKey;
+
+    BindingSelection(Key<T> key) {
+      this.key = key;
+    }
+
+    void checkNotInitialized() {
+      checkConfiguration(!initialized, "already initialized");
+    }
+
+    void initialize(InjectorImpl injector) {
+      // Every one of our providers will call this method, so only execute the logic once.
+      if (initialized) {
+        return;
+      }
+
+      actualBinding = injector.getExistingBinding(getKeyForActualBinding());
+      defaultBinding = injector.getExistingBinding(getKeyForDefaultBinding());
+      // We should never create Jit bindings, but we can use them if some other binding created it.
+      BindingImpl<T> userBinding = injector.getExistingBinding(key);
+      if (actualBinding != null) {
+        // TODO(sameb): Consider exposing an option that will allow
+        // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null.
+        // Right now, an ACTUAL binding can convert from present -> absent
+        // if it's bound to a provider that returns null.
+        binding = actualBinding;
+      } else if (defaultBinding != null) {
+        binding = defaultBinding;
+      } else if (userBinding != null) {
+        // If neither the actual or default is set, then we fallback
+        // to the value bound to the type itself and consider that the
+        // "actual binding" for the SPI.
+        binding = userBinding;
+        actualBinding = userBinding;
+      }
+      if (binding != null) {
+        dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey()));
+        providerDependencies =
+            ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey())));
+      } else {
+        dependencies = ImmutableSet.of();
+        providerDependencies = ImmutableSet.of();
+      }
+      initialized = true;
+    }
+
+    Key<T> getKeyForDefaultBinding() {
+      if (defaultBindingKey == null) {
+        defaultBindingKey = Key.get(key.getTypeLiteral(), new DefaultImpl(getBindingName()));
+      }
+      return defaultBindingKey;
+    }
+
+    Key<T> getKeyForActualBinding() {
+      if (actualBindingKey == null) {
+        actualBindingKey = Key.get(key.getTypeLiteral(), new ActualImpl(getBindingName()));
+      }
+      return actualBindingKey;
+    }
+
+    Key<T> getDirectKey() {
+      return key;
+    }
+
+    private String getBindingName() {
+      // Lazily allocated, most instantiations will never need this because they are deduped during
+      // module installation.
+      if (bindingName == null) {
+        bindingName = Annotations.nameOf(key);
+      }
+      return bindingName;
+    }
+
+    BindingImpl<T> getBinding() {
+      return binding;
+    }
+
+    // Provide default implementations for most of the OptionalBinderBinding interface
+    BindingImpl<T> getDefaultBinding() {
+      return defaultBinding;
+    }
+
+    BindingImpl<T> getActualBinding() {
+      return actualBinding;
+    }
+
+    ImmutableSet<Dependency<?>> providerDependencies() {
+      return providerDependencies;
+    }
+
+    ImmutableSet<Dependency<?>> dependencies() {
+      return dependencies;
+    }
+
+    /**
+     * Returns the Dependency for the target binding, throws NoSuchElementException if no target
+     * exists.
+     *
+     * <p>Calls to this method should typically be guarded by checking if {@link #getBinding()}
+     * returns {@code null}.
+     */
+    Dependency<?> getDependency() {
+      return Iterables.getOnlyElement(dependencies);
+    }
+
+    /** Implementation of {@link OptionalBinderBinding#containsElement}. */
+    boolean containsElement(Element element) {
+      // All of our bindings are ProviderInstanceBindings whose providers extend
+      // RealOptionalBinderProviderWithDependencies and have 'this' as its binding selection.
+      if (element instanceof ProviderInstanceBinding) {
+        javax.inject.Provider<?> providerInstance =
+            ((ProviderInstanceBinding<?>) element).getUserSuppliedProvider();
+        if (providerInstance instanceof RealOptionalBinderProviderWithDependencies) {
+          return ((RealOptionalBinderProviderWithDependencies<?, ?>) providerInstance)
+              .bindingSelection.equals(this);
+        }
+      }
+      if (element instanceof Binding) {
+        Key<?> elementKey = ((Binding) element).getKey();
+        // if it isn't one of the things we bound directly it might be an actual or default key
+        return elementKey.equals(getKeyForActualBinding())
+            || elementKey.equals(getKeyForDefaultBinding());
+      }
+      return false; // cannot match;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return o instanceof BindingSelection && ((BindingSelection) o).key.equals(key);
+    }
+
+    @Override
+    public int hashCode() {
+      return key.hashCode();
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof RealOptionalBinder
+        && ((RealOptionalBinder<?>) o).bindingSelection.equals(bindingSelection);
+  }
+
+  @Override
+  public int hashCode() {
+    return bindingSelection.hashCode();
+  }
+
+  /** A base class for ProviderWithDependencies that need equality based on a specific object. */
+  private abstract static class RealOptionalBinderProviderWithDependencies<T, P>
+      extends InternalProviderInstanceBindingImpl.Factory<P> {
+    protected final BindingSelection<T> bindingSelection;
+
+    RealOptionalBinderProviderWithDependencies(BindingSelection<T> bindingSelection) {
+      // We need delayed initialization so we can detect jit bindings created by other bindings
+      // while not also creating jit bindings ourselves.  This ensures we only pick up user bindings
+      // if the binding would have existed in the injector statically.
+      super(InitializationTiming.DELAYED);
+      this.bindingSelection = bindingSelection;
+    }
+
+    @Override
+    final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
+      bindingSelection.initialize(injector);
+      doInitialize();
+    }
+
+    /**
+     * Initialize the factory. BindingSelection is guaranteed to be initialized at this point and
+     * this will be called prior to any provisioning.
+     */
+    abstract void doInitialize();
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj != null
+          && this.getClass() == obj.getClass()
+          && bindingSelection.equals(
+              ((RealOptionalBinderProviderWithDependencies<?, ?>) obj).bindingSelection);
+    }
+
+    @Override
+    public int hashCode() {
+      return bindingSelection.hashCode();
+    }
+  }
+
+  static class DefaultImpl extends BaseAnnotation implements Default {
+    public DefaultImpl(String value) {
+      super(Default.class, value);
+    }
+  }
+
+  static class ActualImpl extends BaseAnnotation implements Actual {
+    public ActualImpl(String value) {
+      super(Actual.class, value);
+    }
+  }
+
+  abstract static class BaseAnnotation implements Serializable, Annotation {
+
+    private final String value;
+    private final Class<? extends Annotation> clazz;
+
+    BaseAnnotation(Class<? extends Annotation> clazz, String value) {
+      this.clazz = checkNotNull(clazz, "clazz");
+      this.value = checkNotNull(value, "value");
+    }
+
+    public String value() {
+      return this.value;
+    }
+
+    @Override
+    public int hashCode() {
+      // This is specified in java.lang.Annotation.
+      return (127 * "value".hashCode()) ^ value.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      // We check against each annotation type instead of BaseAnnotation
+      // so that we can compare against generated annotation implementations.
+      if (o instanceof Actual && clazz == Actual.class) {
+        Actual other = (Actual) o;
+        return value.equals(other.value());
+      } else if (o instanceof Default && clazz == Default.class) {
+        Default other = (Default) o;
+        return value.equals(other.value());
+      }
+      return false;
+    }
+
+    @Override
+    public String toString() {
+      return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")");
+    }
+
+    @Override
+    public Class<? extends Annotation> annotationType() {
+      return clazz;
+    }
+
+    private static final long serialVersionUID = 0;
+  }
+}
diff --git a/core/src/com/google/inject/internal/ScopeBindingProcessor.java b/core/src/com/google/inject/internal/ScopeBindingProcessor.java
index 3e68b30..83d7f8a 100644
--- a/core/src/com/google/inject/internal/ScopeBindingProcessor.java
+++ b/core/src/com/google/inject/internal/ScopeBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,6 @@
 
 import com.google.inject.Scope;
 import com.google.inject.spi.ScopeBinding;
-
 import java.lang.annotation.Annotation;
 
 /**
@@ -35,9 +34,11 @@
     super(errors);
   }
 
-  @Override public Boolean visit(ScopeBinding command) {
+  @Override
+  public Boolean visit(ScopeBinding command) {
     Scope scope = checkNotNull(command.getScope(), "scope");
-    Class<? extends Annotation> annotationType = checkNotNull(command.getAnnotationType(), "annotation type");
+    Class<? extends Annotation> annotationType =
+        checkNotNull(command.getAnnotationType(), "annotation type");
 
     if (!Annotations.isScopeAnnotation(annotationType)) {
       errors.missingScopeAnnotation(annotationType);
@@ -60,4 +61,4 @@
 
     return true;
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/internal/Scoping.java b/core/src/com/google/inject/internal/Scoping.java
index 334aaef..53b72c0 100644
--- a/core/src/com/google/inject/internal/Scoping.java
+++ b/core/src/com/google/inject/internal/Scoping.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,7 +26,6 @@
 import com.google.inject.binder.ScopedBindingBuilder;
 import com.google.inject.spi.BindingScopingVisitor;
 import com.google.inject.spi.ScopeBinding;
-
 import java.lang.annotation.Annotation;
 
 /**
@@ -41,98 +40,148 @@
    * No scoping annotation has been applied. Note that this is different from {@code
    * in(Scopes.NO_SCOPE)}, where the 'NO_SCOPE' has been explicitly applied.
    */
-  public static final Scoping UNSCOPED = new Scoping() {
-    @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
-      return visitor.visitNoScoping();
-    }
+  public static final Scoping UNSCOPED =
+      new Scoping() {
+        @Override
+        public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+          return visitor.visitNoScoping();
+        }
 
-    @Override public Scope getScopeInstance() {
-      return Scopes.NO_SCOPE;
-    }
+        @Override
+        public Scope getScopeInstance() {
+          return Scopes.NO_SCOPE;
+        }
 
-    @Override public String toString() {
-      return Scopes.NO_SCOPE.toString();
-    }
+        @Override
+        public String toString() {
+          return Scopes.NO_SCOPE.toString();
+        }
 
-    @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
-      // do nothing
-    }
-  };
+        @Override
+        public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+          // do nothing
+        }
+      };
 
-  public static final Scoping SINGLETON_ANNOTATION = new Scoping() {
-    @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
-      return visitor.visitScopeAnnotation(Singleton.class);
-    }
+  /**
+   * No scoping annotation has been applied explicitly. Note that this is is the same as {@code
+   * in(Scopes.NO_SCOPE)}.
+   */
+  private static final Scoping EXPLICITLY_UNSCOPED =
+      new Scoping() {
+        @Override
+        public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+          return visitor.visitNoScoping();
+        }
 
-    @Override public Class<? extends Annotation> getScopeAnnotation() {
-      return Singleton.class;
-    }
+        @Override
+        public Scope getScopeInstance() {
+          return Scopes.NO_SCOPE;
+        }
 
-    @Override public String toString() {
-      return Singleton.class.getName();
-    }
+        @Override
+        public String toString() {
+          return Scopes.NO_SCOPE.toString();
+        }
 
-    @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
-      scopedBindingBuilder.in(Singleton.class);
-    }
-  };
+        @Override
+        public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+          scopedBindingBuilder.in(Scopes.NO_SCOPE);
+        }
+      };
 
-  public static final Scoping SINGLETON_INSTANCE = new Scoping() {
-    @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
-      return visitor.visitScope(Scopes.SINGLETON);
-    }
+  public static final Scoping SINGLETON_ANNOTATION =
+      new Scoping() {
+        @Override
+        public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+          return visitor.visitScopeAnnotation(Singleton.class);
+        }
 
-    @Override public Scope getScopeInstance() {
-      return Scopes.SINGLETON;
-    }
+        @Override
+        public Class<? extends Annotation> getScopeAnnotation() {
+          return Singleton.class;
+        }
 
-    @Override public String toString() {
-      return Scopes.SINGLETON.toString();
-    }
+        @Override
+        public String toString() {
+          return Singleton.class.getName();
+        }
 
-    @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
-      scopedBindingBuilder.in(Scopes.SINGLETON);
-    }
-  };
+        @Override
+        public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+          scopedBindingBuilder.in(Singleton.class);
+        }
+      };
 
-  public static final Scoping EAGER_SINGLETON = new Scoping() {
-    @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
-      return visitor.visitEagerSingleton();
-    }
+  public static final Scoping SINGLETON_INSTANCE =
+      new Scoping() {
+        @Override
+        public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+          return visitor.visitScope(Scopes.SINGLETON);
+        }
 
-    @Override public Scope getScopeInstance() {
-      return Scopes.SINGLETON;
-    }
+        @Override
+        public Scope getScopeInstance() {
+          return Scopes.SINGLETON;
+        }
 
-    @Override public String toString() {
-      return "eager singleton";
-    }
+        @Override
+        public String toString() {
+          return Scopes.SINGLETON.toString();
+        }
 
-    @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
-      scopedBindingBuilder.asEagerSingleton();
-    }
-  };
+        @Override
+        public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+          scopedBindingBuilder.in(Scopes.SINGLETON);
+        }
+      };
+
+  public static final Scoping EAGER_SINGLETON =
+      new Scoping() {
+        @Override
+        public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+          return visitor.visitEagerSingleton();
+        }
+
+        @Override
+        public Scope getScopeInstance() {
+          return Scopes.SINGLETON;
+        }
+
+        @Override
+        public String toString() {
+          return "eager singleton";
+        }
+
+        @Override
+        public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+          scopedBindingBuilder.asEagerSingleton();
+        }
+      };
 
   public static Scoping forAnnotation(final Class<? extends Annotation> scopingAnnotation) {
-    if (scopingAnnotation == Singleton.class
-        || scopingAnnotation == javax.inject.Singleton.class) {
+    if (scopingAnnotation == Singleton.class || scopingAnnotation == javax.inject.Singleton.class) {
       return SINGLETON_ANNOTATION;
     }
 
     return new Scoping() {
-      @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+      @Override
+      public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
         return visitor.visitScopeAnnotation(scopingAnnotation);
       }
 
-      @Override public Class<? extends Annotation> getScopeAnnotation() {
+      @Override
+      public Class<? extends Annotation> getScopeAnnotation() {
         return scopingAnnotation;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return scopingAnnotation.getName();
       }
 
-      @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+      @Override
+      public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
         scopedBindingBuilder.in(scopingAnnotation);
       }
     };
@@ -141,22 +190,28 @@
   public static Scoping forInstance(final Scope scope) {
     if (scope == Scopes.SINGLETON) {
       return SINGLETON_INSTANCE;
+    } else if (scope == Scopes.NO_SCOPE) {
+      return EXPLICITLY_UNSCOPED;
     }
 
     return new Scoping() {
-      @Override public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
+      @Override
+      public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
         return visitor.visitScope(scope);
       }
 
-      @Override public Scope getScopeInstance() {
+      @Override
+      public Scope getScopeInstance() {
         return scope;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return scope.toString();
       }
 
-      @Override public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
+      @Override
+      public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
         scopedBindingBuilder.in(scope);
       }
     };
@@ -178,9 +233,7 @@
     return getScopeInstance() == Scopes.NO_SCOPE;
   }
 
-  /**
-   * Returns true if this scope is a singleton that should be loaded eagerly in {@code stage}.
-   */
+  /** Returns true if this scope is a singleton that should be loaded eagerly in {@code stage}. */
   public boolean isEagerSingleton(Stage stage) {
     if (this == EAGER_SINGLETON) {
       return true;
@@ -193,31 +246,27 @@
     return false;
   }
 
-  /**
-   * Returns the scope instance, or {@code null} if that isn't known for this instance.
-   */
+  /** Returns the scope instance, or {@code null} if that isn't known for this instance. */
   public Scope getScopeInstance() {
     return null;
   }
 
-  /**
-   * Returns the scope annotation, or {@code null} if that isn't known for this instance.
-   */
+  /** Returns the scope annotation, or {@code null} if that isn't known for this instance. */
   public Class<? extends Annotation> getScopeAnnotation() {
     return null;
   }
-  
+
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof Scoping) {
-      Scoping o = (Scoping)obj;
+    if (obj instanceof Scoping) {
+      Scoping o = (Scoping) obj;
       return Objects.equal(getScopeAnnotation(), o.getScopeAnnotation())
-        && Objects.equal(getScopeInstance(), o.getScopeInstance());
+          && Objects.equal(getScopeInstance(), o.getScopeInstance());
     } else {
       return false;
     }
   }
-  
+
   @Override
   public int hashCode() {
     return Objects.hashCode(getScopeAnnotation(), getScopeInstance());
@@ -230,8 +279,12 @@
   private Scoping() {}
 
   /** Scopes an internal factory. */
-  static <T> InternalFactory<? extends T> scope(Key<T> key, InjectorImpl injector,
-      InternalFactory<? extends T> creator, Object source, Scoping scoping) {
+  static <T> InternalFactory<? extends T> scope(
+      Key<T> key,
+      InjectorImpl injector,
+      InternalFactory<? extends T> creator,
+      Object source,
+      Scoping scoping) {
 
     if (scoping.isNoScope()) {
       return creator;
@@ -239,8 +292,11 @@
 
     Scope scope = scoping.getScopeInstance();
 
-    Provider<T> scoped
-        = scope.scope(key, new ProviderToInternalFactoryAdapter<T>(injector, creator));
+    // NOTE: SingletonScope relies on the fact that we are passing a
+    // ProviderToInternalFactoryAdapter here.  If you change the type make sure to update
+    // SingletonScope as well.
+    Provider<T> scoped =
+        scope.scope(key, new ProviderToInternalFactoryAdapter<T>(injector, creator));
     return new InternalFactoryToProviderAdapter<T>(scoped, source);
   }
 
diff --git a/core/src/com/google/inject/internal/SingleFieldInjector.java b/core/src/com/google/inject/internal/SingleFieldInjector.java
index 52be1f4..5319d45 100644
--- a/core/src/com/google/inject/internal/SingleFieldInjector.java
+++ b/core/src/com/google/inject/internal/SingleFieldInjector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,9 @@
 import com.google.inject.internal.InjectorImpl.JitLimitation;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.reflect.Field;
 
-/**
- * Sets an injectable field.
- */
+/** Sets an injectable field. */
 final class SingleFieldInjector implements SingleMemberInjector {
   final Field field;
   final InjectionPoint injectionPoint;
@@ -42,23 +39,24 @@
     binding = injector.getBindingOrThrow(dependency.getKey(), errors, JitLimitation.NO_JIT);
   }
 
+  @Override
   public InjectionPoint getInjectionPoint() {
     return injectionPoint;
   }
 
-  public void inject(Errors errors, InternalContext context, Object o) {
-    errors = errors.withSource(dependency);
-
+  @Override
+  public void inject(InternalContext context, Object o) throws InternalProvisionException {
     Dependency previous = context.pushDependency(dependency, binding.getSource());
+
     try {
-      Object value = binding.getInternalFactory().get(errors, context, dependency, false);
+      Object value = binding.getInternalFactory().get(context, dependency, false);
       field.set(o, value);
-    } catch (ErrorsException e) {
-      errors.withSource(injectionPoint).merge(e.getErrors());
+    } catch (InternalProvisionException e) {
+      throw e.addSource(dependency);
     } catch (IllegalAccessException e) {
       throw new AssertionError(e); // a security manager is blocking us, we're hosed
     } finally {
-      context.popStateAndSetDependency(previous);
-    }
+        context.popStateAndSetDependency(previous);
+      }
   }
 }
diff --git a/core/src/com/google/inject/internal/SingleMemberInjector.java b/core/src/com/google/inject/internal/SingleMemberInjector.java
index fea5733..f20a5e5 100644
--- a/core/src/com/google/inject/internal/SingleMemberInjector.java
+++ b/core/src/com/google/inject/internal/SingleMemberInjector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,9 @@
 
 import com.google.inject.spi.InjectionPoint;
 
-/**
- * Injects a field or method of a given object.
- */
+/** Injects a field or method of a given object. */
 interface SingleMemberInjector {
-  void inject(Errors errors, InternalContext context, Object o);
+  void inject(InternalContext context, Object o) throws InternalProvisionException;
+
   InjectionPoint getInjectionPoint();
 }
diff --git a/core/src/com/google/inject/internal/SingleMethodInjector.java b/core/src/com/google/inject/internal/SingleMethodInjector.java
index 8bc8a34..9cf7d93 100644
--- a/core/src/com/google/inject/internal/SingleMethodInjector.java
+++ b/core/src/com/google/inject/internal/SingleMethodInjector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,17 +16,13 @@
 
 package com.google.inject.internal;
 
-import com.google.inject.internal.BytecodeGen.Visibility;
 import com.google.inject.internal.InjectorImpl.MethodInvoker;
 import com.google.inject.spi.InjectionPoint;
-
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
-/**
- * Invokes an injectable method.
- */
+/** Invokes an injectable method. */
 final class SingleMethodInjector implements SingleMemberInjector {
   private final MethodInvoker methodInvoker;
   private final SingleParameterInjector<?>[] parameterInjectors;
@@ -42,31 +38,33 @@
 
   private MethodInvoker createMethodInvoker(final Method method) {
 
-    // We can't use FastMethod if the method is private.
-    int modifiers = method.getModifiers();
-    if (!Modifier.isPrivate(modifiers) && !Modifier.isProtected(modifiers)) {
-      /*if[AOP]*/
-      try {
-      final net.sf.cglib.reflect.FastMethod fastMethod
-          = BytecodeGen.newFastClass(method.getDeclaringClass(), Visibility.forMember(method))
-              .getMethod(method);
+    /*if[AOP]*/
+    try {
+      final net.sf.cglib.reflect.FastClass fastClass = BytecodeGen.newFastClassForMember(method);
+      if (fastClass != null) {
+        final int index = fastClass.getMethod(method).getIndex();
 
-      return new MethodInvoker() {
-        public Object invoke(Object target, Object... parameters)
-            throws IllegalAccessException, InvocationTargetException {
-          return fastMethod.invoke(target, parameters);
-        }
-      };
-      } catch (net.sf.cglib.core.CodeGenerationException e) {/* fall-through */}
-      /*end[AOP]*/
+        return new MethodInvoker() {
+          @Override
+          public Object invoke(Object target, Object... parameters)
+              throws IllegalAccessException, InvocationTargetException {
+            return fastClass.invoke(index, target, parameters);
+          }
+        };
+      }
+    } catch (net.sf.cglib.core.CodeGenerationException e) {
+      /* fall-through */
     }
+    /*end[AOP]*/
 
-    if (!Modifier.isPublic(modifiers) ||
-        !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
+    int modifiers = method.getModifiers();
+    if (!Modifier.isPublic(modifiers)
+        || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
       method.setAccessible(true);
     }
 
     return new MethodInvoker() {
+      @Override
       public Object invoke(Object target, Object... parameters)
           throws IllegalAccessException, InvocationTargetException {
         return method.invoke(target, parameters);
@@ -74,28 +72,22 @@
     };
   }
 
+  @Override
   public InjectionPoint getInjectionPoint() {
     return injectionPoint;
   }
 
-  public void inject(Errors errors, InternalContext context, Object o) {
-    Object[] parameters;
-    try {
-      parameters = SingleParameterInjector.getAll(errors, context, parameterInjectors);
-    } catch (ErrorsException e) {
-      errors.merge(e.getErrors());
-      return;
-    }
+  @Override
+  public void inject(InternalContext context, Object o) throws InternalProvisionException {
+    Object[] parameters = SingleParameterInjector.getAll(context, parameterInjectors);
 
     try {
       methodInvoker.invoke(o, parameters);
     } catch (IllegalAccessException e) {
       throw new AssertionError(e); // a security manager is blocking us, we're hosed
     } catch (InvocationTargetException userException) {
-      Throwable cause = userException.getCause() != null
-          ? userException.getCause()
-          : userException;
-      errors.withSource(injectionPoint).errorInjectingMethod(cause);
+      Throwable cause = userException.getCause() != null ? userException.getCause() : userException;
+      throw InternalProvisionException.errorInjectingMethod(cause).addSource(injectionPoint);
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/SingleParameterInjector.java b/core/src/com/google/inject/internal/SingleParameterInjector.java
index 708b8b0..3e36ed7 100644
--- a/core/src/com/google/inject/internal/SingleParameterInjector.java
+++ b/core/src/com/google/inject/internal/SingleParameterInjector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,54 +18,52 @@
 
 import com.google.inject.spi.Dependency;
 
-/**
- * Resolves a single parameter, to be used in a constructor or method invocation.
- */
+/** Resolves a single parameter, to be used in a constructor or method invocation. */
 final class SingleParameterInjector<T> {
-  private static final Object[] NO_ARGUMENTS = {}; 
+  private static final Object[] NO_ARGUMENTS = {};
 
   private final Dependency<T> dependency;
-  private final BindingImpl<? extends T> binding;
+
+  private final Object source;
+
+  private final InternalFactory<? extends T> factory;
 
   SingleParameterInjector(Dependency<T> dependency, BindingImpl<? extends T> binding) {
     this.dependency = dependency;
-    this.binding = binding;
+    this.source = binding.getSource();
+    this.factory = binding.getInternalFactory();
   }
 
-  private T inject(Errors errors, InternalContext context) throws ErrorsException {
-    Dependency previous = context.pushDependency(dependency, binding.getSource());
+  T inject(InternalContext context) throws InternalProvisionException {
+    Dependency<T> localDependency = dependency;
+    Dependency previous = context.pushDependency(localDependency, source);
+
     try {
-      return binding.getInternalFactory().get(errors.withSource(dependency), context, dependency, false);
-    } finally {
-      context.popStateAndSetDependency(previous);
+      return factory.get(context, localDependency, false);
+    } catch (InternalProvisionException ipe) {
+      throw ipe.addSource(localDependency);
+      } finally {
+        context.popStateAndSetDependency(previous);
+
     }
   }
 
-  /**
-   * Returns an array of parameter values.
-   */
-  static Object[] getAll(Errors errors, InternalContext context,
-      SingleParameterInjector<?>[] parameterInjectors) throws ErrorsException {
+  // TODO(lukes): inline into callers to decrease stack depth
+
+  /** Returns an array of parameter values. */
+  static Object[] getAll(InternalContext context, SingleParameterInjector<?>[] parameterInjectors)
+      throws InternalProvisionException {
     if (parameterInjectors == null) {
       return NO_ARGUMENTS;
     }
 
-    int numErrorsBefore = errors.size();
-
     int size = parameterInjectors.length;
     Object[] parameters = new Object[size];
 
-    // optimization: use manual for/each to save allocating an iterator here  
+    // optimization: use manual for/each to save allocating an iterator here
     for (int i = 0; i < size; i++) {
-      SingleParameterInjector<?> parameterInjector = parameterInjectors[i];
-      try {
-        parameters[i] = parameterInjector.inject(errors, context);
-      } catch (ErrorsException e) {
-        errors.merge(e.getErrors());
-      }
+      parameters[i] = parameterInjectors[i].inject(context);
     }
-
-    errors.throwIfNewErrors(numErrorsBefore);
     return parameters;
   }
 }
diff --git a/core/src/com/google/inject/internal/SingletonScope.java b/core/src/com/google/inject/internal/SingletonScope.java
index fe6287a..c07ccb7 100644
--- a/core/src/com/google/inject/internal/SingletonScope.java
+++ b/core/src/com/google/inject/internal/SingletonScope.java
@@ -2,10 +2,8 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Provider;
@@ -15,58 +13,43 @@
 import com.google.inject.Singleton;
 import com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory;
 import com.google.inject.spi.Dependency;
-import com.google.inject.spi.DependencyAndSource;
 import com.google.inject.spi.Message;
-
-import java.util.Collections;
+import java.util.Formatter;
 import java.util.List;
-import java.util.Map;
 
 /**
  * One instance per {@link Injector}. Also see {@code @}{@link Singleton}.
  *
- * Introduction from the author:
- * Implementation of this class seems unreasonably complicated at the first sight.
- * I fully agree with you, that the beast below is very complex
- * and it's hard to reason on how does it work or not.
- * Still I want to assure you that hundreds(?) of hours were thrown
- * into making this code simple, while still maintaining Singleton contract.
+ * <p>Introduction from the author: Implementation of this class seems unreasonably complicated at
+ * the first sight. I fully agree with you, that the beast below is very complex and it's hard to
+ * reason on how does it work or not. Still I want to assure you that hundreds(?) of hours were
+ * thrown into making this code simple, while still maintaining Singleton contract.
  *
- * Anyway, why is it so complex? Singleton scope does not seem to be that unique.
- * 1) Guice has never truly expected to be used in multi threading environment
- *    with many Injectors working alongside each other. There is almost no
- *    code with Guice that propagates state between threads. And Singleton
- *    scope is The exception.
- * 2) Guice supports circular dependencies and thus manages proxy objects.
- *    There is no interface that allows user defined Scopes to create proxies,
- *    it is expected to be done by Guice. Singleton scope needs to be
- *    able to detect circular dependencies spanning several threads,
- *    therefore Singleton scope needs to be able to create these proxies.
- * 3) To make things worse, Guice has a very tricky definition for a binding
- *    resolution when Injectors are in in a parent/child relationship.
- *    And Scope does not have access to this information by design,
- *    the only real action that Scope can do is to call or not to call a creator.
- * 4) There is no readily available code in Guice that can detect a potential
- *    deadlock, and no code for handling dependency cycles spanning several threads.
- *    This is significantly harder as all the dependencies in a thread at runtime
- *    can be represented with a list, where in a multi threaded environment
- *    we have more complex dependency trees.
- * 5) Guice has a pretty strong contract regarding Garbage Collection,
- *    which often prevents us from linking objects directly.
- *    So simple domain specific code can not be written and intermediary
- *    id objects need to be managed.
- * 6) Guice is relatively fast and we should not make things worse.
- *    We're trying our best to optimize synchronization for speed and memory.
- *    Happy path should be almost as fast as in a single threaded solution
- *    and should not take much more memory.
- * 7) Error message generation in Guice was not meant to be used like this and to work around
- *    its APIs we need a lot of code. Additional complexity comes from inherent data races
- *    as message is only generated when failure occurs on proxy object generation.
- * Things get ugly pretty fast.
+ * <p>Anyway, why is it so complex? Singleton scope does not seem to be that unique. 1) Guice has
+ * never truly expected to be used in multi threading environment with many Injectors working
+ * alongside each other. There is almost no code with Guice that propagates state between threads.
+ * And Singleton scope is The exception. 2) Guice supports circular dependencies and thus manages
+ * proxy objects. There is no interface that allows user defined Scopes to create proxies, it is
+ * expected to be done by Guice. Singleton scope needs to be able to detect circular dependencies
+ * spanning several threads, therefore Singleton scope needs to be able to create these proxies. 3)
+ * To make things worse, Guice has a very tricky definition for a binding resolution when Injectors
+ * are in in a parent/child relationship. And Scope does not have access to this information by
+ * design, the only real action that Scope can do is to call or not to call a creator. 4) There is
+ * no readily available code in Guice that can detect a potential deadlock, and no code for handling
+ * dependency cycles spanning several threads. This is significantly harder as all the dependencies
+ * in a thread at runtime can be represented with a list, where in a multi threaded environment we
+ * have more complex dependency trees. 5) Guice has a pretty strong contract regarding Garbage
+ * Collection, which often prevents us from linking objects directly. So simple domain specific code
+ * can not be written and intermediary id objects need to be managed. 6) Guice is relatively fast
+ * and we should not make things worse. We're trying our best to optimize synchronization for speed
+ * and memory. Happy path should be almost as fast as in a single threaded solution and should not
+ * take much more memory. 7) Error message generation in Guice was not meant to be used like this
+ * and to work around its APIs we need a lot of code. Additional complexity comes from inherent data
+ * races as message is only generated when failure occurs on proxy object generation. Things get
+ * ugly pretty fast.
  *
  * @see #scope(Key, Provider)
  * @see CycleDetectingLock
- *
  * @author timofeyb (Timothy Basanov)
  */
 public class SingletonScope implements Scope {
@@ -78,36 +61,34 @@
    * Allows us to detect when circular proxies are necessary. It's only used during singleton
    * instance initialization, after initialization direct access through volatile field is used.
    *
-   * NB: Factory uses {@link Key}s as a user locks ids, different injectors can
-   * share them. Cycles are detected properly as cycle detection does not rely on user locks ids,
-   * but error message generated could be less than ideal.
-   *
-   * TODO(user): we may use one factory per injector tree for optimization reasons
+   * <p>NB: Factory uses {@link Key}s as a user locks ids, different injectors can share them.
+   * Cycles are detected properly as cycle detection does not rely on user locks ids, but error
+   * message generated could be less than ideal.
    */
+  // TODO(user): we may use one factory per injector tree for optimization reasons
   private static final CycleDetectingLockFactory<Key<?>> cycleDetectingLockFactory =
       new CycleDetectingLockFactory<Key<?>>();
 
   /**
-   * Provides singleton scope with the following properties:
-   * - creates no more than one instance per Key as a creator is used no more than once,
-   * - result is cached and returned quickly on subsequent calls,
-   * - exception in a creator is not treated as instance creation and is not cached,
-   * - creates singletons in parallel whenever possible,
-   * - waits for dependent singletons to be created even across threads and when dependencies
-   *   are shared as long as no circular dependencies are detected,
-   * - returns circular proxy only when circular dependencies are detected,
-   * - aside from that, blocking synchronization is only used for proxy creation and initialization,
+   * Provides singleton scope with the following properties: - creates no more than one instance per
+   * Key as a creator is used no more than once, - result is cached and returned quickly on
+   * subsequent calls, - exception in a creator is not treated as instance creation and is not
+   * cached, - creates singletons in parallel whenever possible, - waits for dependent singletons to
+   * be created even across threads and when dependencies are shared as long as no circular
+   * dependencies are detected, - returns circular proxy only when circular dependencies are
+   * detected, - aside from that, blocking synchronization is only used for proxy creation and
+   * initialization,
+   *
    * @see CycleDetectingLockFactory
    */
+  @Override
   public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
     /**
-     * Locking strategy:
-     * - volatile instance: double-checked locking for quick exit when scope is initialized,
-     * - constructionContext: manipulations with proxies list or instance initialization
-     * - creationLock: singleton instance creation,
-     *   -- allows to guarantee only one instance per singleton,
-     *   -- special type of a lock, that prevents potential deadlocks,
-     *   -- guards constructionContext for all operations except proxy creation
+     * Locking strategy: - volatile instance: double-checked locking for quick exit when scope is
+     * initialized, - constructionContext: manipulations with proxies list or instance
+     * initialization - creationLock: singleton instance creation, -- allows to guarantee only one
+     * instance per singleton, -- special type of a lock, that prevents potential deadlocks, --
+     * guards constructionContext for all operations except proxy creation
      */
     return new Provider<T>() {
       /**
@@ -120,21 +101,43 @@
        * Circular proxies are used when potential deadlocks are detected. Guarded by itself.
        * ConstructionContext is not thread-safe, so each call should be synchronized.
        */
-      final ConstructionContext<T> constructionContext = new ConstructionContext<T>();
+      final ConstructionContext<T> constructionContext = new ConstructionContext<>();
 
       /** For each binding there is a separate lock that we hold during object creation. */
       final CycleDetectingLock<Key<?>> creationLock = cycleDetectingLockFactory.create(key);
 
+      /**
+       * The singleton provider needs a reference back to the injector, in order to get ahold of
+       * InternalContext during instantiation.
+       */
+      final /* @Nullable */ InjectorImpl injector;
+
+      {
+        // If we are getting called by Scoping
+        if (creator instanceof ProviderToInternalFactoryAdapter) {
+          injector = ((ProviderToInternalFactoryAdapter) creator).getInjector();
+        } else {
+          injector = null;
+        }
+      }
+
       @SuppressWarnings("DoubleCheckedLocking")
+      @Override
       public T get() {
         // cache volatile variable for the usual case of already initialized object
         final Object initialInstance = instance;
         if (initialInstance == null) {
           // instance is not initialized yet
 
+          // first, store the current InternalContext in a map, so that if there is a circular
+          // dependency error, we can use the InternalContext objects to create a complete
+          // error message.
+          // Handle injector being null, which can happen when users call Scoping.scope themselves
+          final InternalContext context = injector == null ? null : injector.getLocalContext();
           // acquire lock for current binding to initialize an instance
-          final ListMultimap<Long, Key<?>> locksCycle =
+          final ListMultimap<Thread, Key<?>> locksCycle =
               creationLock.lockOrDetectPotentialLocksCycle();
+
           if (locksCycle.isEmpty()) {
             // this thread now owns creation of an instance
             try {
@@ -147,7 +150,7 @@
 
                 // scope called recursively can initialize instance as a side effect
                 if (instance == null) {
-                  // instance is still not initialized, se we can proceed
+                  // instance is still not initialized, so we can proceed
 
                   // don't remember proxies created by Guice on circular dependency
                   // detection within the same thread; they are not real instances to cache
@@ -162,7 +165,8 @@
                   }
                 } else {
                   // safety assert in case instance was initialized
-                  Preconditions.checkState(instance == providedNotNull,
+                  Preconditions.checkState(
+                      instance == providedNotNull,
                       "Singleton is called recursively returning different results");
                 }
               }
@@ -178,50 +182,45 @@
               creationLock.unlock();
             }
           } else {
+            if (context == null) {
+              throw new ProvisionException(
+                  ImmutableList.of(createCycleDependenciesMessage(locksCycle, null)));
+            }
             // potential deadlock detected, creation lock is not taken by this thread
             synchronized (constructionContext) {
               // guarantee thread-safety for instance and proxies initialization
               if (instance == null) {
-                // InjectorImpl.callInContext() sets this context when scope is called from Guice
-                Map<Thread, InternalContext> globalInternalContext =
-                    InjectorImpl.getGlobalInternalContext();
-                InternalContext internalContext = globalInternalContext.get(Thread.currentThread());
-
                 // creating a proxy to satisfy circular dependency across several threads
-                Dependency<?> dependency = Preconditions.checkNotNull(
-                    internalContext.getDependency(),
-                    "globalInternalContext.get(currentThread()).getDependency()");
+                Dependency<?> dependency =
+                    Preconditions.checkNotNull(
+                        context.getDependency(), "internalContext.getDependency()");
                 Class<?> rawType = dependency.getKey().getTypeLiteral().getRawType();
 
                 try {
                   @SuppressWarnings("unchecked")
-                  T proxy = (T) constructionContext.createProxy(
-                      new Errors(), internalContext.getInjectorOptions(), rawType);
+                  T proxy =
+                      (T) constructionContext.createProxy(context.getInjectorOptions(), rawType);
                   return proxy;
-                } catch (ErrorsException e) {
+                } catch (InternalProvisionException e) {
                   // best effort to create a rich error message
-                  List<Message> exceptionErrorMessages = e.getErrors().getMessages();
-                  // we expect an error thrown
-                  Preconditions.checkState(exceptionErrorMessages.size() == 1);
-                  // explicitly copy the map to guarantee iteration correctness
-                  // it's ok to have a data race with other threads that are locked
-                  Message cycleDependenciesMessage = createCycleDependenciesMessage(
-                      ImmutableMap.copyOf(globalInternalContext),
-                      locksCycle,
-                      exceptionErrorMessages.get(0));
+                  Message proxyCreationError = Iterables.getOnlyElement(e.getErrors());
+                  Message cycleDependenciesMessage =
+                      createCycleDependenciesMessage(locksCycle, proxyCreationError);
                   // adding stack trace generated by us in addition to a standard one
-                  throw new ProvisionException(ImmutableList.of(
-                      cycleDependenciesMessage, exceptionErrorMessages.get(0)));
+                  throw new ProvisionException(
+                      ImmutableList.of(cycleDependenciesMessage, proxyCreationError));
                 }
               }
             }
           }
+
           // at this point we're sure that singleton was initialized,
           // reread volatile variable to catch all corner cases
 
           // caching volatile variable to minimize number of reads performed
           final Object initializedInstance = instance;
-          Preconditions.checkState(initializedInstance != null,
+          Preconditions.checkState(
+              initializedInstance != null,
               "Internal error: Singleton is not initialized contrary to our expectations");
           @SuppressWarnings("unchecked")
           T initializedTypedInstance = (T) initializedInstance;
@@ -235,99 +234,45 @@
       }
 
       /**
-       * Helper method to create beautiful and rich error descriptions. Best effort and slow.
-       * Tries its best to provide dependency information from injectors currently available
-       * in a global internal context.
+       * Helper method to create beautiful and rich error descriptions. Best effort and slow. Tries
+       * its best to provide dependency information from injectors currently available in a global
+       * internal context.
        *
-       * <p>The main thing being done is creating a list of Dependencies involved into
-       * lock cycle across all the threads involved. This is a structure we're creating:
+       * <p>The main thing being done is creating a list of Dependencies involved into lock cycle
+       * across all the threads involved. This is a structure we're creating:
+       *
        * <pre>
        * { Current Thread, C.class, B.class, Other Thread, B.class, C.class, Current Thread }
        * To be inserted in the beginning by Guice: { A.class, B.class, C.class }
        * </pre>
-       * When we're calling Guice to create A and it fails in the deadlock while trying to
-       * create C, which is being created by another thread, which waits for B. List would
-       * be reversed before printing it to the end user.
+       *
+       * When we're calling Guice to create A and it fails in the deadlock while trying to create C,
+       * which is being created by another thread, which waits for B. List would be reversed before
+       * printing it to the end user.
        */
       private Message createCycleDependenciesMessage(
-          Map<Thread, InternalContext> globalInternalContext,
-          ListMultimap<Long, Key<?>> locksCycle,
-          Message proxyCreationError) {
+          ListMultimap<Thread, Key<?>> locksCycle, /* @Nullable */ Message proxyCreationError) {
         // this is the main thing that we'll show in an error message,
         // current thread is populate by Guice
-        List<Object> sourcesCycle = Lists.newArrayList();
-        sourcesCycle.add(Thread.currentThread());
-        // temp map to speed up look ups
-        Map<Long, Thread> threadById = Maps.newHashMap();
-        for (Thread thread : globalInternalContext.keySet()) {
-          threadById.put(thread.getId(), thread);
+        StringBuilder sb = new StringBuilder();
+        Formatter fmt = new Formatter(sb);
+        fmt.format("Encountered circular dependency spanning several threads.");
+        if (proxyCreationError != null) {
+          fmt.format(" %s", proxyCreationError.getMessage());
         }
-        for (long lockedThreadId : locksCycle.keySet()) {
-          Thread lockedThread = threadById.get(lockedThreadId);
-          List<Key<?>> lockedKeys = Collections.unmodifiableList(locksCycle.get(lockedThreadId));
-          if (lockedThread == null) {
-            // thread in a lock cycle is already terminated
-            continue;
+        fmt.format("%n");
+        for (Thread lockedThread : locksCycle.keySet()) {
+          List<Key<?>> lockedKeys = locksCycle.get(lockedThread);
+          fmt.format("%s is holding locks the following singletons in the cycle:%n", lockedThread);
+          for (Key<?> lockedKey : lockedKeys) {
+            fmt.format("%s%n", Errors.convert(lockedKey));
           }
-          List<DependencyAndSource> dependencyChain = null;
-          boolean allLockedKeysAreFoundInDependencies = false;
-          // thread in a cycle is still present
-          InternalContext lockedThreadInternalContext = globalInternalContext.get(lockedThread);
-          if (lockedThreadInternalContext != null) {
-            dependencyChain = lockedThreadInternalContext.getDependencyChain();
-
-            // check that all of the keys are still present in dependency chain in order
-            List<Key<?>> lockedKeysToFind = Lists.newLinkedList(lockedKeys);
-            // check stack trace of the thread
-            for (DependencyAndSource d : dependencyChain) {
-              Dependency<?> dependency = d.getDependency();
-              if (dependency == null) {
-                continue;
-              }
-              if (dependency.getKey().equals(lockedKeysToFind.get(0))) {
-                lockedKeysToFind.remove(0);
-                if (lockedKeysToFind.isEmpty()) {
-                  // everything is found!
-                  allLockedKeysAreFoundInDependencies = true;
-                  break;
-                }
-              }
-            }
+          for (StackTraceElement traceElement : lockedThread.getStackTrace()) {
+            fmt.format("\tat %s%n", traceElement);
           }
-          if (allLockedKeysAreFoundInDependencies) {
-            // all keys are present in a dependency chain of a thread's last injector,
-            // highly likely that we just have discovered a dependency
-            // chain that is part of a lock cycle starting with the first lock owned
-            Key<?> firstLockedKey = lockedKeys.get(0);
-            boolean firstLockedKeyFound = false;
-            for (DependencyAndSource d : dependencyChain) {
-              Dependency<?> dependency = d.getDependency();
-              if (dependency == null) {
-                continue;
-              }
-              if (firstLockedKeyFound) {
-                sourcesCycle.add(dependency);
-                sourcesCycle.add(d.getBindingSource());
-              } else if (dependency.getKey().equals(firstLockedKey)) {
-                firstLockedKeyFound = true;
-                // for the very first one found we don't care why, so no dependency is added
-                sourcesCycle.add(d.getBindingSource());
-              }
-            }
-          } else {
-            // something went wrong and not all keys are present in a state of an injector
-            // that was used last for a current thread.
-            // let's add all keys we're aware of, still better than nothing
-            sourcesCycle.addAll(lockedKeys);
-          }
-          // mentions that a tread is a part of a cycle
-          sourcesCycle.add(lockedThread);
         }
-        return new Message(
-            sourcesCycle,
-            String.format("Encountered circular dependency spanning several threads. %s",
-                proxyCreationError.getMessage()),
-            null);
+        fmt.close();
+        return new Message(Thread.currentThread(), sb.toString());
       }
 
       @Override
@@ -337,7 +282,8 @@
     };
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "Scopes.SINGLETON";
   }
 }
diff --git a/core/src/com/google/inject/internal/State.java b/core/src/com/google/inject/internal/State.java
index 32c2da6..e49d269 100644
--- a/core/src/com/google/inject/internal/State.java
+++ b/core/src/com/google/inject/internal/State.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,13 +23,11 @@
 import com.google.inject.Key;
 import com.google.inject.Scope;
 import com.google.inject.TypeLiteral;
-import com.google.inject.spi.ModuleAnnotatedMethodScanner;
 import com.google.inject.spi.ModuleAnnotatedMethodScannerBinding;
 import com.google.inject.spi.ProvisionListenerBinding;
 import com.google.inject.spi.ScopeBinding;
 import com.google.inject.spi.TypeConverterBinding;
 import com.google.inject.spi.TypeListenerBinding;
-
 import java.lang.annotation.Annotation;
 import java.util.List;
 import java.util.Map;
@@ -43,101 +41,124 @@
  */
 interface State {
 
-  static final State NONE = new State() {
-    public State parent() {
-      throw new UnsupportedOperationException();
-    }
+  static final State NONE =
+      new State() {
+        @Override
+        public State parent() {
+          throw new UnsupportedOperationException();
+        }
 
-    public <T> BindingImpl<T> getExplicitBinding(Key<T> key) {
-      return null;
-    }
+        @Override
+        public <T> BindingImpl<T> getExplicitBinding(Key<T> key) {
+          return null;
+        }
 
-    public Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel() {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel() {
+          throw new UnsupportedOperationException();
+        }
 
-    public void putBinding(Key<?> key, BindingImpl<?> binding) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void putBinding(Key<?> key, BindingImpl<?> binding) {
+          throw new UnsupportedOperationException();
+        }
 
-    public ScopeBinding getScopeBinding(Class<? extends Annotation> scopingAnnotation) {
-      return null;
-    }
+        @Override
+        public ScopeBinding getScopeBinding(Class<? extends Annotation> scopingAnnotation) {
+          return null;
+        }
 
-    public void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void putScopeBinding(
+            Class<? extends Annotation> annotationType, ScopeBinding scope) {
+          throw new UnsupportedOperationException();
+        }
 
-    public void addConverter(TypeConverterBinding typeConverterBinding) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void addConverter(TypeConverterBinding typeConverterBinding) {
+          throw new UnsupportedOperationException();
+        }
 
-    public TypeConverterBinding getConverter(String stringValue, TypeLiteral<?> type, Errors errors,
-        Object source) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public TypeConverterBinding getConverter(
+            String stringValue, TypeLiteral<?> type, Errors errors, Object source) {
+          throw new UnsupportedOperationException();
+        }
 
-    public Iterable<TypeConverterBinding> getConvertersThisLevel() {
-      return ImmutableSet.of();
-    }
+        @Override
+        public Iterable<TypeConverterBinding> getConvertersThisLevel() {
+          return ImmutableSet.of();
+        }
 
-    /*if[AOP]*/
-    public void addMethodAspect(MethodAspect methodAspect) {
-      throw new UnsupportedOperationException();
-    }
+        /*if[AOP]*/
+        @Override
+        public void addMethodAspect(MethodAspect methodAspect) {
+          throw new UnsupportedOperationException();
+        }
 
-    public ImmutableList<MethodAspect> getMethodAspects() {
-      return ImmutableList.of();
-    }
-    /*end[AOP]*/
+        @Override
+        public ImmutableList<MethodAspect> getMethodAspects() {
+          return ImmutableList.of();
+        }
+        /*end[AOP]*/
 
-    public void addTypeListener(TypeListenerBinding typeListenerBinding) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void addTypeListener(TypeListenerBinding typeListenerBinding) {
+          throw new UnsupportedOperationException();
+        }
 
-    public List<TypeListenerBinding> getTypeListenerBindings() {
-      return ImmutableList.of();
-    }
-    
-    public void addProvisionListener(ProvisionListenerBinding provisionListenerBinding) {
-      throw new UnsupportedOperationException();
-    }
-    
-    public List<ProvisionListenerBinding> getProvisionListenerBindings() {
-      return ImmutableList.of();
-    }
+        @Override
+        public List<TypeListenerBinding> getTypeListenerBindings() {
+          return ImmutableList.of();
+        }
 
-    public void addScanner(ModuleAnnotatedMethodScannerBinding scanner) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void addProvisionListener(ProvisionListenerBinding provisionListenerBinding) {
+          throw new UnsupportedOperationException();
+        }
 
-    public List<ModuleAnnotatedMethodScannerBinding> getScannerBindings() {
-      return ImmutableList.of();
-    }
+        @Override
+        public List<ProvisionListenerBinding> getProvisionListenerBindings() {
+          return ImmutableList.of();
+        }
 
-    public void blacklist(Key<?> key, State state, Object source) {
-    }
+        @Override
+        public void addScanner(ModuleAnnotatedMethodScannerBinding scanner) {
+          throw new UnsupportedOperationException();
+        }
 
-    public boolean isBlacklisted(Key<?> key) {
-      return true;
-    }
-    
-    public Set<Object> getSourcesForBlacklistedKey(Key<?> key) {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public List<ModuleAnnotatedMethodScannerBinding> getScannerBindings() {
+          return ImmutableList.of();
+        }
 
-    public Object lock() {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public void blacklist(Key<?> key, State state, Object source) {}
 
-    public Object singletonCreationLock() {
-      throw new UnsupportedOperationException();
-    }
+        @Override
+        public boolean isBlacklisted(Key<?> key) {
+          return true;
+        }
 
-    public Map<Class<? extends Annotation>, Scope> getScopes() {
-      return ImmutableMap.of();
-    }
-  };
+        @Override
+        public Set<Object> getSourcesForBlacklistedKey(Key<?> key) {
+          throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Object lock() {
+          throw new UnsupportedOperationException();
+        }
+
+        public Object singletonCreationLock() {
+          throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Map<Class<? extends Annotation>, Scope> getScopes() {
+          return ImmutableMap.of();
+        }
+      };
 
   State parent();
 
@@ -148,7 +169,7 @@
   Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel();
 
   void putBinding(Key<?> key, BindingImpl<?> binding);
- 
+
   ScopeBinding getScopeBinding(Class<? extends Annotation> scopingAnnotation);
 
   void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope);
@@ -169,11 +190,11 @@
   /*end[AOP]*/
 
   void addTypeListener(TypeListenerBinding typeListenerBinding);
-  
+
   List<TypeListenerBinding> getTypeListenerBindings();
-  
+
   void addProvisionListener(ProvisionListenerBinding provisionListenerBinding);
-  
+
   List<ProvisionListenerBinding> getProvisionListenerBindings();
 
   void addScanner(ModuleAnnotatedMethodScannerBinding scanner);
@@ -192,7 +213,7 @@
    * one of this injector's descendent's has bound the key.
    */
   boolean isBlacklisted(Key<?> key);
-  
+
   /** Returns the source of a blacklisted key. */
   Set<Object> getSourcesForBlacklistedKey(Key<?> key);
 
@@ -202,8 +223,6 @@
    */
   Object lock();
 
-  /**
-   * Returns all the scope bindings at this level and parent levels.
-   */
+  /** Returns all the scope bindings at this level and parent levels. */
   Map<Class<? extends Annotation>, Scope> getScopes();
 }
diff --git a/core/src/com/google/inject/internal/TypeConverterBindingProcessor.java b/core/src/com/google/inject/internal/TypeConverterBindingProcessor.java
index 7ab52ce..34f2cd0 100644
--- a/core/src/com/google/inject/internal/TypeConverterBindingProcessor.java
+++ b/core/src/com/google/inject/internal/TypeConverterBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.matcher.Matchers;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.TypeConverterBinding;
-
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -51,79 +50,97 @@
     convertToPrimitiveType(injector, float.class, Float.class);
     convertToPrimitiveType(injector, double.class, Double.class);
 
-    convertToClass(injector, Character.class, new TypeConverter() {
-      public Object convert(String value, TypeLiteral<?> toType) {
-        value = value.trim();
-        if (value.length() != 1) {
-          throw new RuntimeException("Length != 1.");
-        }
-        return value.charAt(0);
-      }
-
-      @Override public String toString() {
-        return "TypeConverter<Character>";
-      }
-    });
-
-    convertToClasses(injector, Matchers.subclassesOf(Enum.class), new TypeConverter() {
-      @SuppressWarnings("unchecked")
-      public Object convert(String value, TypeLiteral<?> toType) {
-          return Enum.valueOf((Class) toType.getRawType(), value);
-        }
-
-        @Override public String toString() {
-          return "TypeConverter<E extends Enum<E>>";
-        }
-      });
-
-    internalConvertToTypes(injector, new AbstractMatcher<TypeLiteral<?>>() {
-        public boolean matches(TypeLiteral<?> typeLiteral) {
-          return typeLiteral.getRawType() == Class.class;
-        }
-
-        @Override public String toString() {
-          return "Class<?>";
-        }
-      },
-      new TypeConverter() {
-        @SuppressWarnings("unchecked")
-        public Object convert(String value, TypeLiteral<?> toType) {
-          try {
-            return Class.forName(value);
-          } catch (ClassNotFoundException e) {
-            throw new RuntimeException(e.getMessage());
+    convertToClass(
+        injector,
+        Character.class,
+        new TypeConverter() {
+          @Override
+          public Object convert(String value, TypeLiteral<?> toType) {
+            value = value.trim();
+            if (value.length() != 1) {
+              throw new RuntimeException("Length != 1.");
+            }
+            return value.charAt(0);
           }
-        }
 
-        @Override public String toString() {
-          return "TypeConverter<Class<?>>";
-        }
-      }
-    );
+          @Override
+          public String toString() {
+            return "TypeConverter<Character>";
+          }
+        });
+
+    convertToClasses(
+        injector,
+        Matchers.subclassesOf(Enum.class),
+        new TypeConverter() {
+          @Override
+          @SuppressWarnings("unchecked")
+          public Object convert(String value, TypeLiteral<?> toType) {
+            return Enum.valueOf((Class) toType.getRawType(), value);
+          }
+
+          @Override
+          public String toString() {
+            return "TypeConverter<E extends Enum<E>>";
+          }
+        });
+
+    internalConvertToTypes(
+        injector,
+        new AbstractMatcher<TypeLiteral<?>>() {
+          @Override
+          public boolean matches(TypeLiteral<?> typeLiteral) {
+            return typeLiteral.getRawType() == Class.class;
+          }
+
+          @Override
+          public String toString() {
+            return "Class<?>";
+          }
+        },
+        new TypeConverter() {
+          @Override
+          @SuppressWarnings("unchecked")
+          public Object convert(String value, TypeLiteral<?> toType) {
+            try {
+              return Class.forName(value);
+            } catch (ClassNotFoundException e) {
+              throw new RuntimeException(e.getMessage());
+            }
+          }
+
+          @Override
+          public String toString() {
+            return "TypeConverter<Class<?>>";
+          }
+        });
   }
 
-  private static <T> void convertToPrimitiveType(InjectorImpl injector, Class<T> primitiveType,
-      final Class<T> wrapperType) {
+  private static <T> void convertToPrimitiveType(
+      InjectorImpl injector, Class<T> primitiveType, final Class<T> wrapperType) {
     try {
-      final Method parser = wrapperType.getMethod(
-          "parse" + capitalize(primitiveType.getName()), String.class);
+      final Method parser =
+          wrapperType.getMethod("parse" + capitalize(primitiveType.getName()), String.class);
 
-      TypeConverter typeConverter = new TypeConverter() {
-        @SuppressWarnings("unchecked")
-        public Object convert(String value, TypeLiteral<?> toType) {
-          try {
-            return parser.invoke(null, value);
-          } catch (IllegalAccessException e) {
-            throw new AssertionError(e);
-          } catch (InvocationTargetException e) {
-            throw new RuntimeException(e.getTargetException().getMessage());
-          }
-        }
+      TypeConverter typeConverter =
+          new TypeConverter() {
+            @Override
+            @SuppressWarnings("unchecked")
+            public Object convert(String value, TypeLiteral<?> toType) {
+              try {
+                return parser.invoke(null, value);
+              } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+              } catch (InvocationTargetException e) {
+                throw new RuntimeException(e.getTargetException().getMessage());
+              }
+            }
 
-        @Override public String toString() {
-          return "TypeConverter<" + wrapperType.getSimpleName() + ">";
-        }
-      };
+            @Override
+            public String toString() {
+              return "TypeConverter<" + wrapperType.getSimpleName() + ">";
+            }
+          };
 
       convertToClass(injector, wrapperType, typeConverter);
     } catch (NoSuchMethodException e) {
@@ -131,51 +148,54 @@
     }
   }
 
-  private static <T> void convertToClass(InjectorImpl injector, Class<T> type,
-      TypeConverter converter) {
+  private static <T> void convertToClass(
+      InjectorImpl injector, Class<T> type, TypeConverter converter) {
     convertToClasses(injector, Matchers.identicalTo(type), converter);
   }
 
-  private static void convertToClasses(InjectorImpl injector,
-      final Matcher<? super Class<?>> typeMatcher, TypeConverter converter) {
-    internalConvertToTypes(injector, new AbstractMatcher<TypeLiteral<?>>() {
-      public boolean matches(TypeLiteral<?> typeLiteral) {
-        Type type = typeLiteral.getType();
-        if (!(type instanceof Class)) {
-          return false;
-        }
-        Class<?> clazz = (Class<?>) type;
-        return typeMatcher.matches(clazz);
-      }
+  private static void convertToClasses(
+      InjectorImpl injector, final Matcher<? super Class<?>> typeMatcher, TypeConverter converter) {
+    internalConvertToTypes(
+        injector,
+        new AbstractMatcher<TypeLiteral<?>>() {
+          @Override
+          public boolean matches(TypeLiteral<?> typeLiteral) {
+            Type type = typeLiteral.getType();
+            if (!(type instanceof Class)) {
+              return false;
+            }
+            Class<?> clazz = (Class<?>) type;
+            return typeMatcher.matches(clazz);
+          }
 
-      @Override public String toString() {
-        return typeMatcher.toString();
-      }
-    }, converter);
+          @Override
+          public String toString() {
+            return typeMatcher.toString();
+          }
+        },
+        converter);
   }
 
-  private static void internalConvertToTypes(InjectorImpl injector,
-      Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeConverter converter) {
+  private static void internalConvertToTypes(
+      InjectorImpl injector, Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
     injector.state.addConverter(
         new TypeConverterBinding(SourceProvider.UNKNOWN_SOURCE, typeMatcher, converter));
   }
 
-  @Override public Boolean visit(TypeConverterBinding command) {
-    injector.state.addConverter(new TypeConverterBinding(
-        command.getSource(), command.getTypeMatcher(), command.getTypeConverter()));
+  @Override
+  public Boolean visit(TypeConverterBinding command) {
+    injector.state.addConverter(
+        new TypeConverterBinding(
+            command.getSource(), command.getTypeMatcher(), command.getTypeConverter()));
     return true;
   }
-  
+
   private static String capitalize(String s) {
     if (s.length() == 0) {
       return s;
     }
     char first = s.charAt(0);
     char capitalized = Character.toUpperCase(first);
-    return (first == capitalized)
-        ? s
-        : capitalized + s.substring(1);
+    return (first == capitalized) ? s : capitalized + s.substring(1);
   }
-
 }
diff --git a/core/src/com/google/inject/internal/UniqueAnnotations.java b/core/src/com/google/inject/internal/UniqueAnnotations.java
index 924175e..36b213d 100644
--- a/core/src/com/google/inject/internal/UniqueAnnotations.java
+++ b/core/src/com/google/inject/internal/UniqueAnnotations.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,21 +19,19 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.util.concurrent.atomic.AtomicInteger;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class UniqueAnnotations {
   private UniqueAnnotations() {}
+
   private static final AtomicInteger nextUniqueValue = new AtomicInteger(1);
 
   /**
-   * Returns an annotation instance that is not equal to any other annotation
-   * instances, for use in creating distinct {@link com.google.inject.Key}s.
+   * Returns an annotation instance that is not equal to any other annotation instances, for use in
+   * creating distinct {@link com.google.inject.Key}s.
    */
   public static Annotation create() {
     return create(nextUniqueValue.getAndIncrement());
@@ -41,30 +39,35 @@
 
   static Annotation create(final int value) {
     return new Internal() {
+      @Override
       public int value() {
         return value;
       }
 
+      @Override
       public Class<? extends Annotation> annotationType() {
         return Internal.class;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return "@" + Internal.class.getName() + "(value=" + value + ")";
       }
 
-      @Override public boolean equals(Object o) {
-        return o instanceof Internal
-            && ((Internal) o).value() == value();
+      @Override
+      public boolean equals(Object o) {
+        return o instanceof Internal && ((Internal) o).value() == value();
       }
 
-      @Override public int hashCode() {
+      @Override
+      public int hashCode() {
         return (127 * "value".hashCode()) ^ value;
       }
     };
   }
 
-  @Retention(RUNTIME) @BindingAnnotation
+  @Retention(RUNTIME)
+  @BindingAnnotation
   @interface Internal {
     int value();
   }
diff --git a/core/src/com/google/inject/internal/UntargettedBindingImpl.java b/core/src/com/google/inject/internal/UntargettedBindingImpl.java
index a2d3365..18f0d94 100644
--- a/core/src/com/google/inject/internal/UntargettedBindingImpl.java
+++ b/core/src/com/google/inject/internal/UntargettedBindingImpl.java
@@ -16,6 +16,7 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.inject.Binder;
 import com.google.inject.Key;
@@ -26,35 +27,46 @@
 final class UntargettedBindingImpl<T> extends BindingImpl<T> implements UntargettedBinding<T> {
 
   UntargettedBindingImpl(InjectorImpl injector, Key<T> key, Object source) {
-    super(injector, key, source, new InternalFactory<T>() {
-      public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked) {
-        throw new AssertionError();
-      }
-    }, Scoping.UNSCOPED);
+    super(
+        injector,
+        key,
+        source,
+        new InternalFactory<T>() {
+          @Override
+          public T get(InternalContext context, Dependency<?> dependency, boolean linked) {
+            throw new AssertionError();
+          }
+        },
+        Scoping.UNSCOPED);
   }
 
   public UntargettedBindingImpl(Object source, Key<T> key, Scoping scoping) {
     super(source, key, scoping);
   }
 
+  @Override
   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public BindingImpl<T> withScoping(Scoping scoping) {
     return new UntargettedBindingImpl<T>(getSource(), getKey(), scoping);
   }
 
+  @Override
   public BindingImpl<T> withKey(Key<T> key) {
     return new UntargettedBindingImpl<T>(getSource(), key, getScoping());
   }
 
+  @Override
   public void applyTo(Binder binder) {
     getScoping().applyTo(binder.withSource(getSource()).bind(getKey()));
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(UntargettedBinding.class)
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(UntargettedBinding.class)
         .add("key", getKey())
         .add("source", getSource())
         .toString();
@@ -62,10 +74,9 @@
 
   @Override
   public boolean equals(Object obj) {
-    if(obj instanceof UntargettedBindingImpl) {
-      UntargettedBindingImpl<?> o = (UntargettedBindingImpl<?>)obj;
-      return getKey().equals(o.getKey())
-        && getScoping().equals(o.getScoping());
+    if (obj instanceof UntargettedBindingImpl) {
+      UntargettedBindingImpl<?> o = (UntargettedBindingImpl<?>) obj;
+      return getKey().equals(o.getKey()) && getScoping().equals(o.getScoping());
     } else {
       return false;
     }
diff --git a/core/src/com/google/inject/internal/UntargettedBindingProcessor.java b/core/src/com/google/inject/internal/UntargettedBindingProcessor.java
index 8ca2ecc..0e56995 100644
--- a/core/src/com/google/inject/internal/UntargettedBindingProcessor.java
+++ b/core/src/com/google/inject/internal/UntargettedBindingProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,45 +25,47 @@
  * @author sameb@google.com (Sam Berlin)
  */
 class UntargettedBindingProcessor extends AbstractBindingProcessor {
-  
+
   UntargettedBindingProcessor(Errors errors, ProcessedBindingData bindingData) {
     super(errors, bindingData);
   }
-  
+
   @Override
   public <T> Boolean visit(Binding<T> binding) {
-    return binding.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)binding) {  
-      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
-        prepareBinding();
+    return binding.acceptTargetVisitor(
+        new Processor<T, Boolean>((BindingImpl<T>) binding) {
+          @Override
+          public Boolean visit(UntargettedBinding<? extends T> untargetted) {
+            prepareBinding();
 
-        // Error: Missing implementation.
-        // Example: bind(Date.class).annotatedWith(Red.class);
-        // We can't assume abstract types aren't injectable. They may have an
-        // @ImplementedBy annotation or something.
-        if (key.getAnnotationType() != null) {
-          errors.missingImplementation(key);
-          putBinding(invalidBinding(injector, key, source));
-          return true;
-        }
-    
-        // This cast is safe after the preceeding check.
-        try {
-          BindingImpl<T> binding = injector.createUninitializedBinding(
-              key, scoping, source, errors, false);
-          scheduleInitialization(binding);
-          putBinding(binding);
-        } catch (ErrorsException e) {
-          errors.merge(e.getErrors());
-          putBinding(invalidBinding(injector, key, source));
-        }
-    
-        return true;
-      }
-      
-      @Override
-      protected Boolean visitOther(Binding<? extends T> binding) {
-        return false;
-      }
-    });
+            // Error: Missing implementation.
+            // Example: bind(Date.class).annotatedWith(Red.class);
+            // We can't assume abstract types aren't injectable. They may have an
+            // @ImplementedBy annotation or something.
+            if (key.getAnnotationType() != null) {
+              errors.missingImplementationWithHint(key, injector);
+              putBinding(invalidBinding(injector, key, source));
+              return true;
+            }
+
+            // This cast is safe after the preceeding check.
+            try {
+              BindingImpl<T> binding =
+                  injector.createUninitializedBinding(key, scoping, source, errors, false);
+              scheduleInitialization(binding);
+              putBinding(binding);
+            } catch (ErrorsException e) {
+              errors.merge(e.getErrors());
+              putBinding(invalidBinding(injector, key, source));
+            }
+
+            return true;
+          }
+
+          @Override
+          protected Boolean visitOther(Binding<? extends T> binding) {
+            return false;
+          }
+        });
   }
 }
diff --git a/core/src/com/google/inject/internal/WeakKeySet.java b/core/src/com/google/inject/internal/WeakKeySet.java
index ca137df..c0cf668 100644
--- a/core/src/com/google/inject/internal/WeakKeySet.java
+++ b/core/src/com/google/inject/internal/WeakKeySet.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,7 +29,6 @@
 import com.google.common.collect.Sets;
 import com.google.inject.Key;
 import com.google.inject.internal.util.SourceProvider;
-
 import java.util.Map;
 import java.util.Set;
 
@@ -52,18 +51,19 @@
    * Tracks child injector lifetimes and evicts blacklisted keys/sources after the child injector is
    * garbage collected.
    */
-  private final Cache<State, Set<KeyAndSource>> evictionCache = CacheBuilder.newBuilder()
-      .weakKeys()
-      .removalListener(
-          new RemovalListener<State, Set<KeyAndSource>>() {
-            @Override
-            public void onRemoval(RemovalNotification<State, Set<KeyAndSource>> notification) {
-              Preconditions.checkState(RemovalCause.COLLECTED.equals(notification.getCause()));
+  private final Cache<State, Set<KeyAndSource>> evictionCache =
+      CacheBuilder.newBuilder()
+          .weakKeys()
+          .removalListener(
+              new RemovalListener<State, Set<KeyAndSource>>() {
+                @Override
+                public void onRemoval(RemovalNotification<State, Set<KeyAndSource>> notification) {
+                  Preconditions.checkState(RemovalCause.COLLECTED.equals(notification.getCause()));
 
-              cleanUpForCollectedState(notification.getValue());
-            }
-          })
-      .build();
+                  cleanUpForCollectedState(notification.getValue());
+                }
+              })
+          .build();
 
   /**
    * There may be multiple child injectors blacklisting a certain key so only remove the source
@@ -150,8 +150,7 @@
       }
 
       KeyAndSource other = (KeyAndSource) obj;
-      return Objects.equal(key, other.key)
-          && Objects.equal(source, other.source);
+      return Objects.equal(key, other.key) && Objects.equal(source, other.source);
     }
   }
 }
diff --git a/core/src/com/google/inject/internal/package-info.java b/core/src/com/google/inject/internal/package-info.java
index 4116f11..8e88e92 100644
--- a/core/src/com/google/inject/internal/package-info.java
+++ b/core/src/com/google/inject/internal/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * <i>Guice</i> (sounds like like "juice")
- */
+/** <i>Guice</i> (sounds like "juice") */
 package com.google.inject.internal;
diff --git a/core/src/com/google/inject/internal/util/Classes.java b/core/src/com/google/inject/internal/util/Classes.java
index 0badab1..4717460 100644
--- a/core/src/com/google/inject/internal/util/Classes.java
+++ b/core/src/com/google/inject/internal/util/Classes.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,14 +24,11 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
-/**
- * Class utilities.
- */
+/** Class utilities. */
 public final class Classes {
 
   public static boolean isInnerClass(Class<?> clazz) {
-    return !Modifier.isStatic(clazz.getModifiers())
-        && clazz.getEnclosingClass() != null;
+    return !Modifier.isStatic(clazz.getModifiers()) && clazz.getEnclosingClass() != null;
   }
 
   public static boolean isConcrete(Class<?> clazz) {
@@ -40,12 +37,12 @@
   }
 
   /**
-   * Formats a member as concise string, such as {@code java.util.ArrayList.size},
-   * {@code java.util.ArrayList<init>()} or {@code java.util.List.remove()}.
+   * Formats a member as concise string, such as {@code java.util.ArrayList.size}, {@code
+   * java.util.ArrayList<init>()} or {@code java.util.List.remove()}.
    */
   public static String toString(Member member) {
     Class<? extends Member> memberType = Classes.memberType(member);
-  
+
     if (memberType == Method.class) {
       return member.getDeclaringClass().getName() + "." + member.getName() + "()";
     } else if (memberType == Field.class) {
@@ -57,21 +54,19 @@
     }
   }
 
-  /**
-   * Returns {@code Field.class}, {@code Method.class} or {@code Constructor.class}.
-   */
+  /** Returns {@code Field.class}, {@code Method.class} or {@code Constructor.class}. */
   public static Class<? extends Member> memberType(Member member) {
     checkNotNull(member, "member");
-  
+
     if (member instanceof Field) {
       return Field.class;
-  
+
     } else if (member instanceof Method) {
       return Method.class;
-  
+
     } else if (member instanceof Constructor) {
       return Constructor.class;
-  
+
     } else {
       throw new IllegalArgumentException(
           "Unsupported implementation class for Member, " + member.getClass());
diff --git a/core/src/com/google/inject/internal/util/LineNumbers.java b/core/src/com/google/inject/internal/util/LineNumbers.java
index 57c98b9..0179e8a 100644
--- a/core/src/com/google/inject/internal/util/LineNumbers.java
+++ b/core/src/com/google/inject/internal/util/LineNumbers.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,15 +20,6 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
@@ -36,6 +27,13 @@
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.util.Map;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
 
 /**
  * Looks up line numbers for classes and their members.
@@ -62,7 +60,14 @@
     if (!type.isArray()) {
       InputStream in = type.getResourceAsStream("/" + type.getName().replace('.', '/') + ".class");
       if (in != null) {
-        new ClassReader(in).accept(new LineNumberReader(), ClassReader.SKIP_FRAMES);
+        try {
+          new ClassReader(in).accept(new LineNumberReader(), ClassReader.SKIP_FRAMES);
+        } finally {
+          try {
+            in.close();
+          } catch (IOException ignored) {
+          }
+        }
       }
     }
   }
@@ -82,11 +87,15 @@
    * @param member a field, constructor, or method belonging to the class used during construction
    * @return the wrapped line number, or null if not available
    * @throws IllegalArgumentException if the member does not belong to the class used during
-   * construction
+   *     construction
    */
   public Integer getLineNumber(Member member) {
-    Preconditions.checkArgument(type == member.getDeclaringClass(),
-        "Member %s belongs to %s, not %s", member, member.getDeclaringClass(), type);
+    Preconditions.checkArgument(
+        type == member.getDeclaringClass(),
+        "Member %s belongs to %s, not %s",
+        member,
+        member.getDeclaringClass(),
+        type);
     return lines.get(memberKey(member));
   }
 
@@ -108,7 +117,7 @@
     } else if (member instanceof Constructor) {
       StringBuilder sb = new StringBuilder().append("<init>(");
       for (Class param : ((Constructor) member).getParameterTypes()) {
-          sb.append(org.objectweb.asm.Type.getDescriptor(param));
+        sb.append(org.objectweb.asm.Type.getDescriptor(param));
       }
       return sb.append(")V").toString();
 
@@ -120,7 +129,7 @@
     /*if[NO_AOP]
     return "<NO_MEMBER_KEY>";
     end[NO_AOP]*/
-  }  
+  }
 
   private class LineNumberReader extends ClassVisitor {
 
@@ -129,16 +138,23 @@
     private String name;
 
     LineNumberReader() {
-      super(Opcodes.ASM5);
+      super(Opcodes.ASM6);
     }
 
-    public void visit(int version, int access, String name, String signature,
-        String superName, String[] interfaces) {
+    @Override
+    public void visit(
+        int version,
+        int access,
+        String name,
+        String signature,
+        String superName,
+        String[] interfaces) {
       this.name = name;
     }
 
-    public MethodVisitor visitMethod(int access, String name, String desc,
-        String signature, String[] exceptions) {
+    @Override
+    public MethodVisitor visitMethod(
+        int access, String name, String desc, String signature, String[] exceptions) {
       if ((access & Opcodes.ACC_PRIVATE) != 0) {
         return null;
       }
@@ -147,6 +163,7 @@
       return new LineNumberMethodVisitor();
     }
 
+    @Override
     public void visitSource(String source, String debug) {
       LineNumbers.this.source = source;
     }
@@ -163,41 +180,47 @@
       }
     }
 
-    public FieldVisitor visitField(int access, String name, String desc,
-        String signature, Object value) {
+    @Override
+    public FieldVisitor visitField(
+        int access, String name, String desc, String signature, Object value) {
       return null;
     }
 
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
       return new LineNumberAnnotationVisitor();
     }
 
-    public AnnotationVisitor visitParameterAnnotation(int parameter,
-        String desc, boolean visible) {
+    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
       return new LineNumberAnnotationVisitor();
     }
 
     class LineNumberMethodVisitor extends MethodVisitor {
       LineNumberMethodVisitor() {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
       }
 
+      @Override
       public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         return new LineNumberAnnotationVisitor();
       }
 
+      @Override
       public AnnotationVisitor visitAnnotationDefault() {
         return new LineNumberAnnotationVisitor();
       }
 
-      public void visitFieldInsn(int opcode, String owner, String name,
-          String desc) {
-        if (opcode == Opcodes.PUTFIELD && LineNumberReader.this.name.equals(owner)
-            && !lines.containsKey(name) && line != -1) {
+      @Override
+      public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+        if (opcode == Opcodes.PUTFIELD
+            && LineNumberReader.this.name.equals(owner)
+            && !lines.containsKey(name)
+            && line != -1) {
           lines.put(name, line);
         }
       }
 
+      @Override
       public void visitLineNumber(int line, Label start) {
         LineNumberReader.this.visitLineNumber(line, start);
       }
@@ -205,19 +228,21 @@
 
     class LineNumberAnnotationVisitor extends AnnotationVisitor {
       LineNumberAnnotationVisitor() {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
       }
+
+      @Override
       public AnnotationVisitor visitAnnotation(String name, String desc) {
         return this;
       }
+
+      @Override
       public AnnotationVisitor visitArray(String name) {
         return this;
       }
-      public void visitLocalVariable(String name, String desc, String signature,
-          Label start, Label end, int index) {
-      }
 
+      public void visitLocalVariable(
+          String name, String desc, String signature, Label start, Label end, int index) {}
     }
-
   }
 }
diff --git a/core/src/com/google/inject/internal/util/SourceProvider.java b/core/src/com/google/inject/internal/util/SourceProvider.java
index 9d4b9f9..bcb84de 100644
--- a/core/src/com/google/inject/internal/util/SourceProvider.java
+++ b/core/src/com/google/inject/internal/util/SourceProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
-
 import java.util.List;
 
 /**
  * Provides access to the calling line of code.
- * 
+ *
  * @author crazybob@google.com (Bob Lee)
  */
 public final class SourceProvider {
@@ -34,9 +33,9 @@
 
   private final SourceProvider parent;
   private final ImmutableSet<String> classNamesToSkip;
-  
-  public static final SourceProvider DEFAULT_INSTANCE
-      = new SourceProvider(ImmutableSet.of(SourceProvider.class.getName()));
+
+  public static final SourceProvider DEFAULT_INSTANCE =
+      new SourceProvider(ImmutableSet.of(SourceProvider.class.getName()));
 
   private SourceProvider(Iterable<String> classesToSkip) {
     this(null, classesToSkip);
@@ -44,7 +43,7 @@
 
   private SourceProvider(SourceProvider parent, Iterable<String> classesToSkip) {
     this.parent = parent;
-    
+
     ImmutableSet.Builder<String> classNamesToSkipBuilder = ImmutableSet.builder();
     for (String classToSkip : classesToSkip) {
       if (parent == null || !parent.shouldBeSkipped(classToSkip)) {
@@ -64,7 +63,7 @@
     return (parent != null && parent.shouldBeSkipped(className))
         || classNamesToSkip.contains(className);
   }
-  
+
   /** Returns the class names as Strings */
   private static List<String> asStrings(Class... classes) {
     List<String> strings = Lists.newArrayList();
@@ -82,7 +81,7 @@
     Preconditions.checkNotNull(stackTraceElements, "The stack trace elements cannot be null.");
     for (final StackTraceElement element : stackTraceElements) {
       String className = element.getClassName();
-      
+
       if (!shouldBeSkipped(className)) {
         return element;
       }
@@ -90,9 +89,7 @@
     throw new AssertionError();
   }
 
-  /**
-   * Returns the non-skipped module class name.
-   */
+  /** Returns the non-skipped module class name. */
   public Object getFromClassNames(List<String> moduleClassNames) {
     Preconditions.checkNotNull(moduleClassNames, "The list of module class names cannot be null.");
     for (final String moduleClassName : moduleClassNames) {
diff --git a/core/src/com/google/inject/internal/util/StackTraceElements.java b/core/src/com/google/inject/internal/util/StackTraceElements.java
index 69f930f..486855b 100644
--- a/core/src/com/google/inject/internal/util/StackTraceElements.java
+++ b/core/src/com/google/inject/internal/util/StackTraceElements.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import com.google.common.collect.MapMaker;
-
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 /**
  * Creates stack trace elements for members.
@@ -34,25 +33,31 @@
 public class StackTraceElements {
 
   private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
-  private static final InMemoryStackTraceElement[] EMPTY_INMEMORY_STACK_TRACE = 
+  private static final InMemoryStackTraceElement[] EMPTY_INMEMORY_STACK_TRACE =
       new InMemoryStackTraceElement[0];
 
   /*if[AOP]*/
   static final LoadingCache<Class<?>, LineNumbers> lineNumbersCache =
-      CacheBuilder.newBuilder().weakKeys().softValues().build(
-          new CacheLoader<Class<?>, LineNumbers>() {
-            public LineNumbers load(Class<?> key) {
-              try {
-                return new LineNumbers(key);
-              }
-              catch (IOException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
+      CacheBuilder.newBuilder()
+          .weakKeys()
+          .softValues()
+          .build(
+              new CacheLoader<Class<?>, LineNumbers>() {
+                @Override
+                public LineNumbers load(Class<?> key) {
+                  try {
+                    return new LineNumbers(key);
+                  } catch (IOException e) {
+                    throw new RuntimeException(e);
+                  }
+                }
+              });
   /*end[AOP]*/
 
-  private static Map<Object, Object> cache = new MapMaker().makeMap();
+  private static final ConcurrentMap<InMemoryStackTraceElement, InMemoryStackTraceElement>
+      elementCache = new ConcurrentHashMap<>();
+  private static final ConcurrentMap<String, String> stringCache = new ConcurrentHashMap<>();
+
   private static final String UNKNOWN_SOURCE = "Unknown Source";
 
   public static Object forMember(Member member) {
@@ -91,31 +96,28 @@
 
     return new StackTraceElement(implementation.getName(), "class", fileName, lineNumber);
   }
-  
-  /**
-   * Clears the internal cache for {@link StackTraceElement StackTraceElements}.
-   */
+
+  /** Clears the internal cache for {@link StackTraceElement StackTraceElements}. */
   public static void clearCache() {
-    cache.clear();
+    elementCache.clear();
+    stringCache.clear();
   }
-  
-  /**
-   * Returns encoded in-memory version of {@link StackTraceElement StackTraceElements}.
-   */
+
+  /** Returns encoded in-memory version of {@link StackTraceElement StackTraceElements}. */
   public static InMemoryStackTraceElement[] convertToInMemoryStackTraceElement(
       StackTraceElement[] stackTraceElements) {
     if (stackTraceElements.length == 0) {
       return EMPTY_INMEMORY_STACK_TRACE;
     }
-    InMemoryStackTraceElement[] inMemoryStackTraceElements = 
+    InMemoryStackTraceElement[] inMemoryStackTraceElements =
         new InMemoryStackTraceElement[stackTraceElements.length];
     for (int i = 0; i < stackTraceElements.length; i++) {
-      inMemoryStackTraceElements[i] = 
+      inMemoryStackTraceElements[i] =
           weakIntern(new InMemoryStackTraceElement(stackTraceElements[i]));
     }
     return inMemoryStackTraceElements;
   }
-  
+
   /**
    * Decodes in-memory stack trace elements to regular {@link StackTraceElement StackTraceElements}.
    */
@@ -124,45 +126,43 @@
     if (inMemoryStackTraceElements.length == 0) {
       return EMPTY_STACK_TRACE;
     }
-    StackTraceElement[] stackTraceElements = 
+    StackTraceElement[] stackTraceElements =
         new StackTraceElement[inMemoryStackTraceElements.length];
     for (int i = 0; i < inMemoryStackTraceElements.length; i++) {
       String declaringClass = inMemoryStackTraceElements[i].getClassName();
       String methodName = inMemoryStackTraceElements[i].getMethodName();
       int lineNumber = inMemoryStackTraceElements[i].getLineNumber();
-      stackTraceElements[i] = 
+      stackTraceElements[i] =
           new StackTraceElement(declaringClass, methodName, UNKNOWN_SOURCE, lineNumber);
     }
     return stackTraceElements;
   }
-  
+
   private static InMemoryStackTraceElement weakIntern(
       InMemoryStackTraceElement inMemoryStackTraceElement) {
-    InMemoryStackTraceElement cached = 
-        (InMemoryStackTraceElement) cache.get(inMemoryStackTraceElement);
+    InMemoryStackTraceElement cached = elementCache.get(inMemoryStackTraceElement);
     if (cached != null) {
       return cached;
     }
-    inMemoryStackTraceElement = new InMemoryStackTraceElement(
-        weakIntern(inMemoryStackTraceElement.getClassName()), 
-        weakIntern(inMemoryStackTraceElement.getMethodName()), 
-        inMemoryStackTraceElement.getLineNumber());
-    cache.put(inMemoryStackTraceElement, inMemoryStackTraceElement);
+    inMemoryStackTraceElement =
+        new InMemoryStackTraceElement(
+            weakIntern(inMemoryStackTraceElement.getClassName()),
+            weakIntern(inMemoryStackTraceElement.getMethodName()),
+            inMemoryStackTraceElement.getLineNumber());
+    elementCache.put(inMemoryStackTraceElement, inMemoryStackTraceElement);
     return inMemoryStackTraceElement;
   }
-  
+
   private static String weakIntern(String s) {
-    String cached = (String) cache.get(s);
+    String cached = stringCache.get(s);
     if (cached != null) {
       return cached;
     }
-    cache.put(s, s);
-    return s;  
+    stringCache.put(s, s);
+    return s;
   }
-  
-  /**
-   * In-Memory version of {@link StackTraceElement} that does not store the file name. 
-   */
+
+  /** In-Memory version of {@link StackTraceElement} that does not store the file name. */
   public static class InMemoryStackTraceElement {
     private String declaringClass;
     private String methodName;
@@ -181,11 +181,11 @@
     String getClassName() {
       return declaringClass;
     }
-    
+
     String getMethodName() {
       return methodName;
     }
-    
+
     int getLineNumber() {
       return lineNumber;
     }
@@ -199,8 +199,9 @@
         return false;
       }
       InMemoryStackTraceElement e = (InMemoryStackTraceElement) obj;
-      return e.declaringClass.equals(declaringClass) && e.lineNumber == lineNumber && 
-          methodName.equals(e.methodName);
+      return e.declaringClass.equals(declaringClass)
+          && e.lineNumber == lineNumber
+          && methodName.equals(e.methodName);
     }
 
     @Override
@@ -209,7 +210,7 @@
       result = 31 * result + lineNumber;
       return result;
     }
-    
+
     @Override
     public String toString() {
       return declaringClass + "." + methodName + "(" + lineNumber + ")";
diff --git a/core/src/com/google/inject/internal/util/Stopwatch.java b/core/src/com/google/inject/internal/util/Stopwatch.java
index 92c73fb..04953d4 100644
--- a/core/src/com/google/inject/internal/util/Stopwatch.java
+++ b/core/src/com/google/inject/internal/util/Stopwatch.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,9 +28,7 @@
 
   private long start = System.currentTimeMillis();
 
-  /**
-   * Resets and returns elapsed time in milliseconds.
-   */
+  /** Resets and returns elapsed time in milliseconds. */
   public long reset() {
     long now = System.currentTimeMillis();
     try {
@@ -40,9 +38,7 @@
     }
   }
 
-  /**
-   * Resets and logs elapsed time in milliseconds.
-   */
+  /** Resets and logs elapsed time in milliseconds. */
   public void resetAndLog(String label) {
     logger.fine(label + ": " + reset() + "ms");
   }
diff --git a/core/src/com/google/inject/matcher/AbstractMatcher.java b/core/src/com/google/inject/matcher/AbstractMatcher.java
index 91ea2e6..08209fc 100644
--- a/core/src/com/google/inject/matcher/AbstractMatcher.java
+++ b/core/src/com/google/inject/matcher/AbstractMatcher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,10 +25,12 @@
  */
 public abstract class AbstractMatcher<T> implements Matcher<T> {
 
+  @Override
   public Matcher<T> and(final Matcher<? super T> other) {
     return new AndMatcher<T>(this, other);
   }
 
+  @Override
   public Matcher<T> or(Matcher<? super T> other) {
     return new OrMatcher<T>(this, other);
   }
@@ -41,21 +43,25 @@
       this.b = b;
     }
 
+    @Override
     public boolean matches(T t) {
       return a.matches(t) && b.matches(t);
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof AndMatcher
           && ((AndMatcher) other).a.equals(a)
           && ((AndMatcher) other).b.equals(b);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 41 * (a.hashCode() ^ b.hashCode());
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "and(" + a + ", " + b + ")";
     }
 
@@ -70,21 +76,25 @@
       this.b = b;
     }
 
+    @Override
     public boolean matches(T t) {
       return a.matches(t) || b.matches(t);
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof OrMatcher
           && ((OrMatcher) other).a.equals(a)
           && ((OrMatcher) other).b.equals(b);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * (a.hashCode() ^ b.hashCode());
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "or(" + a + ", " + b + ")";
     }
 
diff --git a/core/src/com/google/inject/matcher/Matcher.java b/core/src/com/google/inject/matcher/Matcher.java
index 681f125..6eb81e8 100644
--- a/core/src/com/google/inject/matcher/Matcher.java
+++ b/core/src/com/google/inject/matcher/Matcher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,20 +23,18 @@
  */
 public interface Matcher<T> {
 
-  /**
-   * Returns {@code true} if this matches {@code t}, {@code false} otherwise.
-   */
+  /** Returns {@code true} if this matches {@code t}, {@code false} otherwise. */
   boolean matches(T t);
 
   /**
-   * Returns a new matcher which returns {@code true} if both this and the
-   * given matcher return {@code true}.
+   * Returns a new matcher which returns {@code true} if both this and the given matcher return
+   * {@code true}.
    */
   Matcher<T> and(Matcher<? super T> other);
 
   /**
-   * Returns a new matcher which returns {@code true} if either this or the
-   * given matcher return {@code true}.
+   * Returns a new matcher which returns {@code true} if either this or the given matcher return
+   * {@code true}.
    */
   Matcher<T> or(Matcher<? super T> other);
 }
diff --git a/core/src/com/google/inject/matcher/Matchers.java b/core/src/com/google/inject/matcher/Matchers.java
index 1bebcdb..7aaf750 100644
--- a/core/src/com/google/inject/matcher/Matchers.java
+++ b/core/src/com/google/inject/matcher/Matchers.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,9 +34,7 @@
 public class Matchers {
   private Matchers() {}
 
-  /**
-   * Returns a matcher which matches any input.
-   */
+  /** Returns a matcher which matches any input. */
   public static Matcher<Object> any() {
     return ANY;
   }
@@ -44,11 +42,13 @@
   private static final Matcher<Object> ANY = new Any();
 
   private static class Any extends AbstractMatcher<Object> implements Serializable {
+    @Override
     public boolean matches(Object o) {
       return true;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "any()";
     }
 
@@ -59,9 +59,7 @@
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Inverts the given matcher.
-   */
+  /** Inverts the given matcher. */
   public static <T> Matcher<T> not(final Matcher<? super T> p) {
     return new Not<T>(p);
   }
@@ -73,37 +71,38 @@
       this.delegate = checkNotNull(delegate, "delegate");
     }
 
+    @Override
     public boolean matches(T t) {
       return !delegate.matches(t);
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof Not
-          && ((Not) other).delegate.equals(delegate);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof Not && ((Not) other).delegate.equals(delegate);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return -delegate.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "not(" + delegate + ")";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  private static void checkForRuntimeRetention(
-      Class<? extends Annotation> annotationType) {
+  private static void checkForRuntimeRetention(Class<? extends Annotation> annotationType) {
     Retention retention = annotationType.getAnnotation(Retention.class);
-    checkArgument(retention != null && retention.value() == RetentionPolicy.RUNTIME,
-        "Annotation %s is missing RUNTIME retention", annotationType.getSimpleName());
+    checkArgument(
+        retention != null && retention.value() == RetentionPolicy.RUNTIME,
+        "Annotation %s is missing RUNTIME retention",
+        annotationType.getSimpleName());
   }
 
-  /**
-   * Returns a matcher which matches elements (methods, classes, etc.)
-   * with a given annotation.
-   */
+  /** Returns a matcher which matches elements (methods, classes, etc.) with a given annotation. */
   public static Matcher<AnnotatedElement> annotatedWith(
       final Class<? extends Annotation> annotationType) {
     return new AnnotatedWithType(annotationType);
@@ -118,32 +117,32 @@
       checkForRuntimeRetention(annotationType);
     }
 
+    @Override
     public boolean matches(AnnotatedElement element) {
       return element.isAnnotationPresent(annotationType);
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof AnnotatedWithType
           && ((AnnotatedWithType) other).annotationType.equals(annotationType);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * annotationType.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "annotatedWith(" + annotationType.getSimpleName() + ".class)";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Returns a matcher which matches elements (methods, classes, etc.)
-   * with a given annotation.
-   */
-  public static Matcher<AnnotatedElement> annotatedWith(
-      final Annotation annotation) {
+  /** Returns a matcher which matches elements (methods, classes, etc.) with a given annotation. */
+  public static Matcher<AnnotatedElement> annotatedWith(final Annotation annotation) {
     return new AnnotatedWith(annotation);
   }
 
@@ -156,127 +155,130 @@
       checkForRuntimeRetention(annotation.annotationType());
     }
 
+    @Override
     public boolean matches(AnnotatedElement element) {
       Annotation fromElement = element.getAnnotation(annotation.annotationType());
       return fromElement != null && annotation.equals(fromElement);
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof AnnotatedWith
           && ((AnnotatedWith) other).annotation.equals(annotation);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * annotation.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "annotatedWith(" + annotation + ")";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Returns a matcher which matches subclasses of the given type (as well as
-   * the given type).
-   */
+  /** Returns a matcher which matches subclasses of the given type (as well as the given type). */
   public static Matcher<Class> subclassesOf(final Class<?> superclass) {
     return new SubclassesOf(superclass);
   }
 
-  private static class SubclassesOf extends AbstractMatcher<Class>
-      implements Serializable {
+  private static class SubclassesOf extends AbstractMatcher<Class> implements Serializable {
     private final Class<?> superclass;
 
     public SubclassesOf(Class<?> superclass) {
       this.superclass = checkNotNull(superclass, "superclass");
     }
 
+    @Override
     public boolean matches(Class subclass) {
       return superclass.isAssignableFrom(subclass);
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof SubclassesOf
-          && ((SubclassesOf) other).superclass.equals(superclass);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof SubclassesOf && ((SubclassesOf) other).superclass.equals(superclass);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * superclass.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "subclassesOf(" + superclass.getSimpleName() + ".class)";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Returns a matcher which matches objects equal to the given object.
-   */
+  /** Returns a matcher which matches objects equal to the given object. */
   public static Matcher<Object> only(Object value) {
     return new Only(value);
   }
 
-  private static class Only extends AbstractMatcher<Object>
-      implements Serializable {
+  private static class Only extends AbstractMatcher<Object> implements Serializable {
     private final Object value;
 
     public Only(Object value) {
       this.value = checkNotNull(value, "value");
     }
 
+    @Override
     public boolean matches(Object other) {
       return value.equals(other);
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof Only
-          && ((Only) other).value.equals(value);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof Only && ((Only) other).value.equals(value);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * value.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "only(" + value + ")";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Returns a matcher which matches only the given object.
-   */
+  /** Returns a matcher which matches only the given object. */
   public static Matcher<Object> identicalTo(final Object value) {
     return new IdenticalTo(value);
   }
 
-  private static class IdenticalTo extends AbstractMatcher<Object>
-      implements Serializable {
+  private static class IdenticalTo extends AbstractMatcher<Object> implements Serializable {
     private final Object value;
 
     public IdenticalTo(Object value) {
       this.value = checkNotNull(value, "value");
     }
 
+    @Override
     public boolean matches(Object other) {
       return value == other;
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof IdenticalTo
-          && ((IdenticalTo) other).value == value;
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof IdenticalTo && ((IdenticalTo) other).value == value;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * System.identityHashCode(value);
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "identicalTo(" + value + ")";
     }
 
@@ -300,20 +302,23 @@
       this.packageName = targetPackage.getName();
     }
 
+    @Override
     public boolean matches(Class c) {
       return c.getPackage().equals(targetPackage);
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof InPackage
-          && ((InPackage) other).targetPackage.equals(targetPackage);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof InPackage && ((InPackage) other).targetPackage.equals(targetPackage);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * targetPackage.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "inPackage(" + targetPackage.getName() + ")";
     }
 
@@ -325,9 +330,9 @@
   }
 
   /**
-   * Returns a matcher which matches classes in the given package and its subpackages. Unlike
-   * {@link #inPackage(Package) inPackage()}, this matches classes from any classloader.
-   * 
+   * Returns a matcher which matches classes in the given package and its subpackages. Unlike {@link
+   * #inPackage(Package) inPackage()}, this matches classes from any classloader.
+   *
    * @since 2.0
    */
   public static Matcher<Class> inSubpackage(final String targetPackageName) {
@@ -341,33 +346,34 @@
       this.targetPackageName = targetPackageName;
     }
 
+    @Override
     public boolean matches(Class c) {
       String classPackageName = c.getPackage().getName();
       return classPackageName.equals(targetPackageName)
           || classPackageName.startsWith(targetPackageName + ".");
     }
 
-    @Override public boolean equals(Object other) {
+    @Override
+    public boolean equals(Object other) {
       return other instanceof InSubpackage
           && ((InSubpackage) other).targetPackageName.equals(targetPackageName);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * targetPackageName.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "inSubpackage(" + targetPackageName + ")";
     }
 
     private static final long serialVersionUID = 0;
   }
 
-  /**
-   * Returns a matcher which matches methods with matching return types.
-   */
-  public static Matcher<Method> returns(
-      final Matcher<? super Class<?>> returnType) {
+  /** Returns a matcher which matches methods with matching return types. */
+  public static Matcher<Method> returns(final Matcher<? super Class<?>> returnType) {
     return new Returns(returnType);
   }
 
@@ -378,20 +384,23 @@
       this.returnType = checkNotNull(returnType, "return type matcher");
     }
 
+    @Override
     public boolean matches(Method m) {
       return returnType.matches(m.getReturnType());
     }
 
-    @Override public boolean equals(Object other) {
-      return other instanceof Returns
-          && ((Returns) other).returnType.equals(returnType);
+    @Override
+    public boolean equals(Object other) {
+      return other instanceof Returns && ((Returns) other).returnType.equals(returnType);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 37 * returnType.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "returns(" + returnType + ")";
     }
 
diff --git a/core/src/com/google/inject/matcher/package-info.java b/core/src/com/google/inject/matcher/package-info.java
index ced3238..d37eed2 100644
--- a/core/src/com/google/inject/matcher/package-info.java
+++ b/core/src/com/google/inject/matcher/package-info.java
@@ -14,8 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Used for matching things. Primarily used to pick out methods to which to
- * apply interceptors.
- */
-package com.google.inject.matcher;
\ No newline at end of file
+/** Used for matching things. Primarily used to pick out methods to which to apply interceptors. */
+package com.google.inject.matcher;
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/ClassMapKey.java b/core/src/com/google/inject/multibindings/ClassMapKey.java
similarity index 99%
rename from extensions/multibindings/src/com/google/inject/multibindings/ClassMapKey.java
rename to core/src/com/google/inject/multibindings/ClassMapKey.java
index d12fe60..19527c7 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/ClassMapKey.java
+++ b/core/src/com/google/inject/multibindings/ClassMapKey.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/core/src/com/google/inject/multibindings/MapBinder.java b/core/src/com/google/inject/multibindings/MapBinder.java
new file mode 100644
index 0000000..fbc506c
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/MapBinder.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.multibindings;
+
+import static com.google.inject.internal.RealMapBinder.newMapRealBinder;
+import static com.google.inject.internal.RealMapBinder.newRealMapBinder;
+
+import com.google.inject.Binder;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.RealMapBinder;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * An API to bind multiple map entries separately, only to later inject them as a complete map.
+ * MapBinder is intended for use in your application's module:
+ *
+ * <pre><code>
+ * public class SnacksModule extends AbstractModule {
+ *   protected void configure() {
+ *     MapBinder&lt;String, Snack&gt; mapbinder
+ *         = MapBinder.newMapBinder(binder(), String.class, Snack.class);
+ *     mapbinder.addBinding("twix").toInstance(new Twix());
+ *     mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
+ *     mapbinder.addBinding("skittles").to(Skittles.class);
+ *   }
+ * }</code></pre>
+ *
+ * <p>With this binding, a {@link Map}{@code <String, Snack>} can now be injected:
+ *
+ * <pre><code>
+ * class SnackMachine {
+ *   {@literal @}Inject
+ *   public SnackMachine(Map&lt;String, Snack&gt; snacks) { ... }
+ * }</code></pre>
+ *
+ * <p>In addition to binding {@code Map<K, V>}, a mapbinder will also bind {@code Map<K,
+ * Provider<V>>} for lazy value provision:
+ *
+ * <pre><code>
+ * class SnackMachine {
+ *   {@literal @}Inject
+ *   public SnackMachine(Map&lt;String, Provider&lt;Snack&gt;&gt; snackProviders) { ... }
+ * }</code></pre>
+ *
+ * <p>Contributing mapbindings from different modules is supported. For example, it is okay to have
+ * both {@code CandyModule} and {@code ChipsModule} both create their own {@code MapBinder<String,
+ * Snack>}, and to each contribute bindings to the snacks map. When that map is injected, it will
+ * contain entries from both modules.
+ *
+ * <p>The map's iteration order is consistent with the binding order. This is convenient when
+ * multiple elements are contributed by the same module because that module can order its bindings
+ * appropriately. Avoid relying on the iteration order of elements contributed by different modules,
+ * since there is no equivalent mechanism to order modules.
+ *
+ * <p>The map is unmodifiable. Elements can only be added to the map by configuring the MapBinder.
+ * Elements can never be removed from the map.
+ *
+ * <p>Values are resolved at map injection time. If a value is bound to a provider, that provider's
+ * get method will be called each time the map is injected (unless the binding is also scoped, or a
+ * map of providers is injected).
+ *
+ * <p>Annotations are used to create different maps of the same key/value type. Each distinct
+ * annotation gets its own independent map.
+ *
+ * <p><strong>Keys must be distinct.</strong> If the same key is bound more than once, map injection
+ * will fail. However, use {@link #permitDuplicates()} in order to allow duplicate keys; extra
+ * bindings to {@code Map<K, Set<V>>} and {@code Map<K, Set<Provider<V>>} will be added.
+ *
+ * <p><strong>Keys must be non-null.</strong> {@code addBinding(null)} will throw an unchecked
+ * exception.
+ *
+ * <p><strong>Values must be non-null to use map injection.</strong> If any value is null, map
+ * injection will fail (although injecting a map of providers will not).
+ *
+ * @author dpb@google.com (David P. Baker)
+ */
+public class MapBinder<K, V> {
+  // This class is non-final due to users mocking this in tests :(
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with no binding annotation.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
+    return new MapBinder<K, V>(
+        newMapRealBinder(binder.skipSources(MapBinder.class), keyType, valueType));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with no binding annotation.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder, Class<K> keyType, Class<V> valueType) {
+    return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotation}.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType, Annotation annotation) {
+    return new MapBinder<K, V>(
+        newRealMapBinder(binder.skipSources(MapBinder.class), keyType, valueType, annotation));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotation}.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder, Class<K> keyType, Class<V> valueType, Annotation annotation) {
+    return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotation);
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotationType}.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder,
+      TypeLiteral<K> keyType,
+      TypeLiteral<V> valueType,
+      Class<? extends Annotation> annotationType) {
+    return new MapBinder<K, V>(
+        newRealMapBinder(binder.skipSources(MapBinder.class), keyType, valueType, annotationType));
+  }
+
+  /**
+   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a {@link
+   * Map} that is itself bound with {@code annotationType}.
+   */
+  public static <K, V> MapBinder<K, V> newMapBinder(
+      Binder binder,
+      Class<K> keyType,
+      Class<V> valueType,
+      Class<? extends Annotation> annotationType) {
+    return newMapBinder(
+        binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotationType);
+  }
+
+  private final RealMapBinder<K, V> delegate;
+
+  private MapBinder(RealMapBinder<K, V> delegate) {
+    this.delegate = delegate;
+  }
+
+  /**
+   * Configures the {@code MapBinder} to handle duplicate entries.
+   *
+   * <p>When multiple equal keys are bound, the value that gets included in the map is arbitrary.
+   *
+   * <p>In addition to the {@code Map<K, V>} and {@code Map<K, Provider<V>>} maps that are normally
+   * bound, a {@code Map<K, Set<V>>} and {@code Map<K, Set<Provider<V>>>} are <em>also</em> bound,
+   * which contain all values bound to each key.
+   *
+   * <p>When multiple modules contribute elements to the map, this configuration option impacts all
+   * of them.
+   *
+   * @return this map binder
+   * @since 3.0
+   */
+  public MapBinder<K, V> permitDuplicates() {
+    delegate.permitDuplicates();
+    return this;
+  }
+
+  /**
+   * Returns a binding builder used to add a new entry in the map. Each key must be distinct (and
+   * non-null). Bound providers will be evaluated each time the map is injected.
+   *
+   * <p>It is an error to call this method without also calling one of the {@code to} methods on the
+   * returned binding builder.
+   *
+   * <p>Scoping elements independently is supported. Use the {@code in} method to specify a binding
+   * scope.
+   */
+  public LinkedBindingBuilder<V> addBinding(K key) {
+    return delegate.addBinding(key);
+  }
+
+  // Some tests rely on MapBinder implementing equals/hashCode
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof MapBinder) {
+      return delegate.equals(((MapBinder<?, ?>) obj).delegate);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+}
diff --git a/core/src/com/google/inject/multibindings/MapBinderBinding.java b/core/src/com/google/inject/multibindings/MapBinderBinding.java
new file mode 100644
index 0000000..b45806f
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/MapBinderBinding.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.multibindings;
+
+import com.google.inject.Binding;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.Elements;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A binding for a MapBinder.
+ *
+ * <p>Although MapBinders may be injected through a variety of generic types (Map&lt;K, V>, Map
+ * &lt;K, Provider&lt;V>>, Map&lt;K, Set&lt;V>>, Map<K, Set&lt; Provider&lt;V>>, and even
+ * Set&lt;Map.Entry&lt;K, Provider&lt;V>>), a MapBinderBinding exists only on the Binding associated
+ * with the Map&lt;K, V> key. Other bindings can be validated to be derived from this
+ * MapBinderBinding using {@link #containsElement(Element)}.
+ *
+ * @param <T> The fully qualified type of the map, including Map. For example: <code>
+ *     MapBinderBinding&lt;Map&lt;String, Snack>></code>
+ * @since 3.0
+ * @author sameb@google.com (Sam Berlin)
+ */
+public interface MapBinderBinding<T> {
+
+  /** Returns the {@link Key} for the map. */
+  Key<T> getMapKey();
+
+  /**
+   * Returns the TypeLiteral describing the keys of the map.
+   *
+   * <p>The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
+   * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a <code>
+   * TypeLiteral&lt;String></code>.
+   */
+  TypeLiteral<?> getKeyTypeLiteral();
+
+  /**
+   * Returns the TypeLiteral describing the values of the map.
+   *
+   * <p>The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
+   * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a <code>
+   * TypeLiteral&lt;Snack></code>.
+   */
+  TypeLiteral<?> getValueTypeLiteral();
+
+  /**
+   * Returns all entries in the Map. The returned list of Map.Entries contains the key and a binding
+   * to the value. Duplicate keys or values will exist as separate Map.Entries in the returned list.
+   * This is only supported on bindings returned from an injector. This will throw {@link
+   * UnsupportedOperationException} if it is called on an element retrieved from {@link
+   * Elements#getElements}.
+   *
+   * <p>The elements will always match the type Map's generic type. For example, if getMapKey
+   * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a list of
+   * type <code>List&lt;Map.Entry&lt;String, Binding&lt;Snack>>></code>.
+   */
+  List<Map.Entry<?, Binding<?>>> getEntries();
+
+  /**
+   * Similar to {@link #getEntries()}, but can be used on a MapBinderBinding retrieved from {@link
+   * Elements#getElements}.
+   *
+   * <p>One way to use this is to pass in the results of {@link Elements#getElements} as the {@code
+   * elements} parameter.
+   *
+   * <p>This differs from {@link #getEntries()} in that it will return duplicates if they are
+   * present in the {@code elements} passed in. This does not run the normal Guice de-duplication
+   * that {@link #getEntries()} does.
+   *
+   * @throws IllegalArgumentException if the provided elements contain partial map entries. If the
+   *     elements come from {@link Elements#getElements} on a module with a MapBinder, there will be
+   *     a 1:1 relationship and no exception will be thrown.
+   * @since 4.2
+   */
+  List<Map.Entry<?, Binding<?>>> getEntries(Iterable<? extends Element> elements);
+
+  /**
+   * Returns true if the MapBinder permits duplicates. This is only supported on bindings returned
+   * from an injector. This will throw {@link UnsupportedOperationException} if it is called on a
+   * MapBinderBinding retrieved from {@link Elements#getElements}.
+   */
+  boolean permitsDuplicates();
+
+  /**
+   * Returns true if this MapBinder contains the given Element in order to build the map or uses the
+   * given Element in order to support building and injecting the map. This will work for
+   * MapBinderBindings retrieved from an injector and {@link Elements#getElements}. Usually this is
+   * only necessary if you are working with elements retrieved from modules (without an Injector),
+   * otherwise {@link #getEntries} and {@link #permitsDuplicates} are better options.
+   *
+   * <p>If you need to introspect the details of the map, such as the keys, values or if it permits
+   * duplicates, it is necessary to pass the elements through an Injector and use {@link
+   * #getEntries()} and {@link #permitsDuplicates()}.
+   */
+  boolean containsElement(Element element);
+}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapKey.java b/core/src/com/google/inject/multibindings/MapKey.java
similarity index 86%
rename from extensions/multibindings/src/com/google/inject/multibindings/MapKey.java
rename to core/src/com/google/inject/multibindings/MapKey.java
index 830f329..3f8af89 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapKey.java
+++ b/core/src/com/google/inject/multibindings/MapKey.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,7 +27,7 @@
  * Allows users define customized key type annotations for map bindings by annotating an annotation
  * of a {@code Map}'s key type. The custom key annotation can be applied to methods also annotated
  * with {@literal @}{@link ProvidesIntoMap}.
- * 
+ *
  * <p>A {@link StringMapKey} and {@link ClassMapKey} are provided for convenience with maps whose
  * keys are strings or classes. For maps with enums or primitive types as keys, you must provide
  * your own MapKey annotation, such as this one for an enum:
@@ -40,10 +40,10 @@
  * }
  * </pre>
  *
- * You can also use the whole annotation as the key, if {@code unwrapValue=false}.
- * When unwrapValue is false, the annotation type will be the key type for the injected map and
- * the annotation instances will be the key values. If {@code unwrapValue=true}, the value() type
- * will be the key type for injected map and the value() instances will be the keys values.
+ * You can also use the whole annotation as the key, if {@code unwrapValue=false}. When unwrapValue
+ * is false, the annotation type will be the key type for the injected map and the annotation
+ * instances will be the key values. If {@code unwrapValue=true}, the value() type will be the key
+ * type for injected map and the value() instances will be the keys values.
  *
  * @since 4.0
  */
diff --git a/core/src/com/google/inject/multibindings/Multibinder.java b/core/src/com/google/inject/multibindings/Multibinder.java
new file mode 100644
index 0000000..058fffe
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/Multibinder.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.multibindings;
+
+import static com.google.inject.internal.RealMultibinder.newRealSetBinder;
+
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.RealMultibinder;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * An API to bind multiple values separately, only to later inject them as a complete collection.
+ * Multibinder is intended for use in your application's module:
+ *
+ * <pre><code>
+ * public class SnacksModule extends AbstractModule {
+ *   protected void configure() {
+ *     Multibinder&lt;Snack&gt; multibinder
+ *         = Multibinder.newSetBinder(binder(), Snack.class);
+ *     multibinder.addBinding().toInstance(new Twix());
+ *     multibinder.addBinding().toProvider(SnickersProvider.class);
+ *     multibinder.addBinding().to(Skittles.class);
+ *   }
+ * }</code></pre>
+ *
+ * <p>With this binding, a {@link Set}{@code <Snack>} can now be injected:
+ *
+ * <pre><code>
+ * class SnackMachine {
+ *   {@literal @}Inject
+ *   public SnackMachine(Set&lt;Snack&gt; snacks) { ... }
+ * }</code></pre>
+ *
+ * If desired, {@link Collection}{@code <Provider<Snack>>} can also be injected.
+ *
+ * <p>Contributing multibindings from different modules is supported. For example, it is okay for
+ * both {@code CandyModule} and {@code ChipsModule} to create their own {@code Multibinder<Snack>},
+ * and to each contribute bindings to the set of snacks. When that set is injected, it will contain
+ * elements from both modules.
+ *
+ * <p>The set's iteration order is consistent with the binding order. This is convenient when
+ * multiple elements are contributed by the same module because that module can order its bindings
+ * appropriately. Avoid relying on the iteration order of elements contributed by different modules,
+ * since there is no equivalent mechanism to order modules.
+ *
+ * <p>The set is unmodifiable. Elements can only be added to the set by configuring the multibinder.
+ * Elements can never be removed from the set.
+ *
+ * <p>Elements are resolved at set injection time. If an element is bound to a provider, that
+ * provider's get method will be called each time the set is injected (unless the binding is also
+ * scoped).
+ *
+ * <p>Annotations are be used to create different sets of the same element type. Each distinct
+ * annotation gets its own independent collection of elements.
+ *
+ * <p><strong>Elements must be distinct.</strong> If multiple bound elements have the same value,
+ * set injection will fail.
+ *
+ * <p><strong>Elements must be non-null.</strong> If any set element is null, set injection will
+ * fail.
+ *
+ * @author jessewilson@google.com (Jesse Wilson)
+ */
+public class Multibinder<T> {
+  // This class is non-final due to users mocking this in tests :(
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with no binding annotation.
+   */
+  public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type) {
+    return newSetBinder(binder, Key.get(type));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with no binding annotation.
+   */
+  public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type) {
+    return newSetBinder(binder, Key.get(type));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with {@code annotation}.
+   */
+  public static <T> Multibinder<T> newSetBinder(
+      Binder binder, TypeLiteral<T> type, Annotation annotation) {
+    return newSetBinder(binder, Key.get(type, annotation));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with {@code annotation}.
+   */
+  public static <T> Multibinder<T> newSetBinder(
+      Binder binder, Class<T> type, Annotation annotation) {
+    return newSetBinder(binder, Key.get(type, annotation));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with {@code annotationType}.
+   */
+  public static <T> Multibinder<T> newSetBinder(
+      Binder binder, TypeLiteral<T> type, Class<? extends Annotation> annotationType) {
+    return newSetBinder(binder, Key.get(type, annotationType));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of the key's type in a {@link Set} that is
+   * itself bound with the annotation (if any) of the key.
+   *
+   * @since 4.0
+   */
+  public static <T> Multibinder<T> newSetBinder(Binder binder, Key<T> key) {
+    return new Multibinder<T>(newRealSetBinder(binder.skipSources(Multibinder.class), key));
+  }
+
+  /**
+   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+   * itself bound with {@code annotationType}.
+   */
+  public static <T> Multibinder<T> newSetBinder(
+      Binder binder, Class<T> type, Class<? extends Annotation> annotationType) {
+    return newSetBinder(binder, Key.get(type, annotationType));
+  }
+
+  private final RealMultibinder<T> delegate;
+
+  private Multibinder(RealMultibinder<T> delegate) {
+    this.delegate = delegate;
+  }
+
+  /**
+   * Configures the bound set to silently discard duplicate elements. When multiple equal values are
+   * bound, the one that gets included is arbitrary. When multiple modules contribute elements to
+   * the set, this configuration option impacts all of them.
+   *
+   * @return this multibinder
+   * @since 3.0
+   */
+  public Multibinder<T> permitDuplicates() {
+    delegate.permitDuplicates();
+    return this;
+  }
+
+  /**
+   * Returns a binding builder used to add a new element in the set. Each bound element must have a
+   * distinct value. Bound providers will be evaluated each time the set is injected.
+   *
+   * <p>It is an error to call this method without also calling one of the {@code to} methods on the
+   * returned binding builder.
+   *
+   * <p>Scoping elements independently is supported. Use the {@code in} method to specify a binding
+   * scope.
+   */
+  public LinkedBindingBuilder<T> addBinding() {
+    return delegate.addBinding();
+  }
+
+  // Some tests rely on Multibinder implementing equals/hashCode
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof Multibinder) {
+      return delegate.equals(((Multibinder<?>) obj).delegate);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MultibinderBinding.java b/core/src/com/google/inject/multibindings/MultibinderBinding.java
similarity index 78%
rename from extensions/multibindings/src/com/google/inject/multibindings/MultibinderBinding.java
rename to core/src/com/google/inject/multibindings/MultibinderBinding.java
index 998452c..43db6a2 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MultibinderBinding.java
+++ b/core/src/com/google/inject/multibindings/MultibinderBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,15 +21,13 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
-
 import java.util.List;
 
 /**
  * A binding for a Multibinder.
- * 
- * @param <T> The fully qualified type of the set, including Set. For example:
- *          <code>MultibinderBinding&lt;Set&lt;Boolean>></code>
- * 
+ *
+ * @param <T> The fully qualified type of the set, including Set. For example: <code>
+ *     MultibinderBinding&lt;Set&lt;Boolean>></code>
  * @since 3.0
  * @author sameb@google.com (Sam Berlin)
  */
@@ -37,13 +35,13 @@
 
   /** Returns the key for the set. */
   Key<T> getSetKey();
-  
+
   /**
    * Returns the TypeLiteral that describes the type of elements in the set.
-   * <p>
-   * The elements will always match the type Set's generic type. For example, if getSetKey returns a
-   * key of <code>Set&lt;String></code>, then this will always return a
-   * <code>TypeLiteral&lt;String></code>.
+   *
+   * <p>The elements will always match the type Set's generic type. For example, if getSetKey
+   * returns a key of <code>Set&lt;String></code>, then this will always return a <code>
+   * TypeLiteral&lt;String></code>.
    */
   TypeLiteral<?> getElementTypeLiteral();
 
@@ -51,9 +49,9 @@
    * Returns all bindings that make up the set. This is only supported on bindings returned from an
    * injector. This will throw {@link UnsupportedOperationException} if it is called on an element
    * retrieved from {@link Elements#getElements}.
-   * <p>
-   * The elements will always match the type Set's generic type. For example, if getSetKey returns a
-   * key of <code>Set&lt;String></code>, then this will always return a list of type
+   *
+   * <p>The elements will always match the type Set's generic type. For example, if getSetKey
+   * returns a key of <code>Set&lt;String></code>, then this will always return a list of type
    * <code>List&lt;Binding&lt;String>></code>.
    */
   List<Binding<?>> getElements();
@@ -71,10 +69,10 @@
    * work for MultibinderBindings retrieved from an injector and {@link Elements#getElements}.
    * Usually this is only necessary if you are working with elements retrieved from modules (without
    * an Injector), otherwise {@link #getElements} and {@link #permitsDuplicates} are better options.
-   * <p>
-   * If you need to introspect the details of the set, such as the values or if it permits
-   * duplicates, it is necessary to pass the elements through an Injector and use
-   * {@link #getElements()} and {@link #permitsDuplicates()}.
+   *
+   * <p>If you need to introspect the details of the set, such as the values or if it permits
+   * duplicates, it is necessary to pass the elements through an Injector and use {@link
+   * #getElements()} and {@link #permitsDuplicates()}.
    */
   boolean containsElement(Element element);
 }
diff --git a/core/src/com/google/inject/multibindings/MultibindingsScanner.java b/core/src/com/google/inject/multibindings/MultibindingsScanner.java
new file mode 100644
index 0000000..3ede7c5
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/MultibindingsScanner.java
@@ -0,0 +1,75 @@
+/*
+ * 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 com.google.inject.multibindings;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.ModuleAnnotatedMethodScanner;
+import com.google.inject.util.Modules;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+/**
+ * Scans a module for annotations that signal multibindings, mapbindings, and optional bindings.
+ *
+ * @since 4.0
+ * @deprecated This functionality is installed by default. All references to this can be safely
+ *     removed. This class will be removed in Guice 4.4
+ */
+@Deprecated
+public class MultibindingsScanner {
+  private MultibindingsScanner() {}
+
+  /**
+   * Returns a module that, when installed, will scan all modules for methods with the annotations
+   * {@literal @}{@link ProvidesIntoMap}, {@literal @}{@link ProvidesIntoSet}, and
+   * {@literal @}{@link ProvidesIntoOptional}.
+   *
+   * <p>This is a convenience method, equivalent to doing {@code
+   * binder().scanModulesForAnnotatedMethods(MultibindingsScanner.scanner())}.
+   *
+   * @deprecated This functionality is now installed by default. All references/installations can be
+   *     eliminated.
+   */
+  @Deprecated
+  public static Module asModule() {
+    return Modules.EMPTY_MODULE;
+  }
+
+  /**
+   * @deprecated This method returns an empty scanner since the preexisting functionality is
+   *     installed by default.
+   */
+  @Deprecated
+  public static ModuleAnnotatedMethodScanner scanner() {
+    return new ModuleAnnotatedMethodScanner() {
+      @Override
+      public Set<? extends Class<? extends Annotation>> annotationClasses() {
+        return ImmutableSet.of();
+      }
+
+      @Override
+      public <T> Key<T> prepareMethod(
+          Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
+        throw new IllegalStateException("Unexpected annotation: " + annotation);
+      }
+    };
+  }
+}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java b/core/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java
similarity index 82%
rename from extensions/multibindings/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java
rename to core/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java
index 9378e19..b6a2eb3 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java
+++ b/core/src/com/google/inject/multibindings/MultibindingsTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,8 +20,8 @@
 
 /**
  * A visitor for the multibinder extension.
- * <p>
- * If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ *
+ * <p>If your {@link BindingTargetVisitor} implements this interface, bindings created by using
  * {@link Multibinder}, {@link MapBinder} or {@link OptionalBinderBinding} will be visited through
  * this interface.
  *
@@ -29,22 +29,17 @@
  * @author sameb@google.com (Sam Berlin)
  */
 public interface MultibindingsTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
-  
-  /**
-   * Visits a binding created through {@link Multibinder}.
-   */
+
+  /** Visits a binding created through {@link Multibinder}. */
   V visit(MultibinderBinding<? extends T> multibinding);
-  
-  /**
-   * Visits a binding created through {@link MapBinder}.
-   */
+
+  /** Visits a binding created through {@link MapBinder}. */
   V visit(MapBinderBinding<? extends T> mapbinding);
-  
+
   /**
    * Visits a binding created through {@link OptionalBinder}.
-   * 
+   *
    * @since 4.0
    */
   V visit(OptionalBinderBinding<? extends T> optionalbinding);
-
 }
diff --git a/core/src/com/google/inject/multibindings/OptionalBinder.java b/core/src/com/google/inject/multibindings/OptionalBinder.java
new file mode 100644
index 0000000..0e015c5
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/OptionalBinder.java
@@ -0,0 +1,199 @@
+/*
+ * 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.google.inject.multibindings;
+
+import static com.google.inject.internal.RealOptionalBinder.newRealOptionalBinder;
+
+import com.google.common.base.Optional;
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.internal.RealOptionalBinder;
+
+/**
+ * An API to bind optional values, optionally with a default value. OptionalBinder fulfills two
+ * roles:
+ *
+ * <ol>
+ * <li>It allows a framework to define an injection point that may or may not be bound by users.
+ * <li>It allows a framework to supply a default value that can be changed by users.
+ * </ol>
+ *
+ * <p>When an OptionalBinder is added, it will always supply the bindings: {@code Optional<T>} and
+ * {@code Optional<Provider<T>>}. If {@link #setBinding} or {@link #setDefault} are called, it will
+ * also bind {@code T}.
+ *
+ * <p>{@code setDefault} is intended for use by frameworks that need a default value. User code can
+ * call {@code setBinding} to override the default. <b>Warning: Even if setBinding is called, the
+ * default binding will still exist in the object graph. If it is a singleton, it will be
+ * instantiated in {@code Stage.PRODUCTION}.</b>
+ *
+ * <p>If setDefault or setBinding are linked to Providers, the Provider may return {@code null}. If
+ * it does, the Optional bindings will be absent. Binding setBinding to a Provider that returns null
+ * will not cause OptionalBinder to fall back to the setDefault binding.
+ *
+ * <p>If neither setDefault nor setBinding are called, it will try to link to a user-supplied
+ * binding of the same type. If no binding exists, the optionals will be absent. Otherwise, if a
+ * user-supplied binding of that type exists, or if setBinding or setDefault are called, the
+ * optionals will return present if they are bound to a non-null value.
+ *
+ * <p>Values are resolved at injection time. If a value is bound to a provider, that provider's get
+ * method will be called each time the optional is injected (unless the binding is also scoped, or
+ * an optional of provider is injected).
+ *
+ * <p>Annotations are used to create different optionals of the same key/value type. Each distinct
+ * annotation gets its own independent binding.
+ *
+ * <pre><code>
+ * public class FrameworkModule extends AbstractModule {
+ *   protected void configure() {
+ *     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
+ *   }
+ * }</code></pre>
+ *
+ * <p>With this module, an {@link Optional}{@code <Renamer>} can now be injected. With no other
+ * bindings, the optional will be absent. Users can specify bindings in one of two ways:
+ *
+ * <p>Option 1:
+ *
+ * <pre><code>
+ * public class UserRenamerModule extends AbstractModule {
+ *   protected void configure() {
+ *     bind(Renamer.class).to(ReplacingRenamer.class);
+ *   }
+ * }</code></pre>
+ *
+ * <p>or Option 2:
+ *
+ * <pre><code>
+ * public class UserRenamerModule extends AbstractModule {
+ *   protected void configure() {
+ *     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
+ *         .setBinding().to(ReplacingRenamer.class);
+ *   }
+ * }</code></pre>
+ *
+ * With both options, the {@code Optional<Renamer>} will be present and supply the ReplacingRenamer.
+ *
+ * <p>Default values can be supplied using:
+ *
+ * <pre><code>
+ * public class FrameworkModule extends AbstractModule {
+ *   protected void configure() {
+ *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+ *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+ *   }
+ * }</code></pre>
+ *
+ * With the above module, code can inject an {@code @LookupUrl String} and it will supply the
+ * DEFAULT_LOOKUP_URL. A user can change this value by binding
+ *
+ * <pre><code>
+ * public class UserLookupModule extends AbstractModule {
+ *   protected void configure() {
+ *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+ *         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
+ *   }
+ * }</code></pre>
+ *
+ * ... which will override the default value.
+ *
+ * <p>If one module uses setDefault the only way to override the default is to use setBinding. It is
+ * an error for a user to specify the binding without using OptionalBinder if setDefault or
+ * setBinding are called. For example,
+ *
+ * <pre><code>
+ * public class FrameworkModule extends AbstractModule {
+ *   protected void configure() {
+ *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+ *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+ *   }
+ * }
+ * public class UserLookupModule extends AbstractModule {
+ *   protected void configure() {
+ *     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
+ *   }
+ * }</code></pre>
+ *
+ * ... would generate an error, because both the framework and the user are trying to bind
+ * {@code @LookupUrl String}.
+ *
+ * @author sameb@google.com (Sam Berlin)
+ * @since 4.0
+ */
+public class OptionalBinder<T> {
+  // This class is non-final due to users mocking this in tests :(
+
+  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type) {
+    return new OptionalBinder<T>(
+        newRealOptionalBinder(binder.skipSources(OptionalBinder.class), Key.get(type)));
+  }
+
+  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type) {
+    return new OptionalBinder<T>(
+        newRealOptionalBinder(binder.skipSources(OptionalBinder.class), Key.get(type)));
+  }
+
+  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type) {
+    return new OptionalBinder<T>(
+        newRealOptionalBinder(binder.skipSources(OptionalBinder.class), type));
+  }
+
+  private final RealOptionalBinder<T> delegate;
+
+  private OptionalBinder(RealOptionalBinder<T> delegate) {
+    this.delegate = delegate;
+  }
+
+  /**
+   * Returns a binding builder used to set the default value that will be injected. The binding set
+   * by this method will be ignored if {@link #setBinding} is called.
+   *
+   * <p>It is an error to call this method without also calling one of the {@code to} methods on the
+   * returned binding builder.
+   */
+  public LinkedBindingBuilder<T> setDefault() {
+    return delegate.setDefault();
+  }
+
+  /**
+   * Returns a binding builder used to set the actual value that will be injected. This overrides
+   * any binding set by {@link #setDefault}.
+   *
+   * <p>It is an error to call this method without also calling one of the {@code to} methods on the
+   * returned binding builder.
+   */
+  public LinkedBindingBuilder<T> setBinding() {
+    return delegate.setBinding();
+  }
+
+  // Some tests depend on equals/hashCode behavior of OptionalBinder
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof OptionalBinder) {
+      return delegate.equals(((OptionalBinder<?>) obj).delegate);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+}
diff --git a/core/src/com/google/inject/multibindings/OptionalBinderBinding.java b/core/src/com/google/inject/multibindings/OptionalBinderBinding.java
new file mode 100644
index 0000000..5fedc4b
--- /dev/null
+++ b/core/src/com/google/inject/multibindings/OptionalBinderBinding.java
@@ -0,0 +1,73 @@
+/*
+ * 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.google.inject.multibindings;
+
+import com.google.inject.Binding;
+import com.google.inject.Key;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.Elements;
+
+/**
+ * A binding for a OptionalBinder.
+ *
+ * <p>Although OptionalBinders may be injected through a variety of types {@code T}, {@code
+ * Optional<T>}, {@code Optional<Provider<T>>}, etc..), an OptionalBinderBinding exists only on the
+ * Binding associated with the {@code Optional<T>} key. Other bindings can be validated to be
+ * derived from this OptionalBinderBinding using {@link #containsElement}.
+ *
+ * @param <T> The fully qualified type of the optional binding, including Optional. For example:
+ *     {@code Optional<String>}.
+ * @since 4.0
+ * @author sameb@google.com (Sam Berlin)
+ */
+public interface OptionalBinderBinding<T> {
+
+  /** Returns the {@link Key} for this binding. */
+  Key<T> getKey();
+
+  /**
+   * Returns the default binding (set by {@link OptionalBinder#setDefault}) if one exists or null if
+   * no default binding is set. This will throw {@link UnsupportedOperationException} if it is
+   * called on an element retrieved from {@link Elements#getElements}.
+   *
+   * <p>The Binding's type will always match the type Optional's generic type. For example, if
+   * getKey returns a key of <code>Optional&lt;String></code>, then this will always return a <code>
+   * Binding&lt;String></code>.
+   */
+  Binding<?> getDefaultBinding();
+
+  /**
+   * Returns the actual binding (set by {@link OptionalBinder#setBinding}) or null if not set. This
+   * will throw {@link UnsupportedOperationException} if it is called on an element retrieved from
+   * {@link Elements#getElements}.
+   *
+   * <p>The Binding's type will always match the type Optional's generic type. For example, if
+   * getKey returns a key of <code>Optional&lt;String></code>, then this will always return a <code>
+   * Binding&lt;String></code>.
+   */
+  Binding<?> getActualBinding();
+
+  /**
+   * Returns true if this OptionalBinder contains the given Element in order to build the optional
+   * binding or uses the given Element in order to support building and injecting its data. This
+   * will work for OptionalBinderBinding retrieved from an injector and {@link
+   * Elements#getElements}. Usually this is only necessary if you are working with elements
+   * retrieved from modules (without an Injector), otherwise {@link #getDefaultBinding} and {@link
+   * #getActualBinding} are better options.
+   */
+  boolean containsElement(Element element);
+}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoMap.java b/core/src/com/google/inject/multibindings/ProvidesIntoMap.java
similarity index 71%
rename from extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoMap.java
rename to core/src/com/google/inject/multibindings/ProvidesIntoMap.java
index 886a0fd..9ab0dd9 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoMap.java
+++ b/core/src/com/google/inject/multibindings/ProvidesIntoMap.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,21 +20,20 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.Module;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * Annotates methods of a {@link Module} to add items to a {@link MapBinder}.
- * The method's return type, binding annotation and additional key annotation determines
- * what Map this will contribute to. For example,
+ * Annotates methods of a {@link Module} to add items to a {@link MapBinder}. The method's return
+ * type, binding annotation and additional key annotation determines what Map this will contribute
+ * to. For example,
  *
  * <pre>
  * {@literal @}ProvidesIntoMap
  * {@literal @}StringMapKey("Foo")
- * {@literal @}Named("plugins")
- * Plugin provideFooUrl(FooManager fm) { returm fm.getPlugin(); }
+ * {@literal @}Named("urls")
+ * Plugin provideFooUrl(FooManager fm) { return fm.getPlugin(); }
  *
  * {@literal @}ProvidesIntoMap
  * {@literal @}StringMapKey("Bar")
@@ -42,12 +41,12 @@
  * Plugin provideBarUrl(BarManager bm) { return bm.getPlugin(); }
  * </pre>
  *
- * will add two items to the {@code @Named("urls") Map<String, Plugin>} map. The key 'Foo'
- * will map to the provideFooUrl method, and the key 'Bar' will map to the provideBarUrl method.
- * The values are bound as providers and will be evaluated at injection time.
+ * will add two items to the {@code @Named("urls") Map<String, Plugin>} map. The key 'Foo' will map
+ * to the provideFooUrl method, and the key 'Bar' will map to the provideBarUrl method. The values
+ * are bound as providers and will be evaluated at injection time.
  *
- * <p>Because the key is specified as an annotation, only Strings, Classes, enums, primitive
- * types and annotation instances are supported as keys.
+ * <p>Because the key is specified as an annotation, only Strings, Classes, enums, primitive types
+ * and annotation instances are supported as keys.
  *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
@@ -55,5 +54,4 @@
 @Documented
 @Target(METHOD)
 @Retention(RUNTIME)
-public @interface ProvidesIntoMap {
-}
+public @interface ProvidesIntoMap {}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoOptional.java b/core/src/com/google/inject/multibindings/ProvidesIntoOptional.java
similarity index 88%
rename from extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoOptional.java
rename to core/src/com/google/inject/multibindings/ProvidesIntoOptional.java
index 23576f6..19799c8 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoOptional.java
+++ b/core/src/com/google/inject/multibindings/ProvidesIntoOptional.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,15 +20,13 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.Module;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
- * The method's return type and binding annotation determines what Optional this will
- * contribute to. For example,
+ * Annotates methods of a {@link Module} to add items to a {@link Multibinder}. The method's return
+ * type and binding annotation determines what Optional this will contribute to. For example,
  *
  * <pre>
  * {@literal @}ProvidesIntoOptional(DEFAULT)
@@ -40,8 +38,8 @@
  * String provideBarUrl(BarManager bm) { return bm.getUrl(); }
  * </pre>
  *
- * will set the default value of {@code @Named("url") Optional<String>} to foo's URL,
- * and then override it to bar's URL.
+ * will set the default value of {@code @Named("url") Optional<String>} to foo's URL, and then
+ * override it to bar's URL.
  *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
@@ -50,9 +48,7 @@
 @Target(METHOD)
 @Retention(RUNTIME)
 public @interface ProvidesIntoOptional {
-  /**
-   * @since 4.0
-   */
+  /** @since 4.0 */
   enum Type {
     /** Corresponds to {@link OptionalBinder#setBinding}. */
     ACTUAL,
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoSet.java b/core/src/com/google/inject/multibindings/ProvidesIntoSet.java
similarity index 89%
rename from extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoSet.java
rename to core/src/com/google/inject/multibindings/ProvidesIntoSet.java
index b26df68..a7618b6 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/ProvidesIntoSet.java
+++ b/core/src/com/google/inject/multibindings/ProvidesIntoSet.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,15 +20,13 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.Module;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
- * The method's return type and binding annotation determines what Set this will
- * contribute to. For example,
+ * Annotates methods of a {@link Module} to add items to a {@link Multibinder}. The method's return
+ * type and binding annotation determines what Set this will contribute to. For example,
  *
  * <pre>
  * {@literal @}ProvidesIntoSet
@@ -49,5 +47,4 @@
 @Documented
 @Target(METHOD)
 @Retention(RUNTIME)
-public @interface ProvidesIntoSet {
-}
+public @interface ProvidesIntoSet {}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/StringMapKey.java b/core/src/com/google/inject/multibindings/StringMapKey.java
similarity index 99%
rename from extensions/multibindings/src/com/google/inject/multibindings/StringMapKey.java
rename to core/src/com/google/inject/multibindings/StringMapKey.java
index 9a4f1bd..7c6e041 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/StringMapKey.java
+++ b/core/src/com/google/inject/multibindings/StringMapKey.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/package-info.java b/core/src/com/google/inject/multibindings/package-info.java
similarity index 100%
rename from extensions/multibindings/src/com/google/inject/multibindings/package-info.java
rename to core/src/com/google/inject/multibindings/package-info.java
diff --git a/core/src/com/google/inject/name/Named.java b/core/src/com/google/inject/name/Named.java
index 23b3d5d..b1d9a4e 100644
--- a/core/src/com/google/inject/name/Named.java
+++ b/core/src/com/google/inject/name/Named.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,6 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
@@ -30,7 +29,7 @@
  * @author crazybob@google.com (Bob Lee)
  */
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
 public @interface Named {
   String value();
diff --git a/core/src/com/google/inject/name/NamedImpl.java b/core/src/com/google/inject/name/NamedImpl.java
index 2fe0107..9c4d10e 100644
--- a/core/src/com/google/inject/name/NamedImpl.java
+++ b/core/src/com/google/inject/name/NamedImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +18,7 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import com.google.inject.internal.Annotations;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 
@@ -29,15 +30,18 @@
     this.value = checkNotNull(value, "name");
   }
 
+  @Override
   public String value() {
     return this.value;
   }
 
+  @Override
   public int hashCode() {
     // This is specified in java.lang.Annotation.
     return (127 * "value".hashCode()) ^ value.hashCode();
   }
 
+  @Override
   public boolean equals(Object o) {
     if (!(o instanceof Named)) {
       return false;
@@ -47,10 +51,12 @@
     return value.equals(other.value());
   }
 
+  @Override
   public String toString() {
-    return "@" + Named.class.getName() + "(value=" + value + ")";
+    return "@" + Named.class.getName() + "(value=" + Annotations.memberValueString(value) + ")";
   }
 
+  @Override
   public Class<? extends Annotation> annotationType() {
     return Named.class;
   }
diff --git a/core/src/com/google/inject/name/Names.java b/core/src/com/google/inject/name/Names.java
index f7ec971..619de81 100644
--- a/core/src/com/google/inject/name/Names.java
+++ b/core/src/com/google/inject/name/Names.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Binder;
 import com.google.inject.Key;
-
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Properties;
@@ -32,17 +31,12 @@
 
   private Names() {}
 
-  /**
-   * Creates a {@link Named} annotation with {@code name} as the value.
-   */
+  /** Creates a {@link Named} annotation with {@code name} as the value. */
   public static Named named(String name) {
     return new NamedImpl(name);
   }
 
-  /**
-   * Creates a constant binding to {@code @Named(key)} for each entry in
-   * {@code properties}.
-   */
+  /** Creates a constant binding to {@code @Named(key)} for each entry in {@code properties}. */
   public static void bindProperties(Binder binder, Map<String, String> properties) {
     binder = binder.skipSources(Names.class);
     for (Map.Entry<String, String> entry : properties.entrySet()) {
@@ -53,9 +47,8 @@
   }
 
   /**
-   * Creates a constant binding to {@code @Named(key)} for each property. This
-   * method binds all properties including those inherited from 
-   * {@link Properties#defaults defaults}.
+   * Creates a constant binding to {@code @Named(key)} for each property. This method binds all
+   * properties including those inherited from {@link Properties#defaults defaults}.
    */
   public static void bindProperties(Binder binder, Properties properties) {
     binder = binder.skipSources(Names.class);
diff --git a/core/src/com/google/inject/name/package-info.java b/core/src/com/google/inject/name/package-info.java
index d6bf05d..8d4482d 100644
--- a/core/src/com/google/inject/name/package-info.java
+++ b/core/src/com/google/inject/name/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Support for binding to string-based names.
- */
-package com.google.inject.name;
\ No newline at end of file
+/** Support for binding to string-based names. */
+package com.google.inject.name;
diff --git a/core/src/com/google/inject/package-info.java b/core/src/com/google/inject/package-info.java
index 626bde2..12b3b1e 100644
--- a/core/src/com/google/inject/package-info.java
+++ b/core/src/com/google/inject/package-info.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,33 +15,25 @@
  */
 
 /**
- * <i>Google Guice</i> (pronounced "juice") is an ultra-lightweight dependency
- * injection framework.  Please refer to the Guice
- * <a href="http://docs.google.com/Doc?id=dd2fhx4z_5df5hw8">User's Guide</a>
- * for a gentle introduction.
+ * <i>Google Guice</i> (pronounced "juice") is an ultra-lightweight dependency injection framework.
+ * Please refer to the Guice <a href="http://docs.google.com/Doc?id=dd2fhx4z_5df5hw8">User's
+ * Guide</a> for a gentle introduction.
  *
  * <p>The principal public APIs in this package are:
  *
  * <dl>
  * <dt>{@link com.google.inject.Inject}
- * <dd>The annotation you will use in your implementation classes to tell Guice
- *     where and how it should send in ("inject") the objects you depend on
- *     (your "dependencies").
- *
+ * <dd>The annotation you will use in your implementation classes to tell Guice where and how it
+ *     should send in ("inject") the objects you depend on (your "dependencies").
  * <dt>{@link com.google.inject.Module}
- * <dd>The interface you will implement in order to specify "bindings" --
- *     instructions for how Guice should handle injection -- for a particular
- *     set of interfaces.
- *
+ * <dd>The interface you will implement in order to specify "bindings" -- instructions for how Guice
+ *     should handle injection -- for a particular set of interfaces.
  * <dt>{@link com.google.inject.Binder}
- * <dd>The object that Guice passes into your {@link com.google.inject.Module}
- *     to collect these bindings.
- *
+ * <dd>The object that Guice passes into your {@link com.google.inject.Module} to collect these
+ *     bindings.
  * <dt>{@link com.google.inject.Provider}
- * <dd>The interface you will implement when you need to customize exactly how
- *     Guice creates instances for a particular binding.
- *
+ * <dd>The interface you will implement when you need to customize exactly how Guice creates
+ *     instances for a particular binding.
  * </dl>
- *
  */
-package com.google.inject;
\ No newline at end of file
+package com.google.inject;
diff --git a/core/src/com/google/inject/spi/BindingScopingVisitor.java b/core/src/com/google/inject/spi/BindingScopingVisitor.java
index 2abfc9e..41bd069 100644
--- a/core/src/com/google/inject/spi/BindingScopingVisitor.java
+++ b/core/src/com/google/inject/spi/BindingScopingVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,14 +17,13 @@
 package com.google.inject.spi;
 
 import com.google.inject.Scope;
-
 import java.lang.annotation.Annotation;
 
 /**
  * Visits each of the strategies used to scope an injection.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @since 2.0
  */
 public interface BindingScopingVisitor<V> {
@@ -35,9 +34,7 @@
    */
   V visitEagerSingleton();
 
-  /**
-   * Visit a scope instance. This scope strategy is found on both module and injector bindings.
-   */
+  /** Visit a scope instance. This scope strategy is found on both module and injector bindings. */
   V visitScope(Scope scope);
 
   /**
@@ -49,9 +46,9 @@
 
   /**
    * Visit an unspecified or unscoped strategy. On a module, this strategy indicates that the
-   * injector should use scoping annotations to find a scope. On an injector, it indicates that
-   * no scope is applied to the binding. An unscoped binding will behave like a scoped one when it
-   * is linked to a scoped binding.
+   * injector should use scoping annotations to find a scope. On an injector, it indicates that no
+   * scope is applied to the binding. An unscoped binding will behave like a scoped one when it is
+   * linked to a scoped binding.
    */
   V visitNoScoping();
 }
diff --git a/core/src/com/google/inject/spi/BindingTargetVisitor.java b/core/src/com/google/inject/spi/BindingTargetVisitor.java
index 7137d74..890aeba 100644
--- a/core/src/com/google/inject/spi/BindingTargetVisitor.java
+++ b/core/src/com/google/inject/spi/BindingTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,8 +19,8 @@
 /**
  * Visits each of the strategies used to find an instance to satisfy an injection.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @since 2.0
  */
 public interface BindingTargetVisitor<T, V> {
@@ -45,8 +45,8 @@
   V visit(ProviderKeyBinding<? extends T> binding);
 
   /**
-   * Visit a linked key binding. The other key's binding is used to resolve injections. This
-   * target is found in both module and injector bindings.
+   * Visit a linked key binding. The other key's binding is used to resolve injections. This target
+   * is found in both module and injector bindings.
    */
   V visit(LinkedKeyBinding<? extends T> binding);
 
@@ -57,8 +57,8 @@
   V visit(ExposedBinding<? extends T> binding);
 
   /**
-   * Visit an untargetted binding. This target is found only on module bindings. It indicates
-   * that the injector should use its implicit binding strategies to resolve injections.
+   * Visit an untargetted binding. This target is found only on module bindings. It indicates that
+   * the injector should use its implicit binding strategies to resolve injections.
    */
   V visit(UntargettedBinding<? extends T> binding);
 
@@ -69,8 +69,8 @@
   V visit(ConstructorBinding<? extends T> binding);
 
   /**
-   * Visit a binding created from converting a bound instance to a new type. The source binding
-   * has the same binding annotation but a different type. This target is found only on injector
+   * Visit a binding created from converting a bound instance to a new type. The source binding has
+   * the same binding annotation but a different type. This target is found only on injector
    * bindings.
    */
   V visit(ConvertedConstantBinding<? extends T> binding);
diff --git a/core/src/com/google/inject/spi/ConstructorBinding.java b/core/src/com/google/inject/spi/ConstructorBinding.java
index 6799941..4e6e5f5 100644
--- a/core/src/com/google/inject/spi/ConstructorBinding.java
+++ b/core/src/com/google/inject/spi/ConstructorBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.spi;
 
 import com.google.inject.Binding;
-
 import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
@@ -32,17 +31,15 @@
  */
 public interface ConstructorBinding<T> extends Binding<T>, HasDependencies {
 
-  /**
-   * Gets the constructor this binding injects.
-   */
+  /** Gets the constructor this binding injects. */
   InjectionPoint getConstructor();
 
   /**
    * Returns all instance method and field injection points on {@code type}.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    */
   Set<InjectionPoint> getInjectableMembers();
 
@@ -54,4 +51,4 @@
    */
   Map<Method, List<org.aopalliance.intercept.MethodInterceptor>> getMethodInterceptors();
   /*end[AOP]*/
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/ConvertedConstantBinding.java b/core/src/com/google/inject/spi/ConvertedConstantBinding.java
index 5582fb6..ebafdf6 100644
--- a/core/src/com/google/inject/spi/ConvertedConstantBinding.java
+++ b/core/src/com/google/inject/spi/ConvertedConstantBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Binding;
 import com.google.inject.Key;
-
 import java.util.Set;
 
 /**
@@ -30,14 +29,12 @@
  */
 public interface ConvertedConstantBinding<T> extends Binding<T>, HasDependencies {
 
-  /**
-   * Returns the converted value.
-   */
+  /** Returns the converted value. */
   T getValue();
 
   /**
    * Returns the type converter binding used to convert the constant.
-   * 
+   *
    * @since 3.0
    */
   TypeConverterBinding getTypeConverterBinding();
@@ -48,8 +45,7 @@
    */
   Key<String> getSourceKey();
 
-  /**
-   * Returns a singleton set containing only the converted key.
-   */
+  /** Returns a singleton set containing only the converted key. */
+  @Override
   Set<Dependency<?>> getDependencies();
 }
diff --git a/core/src/com/google/inject/spi/DefaultBindingScopingVisitor.java b/core/src/com/google/inject/spi/DefaultBindingScopingVisitor.java
index b517272..edaa660 100644
--- a/core/src/com/google/inject/spi/DefaultBindingScopingVisitor.java
+++ b/core/src/com/google/inject/spi/DefaultBindingScopingVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,40 +17,40 @@
 package com.google.inject.spi;
 
 import com.google.inject.Scope;
-
 import java.lang.annotation.Annotation;
 
 /**
- * No-op visitor for subclassing. All interface methods simply delegate to
- * {@link #visitOther()}, returning its result.
+ * No-op visitor for subclassing. All interface methods simply delegate to {@link #visitOther()},
+ * returning its result.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
- * 
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
  */
 public class DefaultBindingScopingVisitor<V> implements BindingScopingVisitor<V> {
 
-  /**
-   * Default visit implementation. Returns {@code null}.
-   */
+  /** Default visit implementation. Returns {@code null}. */
   protected V visitOther() {
     return null;
   }
 
+  @Override
   public V visitEagerSingleton() {
     return visitOther();
   }
 
+  @Override
   public V visitScope(Scope scope) {
     return visitOther();
   }
 
+  @Override
   public V visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
     return visitOther();
   }
 
+  @Override
   public V visitNoScoping() {
     return visitOther();
   }
diff --git a/core/src/com/google/inject/spi/DefaultBindingTargetVisitor.java b/core/src/com/google/inject/spi/DefaultBindingTargetVisitor.java
index 3deb9dd..5bd1066 100644
--- a/core/src/com/google/inject/spi/DefaultBindingTargetVisitor.java
+++ b/core/src/com/google/inject/spi/DefaultBindingTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,53 +22,59 @@
  * No-op visitor for subclassing. All interface methods simply delegate to {@link
  * #visitOther(Binding)}, returning its result.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
- *
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
  */
 public abstract class DefaultBindingTargetVisitor<T, V> implements BindingTargetVisitor<T, V> {
 
-  /**
-   * Default visit implementation. Returns {@code null}.
-   */
+  /** Default visit implementation. Returns {@code null}. */
   protected V visitOther(Binding<? extends T> binding) {
     return null;
   }
 
+  @Override
   public V visit(InstanceBinding<? extends T> instanceBinding) {
     return visitOther(instanceBinding);
   }
 
+  @Override
   public V visit(ProviderInstanceBinding<? extends T> providerInstanceBinding) {
     return visitOther(providerInstanceBinding);
   }
 
+  @Override
   public V visit(ProviderKeyBinding<? extends T> providerKeyBinding) {
     return visitOther(providerKeyBinding);
   }
 
+  @Override
   public V visit(LinkedKeyBinding<? extends T> linkedKeyBinding) {
     return visitOther(linkedKeyBinding);
   }
 
+  @Override
   public V visit(ExposedBinding<? extends T> exposedBinding) {
     return visitOther(exposedBinding);
   }
 
+  @Override
   public V visit(UntargettedBinding<? extends T> untargettedBinding) {
     return visitOther(untargettedBinding);
   }
 
+  @Override
   public V visit(ConstructorBinding<? extends T> constructorBinding) {
     return visitOther(constructorBinding);
   }
 
+  @Override
   public V visit(ConvertedConstantBinding<? extends T> convertedConstantBinding) {
     return visitOther(convertedConstantBinding);
   }
 
+  @Override
   @SuppressWarnings("unchecked")
   public V visit(ProviderBinding<? extends T> providerBinding) {
     // TODO(cushon): remove raw (Binding) cast when we don't care about javac 6 anymore
diff --git a/core/src/com/google/inject/spi/DefaultElementVisitor.java b/core/src/com/google/inject/spi/DefaultElementVisitor.java
index 1bbea0d..1f1aace 100644
--- a/core/src/com/google/inject/spi/DefaultElementVisitor.java
+++ b/core/src/com/google/inject/spi/DefaultElementVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,90 +19,104 @@
 import com.google.inject.Binding;
 
 /**
- * No-op visitor for subclassing. All interface methods simply delegate to
- * {@link #visitOther(Element)}, returning its result.
+ * No-op visitor for subclassing. All interface methods simply delegate to {@link
+ * #visitOther(Element)}, returning its result.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
- *
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @author sberlin@gmail.com (Sam Berlin)
  * @since 2.0
  */
 public abstract class DefaultElementVisitor<V> implements ElementVisitor<V> {
 
-  /**
-   * Default visit implementation. Returns {@code null}.
-   */
+  /** Default visit implementation. Returns {@code null}. */
   protected V visitOther(Element element) {
     return null;
   }
 
+  @Override
   public V visit(Message message) {
     return visitOther(message);
   }
 
+  @Override
   public <T> V visit(Binding<T> binding) {
     return visitOther(binding);
   }
 
   /*if[AOP]*/
+  @Override
   public V visit(InterceptorBinding interceptorBinding) {
     return visitOther(interceptorBinding);
   }
   /*end[AOP]*/
 
+  @Override
   public V visit(ScopeBinding scopeBinding) {
     return visitOther(scopeBinding);
   }
 
+  @Override
   public V visit(TypeConverterBinding typeConverterBinding) {
     return visitOther(typeConverterBinding);
   }
 
+  @Override
   public <T> V visit(ProviderLookup<T> providerLookup) {
     return visitOther(providerLookup);
   }
 
+  @Override
   public V visit(InjectionRequest<?> injectionRequest) {
     return visitOther(injectionRequest);
   }
 
+  @Override
   public V visit(StaticInjectionRequest staticInjectionRequest) {
     return visitOther(staticInjectionRequest);
   }
 
+  @Override
   public V visit(PrivateElements privateElements) {
     return visitOther(privateElements);
   }
 
+  @Override
   public <T> V visit(MembersInjectorLookup<T> lookup) {
     return visitOther(lookup);
   }
 
+  @Override
   public V visit(TypeListenerBinding binding) {
     return visitOther(binding);
   }
-  
+
+  @Override
   public V visit(ProvisionListenerBinding binding) {
     return visitOther(binding);
   }
-  
+
+  @Override
   public V visit(DisableCircularProxiesOption option) {
     return visitOther(option);
   }
-  
+
+  @Override
   public V visit(RequireExplicitBindingsOption option) {
     return visitOther(option);
   }
-  
+
+  @Override
   public V visit(RequireAtInjectOnConstructorsOption option) {
     return visitOther(option);
   }
 
+  @Override
   public V visit(RequireExactBindingAnnotationsOption option) {
     return visitOther(option);
   }
 
+  @Override
   public V visit(ModuleAnnotatedMethodScannerBinding binding) {
     return visitOther(binding);
   }
diff --git a/core/src/com/google/inject/spi/Dependency.java b/core/src/com/google/inject/spi/Dependency.java
index f86e255..5a084c6 100644
--- a/core/src/com/google/inject/spi/Dependency.java
+++ b/core/src/com/google/inject/spi/Dependency.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.common.collect.Lists;
 import com.google.inject.Key;
 import com.google.inject.internal.MoreTypes;
-
 import java.util.List;
 import java.util.Set;
 
@@ -58,9 +57,7 @@
     return new Dependency<T>(null, MoreTypes.canonicalizeKey(key), true, -1);
   }
 
-  /**
-   * Returns the dependencies from the given injection points.
-   */
+  /** Returns the dependencies from the given injection points. */
   public static Set<Dependency<?>> forInjectionPoints(Set<InjectionPoint> injectionPoints) {
     List<Dependency<?>> dependencies = Lists.newArrayList();
     for (InjectionPoint injectionPoint : injectionPoints) {
@@ -69,16 +66,12 @@
     return ImmutableSet.copyOf(dependencies);
   }
 
-  /**
-   * Returns the key to the binding that satisfies this dependency.
-   */
+  /** Returns the key to the binding that satisfies this dependency. */
   public Key<T> getKey() {
     return this.key;
   }
 
-  /**
-   * Returns true if null is a legal value for this dependency.
-   */
+  /** Returns true if null is a legal value for this dependency. */
   public boolean isNullable() {
     return nullable;
   }
@@ -100,11 +93,13 @@
     return parameterIndex;
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return Objects.hashCode(injectionPoint, parameterIndex, key);
   }
 
-  @Override public boolean equals(Object o) {
+  @Override
+  public boolean equals(Object o) {
     if (o instanceof Dependency) {
       Dependency dependency = (Dependency) o;
       return Objects.equal(injectionPoint, dependency.injectionPoint)
@@ -115,7 +110,8 @@
     }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     StringBuilder builder = new StringBuilder();
     builder.append(key);
     if (injectionPoint != null) {
diff --git a/core/src/com/google/inject/spi/DependencyAndSource.java b/core/src/com/google/inject/spi/DependencyAndSource.java
index ce52aae..321e949 100644
--- a/core/src/com/google/inject/spi/DependencyAndSource.java
+++ b/core/src/com/google/inject/spi/DependencyAndSource.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2011 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -20,16 +20,19 @@
 import com.google.inject.Binding;
 import com.google.inject.Injector;
 import com.google.inject.internal.util.StackTraceElements;
-
 import java.lang.reflect.Member;
 
 /**
- * A combination of a {@link Dependency} and the {@link Binding#getSource()
- * source} where the dependency was bound.
- * 
+ * A combination of a {@link Dependency} and the {@link Binding#getSource() source} where the
+ * dependency was bound.
+ *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
+ * @deprecated The only use of this object is for {@link
+ *     ProvisionListener.ProvisionInvocation#getDependencyChain()} which is also deprecated. This
+ *     object will also be removed in Guice 4.4.
  */
+@Deprecated
 public final class DependencyAndSource {
   private final Dependency<?> dependency;
   private final Object source;
@@ -40,21 +43,19 @@
   }
 
   /**
-   * Returns the Dependency, if one exists. For anything that can be referenced
-   * by {@link Injector#getBinding}, a dependency exists. A dependency will not
-   * exist (and this will return null) for types initialized with
-   * {@link Binder#requestInjection} or {@link Injector#injectMembers(Object)},
-   * nor will it exist for objects injected into Providers bound with
-   * LinkedBindingBuilder#toProvider(Provider).
+   * Returns the Dependency, if one exists. For anything that can be referenced by {@link
+   * Injector#getBinding}, a dependency exists. A dependency will not exist (and this will return
+   * null) for types initialized with {@link Binder#requestInjection} or {@link
+   * Injector#injectMembers(Object)}, nor will it exist for objects injected into Providers bound
+   * with LinkedBindingBuilder#toProvider(Provider).
    */
   public Dependency<?> getDependency() {
     return dependency;
   }
 
   /**
-   * Returns a string describing where this dependency was bound. If the binding
-   * was just-in-time, there is no valid binding source, so this describes the
-   * class in question.
+   * Returns a string describing where this dependency was bound. If the binding was just-in-time,
+   * there is no valid binding source, so this describes the class in question.
    */
   public String getBindingSource() {
     if (source instanceof Class) {
@@ -76,4 +77,4 @@
       return "Source: " + source;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/DisableCircularProxiesOption.java b/core/src/com/google/inject/spi/DisableCircularProxiesOption.java
index 4193e0a..ad6812c 100644
--- a/core/src/com/google/inject/spi/DisableCircularProxiesOption.java
+++ b/core/src/com/google/inject/spi/DisableCircularProxiesOption.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,14 +33,17 @@
     this.source = checkNotNull(source, "source");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).disableCircularProxies();
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/core/src/com/google/inject/spi/Element.java b/core/src/com/google/inject/spi/Element.java
index 814ccef..9b42b7e 100644
--- a/core/src/com/google/inject/spi/Element.java
+++ b/core/src/com/google/inject/spi/Element.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -60,5 +60,4 @@
    *     element.
    */
   void applyTo(Binder binder);
-
 }
diff --git a/core/src/com/google/inject/spi/ElementSource.java b/core/src/com/google/inject/spi/ElementSource.java
index 52783c9..5a0d6cc 100644
--- a/core/src/com/google/inject/spi/ElementSource.java
+++ b/core/src/com/google/inject/spi/ElementSource.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2013 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,79 +20,76 @@
 import com.google.common.collect.ImmutableList;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.internal.util.StackTraceElements.InMemoryStackTraceElement;
-
 import java.util.List;
 
 /**
- * Contains information about where and how an {@link Element element} was
- * bound.
- * <p>
- * The {@link #getDeclaringSource() declaring source} refers to a location in
- * source code that defines the Guice {@link Element element}. For example, if
- * the element is created from a method annotated by {@literal @Provides}, the
- * declaring source of element would be the method itself.
- * <p>
- * The {@link #getStackTrace()} refers to the sequence of calls ends at one of
- * {@link com.google.inject.Binder} {@code bindXXX()} methods and eventually
- * defines the element. Note that {@link #getStackTrace()} lists
- * {@link StackTraceElement StackTraceElements} in reverse chronological order.
- * The first element (index zero) is the last method call and the last element
- * is the first method invocation. By default, the stack trace is not collected.
- * The default behavior can be changed by setting the
- * {@code guice_include_stack_traces} flag value. The value can be either
- * {@code OFF}, {@code ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that
- * collecting stack traces for every binding can cause a performance hit when
- * the injector is created.
- * <p>
- * The sequence of class names of {@link com.google.inject.Module modules}
- * involved in the element creation can be retrieved by
- * {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the
- * order is reverse chronological. The first module (index 0) is the module that
- * installs the {@link Element element}. The last module is the root module.
- * <p>
- * In order to support the cases where a Guice {@link Element element} is
- * created from another Guice {@link Element element} (original) (e.g., by
- * {@link Element#applyTo}), it also provides a reference to the original
- * element source ({@link #getOriginalElementSource()}).
+ * Contains information about where and how an {@link Element element} was bound.
+ *
+ * <p>The {@link #getDeclaringSource() declaring source} refers to a location in source code that
+ * defines the Guice {@link Element element}. For example, if the element is created from a method
+ * annotated by {@literal @Provides}, the declaring source of element would be the method itself.
+ *
+ * <p>The {@link #getStackTrace()} refers to the sequence of calls ends at one of {@link
+ * com.google.inject.Binder} {@code bindXXX()} methods and eventually defines the element. Note that
+ * {@link #getStackTrace()} lists {@link StackTraceElement StackTraceElements} in reverse
+ * chronological order. The first element (index zero) is the last method call and the last element
+ * is the first method invocation. By default, the stack trace is not collected. The default
+ * behavior can be changed by setting the {@code guice_include_stack_traces} flag value. The value
+ * can be either {@code OFF}, {@code ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that
+ * collecting stack traces for every binding can cause a performance hit when the injector is
+ * created.
+ *
+ * <p>The sequence of class names of {@link com.google.inject.Module modules} involved in the
+ * element creation can be retrieved by {@link #getModuleClassNames()}. Similar to {@link
+ * #getStackTrace()}, the order is reverse chronological. The first module (index 0) is the module
+ * that installs the {@link Element element}. The last module is the root module.
+ *
+ * <p>In order to support the cases where a Guice {@link Element element} is created from another
+ * Guice {@link Element element} (original) (e.g., by {@link Element#applyTo}), it also provides a
+ * reference to the original element source ({@link #getOriginalElementSource()}).
  *
  * @since 4.0
  */
 public final class ElementSource {
 
-  /** 
+  /**
    * The {@link ElementSource source} of element that this element created from (if there is any),
    * otherwise {@code null}.
    */
   final ElementSource originalElementSource;
-  
+
   /** The {@link ModuleSource source} of module creates the element. */
   final ModuleSource moduleSource;
-  
-  /** 
+
+  /**
    * The partial call stack that starts at the last module {@link Module#Configure(Binder)
    * configure(Binder)} call. The value is empty if stack trace collection is off.
    */
   final InMemoryStackTraceElement[] partialCallStack;
-  
-  /** 
-   * Refers to a single location in source code that causes the element creation. It can be any 
-   * object such as {@link Constructor}, {@link Method}, {@link Field}, {@link StackTraceElement}, 
-   * etc. For example, if the element is created from a method annotated by {@literal @Provides}, 
+
+  /**
+   * Refers to a single location in source code that causes the element creation. It can be any
+   * object such as {@link Constructor}, {@link Method}, {@link Field}, {@link StackTraceElement},
+   * etc. For example, if the element is created from a method annotated by {@literal @Provides},
    * the declaring source of element would be the method itself.
    */
   final Object declaringSource;
 
   /**
-   * Creates a new {@ElementSource} from the given parameters. 
+   * Creates a new {@ElementSource} from the given parameters.
+   *
    * @param originalElementSource The source of element that this element created from (if there is
-   * any), otherwise {@code null}.
+   *     any), otherwise {@code null}.
    * @param declaringSource the source (in)directly declared the element.
    * @param moduleSource the moduleSource when the element is bound
-   * @param partialCallStack the partial call stack from the top module to where the element is 
-   * bound
+   * @param partialCallStack the partial call stack from the top module to where the element is
+   *     bound
    */
-  ElementSource(/* @Nullable */ ElementSource originalSource, Object declaringSource, 
-      ModuleSource moduleSource, StackTraceElement[] partialCallStack) {
+  ElementSource(
+      /* @Nullable */ ElementSource originalSource,
+      Object declaringSource,
+      ModuleSource moduleSource,
+      StackTraceElement[] partialCallStack) {
     Preconditions.checkNotNull(declaringSource, "declaringSource cannot be null.");
     Preconditions.checkNotNull(moduleSource, "moduleSource cannot be null.");
     Preconditions.checkNotNull(partialCallStack, "partialCallStack cannot be null.");
@@ -101,7 +98,7 @@
     this.moduleSource = moduleSource;
     this.partialCallStack = StackTraceElements.convertToInMemoryStackTraceElement(partialCallStack);
   }
-  
+
   /**
    * Returns the {@link ElementSource} of the element this was created or copied from. If this was
    * not created or copied from another element, returns {@code null}.
@@ -109,22 +106,22 @@
   public ElementSource getOriginalElementSource() {
     return originalElementSource;
   }
-  
+
   /**
-   * Returns a single location in source code that defines the element. It can be any object
-   * such as {@link java.lang.reflect.Constructor}, {@link java.lang.reflect.Method},
-   * {@link java.lang.reflect.Field}, {@link StackTraceElement}, etc. For
-   * example, if the element is created from a method annotated by {@literal @Provides}, the
-   * declaring source of element would be the method itself.
+   * Returns a single location in source code that defines the element. It can be any object such as
+   * {@link java.lang.reflect.Constructor}, {@link java.lang.reflect.Method}, {@link
+   * java.lang.reflect.Field}, {@link StackTraceElement}, etc. For example, if the element is
+   * created from a method annotated by {@literal @Provides}, the declaring source of element would
+   * be the method itself.
    */
   public Object getDeclaringSource() {
     return declaringSource;
   }
-  
+
   /**
-   * Returns the class names of modules involved in creating this {@link Element}. The first
-   * element (index 0) is the class name of module that defined the element, and the last element
-   * is the class name of root module.
+   * Returns the class names of modules involved in creating this {@link Element}. The first element
+   * (index 0) is the class name of module that defined the element, and the last element is the
+   * class name of root module.
    */
   public List<String> getModuleClassNames() {
     return moduleSource.getModuleClassNames();
@@ -134,18 +131,18 @@
    * Returns the position of {@link com.google.inject.Module#configure configure(Binder)} method
    * call in the {@link #getStackTrace stack trace} for modules that their classes returned by
    * {@link #getModuleClassNames}. For example, if the stack trace looks like the following:
-   * <p>
-   * {@code
-   *  0 - Binder.bind(),
-   *  1 - ModuleTwo.configure(),
-   *  2 - Binder.install(),
-   *  3 - ModuleOne.configure(),
-   *  4 - theRest(). 
-   * }
-   * <p>
-   * 1 and 3 are returned.
-   * <p>
-   * In the cases where stack trace is not available (i.e., the stack trace was not collected),
+   *
+   * <ol>
+   *   <li>{@code Binder.bind()}
+   *   <li>{@code ModuleTwo.configure()}
+   *   <li>{@code Binder.install()}
+   *   <li>{@code ModuleOne.configure()}
+   *   <li>{@code theRest().
+   * </ol>
+   *
+   * <p>1 and 3 are returned.
+   *
+   * <p>In the cases where stack trace is not available (i.e., the stack trace was not collected),
    * it returns -1 for all module positions.
    */
   public List<Integer> getModuleConfigurePositionsInStackTrace() {
@@ -164,11 +161,11 @@
 
   /**
    * Returns the sequence of method calls that ends at one of {@link com.google.inject.Binder}
-   * {@code bindXXX()} methods and eventually defines the element. Note that
-   * {@link #getStackTrace} lists {@link StackTraceElement StackTraceElements} in reverse
-   * chronological order. The first element (index zero) is the last method call and the last
-   * element is the first method invocation. In the cases where stack trace is not available
-   * (i.e.,the stack trace was not collected), it returns an empty array.
+   * {@code bindXXX()} methods and eventually defines the element. Note that {@link #getStackTrace}
+   * lists {@link StackTraceElement StackTraceElements} in reverse chronological order. The first
+   * element (index zero) is the last method call and the last element is the first method
+   * invocation. In the cases where stack trace is not available (i.e.,the stack trace was not
+   * collected), it returns an empty array.
    */
   public StackTraceElement[] getStackTrace() {
     int modulesCallStackSize = moduleSource.getStackTraceSize();
@@ -176,15 +173,16 @@
     int size = moduleSource.getStackTraceSize() + chunkSize;
     StackTraceElement[] callStack = new StackTraceElement[size];
     System.arraycopy(
-        StackTraceElements.convertToStackTraceElement(partialCallStack), 0, callStack, 0, 
+        StackTraceElements.convertToStackTraceElement(partialCallStack),
+        0,
+        callStack,
+        0,
         chunkSize);
     System.arraycopy(moduleSource.getStackTrace(), 0, callStack, chunkSize, modulesCallStackSize);
     return callStack;
   }
 
-  /**
-   * Returns {@code getDeclaringSource().toString()} value.
-   */
+  /** Returns {@code getDeclaringSource().toString()} value. */
   @Override
   public String toString() {
     return getDeclaringSource().toString();
diff --git a/core/src/com/google/inject/spi/ElementVisitor.java b/core/src/com/google/inject/spi/ElementVisitor.java
index bc0d910..b99f884 100644
--- a/core/src/com/google/inject/spi/ElementVisitor.java
+++ b/core/src/com/google/inject/spi/ElementVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,59 +23,42 @@
 /**
  * Visit elements.
  *
- * @param <V> any type to be returned by the visit method. Use {@link Void} with
- *     {@code return null} if no return type is needed.
- * 
+ * @param <V> any type to be returned by the visit method. Use {@link Void} with {@code return null}
+ *     if no return type is needed.
  * @since 2.0
  */
 public interface ElementVisitor<V> {
 
   /**
-   * Visit a mapping from a key (type and optional annotation) to the strategy for getting
-   * instances of the type.
+   * Visit a mapping from a key (type and optional annotation) to the strategy for getting instances
+   * of the type.
    */
   <T> V visit(Binding<T> binding);
 
   /*if[AOP]*/
-  /**
-   * Visit a registration of interceptors for matching methods of matching classes.
-   */
+  /** Visit a registration of interceptors for matching methods of matching classes. */
   V visit(InterceptorBinding binding);
   /*end[AOP]*/
 
-  /**
-   * Visit a registration of a scope annotation with the scope that implements it.
-   */
+  /** Visit a registration of a scope annotation with the scope that implements it. */
   V visit(ScopeBinding binding);
 
-  /**
-   * Visit a registration of type converters for matching target types.
-   */
+  /** Visit a registration of type converters for matching target types. */
   V visit(TypeConverterBinding binding);
 
-  /**
-   * Visit a request to inject the instance fields and methods of an instance.
-   */
+  /** Visit a request to inject the instance fields and methods of an instance. */
   V visit(InjectionRequest<?> request);
 
-  /**
-   * Visit a request to inject the static fields and methods of type.
-   */
+  /** Visit a request to inject the static fields and methods of type. */
   V visit(StaticInjectionRequest request);
 
-  /**
-   * Visit a lookup of the provider for a type.
-   */
+  /** Visit a lookup of the provider for a type. */
   <T> V visit(ProviderLookup<T> lookup);
 
-  /**
-   * Visit a lookup of the members injector.
-   */
+  /** Visit a lookup of the members injector. */
   <T> V visit(MembersInjectorLookup<T> lookup);
 
-  /**
-   * Visit an error message and the context in which it occured.
-   */
+  /** Visit an error message and the context in which it occured. */
   V visit(Message message);
 
   /**
@@ -84,35 +67,33 @@
    */
   V visit(PrivateElements elements);
 
-  /**
-   * Visit an injectable type listener binding.
-   */
+  /** Visit an injectable type listener binding. */
   V visit(TypeListenerBinding binding);
-  
+
   /**
    * Visit a provision listener binding.
    *
    * @since 4.0
    */
   V visit(ProvisionListenerBinding binding);
-  
+
   /**
    * Visit a require explicit bindings command.
-   * 
+   *
    * @since 3.0
    */
   V visit(RequireExplicitBindingsOption option);
-  
+
   /**
    * Visit a disable circular proxies command.
-   * 
+   *
    * @since 3.0
    */
   V visit(DisableCircularProxiesOption option);
-  
+
   /**
    * Visit a require explicit {@literal @}{@link Inject} command.
-   * 
+   *
    * @since 4.0
    */
   V visit(RequireAtInjectOnConstructorsOption option);
diff --git a/core/src/com/google/inject/spi/Elements.java b/core/src/com/google/inject/spi/Elements.java
index 9348276..724fa1c 100644
--- a/core/src/com/google/inject/spi/Elements.java
+++ b/core/src/com/google/inject/spi/Elements.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -50,7 +50,6 @@
 import com.google.inject.internal.util.SourceProvider;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.matcher.Matcher;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.Arrays;
@@ -69,41 +68,35 @@
  */
 public final class Elements {
 
-  private static final BindingTargetVisitor<Object, Object> GET_INSTANCE_VISITOR
-      = new DefaultBindingTargetVisitor<Object, Object>() {
-    @Override public Object visit(InstanceBinding<?> binding) {
-      return binding.getInstance();
-    }
+  private static final BindingTargetVisitor<Object, Object> GET_INSTANCE_VISITOR =
+      new DefaultBindingTargetVisitor<Object, Object>() {
+        @Override
+        public Object visit(InstanceBinding<?> binding) {
+          return binding.getInstance();
+        }
 
-    @Override protected Object visitOther(Binding<?> binding) {
-      throw new IllegalArgumentException();
-    }
-  };
+        @Override
+        protected Object visitOther(Binding<?> binding) {
+          throw new IllegalArgumentException();
+        }
+      };
 
-  /**
-   * Records the elements executed by {@code modules}.
-   */
+  /** Records the elements executed by {@code modules}. */
   public static List<Element> getElements(Module... modules) {
     return getElements(Stage.DEVELOPMENT, Arrays.asList(modules));
   }
 
-  /**
-   * Records the elements executed by {@code modules}.
-   */
+  /** Records the elements executed by {@code modules}. */
   public static List<Element> getElements(Stage stage, Module... modules) {
     return getElements(stage, Arrays.asList(modules));
   }
 
-  /**
-   * Records the elements executed by {@code modules}.
-   */
+  /** Records the elements executed by {@code modules}. */
   public static List<Element> getElements(Iterable<? extends Module> modules) {
     return getElements(Stage.DEVELOPMENT, modules);
   }
 
-  /**
-   * Records the elements executed by {@code modules}.
-   */
+  /** Records the elements executed by {@code modules}. */
   public static List<Element> getElements(Stage stage, Iterable<? extends Module> modules) {
     RecordingBinder binder = new RecordingBinder(stage);
     for (Module module : modules) {
@@ -133,9 +126,7 @@
     }
   }
 
-  /**
-   * Returns the module composed of {@code elements}.
-   */
+  /** Returns the module composed of {@code elements}. */
   public static Module getModule(final Iterable<? extends Element> elements) {
     return new ElementsAsModule(elements);
   }
@@ -164,11 +155,13 @@
     private final Object source;
     /** The current modules stack */
     private ModuleSource moduleSource = null;
+
     private final SourceProvider sourceProvider;
     private final Set<ModuleAnnotatedMethodScanner> scanners;
 
     /** The binder where exposed bindings will be created */
     private final RecordingBinder parent;
+
     private final PrivateElementsImpl privateElements;
 
     /** All children private binders, so we can scan through them. */
@@ -180,9 +173,14 @@
       this.scanners = Sets.newLinkedHashSet();
       this.elements = Lists.newArrayList();
       this.source = null;
-      this.sourceProvider = SourceProvider.DEFAULT_INSTANCE.plusSkippedClasses(
-          Elements.class, RecordingBinder.class, AbstractModule.class,
-          ConstantBindingBuilderImpl.class, AbstractBindingBuilder.class, BindingBuilder.class);
+      this.sourceProvider =
+          SourceProvider.DEFAULT_INSTANCE.plusSkippedClasses(
+              Elements.class,
+              RecordingBinder.class,
+              AbstractModule.class,
+              ConstantBindingBuilderImpl.class,
+              AbstractBindingBuilder.class,
+              BindingBuilder.class);
       this.parent = null;
       this.privateElements = null;
       this.privateBinders = Lists.newArrayList();
@@ -225,8 +223,8 @@
         Matcher<? super Class<?>> classMatcher,
         Matcher<? super Method> methodMatcher,
         org.aopalliance.intercept.MethodInterceptor... interceptors) {
-      elements.add(new InterceptorBinding(
-          getElementSource(), classMatcher, methodMatcher, interceptors));
+      elements.add(
+          new InterceptorBinding(getElementSource(), classMatcher, methodMatcher, interceptors));
     }
     /*end[AOP]*/
 
@@ -243,31 +241,37 @@
 
     @Override
     public <T> void requestInjection(TypeLiteral<T> type, T instance) {
-      elements.add(new InjectionRequest<T>(getElementSource(), MoreTypes.canonicalizeForKey(type),
-          instance));
+      elements.add(
+          new InjectionRequest<T>(
+              getElementSource(), MoreTypes.canonicalizeForKey(type), instance));
     }
 
     @Override
     public <T> MembersInjector<T> getMembersInjector(final TypeLiteral<T> typeLiteral) {
-      final MembersInjectorLookup<T> element = new MembersInjectorLookup<T>(getElementSource(),
-          MoreTypes.canonicalizeForKey(typeLiteral));
+      final MembersInjectorLookup<T> element =
+          new MembersInjectorLookup<T>(
+              getElementSource(), MoreTypes.canonicalizeForKey(typeLiteral));
       elements.add(element);
       return element.getMembersInjector();
     }
 
+    @Override
     public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
       return getMembersInjector(TypeLiteral.get(type));
     }
 
+    @Override
     public void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
       elements.add(new TypeListenerBinding(getElementSource(), listener, typeMatcher));
     }
-    
-    public void bindListener(Matcher<? super Binding<?>> bindingMatcher,
-        ProvisionListener... listeners) {
+
+    @Override
+    public void bindListener(
+        Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listeners) {
       elements.add(new ProvisionListenerBinding(getElementSource(), bindingMatcher, listeners));
     }
 
+    @Override
     public void requestStaticInjection(Class<?>... types) {
       for (Class<?> type : types) {
         elements.add(new StaticInjectionRequest(getElementSource(), type));
@@ -275,10 +279,9 @@
     }
 
     /**
-     * Applies all scanners to the modules we've installed. We skip certain
-     * PrivateModules because store them in more than one Modules map and only
-     * want to process them through one of the maps.  (They're stored in both
-     * maps to prevent a module from being installed more than once.)
+     * Applies all scanners to the modules we've installed. We skip certain PrivateModules because
+     * store them in more than one Modules map and only want to process them through one of the
+     * maps. (They're stored in both maps to prevent a module from being installed more than once.)
      */
     void scanForAnnotatedMethods() {
       for (ModuleAnnotatedMethodScanner scanner : scanners) {
@@ -293,7 +296,7 @@
           moduleSource = entry.getValue().moduleSource;
           try {
             info.binder.install(ProviderMethodsModule.forModule(module, scanner));
-          } catch(RuntimeException e) {
+          } catch (RuntimeException e) {
             Collection<Message> messages = Errors.getMessagesFromThrowable(e);
             if (!messages.isEmpty()) {
               elements.addAll(messages);
@@ -306,6 +309,7 @@
       moduleSource = null;
     }
 
+    @Override
     public void install(Module module) {
       if (!modules.containsKey(module)) {
         RecordingBinder binder = this;
@@ -354,64 +358,78 @@
       }
     }
 
+    @Override
     public Stage currentStage() {
       return stage;
     }
 
+    @Override
     public void addError(String message, Object... arguments) {
       elements.add(new Message(getElementSource(), Errors.format(message, arguments)));
     }
 
+    @Override
     public void addError(Throwable t) {
       String message = "An exception was caught and reported. Message: " + t.getMessage();
       elements.add(new Message(ImmutableList.of((Object) getElementSource()), message, t));
     }
 
+    @Override
     public void addError(Message message) {
       elements.add(message);
     }
 
+    @Override
     public <T> AnnotatedBindingBuilder<T> bind(Key<T> key) {
       BindingBuilder<T> builder =
           new BindingBuilder<T>(this, elements, getElementSource(), MoreTypes.canonicalizeKey(key));
       return builder;
     }
 
+    @Override
     public <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
       return bind(Key.get(typeLiteral));
     }
 
+    @Override
     public <T> AnnotatedBindingBuilder<T> bind(Class<T> type) {
       return bind(Key.get(type));
     }
 
+    @Override
     public AnnotatedConstantBindingBuilder bindConstant() {
       return new ConstantBindingBuilderImpl<Void>(this, elements, getElementSource());
     }
 
+    @Override
     public <T> Provider<T> getProvider(final Key<T> key) {
       return getProvider(Dependency.get(key));
     }
 
+    @Override
     public <T> Provider<T> getProvider(final Dependency<T> dependency) {
-      final ProviderLookup<T> element = new ProviderLookup<T>(getElementSource(), dependency);
+      final ProviderLookup<T> element = new ProviderLookup<>(getElementSource(), dependency);
       elements.add(element);
       return element.getProvider();
     }
 
+    @Override
     public <T> Provider<T> getProvider(Class<T> type) {
       return getProvider(Key.get(type));
     }
 
-    public void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
-        TypeConverter converter) {
+    @Override
+    public void convertToTypes(
+        Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
       elements.add(new TypeConverterBinding(getElementSource(), typeMatcher, converter));
     }
 
-    public RecordingBinder withSource(final Object source) {            
+    @Override
+    public RecordingBinder withSource(final Object source) {
       return source == this.source ? this : new RecordingBinder(this, source, null);
     }
 
+    @Override
     public RecordingBinder skipSources(Class... classesToSkip) {
       // if a source is specified explicitly, we don't need to skip sources
       if (source != null) {
@@ -457,6 +475,7 @@
       elements.add(new ModuleAnnotatedMethodScannerBinding(getElementSource(), scanner));
     }
 
+    @Override
     public void expose(Key<?> key) {
       exposeInternal(key);
     }
@@ -473,11 +492,14 @@
 
     private <T> AnnotatedElementBuilder exposeInternal(Key<T> key) {
       if (privateElements == null) {
-        addError("Cannot expose %s on a standard binder. "
-            + "Exposed bindings are only applicable to private binders.", key);
+        addError(
+            "Cannot expose %s on a standard binder. "
+                + "Exposed bindings are only applicable to private binders.",
+            key);
         return new AnnotatedElementBuilder() {
           @Override
           public void annotatedWith(Class<? extends Annotation> annotationType) {}
+
           @Override
           public void annotatedWith(Annotation annotation) {}
         };
@@ -516,9 +538,9 @@
         declaringSource = originalSource.getDeclaringSource();
       }
       IncludeStackTraceOption stackTraceOption = getIncludeStackTraceOption();
-      if (stackTraceOption == IncludeStackTraceOption.COMPLETE ||
-          (stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE
-          && declaringSource == null)) {
+      if (stackTraceOption == IncludeStackTraceOption.COMPLETE
+          || (stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE
+              && declaringSource == null)) {
         callStack = new Throwable().getStackTrace();
       }
       if (stackTraceOption == IncludeStackTraceOption.COMPLETE) {
@@ -526,8 +548,8 @@
       }
       if (declaringSource == null) {
         // So 'source' and 'originalSource' are null otherwise declaringSource has some value
-        if (stackTraceOption == IncludeStackTraceOption.COMPLETE ||
-            stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE) {
+        if (stackTraceOption == IncludeStackTraceOption.COMPLETE
+            || stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE) {
           // With the above conditions and assignments 'callStack' is non-null
           declaringSource = sourceProvider.get(callStack);
         } else { // or if (stackTraceOption == IncludeStackTraceOptions.OFF)
@@ -536,14 +558,13 @@
         }
       }
       // Build the binding call stack
-      return new ElementSource(
-          originalSource, declaringSource, moduleSource, partialCallStack);
+      return new ElementSource(originalSource, declaringSource, moduleSource, partialCallStack);
     }
 
     /**
      * Removes the {@link #moduleSource} call stack from the beginning of current call stack. It
-     * also removes the last two elements in order to make {@link #install(Module)} the last call
-     * in the call stack.
+     * also removes the last two elements in order to make {@link #install(Module)} the last call in
+     * the call stack.
      */
     private StackTraceElement[] getPartialCallStack(StackTraceElement[] callStack) {
       int toSkip = 0;
@@ -558,7 +579,8 @@
       return partialCallStack;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "Binder";
     }
   }
diff --git a/core/src/com/google/inject/spi/ExposedBinding.java b/core/src/com/google/inject/spi/ExposedBinding.java
index 16a569e..501d884 100644
--- a/core/src/com/google/inject/spi/ExposedBinding.java
+++ b/core/src/com/google/inject/spi/ExposedBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,13 +27,10 @@
  */
 public interface ExposedBinding<T> extends Binding<T>, HasDependencies {
 
-  /**
-   * Returns the enclosed environment that holds the original binding.
-   */
+  /** Returns the enclosed environment that holds the original binding. */
   PrivateElements getPrivateElements();
 
-  /**
-   * Unsupported. Always throws {@link UnsupportedOperationException}.
-   */
+  /** Unsupported. Always throws {@link UnsupportedOperationException}. */
+  @Override
   void applyTo(Binder binder);
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/HasDependencies.java b/core/src/com/google/inject/spi/HasDependencies.java
index 77a5523..f28f1a3 100644
--- a/core/src/com/google/inject/spi/HasDependencies.java
+++ b/core/src/com/google/inject/spi/HasDependencies.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,7 +31,7 @@
    * Returns the known dependencies for this type. If this has dependencies whose values are not
    * known statically, a dependency for the {@link com.google.inject.Injector Injector} will be
    * included in the returned set.
-   * 
+   *
    * @return a possibly empty set
    */
   Set<Dependency<?>> getDependencies();
diff --git a/core/src/com/google/inject/spi/InjectionPoint.java b/core/src/com/google/inject/spi/InjectionPoint.java
index 267e0ab..2a302a4 100644
--- a/core/src/com/google/inject/spi/InjectionPoint.java
+++ b/core/src/com/google/inject/spi/InjectionPoint.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,11 @@
 
 import static com.google.inject.internal.MoreTypes.getRawType;
 
+import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
 import com.google.inject.ConfigurationException;
 import com.google.inject.Inject;
 import com.google.inject.Key;
@@ -30,7 +32,6 @@
 import com.google.inject.internal.ErrorsException;
 import com.google.inject.internal.Nullability;
 import com.google.inject.internal.util.Classes;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
@@ -58,7 +59,7 @@
  * @since 2.0
  */
 public final class InjectionPoint {
-  
+
   private static final Logger logger = Logger.getLogger(InjectionPoint.class.getName());
 
   private final boolean optional;
@@ -77,8 +78,8 @@
     this.member = constructor;
     this.declaringType = declaringType;
     this.optional = false;
-    this.dependencies = forMember(
-        constructor, declaringType, constructor.getParameterAnnotations());
+    this.dependencies =
+        forMember(constructor, declaringType, constructor.getParameterAnnotations());
   }
 
   InjectionPoint(TypeLiteral<?> declaringType, Field field, boolean optional) {
@@ -99,21 +100,21 @@
     }
     errors.throwConfigurationExceptionIfErrorsExist();
 
-    this.dependencies = ImmutableList.<Dependency<?>>of(
-        newDependency(key, Nullability.allowsNull(annotations), -1));
+    this.dependencies =
+        ImmutableList.<Dependency<?>>of(
+            newDependency(key, Nullability.allowsNull(annotations), -1));
   }
 
-  private ImmutableList<Dependency<?>> forMember(Member member, TypeLiteral<?> type,
-      Annotation[][] paramterAnnotations) {
+  private ImmutableList<Dependency<?>> forMember(
+      Member member, TypeLiteral<?> type, Annotation[][] paramterAnnotations) {
     Errors errors = new Errors(member);
-    Iterator<Annotation[]> annotationsIterator = Arrays.asList(paramterAnnotations).iterator();
 
     List<Dependency<?>> dependencies = Lists.newArrayList();
     int index = 0;
 
     for (TypeLiteral<?> parameterType : type.getParameterTypes(member)) {
       try {
-        Annotation[] parameterAnnotations = annotationsIterator.next();
+        Annotation[] parameterAnnotations = paramterAnnotations[index];
         Key<?> key = Annotations.getKey(parameterType, member, parameterAnnotations, errors);
         dependencies.add(newDependency(key, Nullability.allowsNull(parameterAnnotations), index));
         index++;
@@ -133,9 +134,7 @@
     return new Dependency<T>(this, key, allowsNull, parameterIndex);
   }
 
-  /**
-   * Returns the injected constructor, field, or method.
-   */
+  /** Returns the injected constructor, field, or method. */
   public Member getMember() {
     // TODO: Don't expose the original member (which probably has setAccessible(true)).
     return member;
@@ -161,38 +160,41 @@
   public boolean isOptional() {
     return optional;
   }
-  
+
   /**
    * Returns true if the element is annotated with {@literal @}{@link Toolable}.
-   * 
+   *
    * @since 3.0
    */
   public boolean isToolable() {
-    return ((AnnotatedElement)member).isAnnotationPresent(Toolable.class);
+    return ((AnnotatedElement) member).isAnnotationPresent(Toolable.class);
   }
 
   /**
    * Returns the generic type that defines this injection point. If the member exists on a
    * parameterized type, the result will include more type information than the member's {@link
    * Member#getDeclaringClass() raw declaring class}.
-   * 
+   *
    * @since 3.0
    */
   public TypeLiteral<?> getDeclaringType() {
     return declaringType;
   }
 
-  @Override public boolean equals(Object o) {
+  @Override
+  public boolean equals(Object o) {
     return o instanceof InjectionPoint
         && member.equals(((InjectionPoint) o).member)
         && declaringType.equals(((InjectionPoint) o).declaringType);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return member.hashCode() ^ declaringType.hashCode();
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return Classes.toString(member);
   }
 
@@ -202,7 +204,6 @@
    * type literal.
    *
    * @param constructor any single constructor present on {@code type}.
-   * 
    * @since 3.0
    */
   public static <T> InjectionPoint forConstructor(Constructor<T> constructor) {
@@ -214,7 +215,6 @@
    *
    * @param constructor any single constructor present on {@code type}.
    * @param type the concrete type that defines {@code constructor}.
-   * 
    * @since 3.0
    */
   public static <T> InjectionPoint forConstructor(
@@ -307,13 +307,11 @@
   }
 
   /**
-   * Returns a new injection point for the specified method of {@code type}.
-   * This is useful for extensions that need to build dependency graphs from
-   * arbitrary methods.
+   * Returns a new injection point for the specified method of {@code type}. This is useful for
+   * extensions that need to build dependency graphs from arbitrary methods.
    *
    * @param method any single method present on {@code type}.
    * @param type the concrete type that defines {@code method}.
-   *
    * @since 4.0
    */
   public static <T> InjectionPoint forMethod(Method method, TypeLiteral<T> type) {
@@ -324,25 +322,25 @@
    * Returns all static method and field injection points on {@code type}.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public static Set<InjectionPoint> forStaticMethodsAndFields(TypeLiteral<?> type) {
     Errors errors = new Errors();
-    
+
     Set<InjectionPoint> result;
-    
+
     if (type.getRawType().isInterface()) {
       errors.staticInjectionOnInterface(type.getRawType());
       result = null;
     } else {
       result = getInjectionPoints(type, true, errors);
     }
-    
+
     if (errors.hasErrors()) {
       throw new ConfigurationException(errors.getMessages()).withPartialValue(result);
     }
@@ -353,12 +351,12 @@
    * Returns all static method and field injection points on {@code type}.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public static Set<InjectionPoint> forStaticMethodsAndFields(Class<?> type) {
     return forStaticMethodsAndFields(TypeLiteral.get(type));
@@ -368,12 +366,12 @@
    * Returns all instance method and field injection points on {@code type}.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public static Set<InjectionPoint> forInstanceMethodsAndFields(TypeLiteral<?> type) {
     Errors errors = new Errors();
@@ -388,23 +386,22 @@
    * Returns all instance method and field injection points on {@code type}.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public static Set<InjectionPoint> forInstanceMethodsAndFields(Class<?> type) {
     return forInstanceMethodsAndFields(TypeLiteral.get(type));
   }
 
-  /**
-   * Returns true if the binding annotation is in the wrong place.
-   */
+  /** Returns true if the binding annotation is in the wrong place. */
   private static boolean checkForMisplacedBindingAnnotations(Member member, Errors errors) {
-    Annotation misplacedBindingAnnotation = Annotations.findBindingAnnotation(
-        errors, member, ((AnnotatedElement) member).getAnnotations());
+    Annotation misplacedBindingAnnotation =
+        Annotations.findBindingAnnotation(
+            errors, member, ((AnnotatedElement) member).getAnnotations());
     if (misplacedBindingAnnotation == null) {
       return false;
     }
@@ -424,10 +421,8 @@
     return true;
   }
 
-  /**
-   * Node in the doubly-linked list of injectable members (fields and methods).
-   */
-  static abstract class InjectableMember {
+  /** Node in the doubly-linked list of injectable members (fields and methods). */
+  abstract static class InjectableMember {
     final TypeLiteral<?> declaringType;
     final boolean optional;
     final boolean jsr330;
@@ -452,8 +447,8 @@
 
   static class InjectableField extends InjectableMember {
     final Field field;
-    InjectableField(TypeLiteral<?> declaringType, Field field,
-        Annotation atInject) {
+
+    InjectableField(TypeLiteral<?> declaringType, Field field, Annotation atInject) {
       super(declaringType, atInject);
       this.field = field;
     }
@@ -467,13 +462,12 @@
   static class InjectableMethod extends InjectableMember {
     final Method method;
     /**
-     * true if this method overrode a method that was annotated
-     * with com.google.inject.Inject.  used to allow different
-     * override behavior for guice inject vs javax.inject.Inject
+     * true if this method overrode a method that was annotated with com.google.inject.Inject. used
+     * to allow different override behavior for guice inject vs javax.inject.Inject
      */
     boolean overrodeGuiceInject;
-    InjectableMethod(TypeLiteral<?> declaringType, Method method,
-        Annotation atInject) {
+
+    InjectableMethod(TypeLiteral<?> declaringType, Method method, Annotation atInject) {
       super(declaringType, atInject);
       this.method = method;
     }
@@ -493,9 +487,7 @@
     return a == null ? member.getAnnotation(Inject.class) : a;
   }
 
-  /**
-   * Linked list of injectable members.
-   */
+  /** Linked list of injectable members. */
   static class InjectableMembers {
     InjectableMember head;
     InjectableMember tail;
@@ -555,23 +547,19 @@
     Signature lastSignature;
 
     /**
-     * Removes a method overridden by the given method, if present. In order to
-     * remain backwards compatible with prior Guice versions, this will *not*
-     * remove overridden methods if 'alwaysRemove' is false and the overridden
-     * signature was annotated with a com.google.inject.Inject.
-     * 
-     * @param method
-     *          The method used to determine what is overridden and should be
-     *          removed.
-     * @param alwaysRemove
-     *          true if overridden methods should be removed even if they were
-     *          guice @Inject
-     * @param injectableMethod
-     *          if this method overrode any guice @Inject methods,
-     *          {@link InjectableMethod#overrodeGuiceInject} is set to true
+     * Removes a method overridden by the given method, if present. In order to remain backwards
+     * compatible with prior Guice versions, this will *not* remove overridden methods if
+     * 'alwaysRemove' is false and the overridden signature was annotated with a
+     * com.google.inject.Inject.
+     *
+     * @param method The method used to determine what is overridden and should be removed.
+     * @param alwaysRemove true if overridden methods should be removed even if they were
+     *     guice @Inject
+     * @param injectableMethod if this method overrode any guice @Inject methods, {@link
+     *     InjectableMethod#overrodeGuiceInject} is set to true
      */
-    boolean removeIfOverriddenBy(Method method, boolean alwaysRemove, 
-        InjectableMethod injectableMethod) {
+    boolean removeIfOverriddenBy(
+        Method method, boolean alwaysRemove, InjectableMethod injectableMethod) {
       if (position == Position.TOP) {
         // If we're at the top of the hierarchy, there's nothing to override.
         return false;
@@ -580,13 +568,18 @@
       if (bySignature == null) {
         // We encountered a method in a subclass. Time to index the
         // methods in the parent class.
-        bySignature = new HashMap<Signature, List<InjectableMethod>>();
-        for (InjectableMember member = injectableMembers.head; member != null;
+        bySignature = new HashMap<>();
+        for (InjectableMember member = injectableMembers.head;
+            member != null;
             member = member.next) {
-          if (!(member instanceof InjectableMethod)) continue;
+          if (!(member instanceof InjectableMethod)) {
+            continue;
+          }
           InjectableMethod im = (InjectableMethod) member;
-          if (im.isFinal()) continue;
-          List<InjectableMethod> methods = new ArrayList<InjectableMethod>();
+          if (im.isFinal()) {
+            continue;
+          }
+          List<InjectableMethod> methods = new ArrayList<>();
           methods.add(im);
           bySignature.put(new Signature(im.method), methods);
         }
@@ -597,19 +590,18 @@
       List<InjectableMethod> methods = bySignature.get(signature);
       boolean removed = false;
       if (methods != null) {
-        for (Iterator<InjectableMethod> iterator = methods.iterator();
-            iterator.hasNext();) {
+        for (Iterator<InjectableMethod> iterator = methods.iterator(); iterator.hasNext(); ) {
           InjectableMethod possiblyOverridden = iterator.next();
           if (overrides(method, possiblyOverridden.method)) {
             boolean wasGuiceInject =
-              !possiblyOverridden.jsr330 || possiblyOverridden.overrodeGuiceInject;
-            if(injectableMethod != null) {
+                !possiblyOverridden.jsr330 || possiblyOverridden.overrodeGuiceInject;
+            if (injectableMethod != null) {
               injectableMethod.overrodeGuiceInject = wasGuiceInject;
             }
             // Only actually remove the methods if we want to force
             // remove or if the signature never specified @com.google.inject.Inject
             // somewhere.
-            if(alwaysRemove || !wasGuiceInject) {
+            if (alwaysRemove || !wasGuiceInject) {
               removed = true;
               iterator.remove();
               injectableMembers.remove(possiblyOverridden);
@@ -621,23 +613,25 @@
     }
 
     /**
-     * Adds the given method to the list of injection points. Keeps track of it in this index
-     * in case it gets overridden.
+     * Adds the given method to the list of injection points. Keeps track of it in this index in
+     * case it gets overridden.
      */
     void add(InjectableMethod injectableMethod) {
       injectableMembers.add(injectableMethod);
-      if (position == Position.BOTTOM
-          || injectableMethod.isFinal()) {
+      if (position == Position.BOTTOM || injectableMethod.isFinal()) {
         // This method can't be overridden, so there's no need to index it.
         return;
       }
       if (bySignature != null) {
         // Try to reuse the signature we created during removal
-        Signature signature = injectableMethod.method == lastMethod
-            ? lastSignature : new Signature(injectableMethod.method);
+        @SuppressWarnings("ReferenceEquality")
+        Signature signature =
+            injectableMethod.method == lastMethod
+                ? lastSignature
+                : new Signature(injectableMethod.method);
         List<InjectableMethod> methods = bySignature.get(signature);
         if (methods == null) {
-          methods = new ArrayList<InjectableMethod>();
+          methods = new ArrayList<>();
           bySignature.put(signature, methods);
         }
         methods.add(injectableMethod);
@@ -648,13 +642,14 @@
   /**
    * Returns an ordered, immutable set of injection points for the given type. Members in
    * superclasses come before members in subclasses. Within a class, fields come before methods.
-   * Overridden methods are filtered out.
+   * Overridden methods are filtered out. The order of fields/methods within a class is consistent
+   * but undefined.
    *
    * @param statics true is this method should return static members, false for instance members
    * @param errors used to record errors
    */
-  private static Set<InjectionPoint> getInjectionPoints(final TypeLiteral<?> type,
-      boolean statics, Errors errors) {
+  private static Set<InjectionPoint> getInjectionPoints(
+      final TypeLiteral<?> type, boolean statics, Errors errors) {
     InjectableMembers injectableMembers = new InjectableMembers();
     OverrideIndex overrideIndex = null;
 
@@ -672,7 +667,7 @@
 
       TypeLiteral<?> current = hierarchy.get(i);
 
-      for (Field field : current.getRawType().getDeclaredFields()) {
+      for (Field field : getDeclaredFields(current)) {
         if (Modifier.isStatic(field.getModifiers()) == statics) {
           Annotation atInject = getAtInject(field);
           if (atInject != null) {
@@ -685,22 +680,25 @@
         }
       }
 
-      for (Method method : current.getRawType().getDeclaredMethods()) {
+      for (Method method : getDeclaredMethods(current)) {
         if (isEligibleForInjection(method, statics)) {
           Annotation atInject = getAtInject(method);
           if (atInject != null) {
-            InjectableMethod injectableMethod = new InjectableMethod(
-                current, method, atInject);
+            InjectableMethod injectableMethod = new InjectableMethod(current, method, atInject);
             if (checkForMisplacedBindingAnnotations(method, errors)
                 || !isValidMethod(injectableMethod, errors)) {
               if (overrideIndex != null) {
-                boolean removed = overrideIndex.removeIfOverriddenBy(method, false, injectableMethod);
-                if(removed) {
-                  logger.log(Level.WARNING, "Method: {0} is not a valid injectable method ("
-                      + "because it either has misplaced binding annotations "
-                      + "or specifies type parameters) but is overriding a method that is valid. "
-                      + "Because it is not valid, the method will not be injected. "
-                      + "To fix this, make the method a valid injectable method.", method);
+                boolean removed =
+                    overrideIndex.removeIfOverriddenBy(method, false, injectableMethod);
+                if (removed) {
+                  logger.log(
+                      Level.WARNING,
+                      "Method: {0} is not a valid injectable method ("
+                          + "because it either has misplaced binding annotations "
+                          + "or specifies type parameters) but is overriding a method that is "
+                          + "valid. Because it is not valid, the method will not be injected. "
+                          + "To fix this, make the method a valid injectable method.",
+                      method);
                 }
               }
               continue;
@@ -717,20 +715,23 @@
                  */
                 overrideIndex = new OverrideIndex(injectableMembers);
               } else {
-                // Forcibly remove the overriden method, otherwise we'll inject
+                // Forcibly remove the overridden method, otherwise we'll inject
                 // it twice.
                 overrideIndex.removeIfOverriddenBy(method, true, injectableMethod);
               }
               overrideIndex.add(injectableMethod);
             }
           } else {
-            if(overrideIndex != null) {
+            if (overrideIndex != null) {
               boolean removed = overrideIndex.removeIfOverriddenBy(method, false, null);
-              if(removed) {
-                logger.log(Level.WARNING, "Method: {0} is not annotated with @Inject but "
-                    + "is overriding a method that is annotated with @javax.inject.Inject.  Because "
-                    + "it is not annotated with @Inject, the method will not be injected. "
-                    + "To fix this, annotate the method with @Inject.", method);
+              if (removed) {
+                logger.log(
+                    Level.WARNING,
+                    "Method: {0} is not annotated with @Inject but "
+                        + "is overriding a method that is annotated with @javax.inject.Inject."
+                        + "Because it is not annotated with @Inject, the method will not be "
+                        + "injected. To fix this, annotate the method with @Inject.",
+                    method);
               }
             }
           }
@@ -743,8 +744,7 @@
     }
 
     ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
-    for (InjectableMember im = injectableMembers.head; im != null;
-        im = im.next) {
+    for (InjectableMember im = injectableMembers.head; im != null; im = im.next) {
       try {
         builder.add(im.toInjectionPoint());
       } catch (ConfigurationException ignorable) {
@@ -756,22 +756,86 @@
     return builder.build();
   }
 
-  /** 
-   * Returns true if the method is eligible to be injected.  This is different than
-   * {@link #isValidMethod}, because ineligibility will not drop a method
-   * from being injected if a superclass was eligible & valid. 
-   * Bridge & synthetic methods are excluded from eligibility for two reasons:
-   * 
-   * <p>Prior to Java8, javac would generate these methods in subclasses without
-   * annotations, which means this would accidentally stop injecting a method
-   * annotated with {@link javax.inject.Inject}, since the spec says to stop
-   * injecting if a subclass isn't annotated with it.
-   * 
-   * <p>Starting at Java8, javac copies the annotations to the generated subclass
-   * method, except it leaves out the generic types.  If this considered it a valid
-   * injectable method, this would eject the parent's overridden method that had the
-   * proper generic types, and would use invalid injectable parameters as a result.
-   * 
+  private static Field[] getDeclaredFields(TypeLiteral<?> type) {
+    Field[] fields = type.getRawType().getDeclaredFields();
+    Arrays.sort(fields, FIELD_ORDERING);
+    return fields;
+  }
+
+  private static Method[] getDeclaredMethods(TypeLiteral<?> type) {
+    Method[] methods = type.getRawType().getDeclaredMethods();
+    Arrays.sort(methods, METHOD_ORDERING);
+    return methods;
+  }
+
+  /**
+   * An ordering suitable for comparing two classes if they are loaded by the same classloader
+   *
+   * <p>Within a single classloader there can only be one class with a given name, so we just
+   * compare the names.
+   */
+  private static final Ordering<Class<?>> CLASS_ORDERING =
+      new Ordering<Class<?>>() {
+        @Override
+        public int compare(Class<?> o1, Class<?> o2) {
+          return o1.getName().compareTo(o2.getName());
+        }
+      };
+
+  /**
+   * An ordering suitable for comparing two fields if they are owned by the same class.
+   *
+   * <p>Within a single class it is sufficent to compare the non-generic field signature which
+   * consists of the field name and type.
+   */
+  private static final Ordering<Field> FIELD_ORDERING =
+      new Ordering<Field>() {
+        @Override
+        public int compare(Field left, Field right) {
+          return ComparisonChain.start()
+              .compare(left.getName(), right.getName())
+              .compare(left.getType(), right.getType(), CLASS_ORDERING)
+              .result();
+        }
+      };
+
+  /**
+   * An ordering suitable for comparing two methods if they are owned by the same class.
+   *
+   * <p>Within a single class it is sufficient to compare the non-generic method signature which
+   * consists of the name, return type and parameter types.
+   */
+  private static final Ordering<Method> METHOD_ORDERING =
+      new Ordering<Method>() {
+        @Override
+        public int compare(Method left, Method right) {
+          return ComparisonChain.start()
+              .compare(left.getName(), right.getName())
+              .compare(left.getReturnType(), right.getReturnType(), CLASS_ORDERING)
+              .compare(
+                  Arrays.asList(left.getParameterTypes()),
+                  Arrays.asList(right.getParameterTypes()),
+                  CLASS_ORDERING.lexicographical())
+              .result();
+        }
+      };
+
+  /**
+   * Returns true if the method is eligible to be injected. This is different than {@link
+   * #isValidMethod}, because ineligibility will not drop a method from being injected if a
+   * superclass was eligible & valid. Bridge & synthetic methods are excluded from eligibility for
+   * two reasons:
+   *
+   * <p>Prior to Java8, javac would generate these methods in subclasses without annotations, which
+   * means this would accidentally stop injecting a method annotated with {@link
+   * javax.inject.Inject}, since the spec says to stop injecting if a subclass isn't annotated with
+   * it.
+   *
+   * <p>Starting at Java8, javac copies the annotations to the generated subclass method, except it
+   * leaves out the generic types. If this considered it a valid injectable method, this would eject
+   * the parent's overridden method that had the proper generic types, and would use invalid
+   * injectable parameters as a result.
+   *
    * <p>The fix for both is simply to ignore these synthetic bridge methods.
    */
   private static boolean isEligibleForInjection(Method method, boolean statics) {
@@ -780,8 +844,7 @@
         && !method.isSynthetic();
   }
 
-  private static boolean isValidMethod(InjectableMethod injectableMethod,
-      Errors errors) {
+  private static boolean isValidMethod(InjectableMethod injectableMethod, Errors errors) {
     boolean result = true;
     if (injectableMethod.jsr330) {
       Method method = injectableMethod.method;
@@ -798,7 +861,7 @@
   }
 
   private static List<TypeLiteral<?>> hierarchyFor(TypeLiteral<?> type) {
-    List<TypeLiteral<?>> hierarchy = new ArrayList<TypeLiteral<?>>();
+    List<TypeLiteral<?>> hierarchy = new ArrayList<>();
     TypeLiteral<?> current = type;
     while (current.getRawType() != Object.class) {
       hierarchy.add(current);
@@ -824,9 +887,7 @@
     return a.getDeclaringClass().getPackage().equals(b.getDeclaringClass().getPackage());
   }
 
-  /**
-   * A method signature. Used to handle method overridding.
-   */
+  /** A method signature. Used to handle method overridding. */
   static class Signature {
 
     final String name;
@@ -845,11 +906,13 @@
       this.hash = h;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return this.hash;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
       if (!(o instanceof Signature)) {
         return false;
       }
diff --git a/core/src/com/google/inject/spi/InjectionRequest.java b/core/src/com/google/inject/spi/InjectionRequest.java
index f80e37a..8fbd16d 100644
--- a/core/src/com/google/inject/spi/InjectionRequest.java
+++ b/core/src/com/google/inject/spi/InjectionRequest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,13 +21,13 @@
 import com.google.inject.Binder;
 import com.google.inject.ConfigurationException;
 import com.google.inject.TypeLiteral;
-
 import java.util.Set;
 
 /**
  * A request to inject the instance fields and methods of an instance. Requests are created
  * explicitly in a module using {@link com.google.inject.Binder#requestInjection(Object)
  * requestInjection()} statements:
+ *
  * <pre>
  *     requestInjection(serviceInstance);</pre>
  *
@@ -46,6 +46,7 @@
     this.instance = checkNotNull(instance, "instance");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -63,21 +64,23 @@
    * this request.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on the class of {@code
-   *      instance}, such as a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     instance}, such as a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException {
     return InjectionPoint.forInstanceMethodsAndFields(instance.getClass());
   }
 
+  @Override
   public <R> R acceptVisitor(ElementVisitor<R> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).requestInjection(type, instance);
   }
diff --git a/core/src/com/google/inject/spi/InstanceBinding.java b/core/src/com/google/inject/spi/InstanceBinding.java
index 2e2270c..478b085 100644
--- a/core/src/com/google/inject/spi/InstanceBinding.java
+++ b/core/src/com/google/inject/spi/InstanceBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.spi;
 
 import com.google.inject.Binding;
-
 import java.util.Set;
 
 /**
@@ -28,9 +27,7 @@
  */
 public interface InstanceBinding<T> extends Binding<T>, HasDependencies {
 
-  /**
-   * Returns the user-supplied instance.
-   */
+  /** Returns the user-supplied instance. */
   T getInstance();
 
   /**
@@ -40,5 +37,4 @@
    * @return a possibly empty set
    */
   Set<InjectionPoint> getInjectionPoints();
-
 }
diff --git a/core/src/com/google/inject/spi/InterceptorBinding.java b/core/src/com/google/inject/spi/InterceptorBinding.java
index a16e701..49e6349 100644
--- a/core/src/com/google/inject/spi/InterceptorBinding.java
+++ b/core/src/com/google/inject/spi/InterceptorBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,16 +21,15 @@
 import com.google.common.collect.ImmutableList;
 import com.google.inject.Binder;
 import com.google.inject.matcher.Matcher;
-
-import org.aopalliance.intercept.MethodInterceptor;
-
 import java.lang.reflect.Method;
 import java.util.List;
+import org.aopalliance.intercept.MethodInterceptor;
 
 /**
  * Registration of interceptors for matching methods of matching classes. Instances are created
- * explicitly in a module using {@link com.google.inject.Binder#bindInterceptor(
- * Matcher, Matcher, MethodInterceptor[]) bindInterceptor()} statements:
+ * explicitly in a module using {@link com.google.inject.Binder#bindInterceptor( Matcher, Matcher,
+ * MethodInterceptor[]) bindInterceptor()} statements:
+ *
  * <pre>
  *     bindInterceptor(Matchers.subclassesOf(MyAction.class),
  *         Matchers.annotatedWith(Transactional.class),
@@ -59,6 +58,7 @@
     this.interceptors = ImmutableList.copyOf(interceptors);
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -75,12 +75,18 @@
     return interceptors;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
-    binder.withSource(getSource()).bindInterceptor(classMatcher, methodMatcher,
-        interceptors.toArray(new MethodInterceptor[interceptors.size()]));
+    binder
+        .withSource(getSource())
+        .bindInterceptor(
+            classMatcher,
+            methodMatcher,
+            interceptors.toArray(new MethodInterceptor[interceptors.size()]));
   }
 }
diff --git a/core/src/com/google/inject/spi/LinkedKeyBinding.java b/core/src/com/google/inject/spi/LinkedKeyBinding.java
index 7b823a6..2d59d8e 100644
--- a/core/src/com/google/inject/spi/LinkedKeyBinding.java
+++ b/core/src/com/google/inject/spi/LinkedKeyBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,5 +32,4 @@
    * injector using {@link com.google.inject.Injector#getBinding(Key) Injector.getBinding(key)}.
    */
   Key<? extends T> getLinkedKey();
-
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/MembersInjectorLookup.java b/core/src/com/google/inject/spi/MembersInjectorLookup.java
index d4da8bd..2944de3 100644
--- a/core/src/com/google/inject/spi/MembersInjectorLookup.java
+++ b/core/src/com/google/inject/spi/MembersInjectorLookup.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,6 +26,7 @@
 /**
  * A lookup of the members injector for a type. Lookups are created explicitly in a module using
  * {@link com.google.inject.Binder#getMembersInjector(Class) getMembersInjector()} statements:
+ *
  * <pre>
  *     MembersInjector&lt;PaymentService&gt; membersInjector
  *         = getMembersInjector(PaymentService.class);</pre>
@@ -44,17 +45,17 @@
     this.type = checkNotNull(type, "type");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
-  /**
-   * Gets the type containing the members to be injected.
-   */
+  /** Gets the type containing the members to be injected. */
   public TypeLiteral<T> getType() {
     return type;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
@@ -69,14 +70,15 @@
     this.delegate = checkNotNull(delegate, "delegate");
   }
 
+  @Override
   public void applyTo(Binder binder) {
     initializeDelegate(binder.withSource(getSource()).getMembersInjector(type));
   }
 
   /**
-   * Returns the delegate members injector, or {@code null} if it has not yet been initialized.
-   * The delegate will be initialized when this element is processed, or otherwise used to create
-   * an injector.
+   * Returns the delegate members injector, or {@code null} if it has not yet been initialized. The
+   * delegate will be initialized when this element is processed, or otherwise used to create an
+   * injector.
    */
   public MembersInjector<T> getDelegate() {
     return delegate;
@@ -89,15 +91,20 @@
    */
   public MembersInjector<T> getMembersInjector() {
     return new MembersInjector<T>() {
+      @Override
       public void injectMembers(T instance) {
-        checkState(delegate != null,
-            "This MembersInjector cannot be used until the Injector has been created.");
-        delegate.injectMembers(instance);
+        MembersInjector<T> local = delegate;
+        if (local == null) {
+          throw new IllegalStateException(
+              "This MembersInjector cannot be used until the Injector has been created.");
+        }
+        local.injectMembers(instance);
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return "MembersInjector<" + type + ">";
       }
     };
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/Message.java b/core/src/com/google/inject/spi/Message.java
index 59c4072..282f80c 100644
--- a/core/src/com/google/inject/spi/Message.java
+++ b/core/src/com/google/inject/spi/Message.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.Binder;
 import com.google.inject.internal.Errors;
 import com.google.inject.internal.util.SourceProvider;
-
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.util.List;
@@ -32,6 +31,7 @@
  * An error message and the context in which it occured. Messages are usually created internally by
  * Guice and its extensions. Messages can be created explicitly in a module using {@link
  * com.google.inject.Binder#addError(Throwable) addError()} statements:
+ *
  * <pre>
  *     try {
  *       bindPropertiesFromFile();
@@ -46,18 +46,14 @@
   private final Throwable cause;
   private final List<Object> sources;
 
-  /**
-   * @since 2.0
-   */
+  /** @since 2.0 */
   public Message(List<Object> sources, String message, Throwable cause) {
     this.sources = ImmutableList.copyOf(sources);
     this.message = checkNotNull(message, "message");
     this.cause = cause;
   }
 
-  /**
-   * @since 4.0
-   */
+  /** @since 4.0 */
   public Message(String message, Throwable cause) {
     this(ImmutableList.of(), message, cause);
   }
@@ -70,6 +66,7 @@
     this(ImmutableList.of(), message, null);
   }
 
+  @Override
   public String getSource() {
     return sources.isEmpty()
         ? SourceProvider.UNKNOWN_SOURCE.toString()
@@ -81,21 +78,20 @@
     return sources;
   }
 
-  /**
-   * Gets the error message text.
-   */
+  /** Gets the error message text. */
   public String getMessage() {
     return message;
   }
 
   /** @since 2.0 */
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
   /**
-   * Returns the throwable that caused this message, or {@code null} if this
-   * message was not caused by a throwable.
+   * Returns the throwable that caused this message, or {@code null} if this message was not caused
+   * by a throwable.
    *
    * @since 2.0
    */
@@ -103,15 +99,18 @@
     return cause;
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return message;
   }
 
-  @Override public int hashCode() {
-    return message.hashCode();
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(message, cause, sources);
   }
 
-  @Override public boolean equals(Object o) {
+  @Override
+  public boolean equals(Object o) {
     if (!(o instanceof Message)) {
       return false;
     }
@@ -120,6 +119,7 @@
   }
 
   /** @since 2.0 */
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).addError(this);
   }
diff --git a/core/src/com/google/inject/spi/ModuleAnnotatedMethodScanner.java b/core/src/com/google/inject/spi/ModuleAnnotatedMethodScanner.java
index 3c90825..48343cb 100644
--- a/core/src/com/google/inject/spi/ModuleAnnotatedMethodScanner.java
+++ b/core/src/com/google/inject/spi/ModuleAnnotatedMethodScanner.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,13 +18,12 @@
 
 import com.google.inject.Binder;
 import com.google.inject.Key;
-
 import java.lang.annotation.Annotation;
 import java.util.Set;
 
 /**
- * Allows extensions to scan modules for annotated methods and bind those methods
- * as providers, similar to {@code @Provides} methods.
+ * Allows extensions to scan modules for annotated methods and bind those methods as providers,
+ * similar to {@code @Provides} methods.
  *
  * @since 4.0
  */
@@ -40,16 +39,15 @@
   /**
    * Prepares a method for binding. This {@code key} parameter is the key discovered from looking at
    * the binding annotation and return value of the method. Implementations can modify the key to
-   * instead bind to another key. For example, Multibinder may want to change
-   * {@code @SetProvides String provideFoo()} to bind into a unique Key within the multibinder
-   * instead of binding {@code String}.
+   * instead bind to another key. For example, Multibinder may want to change {@code @SetProvides
+   * String provideFoo()} to bind into a unique Key within the multibinder instead of binding {@code
+   * String}.
    *
    * <p>The injection point and annotation are provided in case the implementation wants to set the
    * key based on the property of the annotation or if any additional preparation is needed for any
    * of the dependencies. The annotation is guaranteed to be an instance of one the classes returned
    * by {@link #annotationClasses}.
    */
-  public abstract <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key,
-      InjectionPoint injectionPoint);
-
+  public abstract <T> Key<T> prepareMethod(
+      Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint);
 }
diff --git a/core/src/com/google/inject/spi/ModuleAnnotatedMethodScannerBinding.java b/core/src/com/google/inject/spi/ModuleAnnotatedMethodScannerBinding.java
index d632420..91cbe67 100644
--- a/core/src/com/google/inject/spi/ModuleAnnotatedMethodScannerBinding.java
+++ b/core/src/com/google/inject/spi/ModuleAnnotatedMethodScannerBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,7 @@
 
 /**
  * Represents a call to {@link Binder#scanModulesForAnnotatedMethods} in a module.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
  */
@@ -36,6 +36,7 @@
     this.scanner = checkNotNull(scanner, "scanner");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -43,17 +44,24 @@
   public ModuleAnnotatedMethodScanner getScanner() {
     return scanner;
   }
-  
+
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).scanModulesForAnnotatedMethods(scanner);
   }
 
-  @Override public String toString() {
-    return scanner + " which scans for " + scanner.annotationClasses()
-        + " (bound at " + Errors.convert(source) + ")";
+  @Override
+  public String toString() {
+    return scanner
+        + " which scans for "
+        + scanner.annotationClasses()
+        + " (bound at "
+        + Errors.convert(source)
+        + ")";
   }
 }
diff --git a/core/src/com/google/inject/spi/ModuleSource.java b/core/src/com/google/inject/spi/ModuleSource.java
index 1e07de2..cd9435a 100644
--- a/core/src/com/google/inject/spi/ModuleSource.java
+++ b/core/src/com/google/inject/spi/ModuleSource.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2013 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
 import com.google.inject.Module;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.internal.util.StackTraceElements.InMemoryStackTraceElement;
-
 import java.util.List;
 
 /**
@@ -31,14 +30,10 @@
  */
 final class ModuleSource {
 
-  /**
-   * The class name of module that this {@link ModuleSource} associated to.
-   */
+  /** The class name of module that this {@link ModuleSource} associated to. */
   private final String moduleClassName;
 
-  /**
-   * The parent {@link ModuleSource module source}.
-   */
+  /** The parent {@link ModuleSource module source}. */
   private final ModuleSource parent;
 
   /**
@@ -51,22 +46,24 @@
 
   /**
    * Creates a new {@link ModuleSource} with a {@literal null} parent.
+   *
    * @param module the corresponding module
    * @param partialCallStack the chunk of call stack that starts from the parent module {@link
-   * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
-   * Module#configure(Binder) configure(Binder)} method invocation
+   *     Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
+   *     Module#configure(Binder) configure(Binder)} method invocation
    */
   ModuleSource(Object module, StackTraceElement[] partialCallStack) {
     this(null, module, partialCallStack);
   }
 
- /**
+  /**
    * Creates a new {@link ModuleSource} Object.
+   *
    * @param parent the parent module {@link ModuleSource source}
    * @param module the corresponding module
    * @param partialCallStack the chunk of call stack that starts from the parent module {@link
-   * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
-   * Module#configure(Binder) configure(Binder)} method invocation
+   *     Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
+   *     Module#configure(Binder) configure(Binder)} method invocation
    */
   private ModuleSource(
       /* @Nullable */ ModuleSource parent, Object module, StackTraceElement[] partialCallStack) {
@@ -96,27 +93,24 @@
     return StackTraceElements.convertToStackTraceElement(partialCallStack);
   }
 
-  /**
-   * Returns the size of partial call stack if stack trace collection is on otherwise zero.
-   */
+  /** Returns the size of partial call stack if stack trace collection is on otherwise zero. */
   int getPartialCallStackSize() {
     return partialCallStack.length;
   }
 
   /**
    * Creates and returns a child {@link ModuleSource} corresponding to the {@link Module module}.
+   *
    * @param module the corresponding module
    * @param partialCallStack the chunk of call stack that starts from the parent module {@link
-   * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
-   * Module#configure(Binder) configure(Binder)} method invocation
+   *     Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
+   *     Module#configure(Binder) configure(Binder)} method invocation
    */
   ModuleSource createChild(Object module, StackTraceElement[] partialCallStack) {
     return new ModuleSource(this, module, partialCallStack);
   }
 
-  /**
-   * Returns the parent module {@link ModuleSource source}.
-   */
+  /** Returns the parent module {@link ModuleSource source}. */
   ModuleSource getParent() {
     return parent;
   }
diff --git a/core/src/com/google/inject/spi/PrivateElements.java b/core/src/com/google/inject/spi/PrivateElements.java
index fc36305..f3bc0e6 100644
--- a/core/src/com/google/inject/spi/PrivateElements.java
+++ b/core/src/com/google/inject/spi/PrivateElements.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
 import java.util.List;
 import java.util.Set;
 
@@ -31,9 +30,7 @@
  */
 public interface PrivateElements extends Element {
 
-  /**
-   * Returns the configuration information in this private environment.
-   */
+  /** Returns the configuration information in this private environment. */
   List<Element> getElements();
 
   /**
@@ -42,9 +39,7 @@
    */
   Injector getInjector();
 
-  /**
-   * Returns the unique exposed keys for these private elements.
-   */
+  /** Returns the unique exposed keys for these private elements. */
   Set<Key<?>> getExposedKeys();
 
   /**
diff --git a/core/src/com/google/inject/spi/ProviderBinding.java b/core/src/com/google/inject/spi/ProviderBinding.java
index caec274..092f645 100644
--- a/core/src/com/google/inject/spi/ProviderBinding.java
+++ b/core/src/com/google/inject/spi/ProviderBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,4 +35,4 @@
    * Injector.getBinding(providedKey)}
    */
   Key<?> getProvidedKey();
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/ProviderInstanceBinding.java b/core/src/com/google/inject/spi/ProviderInstanceBinding.java
index 99cd9db..73f3b2e 100644
--- a/core/src/com/google/inject/spi/ProviderInstanceBinding.java
+++ b/core/src/com/google/inject/spi/ProviderInstanceBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Binding;
 import com.google.inject.Provider;
-
 import java.util.Set;
 
 /**
@@ -33,14 +32,15 @@
   /**
    * If the user supplied a JSR330 binding, then this will wrap that one. To always return the
    * user-supplied provider, use {@link #getUserSuppliedProvider}.
-   * 
+   *
    * @deprecated Use {@link #getUserSuppliedProvider} instead.
    */
   @Deprecated
   Provider<? extends T> getProviderInstance();
-  
+
   /**
    * Returns the user-supplied, unscoped provider.
+   *
    * @since 4.0
    */
   javax.inject.Provider<? extends T> getUserSuppliedProvider();
@@ -52,5 +52,4 @@
    * @return a possibly empty set
    */
   Set<InjectionPoint> getInjectionPoints();
-
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/ProviderKeyBinding.java b/core/src/com/google/inject/spi/ProviderKeyBinding.java
index 4a6cfdc..9f28967 100644
--- a/core/src/com/google/inject/spi/ProviderKeyBinding.java
+++ b/core/src/com/google/inject/spi/ProviderKeyBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,5 +34,4 @@
    * Injector.getBinding(providerKey)}
    */
   Key<? extends javax.inject.Provider<? extends T>> getProviderKey();
-
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/inject/spi/ProviderLookup.java b/core/src/com/google/inject/spi/ProviderLookup.java
index 3cc2d05..a3b5163 100644
--- a/core/src/com/google/inject/spi/ProviderLookup.java
+++ b/core/src/com/google/inject/spi/ProviderLookup.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,12 +24,12 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.util.Types;
-
 import java.util.Set;
 
 /**
- * A lookup of the provider for a type. Lookups are created explicitly in a module using
- * {@link com.google.inject.Binder#getProvider(Class) getProvider()} statements:
+ * A lookup of the provider for a type. Lookups are created explicitly in a module using {@link
+ * com.google.inject.Binder#getProvider(Class) getProvider()} statements:
+ *
  * <pre>
  *     Provider&lt;PaymentService&gt; paymentServiceProvider
  *         = getProvider(PaymentService.class);</pre>
@@ -52,6 +52,7 @@
     this.dependency = checkNotNull(dependency, "dependency");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -65,6 +66,7 @@
     return dependency;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
@@ -79,6 +81,7 @@
     this.delegate = checkNotNull(delegate, "delegate");
   }
 
+  @Override
   public void applyTo(Binder binder) {
     initializeDelegate(binder.withSource(getSource()).getProvider(dependency));
   }
@@ -98,12 +101,17 @@
    */
   public Provider<T> getProvider() {
     return new ProviderWithDependencies<T>() {
+      @Override
       public T get() {
-        checkState(delegate != null,
-            "This Provider cannot be used until the Injector has been created.");
-        return delegate.get();
+        Provider<T> local = delegate;
+        if (local == null) {
+          throw new IllegalStateException(
+              "This Provider cannot be used until the Injector has been created.");
+        }
+        return local.get();
       }
 
+      @Override
       public Set<Dependency<?>> getDependencies() {
         // We depend on Provider<T>, not T directly.  This is an important distinction
         // for dependency analysis tools that short-circuit on providers.
@@ -111,7 +119,8 @@
         return ImmutableSet.<Dependency<?>>of(Dependency.get(providerKey));
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return "Provider<" + getKey().getTypeLiteral() + ">";
       }
     };
diff --git a/core/src/com/google/inject/spi/ProviderWithDependencies.java b/core/src/com/google/inject/spi/ProviderWithDependencies.java
index be87379..a47a051 100644
--- a/core/src/com/google/inject/spi/ProviderWithDependencies.java
+++ b/core/src/com/google/inject/spi/ProviderWithDependencies.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/core/src/com/google/inject/spi/ProviderWithExtensionVisitor.java b/core/src/com/google/inject/spi/ProviderWithExtensionVisitor.java
index b835b71..2d3f3be 100644
--- a/core/src/com/google/inject/spi/ProviderWithExtensionVisitor.java
+++ b/core/src/com/google/inject/spi/ProviderWithExtensionVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,26 +20,25 @@
 import com.google.inject.Provider;
 
 /**
- * A Provider that is part of an extension which supports a custom
- * BindingTargetVisitor.
- * <p> 
- * When an extension binds a provider instance, the provider can implement this
- * interface to allow users using the
- * {@link Binding#acceptTargetVisitor(BindingTargetVisitor)} method to visit a
- * custom visitor designed for that extension. A typical implementation within
- * the extension would look like
- * <pre> 
+ * A Provider that is part of an extension which supports a custom BindingTargetVisitor.
+ *
+ * <p>When an extension binds a provider instance, the provider can implement this interface to
+ * allow users using the {@link Binding#acceptTargetVisitor(BindingTargetVisitor)} method to visit a
+ * custom visitor designed for that extension. A typical implementation within the extension would
+ * look like
+ *
+ * <pre>
  * &lt;V, B> V acceptExtensionVisitor(BindingTargetVisitor&lt;B, V> visitor, ProviderInstanceBinding&lt;? extends B> binding) {
  *   if(visitor instanceof MyCustomExtensionVisitor) {
  *     return ((MyCustomExtensionVisitor&lt;B, V>)visitor).visitCustomExtension(customProperties, binding);
  *   } else {
  *     return visitor.visit(binding);
  *   }
- * }</pre> 
- * 'MyCustomExtensionVisitor' in the example above would be an interface the
- * extension provides that users can implement in order to be notified of custom
- * extension information. These visitor interfaces must extend from
- * BindingTargetVisitor.
+ * }</pre>
+ *
+ * 'MyCustomExtensionVisitor' in the example above would be an interface the extension provides that
+ * users can implement in order to be notified of custom extension information. These visitor
+ * interfaces must extend from BindingTargetVisitor.
  *
  * @since 3.0
  * @author sameb@google.com (Sam Berlin)
@@ -47,15 +46,13 @@
 public interface ProviderWithExtensionVisitor<T> extends Provider<T> {
 
   /**
-   * Instructs the extension determine if the visitor is an instance of a custom
-   * extension visitor, and if so, visit it using that method. If the visitor is
-   * not an instance of the custom extension visitor, this method <b>MUST</b>
-   * call visitor.visit(binding).
-   * <p> 
-   * Due to issues with generics, the type parameters of this method do not
-   * relate to the type of the provider. In practice, the 'B' type will always
-   * be a supertype of 'T'.
+   * Instructs the extension determine if the visitor is an instance of a custom extension visitor,
+   * and if so, visit it using that method. If the visitor is not an instance of the custom
+   * extension visitor, this method <b>MUST</b> call visitor.visit(binding).
+   *
+   * <p>Due to issues with generics, the type parameters of this method do not relate to the type of
+   * the provider. In practice, the 'B' type will always be a supertype of 'T'.
    */
-  <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
-      ProviderInstanceBinding<? extends B> binding);
+  <B, V> V acceptExtensionVisitor(
+      BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding);
 }
diff --git a/core/src/com/google/inject/spi/ProvidesMethodBinding.java b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
index a862fcc..ec56300 100644
--- a/core/src/com/google/inject/spi/ProvidesMethodBinding.java
+++ b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,33 +18,32 @@
 
 import com.google.inject.Key;
 import com.google.inject.Provides;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
 /**
- * An {@literal @}{@link Provides} binding or binding produced by a
- * {@link ModuleAnnotatedMethodScanner}.
+ * An {@literal @}{@link Provides} binding or binding produced by a {@link
+ * ModuleAnnotatedMethodScanner}.
  *
  * @since 4.0
  * @author sameb@google.com (Sam Berlin)
  */
 public interface ProvidesMethodBinding<T> extends HasDependencies {
-  
+
   /** Returns the method this binding uses. */
-  Method getMethod(); 
-  
+  Method getMethod();
+
   /** Returns the instance of the object the method is defined in. */
   Object getEnclosingInstance();
-  
+
   /** Returns the key of the binding. */
   Key<T> getKey();
 
   /**
    * Returns the annotation that caused this binding to be created. For {@code @Provides} methods,
-   * this is an instance of the {@code @Provides} annotation. For bindings from
-   * {@link ModuleAnnotatedMethodScanner}, this is the annotation that caused the scanner to produce
-   * the binding.
+   * this is an instance of the {@code @Provides} annotation. For bindings from {@link
+   * ModuleAnnotatedMethodScanner}, this is the annotation that caused the scanner to produce the
+   * binding.
    */
   Annotation getAnnotation();
 }
diff --git a/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
index 62c8721..1a8c0f6 100644
--- a/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
+++ b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,19 +17,18 @@
 package com.google.inject.spi;
 
 import com.google.inject.Provides;
-import com.google.inject.spi.BindingTargetVisitor;
 
 /**
  * A visitor for the {@literal @}{@link Provides} bindings.
- * <p>
- * If your {@link BindingTargetVisitor} implements this interface, bindings created by using
- * {@code @Provides} will be visited through this interface.
+ *
+ * <p>If your {@link com.google.inject.spi.BindingTargetVisitor} implements this interface, bindings
+ * created by using {@code @Provides} will be visited through this interface.
  *
  * @since 4.0
  * @author sameb@google.com (Sam Berlin)
  */
 public interface ProvidesMethodTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
-  
+
   /**
    * Visits an {@link ProvidesMethodBinding} created with an {@literal @}{@link Provides} method.
    */
diff --git a/core/src/com/google/inject/spi/ProvisionListener.java b/core/src/com/google/inject/spi/ProvisionListener.java
index 274b8c3..3977224 100644
--- a/core/src/com/google/inject/spi/ProvisionListener.java
+++ b/core/src/com/google/inject/spi/ProvisionListener.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2011 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -20,32 +20,28 @@
 import com.google.inject.Provider;
 import com.google.inject.Scope;
 
-import java.util.List;
-
 /**
- * Listens for provisioning of objects. Useful for gathering timing information
- * about provisioning, post-provision initialization, and more.
- * 
+ * Listens for provisioning of objects. Useful for gathering timing information about provisioning,
+ * post-provision initialization, and more.
+ *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
  */
 public interface ProvisionListener {
 
   /**
-   * Invoked by Guice when an object requires provisioning. Provisioning occurs
-   * when Guice locates and injects the dependencies for a binding. For types
-   * bound to a Provider, provisioning encapsulates the {@link Provider#get}
-   * method. For toInstance or constant bindings, provisioning encapsulates
-   * the injecting of {@literal @}{@code Inject}ed fields or methods.
-   * For other types, provisioning encapsulates the construction of the
-   * object. If a type is bound within a {@link Scope}, provisioning depends on
-   * the scope. Types bound in Singleton scope will only be provisioned once.
-   * Types bound in no scope will be provisioned every time they are injected.
+   * Invoked by Guice when an object requires provisioning. Provisioning occurs when Guice locates
+   * and injects the dependencies for a binding. For types bound to a Provider, provisioning
+   * encapsulates the {@link Provider#get} method. For toInstance or constant bindings, provisioning
+   * encapsulates the injecting of {@literal @}{@code Inject}ed fields or methods. For other types,
+   * provisioning encapsulates the construction of the object. If a type is bound within a {@link
+   * Scope}, provisioning depends on the scope. Types bound in Singleton scope will only be
+   * provisioned once. Types bound in no scope will be provisioned every time they are injected.
    * Other scopes define their own behavior for provisioning.
-   * <p>
-   * To perform the provision, call {@link ProvisionInvocation#provision()}.
-   * If you do not explicitly call provision, it will be automatically done after
-   * this method returns.  It is an error to call provision more than once.
+   *
+   * <p>To perform the provision, call {@link ProvisionInvocation#provision()}. If you do not
+   * explicitly call provision, it will be automatically done after this method returns. It is an
+   * error to call provision more than once.
    */
   <T> void onProvision(ProvisionInvocation<T> provision);
 
@@ -53,22 +49,57 @@
    * Encapsulates a single act of provisioning.
    *
    * @since 4.0
-   */ 
+   */
   public abstract static class ProvisionInvocation<T> {
 
     /**
      * Returns the Binding this is provisioning.
-     * <p>
-     * You must not call {@link Provider#get()} on the provider returned by
-     * {@link Binding#getProvider}, otherwise you will get confusing error messages.
+     *
+     * <p>You must not call {@link Provider#get()} on the provider returned by {@link
+     * Binding#getProvider}, otherwise you will get confusing error messages.
      */
     public abstract Binding<T> getBinding();
 
     /** Performs the provision, returning the object provisioned. */
     public abstract T provision();
-    
-    /** Returns the dependency chain that led to this object being provisioned. */
-    public abstract List<DependencyAndSource> getDependencyChain();
-    
+
+    /**
+     * Returns the dependency chain that led to this object being provisioned.
+     *
+     * @deprecated This method is planned for removal in Guice 4.4.  Some use cases can be replaced
+     * by inferring the current chain via ThreadLocals in the listener, other use cases can use
+     * the static dependency graph.  For example,
+     * <pre>{@code
+     *   bindListener(Matchers.any(), new MyListener());
+     *   ...
+     *
+     *   private static final class MyListener implements ProvisionListener {
+     *     private final ThreadLocal<ArrayDeque<Binding<?>>> bindingStack =
+     *         new ThreadLocal<ArrayDeque<Binding<?>>>() {
+     *           {@literal @}Override protected ArrayDeque<Binding<?>> initialValue() {
+     *             return new ArrayDeque<>();
+     *           }
+     *         };
+     *     {@literal @}Override public <T> void onProvision(ProvisionInvocation<T> invocation) {
+     *       bindingStack.get().push(invocation.getBinding());
+     *       try {
+     *         invocation.provision();
+     *       } finally {
+     *         bindingStack.get().pop();
+     *       }
+     *       // Inspect the binding stack...
+     *     }
+     *   }
+     *
+     * }<pre>
+     *
+     * In this example the bindingStack thread local will contain a data structure that is very
+     * similar to the data returned by this list.  The main differences are that linked keys are
+     * not in the stack, but such edges do exist in the static dependency graph (inspectable via
+     * {@link HasDependencies#getDependencies()}), so you could infer some of the missing edges..
+     */
+    @Deprecated
+    public abstract java.util.List<DependencyAndSource> getDependencyChain();
+
   }
 }
diff --git a/core/src/com/google/inject/spi/ProvisionListenerBinding.java b/core/src/com/google/inject/spi/ProvisionListenerBinding.java
index 4f349d4..d94d183 100644
--- a/core/src/com/google/inject/spi/ProvisionListenerBinding.java
+++ b/core/src/com/google/inject/spi/ProvisionListenerBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,6 @@
 import com.google.inject.Binder;
 import com.google.inject.Binding;
 import com.google.inject.matcher.Matcher;
-
 import java.util.List;
 
 /**
@@ -36,9 +35,8 @@
   private final Matcher<? super Binding<?>> bindingMatcher;
   private final List<ProvisionListener> listeners;
 
-  ProvisionListenerBinding(Object source,
-      Matcher<? super Binding<?>> bindingMatcher,
-      ProvisionListener[] listeners) {
+  ProvisionListenerBinding(
+      Object source, Matcher<? super Binding<?>> bindingMatcher, ProvisionListener[] listeners) {
     this.source = source;
     this.bindingMatcher = bindingMatcher;
     this.listeners = ImmutableList.copyOf(listeners);
@@ -51,21 +49,25 @@
 
   /**
    * Returns the binding matcher which chooses which bindings the listener should be notified of.
-   */  
+   */
   public Matcher<? super Binding<?>> getBindingMatcher() {
     return bindingMatcher;
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public <R> R acceptVisitor(ElementVisitor<R> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
-    binder.withSource(getSource()).bindListener(bindingMatcher,
-        listeners.toArray(new ProvisionListener[listeners.size()]));
+    binder
+        .withSource(getSource())
+        .bindListener(bindingMatcher, listeners.toArray(new ProvisionListener[listeners.size()]));
   }
 }
diff --git a/core/src/com/google/inject/spi/RequireAtInjectOnConstructorsOption.java b/core/src/com/google/inject/spi/RequireAtInjectOnConstructorsOption.java
index 03d8c34..667df44 100644
--- a/core/src/com/google/inject/spi/RequireAtInjectOnConstructorsOption.java
+++ b/core/src/com/google/inject/spi/RequireAtInjectOnConstructorsOption.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,14 +34,17 @@
     this.source = checkNotNull(source, "source");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).requireAtInjectOnConstructors();
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/core/src/com/google/inject/spi/RequireExactBindingAnnotationsOption.java b/core/src/com/google/inject/spi/RequireExactBindingAnnotationsOption.java
index ee52cfc..2cc91ff 100644
--- a/core/src/com/google/inject/spi/RequireExactBindingAnnotationsOption.java
+++ b/core/src/com/google/inject/spi/RequireExactBindingAnnotationsOption.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,14 +33,17 @@
     this.source = checkNotNull(source, "source");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).requireExactBindingAnnotations();
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/core/src/com/google/inject/spi/RequireExplicitBindingsOption.java b/core/src/com/google/inject/spi/RequireExplicitBindingsOption.java
index 5962eb7..ee6f210 100644
--- a/core/src/com/google/inject/spi/RequireExplicitBindingsOption.java
+++ b/core/src/com/google/inject/spi/RequireExplicitBindingsOption.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,14 +33,17 @@
     this.source = checkNotNull(source, "source");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).requireExplicitBindings();
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/core/src/com/google/inject/spi/ScopeBinding.java b/core/src/com/google/inject/spi/ScopeBinding.java
index 86ed685..563f5f5 100644
--- a/core/src/com/google/inject/spi/ScopeBinding.java
+++ b/core/src/com/google/inject/spi/ScopeBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +20,13 @@
 
 import com.google.inject.Binder;
 import com.google.inject.Scope;
-
 import java.lang.annotation.Annotation;
 
 /**
  * Registration of a scope annotation with the scope that implements it. Instances are created
  * explicitly in a module using {@link com.google.inject.Binder#bindScope(Class, Scope) bindScope()}
  * statements:
+ *
  * <pre>
  *     Scope recordScope = new RecordScope();
  *     bindScope(RecordScoped.class, new RecordScope());</pre>
@@ -45,6 +45,7 @@
     this.scope = checkNotNull(scope, "scope");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -57,10 +58,12 @@
     return scope;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).bindScope(annotationType, scope);
   }
diff --git a/core/src/com/google/inject/spi/StaticInjectionRequest.java b/core/src/com/google/inject/spi/StaticInjectionRequest.java
index 87e5376..fddba94 100644
--- a/core/src/com/google/inject/spi/StaticInjectionRequest.java
+++ b/core/src/com/google/inject/spi/StaticInjectionRequest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +20,13 @@
 
 import com.google.inject.Binder;
 import com.google.inject.ConfigurationException;
-
 import java.util.Set;
 
 /**
- * A request to inject the static fields and methods of a type. Requests are created
- * explicitly in a module using {@link com.google.inject.Binder#requestStaticInjection(Class[])
+ * A request to inject the static fields and methods of a type. Requests are created explicitly in a
+ * module using {@link com.google.inject.Binder#requestStaticInjection(Class[])
  * requestStaticInjection()} statements:
+ *
  * <pre>
  *     requestStaticInjection(MyLegacyService.class);</pre>
  *
@@ -42,6 +42,7 @@
     this.type = checkNotNull(type, "type");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -55,21 +56,23 @@
    * request.
    *
    * @return a possibly empty set of injection points. The set has a specified iteration order. All
-   *      fields are returned and then all methods. Within the fields, supertype fields are returned
-   *      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+   *     fields are returned and then all methods. Within the fields, supertype fields are returned
+   *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. The exception's {@link
-   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
-   *      of the valid injection points.
+   *     a field with multiple binding annotations. The exception's {@link
+   *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
+   *     the valid injection points.
    */
   public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException {
     return InjectionPoint.forStaticMethodsAndFields(type);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).requestStaticInjection(type);
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/core/src/com/google/inject/spi/Toolable.java b/core/src/com/google/inject/spi/Toolable.java
index ffabd9d..d09ab30 100644
--- a/core/src/com/google/inject/spi/Toolable.java
+++ b/core/src/com/google/inject/spi/Toolable.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
 
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
@@ -29,17 +28,16 @@
 /**
  * Instructs an {@link Injector} running in {@link Stage#TOOL} that a method should be injected.
  * This is typically useful for for extensions to Guice that perform additional validation in an
- * injected method or field.  This only applies to objects that are already constructed when
- * bindings are created (ie., something bound using {@link
+ * injected method or field. This only applies to objects that are already constructed when bindings
+ * are created (ie., something bound using {@link
  * com.google.inject.binder.LinkedBindingBuilder#toProvider toProvider}, {@link
  * com.google.inject.binder.LinkedBindingBuilder#toInstance toInstance}, or {@link
  * com.google.inject.Binder#requestInjection requestInjection}.
- * 
+ *
  * @author sberlin@gmail.com (Sam Berlin)
  * @since 3.0
  */
-@Target({ METHOD })
+@Target({METHOD})
 @Retention(RUNTIME)
 @Documented
-public @interface Toolable {
-}
+public @interface Toolable {}
diff --git a/core/src/com/google/inject/spi/TypeConverter.java b/core/src/com/google/inject/spi/TypeConverter.java
index 6dd07a3..473c0ad 100644
--- a/core/src/com/google/inject/spi/TypeConverter.java
+++ b/core/src/com/google/inject/spi/TypeConverter.java
@@ -26,8 +26,6 @@
  */
 public interface TypeConverter {
 
-  /**
-   * Converts a string value. Throws an exception if a conversion error occurs.
-   */
+  /** Converts a string value. Throws an exception if a conversion error occurs. */
   Object convert(String value, TypeLiteral<?> toType);
 }
diff --git a/core/src/com/google/inject/spi/TypeConverterBinding.java b/core/src/com/google/inject/spi/TypeConverterBinding.java
index 4478627..d54ad05 100644
--- a/core/src/com/google/inject/spi/TypeConverterBinding.java
+++ b/core/src/com/google/inject/spi/TypeConverterBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,11 +24,13 @@
 import com.google.inject.matcher.Matcher;
 
 /**
- * Registration of type converters for matching target types. Instances are created
- * explicitly in a module using {@link com.google.inject.Binder#convertToTypes(Matcher,
- * TypeConverter) convertToTypes()} statements:
+ * Registration of type converters for matching target types. Instances are created explicitly in a
+ * module using {@link com.google.inject.Binder#convertToTypes(Matcher, TypeConverter)
+ * convertToTypes()} statements:
+ *
  * <pre>
- *     convertToTypes(Matchers.only(TypeLiteral.get(DateTime.class)), new DateTimeConverter());</pre>
+ *     convertToTypes(Matchers.only(TypeLiteral.get(DateTime.class)), new DateTimeConverter());
+ * </pre>
  *
  * @author jessewilson@google.com (Jesse Wilson)
  * @since 2.0
@@ -39,13 +41,14 @@
   private final TypeConverter typeConverter;
 
   /** @since 3.0 */
-  public TypeConverterBinding(Object source, Matcher<? super TypeLiteral<?>> typeMatcher,
-      TypeConverter typeConverter) {
+  public TypeConverterBinding(
+      Object source, Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter typeConverter) {
     this.source = checkNotNull(source, "source");
     this.typeMatcher = checkNotNull(typeMatcher, "typeMatcher");
     this.typeConverter = checkNotNull(typeConverter, "typeConverter");
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
@@ -58,16 +61,23 @@
     return typeConverter;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).convertToTypes(typeMatcher, typeConverter);
   }
 
-  @Override public String toString() {
-    return typeConverter + " which matches " + typeMatcher
-        + " (bound at " + Errors.convert(source) + ")";
+  @Override
+  public String toString() {
+    return typeConverter
+        + " which matches "
+        + typeMatcher
+        + " (bound at "
+        + Errors.convert(source)
+        + ")";
   }
 }
diff --git a/core/src/com/google/inject/spi/TypeEncounter.java b/core/src/com/google/inject/spi/TypeEncounter.java
index 2ed0ee7..159d767 100644
--- a/core/src/com/google/inject/spi/TypeEncounter.java
+++ b/core/src/com/google/inject/spi/TypeEncounter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,13 +21,12 @@
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
 import com.google.inject.matcher.Matcher;
-
 import java.lang.reflect.Method;
 
 /**
  * Context of an injectable type encounter. Enables reporting errors, registering injection
- * listeners and binding method interceptors for injectable type {@code I}. It is an error to use
- * an encounter after the {@link TypeListener#hear(TypeLiteral, TypeEncounter) hear()} method has
+ * listeners and binding method interceptors for injectable type {@code I}. It is an error to use an
+ * encounter after the {@link TypeListener#hear(TypeLiteral, TypeEncounter) hear()} method has
  * returned.
  *
  * @param <I> the injectable type encountered
@@ -38,8 +37,8 @@
   /**
    * Records an error message for type {@code I} which will be presented to the user at a later
    * time. Unlike throwing an exception, this enable us to continue configuring the Injector and
-   * discover more errors. Uses {@link String#format(String, Object[])} to insert the arguments
-   * into the message.
+   * discover more errors. Uses {@link String#format(String, Object[])} to insert the arguments into
+   * the message.
    */
   void addError(String message, Object... arguments);
 
@@ -50,9 +49,7 @@
    */
   void addError(Throwable t);
 
-  /**
-   * Records an error message to be presented to the user at a later time.
-   */
+  /** Records an error message to be presented to the user at a later time. */
   void addError(Message message);
 
   /**
@@ -72,8 +69,8 @@
   /**
    * Returns the members injector used to inject dependencies into methods and fields on instances
    * of the given type {@code T}. The returned members injector will not be valid until the main
-   * injector has been created. The members injector will throw an {@code IllegalStateException}
-   * if you try to use it beforehand.
+   * injector has been created. The members injector will throw an {@code IllegalStateException} if
+   * you try to use it beforehand.
    *
    * @param typeLiteral type to get members injector for
    */
@@ -82,8 +79,8 @@
   /**
    * Returns the members injector used to inject dependencies into methods and fields on instances
    * of the given type {@code T}. The returned members injector will not be valid until the main
-   * injector has been created. The members injector will throw an {@code IllegalStateException}
-   * if you try to use it beforehand.
+   * injector has been created. The members injector will throw an {@code IllegalStateException} if
+   * you try to use it beforehand.
    *
    * @param type type to get members injector for
    */
@@ -103,20 +100,21 @@
 
   /*if[AOP]*/
   /**
-   * Binds method interceptor[s] to methods matched in type {@code I} and its supertypes. A
-   * method is eligible for interception if:
+   * Binds method interceptor[s] to methods matched in type {@code I} and its supertypes. A method
+   * is eligible for interception if:
    *
    * <ul>
-   *  <li>Guice created the instance the method is on</li>
-   *  <li>Neither the enclosing type nor the method is final</li>
-   *  <li>And the method is package-private or more accessible</li>
+   * <li>Guice created the instance the method is on
+   * <li>Neither the enclosing type nor the method is final
+   * <li>And the method is package-private or more accessible
    * </ul>
    *
-   * @param methodMatcher matches methods the interceptor should apply to. For
-   *     example: {@code annotatedWith(Transactional.class)}.
+   * @param methodMatcher matches methods the interceptor should apply to. For example: {@code
+   *     annotatedWith(Transactional.class)}.
    * @param interceptors to bind
    */
-  void bindInterceptor(Matcher<? super Method> methodMatcher,
+  void bindInterceptor(
+      Matcher<? super Method> methodMatcher,
       org.aopalliance.intercept.MethodInterceptor... interceptors);
   /*end[AOP]*/
 }
diff --git a/core/src/com/google/inject/spi/TypeListener.java b/core/src/com/google/inject/spi/TypeListener.java
index ed9d8d3..b0195ab 100644
--- a/core/src/com/google/inject/spi/TypeListener.java
+++ b/core/src/com/google/inject/spi/TypeListener.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,24 +25,22 @@
  *
  * <p>Useful for extra type checking, {@linkplain TypeEncounter#register(InjectionListener)
  * registering injection listeners}, and {@linkplain TypeEncounter#bindInterceptor(
- * com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
- * binding method interceptors}.
- * 
+ * com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[]) binding method
+ * interceptors}.
+ *
  * @since 2.0
  */
 public interface TypeListener {
 
   /**
-   * Invoked when Guice encounters a new type eligible for constructor or members injection.
-   * Called during injector creation (or afterwords if Guice encounters a type at run time and
-   * creates a JIT binding).
+   * Invoked when Guice encounters a new type eligible for constructor or members injection. Called
+   * during injector creation (or afterwards if Guice encounters a type at run time and creates a
+   * JIT binding).
    *
    * @param type encountered by Guice
    * @param encounter context of this encounter, enables reporting errors, registering injection
    *     listeners and binding method interceptors for {@code type}.
-   *
    * @param <I> the injectable type
    */
   <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter);
-
 }
diff --git a/core/src/com/google/inject/spi/TypeListenerBinding.java b/core/src/com/google/inject/spi/TypeListenerBinding.java
index 8ad4672..ec609cb 100644
--- a/core/src/com/google/inject/spi/TypeListenerBinding.java
+++ b/core/src/com/google/inject/spi/TypeListenerBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,8 +36,8 @@
   private final Matcher<? super TypeLiteral<?>> typeMatcher;
   private final TypeListener listener;
 
-  TypeListenerBinding(Object source, TypeListener listener,
-      Matcher<? super TypeLiteral<?>> typeMatcher) {
+  TypeListenerBinding(
+      Object source, TypeListener listener, Matcher<? super TypeLiteral<?>> typeMatcher) {
     this.source = source;
     this.listener = listener;
     this.typeMatcher = typeMatcher;
@@ -53,14 +53,17 @@
     return typeMatcher;
   }
 
+  @Override
   public Object getSource() {
     return source;
   }
 
+  @Override
   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
     return visitor.visit(this);
   }
 
+  @Override
   public void applyTo(Binder binder) {
     binder.withSource(getSource()).bindListener(typeMatcher, listener);
   }
diff --git a/core/src/com/google/inject/spi/UntargettedBinding.java b/core/src/com/google/inject/spi/UntargettedBinding.java
index 4f6f823..c605c94 100644
--- a/core/src/com/google/inject/spi/UntargettedBinding.java
+++ b/core/src/com/google/inject/spi/UntargettedBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/core/src/com/google/inject/spi/package-info.java b/core/src/com/google/inject/spi/package-info.java
index 1224837..c217d26 100644
--- a/core/src/com/google/inject/spi/package-info.java
+++ b/core/src/com/google/inject/spi/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Guice service provider interface
- */
+/** Guice service provider interface */
 package com.google.inject.spi;
diff --git a/core/src/com/google/inject/util/Modules.java b/core/src/com/google/inject/util/Modules.java
index 08ec92c..5378392 100644
--- a/core/src/com/google/inject/util/Modules.java
+++ b/core/src/com/google/inject/util/Modules.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,7 +39,6 @@
 import com.google.inject.spi.ModuleAnnotatedMethodScannerBinding;
 import com.google.inject.spi.PrivateElements;
 import com.google.inject.spi.ScopeBinding;
-
 import java.lang.annotation.Annotation;
 import java.util.Arrays;
 import java.util.LinkedHashSet;
@@ -55,19 +54,22 @@
  */
 public final class Modules {
   private Modules() {}
-  
+
   public static final Module EMPTY_MODULE = new EmptyModule();
+
   private static class EmptyModule implements Module {
+    @Override
     public void configure(Binder binder) {}
   }
 
   /**
-   * Returns a builder that creates a module that overlays override modules over the given
-   * modules. If a key is bound in both sets of modules, only the binding from the override modules
-   * is kept. If a single {@link PrivateModule} is supplied or all elements are from
-   * a single {@link PrivateBinder}, then this will overwrite the private bindings.
-   * Otherwise, private bindings will not be overwritten unless they are exposed. 
-   * This can be used to replace the bindings of a production module with test bindings:
+   * Returns a builder that creates a module that overlays override modules over the given modules.
+   * If a key is bound in both sets of modules, only the binding from the override modules is kept.
+   * If a single {@link PrivateModule} is supplied or all elements are from a single {@link
+   * PrivateBinder}, then this will overwrite the private bindings. Otherwise, private bindings will
+   * not be overwritten unless they are exposed. This can be used to replace the bindings of a
+   * production module with test bindings:
+   *
    * <pre>
    * Module functionalTestModule
    *     = Modules.override(new ProductionModule()).with(new TestModule());
@@ -82,12 +84,13 @@
   }
 
   /**
-   * Returns a builder that creates a module that overlays override modules over the given
-   * modules. If a key is bound in both sets of modules, only the binding from the override modules
-   * is kept. If a single {@link PrivateModule} is supplied or all elements are from
-   * a single {@link PrivateBinder}, then this will overwrite the private bindings.
-   * Otherwise, private bindings will not be overwritten unless they are exposed. 
-   * This can be used to replace the bindings of a production module with test bindings:
+   * Returns a builder that creates a module that overlays override modules over the given modules.
+   * If a key is bound in both sets of modules, only the binding from the override modules is kept.
+   * If a single {@link PrivateModule} is supplied or all elements are from a single {@link
+   * PrivateBinder}, then this will overwrite the private bindings. Otherwise, private bindings will
+   * not be overwritten unless they are exposed. This can be used to replace the bindings of a
+   * production module with test bindings:
+   *
    * <pre>
    * Module functionalTestModule
    *     = Modules.override(getProductionModules()).with(getTestModules());
@@ -101,27 +104,24 @@
     return new RealOverriddenModuleBuilder(modules);
   }
 
-  /**
-   * Returns a new module that installs all of {@code modules}.
-   */
+  /** Returns a new module that installs all of {@code modules}. */
   public static Module combine(Module... modules) {
     return combine(ImmutableSet.copyOf(modules));
   }
 
-  /**
-   * Returns a new module that installs all of {@code modules}.
-   */
+  /** Returns a new module that installs all of {@code modules}. */
   public static Module combine(Iterable<? extends Module> modules) {
     return new CombinedModule(modules);
   }
-  
+
   private static class CombinedModule implements Module {
     final Set<Module> modulesSet;
-    
+
     CombinedModule(Iterable<? extends Module> modules) {
       this.modulesSet = ImmutableSet.copyOf(modules);
     }
-    
+
+    @Override
     public void configure(Binder binder) {
       binder = binder.skipSources(getClass());
       for (Module module : modulesSet) {
@@ -130,19 +130,13 @@
     }
   }
 
-  /**
-   * See the EDSL example at {@link Modules#override(Module[]) override()}.
-   */
+  /** See the EDSL example at {@link Modules#override(Module[]) override()}. */
   public interface OverriddenModuleBuilder {
 
-    /**
-     * See the EDSL example at {@link Modules#override(Module[]) override()}.
-     */
+    /** See the EDSL example at {@link Modules#override(Module[]) override()}. */
     Module with(Module... overrides);
 
-    /**
-     * See the EDSL example at {@link Modules#override(Module[]) override()}.
-     */
+    /** See the EDSL example at {@link Modules#override(Module[]) override()}. */
     Module with(Iterable<? extends Module> overrides);
   }
 
@@ -153,19 +147,21 @@
       this.baseModules = ImmutableSet.copyOf(baseModules);
     }
 
+    @Override
     public Module with(Module... overrides) {
       return with(Arrays.asList(overrides));
     }
 
+    @Override
     public Module with(Iterable<? extends Module> overrides) {
       return new OverrideModule(overrides, baseModules);
     }
   }
-  
+
   static class OverrideModule extends AbstractModule {
     private final ImmutableSet<Module> overrides;
     private final ImmutableSet<Module> baseModules;
-    
+
     OverrideModule(Iterable<? extends Module> overrides, ImmutableSet<Module> baseModules) {
       this.overrides = ImmutableSet.copyOf(overrides);
       this.baseModules = baseModules;
@@ -179,24 +175,27 @@
       // If the sole element was a PrivateElements, we want to override
       // the private elements within that -- so refocus our elements
       // and binder.
-      if(baseElements.size() == 1) {
+      if (baseElements.size() == 1) {
         Element element = Iterables.getOnlyElement(baseElements);
-        if(element instanceof PrivateElements) {
-          PrivateElements privateElements = (PrivateElements)element;
-          PrivateBinder privateBinder = baseBinder.newPrivateBinder().withSource(privateElements.getSource());
-          for(Key exposed : privateElements.getExposedKeys()) {
+        if (element instanceof PrivateElements) {
+          PrivateElements privateElements = (PrivateElements) element;
+          PrivateBinder privateBinder =
+              baseBinder.newPrivateBinder().withSource(privateElements.getSource());
+          for (Key exposed : privateElements.getExposedKeys()) {
             privateBinder.withSource(privateElements.getExposedSource(exposed)).expose(exposed);
           }
           baseBinder = privateBinder;
           baseElements = privateElements.getElements();
         }
       }
-      
+
       final Binder binder = baseBinder.skipSources(this.getClass());
-      final LinkedHashSet<Element> elements = new LinkedHashSet<Element>(baseElements);
+      final LinkedHashSet<Element> elements = new LinkedHashSet<>(baseElements);
       final Module scannersModule = extractScanners(elements);
-      final List<Element> overrideElements = Elements.getElements(currentStage(),
-          ImmutableList.<Module>builder().addAll(overrides).add(scannersModule).build());
+      final List<Element> overrideElements =
+          Elements.getElements(
+              currentStage(),
+              ImmutableList.<Module>builder().addAll(overrides).add(scannersModule).build());
 
       final Set<Key<?>> overriddenKeys = Sets.newHashSet();
       final Map<Class<? extends Annotation>, ScopeBinding> overridesScopeAnnotations =
@@ -204,17 +203,20 @@
 
       // execute the overrides module, keeping track of which keys and scopes are bound
       new ModuleWriter(binder) {
-        @Override public <T> Void visit(Binding<T> binding) {
+        @Override
+        public <T> Void visit(Binding<T> binding) {
           overriddenKeys.add(binding.getKey());
           return super.visit(binding);
         }
 
-        @Override public Void visit(ScopeBinding scopeBinding) {
+        @Override
+        public Void visit(ScopeBinding scopeBinding) {
           overridesScopeAnnotations.put(scopeBinding.getAnnotationType(), scopeBinding);
           return super.visit(scopeBinding);
         }
 
-        @Override public Void visit(PrivateElements privateElements) {
+        @Override
+        public Void visit(PrivateElements privateElements) {
           overriddenKeys.addAll(privateElements.getExposedKeys());
           return super.visit(privateElements);
         }
@@ -226,7 +228,8 @@
       final Map<Scope, List<Object>> scopeInstancesInUse = Maps.newHashMap();
       final List<ScopeBinding> scopeBindings = Lists.newArrayList();
       new ModuleWriter(binder) {
-        @Override public <T> Void visit(Binding<T> binding) {
+        @Override
+        public <T> Void visit(Binding<T> binding) {
           if (!overriddenKeys.remove(binding.getKey())) {
             super.visit(binding);
 
@@ -246,8 +249,8 @@
         }
 
         void rewrite(Binder binder, PrivateElements privateElements, Set<Key<?>> keysToSkip) {
-          PrivateBinder privateBinder = binder.withSource(privateElements.getSource())
-              .newPrivateBinder();
+          PrivateBinder privateBinder =
+              binder.withSource(privateElements.getSource()).newPrivateBinder();
 
           Set<Key<?>> skippedExposes = Sets.newHashSet();
 
@@ -260,8 +263,7 @@
           }
 
           for (Element element : privateElements.getElements()) {
-            if (element instanceof Binding
-                && skippedExposes.remove(((Binding) element).getKey())) {
+            if (element instanceof Binding && skippedExposes.remove(((Binding) element).getKey())) {
               continue;
             }
             if (element instanceof PrivateElements) {
@@ -272,12 +274,14 @@
           }
         }
 
-        @Override public Void visit(PrivateElements privateElements) {
+        @Override
+        public Void visit(PrivateElements privateElements) {
           rewrite(binder, privateElements, overriddenKeys);
           return null;
         }
 
-        @Override public Void visit(ScopeBinding scopeBinding) {
+        @Override
+        public Void visit(ScopeBinding scopeBinding) {
           scopeBindings.add(scopeBinding);
           return null;
         }
@@ -286,7 +290,8 @@
       // execute the scope bindings, skipping scopes that have been overridden. Any scope that
       // is overridden and in active use will prompt an error
       new ModuleWriter(binder) {
-        @Override public Void visit(ScopeBinding scopeBinding) {
+        @Override
+        public Void visit(ScopeBinding scopeBinding) {
           ScopeBinding overideBinding =
               overridesScopeAnnotations.remove(scopeBinding.getAnnotationType());
           if (overideBinding == null) {
@@ -294,13 +299,15 @@
           } else {
             List<Object> usedSources = scopeInstancesInUse.get(scopeBinding.getScope());
             if (usedSources != null) {
-              StringBuilder sb = new StringBuilder(
-                  "The scope for @%s is bound directly and cannot be overridden.");
+              StringBuilder sb =
+                  new StringBuilder(
+                      "The scope for @%s is bound directly and cannot be overridden.");
               sb.append("%n     original binding at " + Errors.convert(scopeBinding.getSource()));
               for (Object usedSource : usedSources) {
                 sb.append("%n     bound directly at " + Errors.convert(usedSource) + "");
               }
-              binder.withSource(overideBinding.getSource())
+              binder
+                  .withSource(overideBinding.getSource())
                   .addError(sb.toString(), scopeBinding.getAnnotationType().getSimpleName());
             }
           }
@@ -310,11 +317,13 @@
     }
 
     private Scope getScopeInstanceOrNull(Binding<?> binding) {
-      return binding.acceptScopingVisitor(new DefaultBindingScopingVisitor<Scope>() {
-        @Override public Scope visitScope(Scope scope) {
-          return scope;
-        }
-      });
+      return binding.acceptScopingVisitor(
+          new DefaultBindingScopingVisitor<Scope>() {
+            @Override
+            public Scope visitScope(Scope scope) {
+              return scope;
+            }
+          });
     }
   }
 
@@ -325,7 +334,8 @@
       this.binder = binder.skipSources(this.getClass());
     }
 
-    @Override protected Void visitOther(Element element) {
+    @Override
+    protected Void visitOther(Element element) {
       element.applyTo(binder);
       return null;
     }
@@ -339,17 +349,20 @@
 
   private static Module extractScanners(Iterable<Element> elements) {
     final List<ModuleAnnotatedMethodScannerBinding> scanners = Lists.newArrayList();
-    ElementVisitor<Void> visitor = new DefaultElementVisitor<Void>() {
-      @Override public Void visit(ModuleAnnotatedMethodScannerBinding binding) {
-        scanners.add(binding);
-        return null;
-      }
-    };
+    ElementVisitor<Void> visitor =
+        new DefaultElementVisitor<Void>() {
+          @Override
+          public Void visit(ModuleAnnotatedMethodScannerBinding binding) {
+            scanners.add(binding);
+            return null;
+          }
+        };
     for (Element element : elements) {
       element.acceptVisitor(visitor);
     }
     return new AbstractModule() {
-      @Override protected void configure() {
+      @Override
+      protected void configure() {
         for (ModuleAnnotatedMethodScannerBinding scanner : scanners) {
           scanner.applyTo(binder());
         }
diff --git a/core/src/com/google/inject/util/Providers.java b/core/src/com/google/inject/util/Providers.java
index c18d351..f8c5d21 100644
--- a/core/src/com/google/inject/util/Providers.java
+++ b/core/src/com/google/inject/util/Providers.java
@@ -27,12 +27,10 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.ProviderWithDependencies;
-
 import java.util.Set;
 
 /**
- * Static utility methods for creating and working with instances of
- * {@link Provider}.
+ * Static utility methods for creating and working with instances of {@link Provider}.
  *
  * @author Kevin Bourrillion (kevinb9n@gmail.com)
  * @since 2.0
@@ -42,13 +40,12 @@
   private Providers() {}
 
   /**
-   * Returns a provider which always provides {@code instance}.  This should not
-   * be necessary to use in your application, but is helpful for several types
-   * of unit tests.
+   * Returns a provider which always provides {@code instance}. This should not be necessary to use
+   * in your application, but is helpful for several types of unit tests.
    *
-   * @param instance the instance that should always be provided.  This is also
-   *     permitted to be null, to enable aggressive testing, although in real
-   *     life a Guice-supplied Provider will never return null.
+   * @param instance the instance that should always be provided. This is also permitted to be null,
+   *     to enable aggressive testing, although in real life a Guice-supplied Provider will never
+   *     return null.
    */
   public static <T> Provider<T> of(final T instance) {
     return new ConstantProvider<T>(instance);
@@ -61,46 +58,50 @@
       this.instance = instance;
     }
 
+    @Override
     public T get() {
       return instance;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "of(" + instance + ")";
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
       return (obj instanceof ConstantProvider)
           && Objects.equal(instance, ((ConstantProvider<?>) obj).instance);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return Objects.hashCode(instance);
     }
   }
 
   /**
-   * Returns a Guice-friendly {@code com.google.inject.Provider} for the given
-   * JSR-330 {@code javax.inject.Provider}. The converse method is unnecessary,
-   * since Guice providers directly implement the JSR-330 interface.
-   * 
+   * Returns a Guice-friendly {@code com.google.inject.Provider} for the given JSR-330 {@code
+   * javax.inject.Provider}. The converse method is unnecessary, since Guice providers directly
+   * implement the JSR-330 interface.
+   *
    * @since 3.0
    */
   public static <T> Provider<T> guicify(javax.inject.Provider<T> provider) {
     if (provider instanceof Provider) {
       return (Provider<T>) provider;
     }
-  
+
     final javax.inject.Provider<T> delegate = checkNotNull(provider, "provider");
-    
+
     // Ensure that we inject all injection points from the delegate provider.
     Set<InjectionPoint> injectionPoints =
         InjectionPoint.forInstanceMethodsAndFields(provider.getClass());
-    if(injectionPoints.isEmpty()) {
+    if (injectionPoints.isEmpty()) {
       return new GuicifiedProvider<T>(delegate);
     } else {
       Set<Dependency<?>> mutableDeps = Sets.newHashSet();
-      for(InjectionPoint ip : injectionPoints) {
+      for (InjectionPoint ip : injectionPoints) {
         mutableDeps.addAll(ip.getDependencies());
       }
       final Set<Dependency<?>> dependencies = ImmutableSet.copyOf(mutableDeps);
@@ -115,30 +116,34 @@
       this.delegate = delegate;
     }
 
+    @Override
     public T get() {
       return delegate.get();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "guicified(" + delegate + ")";
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
       return (obj instanceof GuicifiedProvider)
           && Objects.equal(delegate, ((GuicifiedProvider<?>) obj).delegate);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return Objects.hashCode(delegate);
     }
   }
 
-  private static final class GuicifiedProviderWithDependencies<T>
-      extends GuicifiedProvider<T> implements ProviderWithDependencies<T> {
+  private static final class GuicifiedProviderWithDependencies<T> extends GuicifiedProvider<T>
+      implements ProviderWithDependencies<T> {
     private final Set<Dependency<?>> dependencies;
 
-    private GuicifiedProviderWithDependencies(Set<Dependency<?>> dependencies,
-        javax.inject.Provider<T> delegate) {
+    private GuicifiedProviderWithDependencies(
+        Set<Dependency<?>> dependencies, javax.inject.Provider<T> delegate) {
       super(delegate);
       this.dependencies = dependencies;
     }
@@ -149,6 +154,7 @@
       injector.injectMembers(delegate);
     }
 
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return dependencies;
     }
diff --git a/core/src/com/google/inject/util/Types.java b/core/src/com/google/inject/util/Types.java
index c3b3a2a..32714cc 100644
--- a/core/src/com/google/inject/util/Types.java
+++ b/core/src/com/google/inject/util/Types.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.util;
 
 import com.google.inject.Provider;
@@ -22,11 +21,11 @@
 import com.google.inject.internal.MoreTypes.GenericArrayTypeImpl;
 import com.google.inject.internal.MoreTypes.ParameterizedTypeImpl;
 import com.google.inject.internal.MoreTypes.WildcardTypeImpl;
-
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.WildcardType;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -41,8 +40,8 @@
   private Types() {}
 
   /**
-   * Returns a new parameterized type, applying {@code typeArguments} to
-   * {@code rawType}. The returned type does not have an owner type.
+   * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType}. The
+   * returned type does not have an owner type.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
@@ -51,8 +50,8 @@
   }
 
   /**
-   * Returns a new parameterized type, applying {@code typeArguments} to
-   * {@code rawType} and enclosed by {@code ownerType}.
+   * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType} and
+   * enclosed by {@code ownerType}.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
@@ -62,8 +61,7 @@
   }
 
   /**
-   * Returns an array type whose elements are all instances of
-   * {@code componentType}.
+   * Returns an array type whose elements are all instances of {@code componentType}.
    *
    * @return a {@link java.io.Serializable serializable} generic array type.
    */
@@ -72,27 +70,25 @@
   }
 
   /**
-   * Returns a type that represents an unknown type that extends {@code bound}.
-   * For example, if {@code bound} is {@code CharSequence.class}, this returns
-   * {@code ? extends CharSequence}. If {@code bound} is {@code Object.class},
-   * this returns {@code ?}, which is shorthand for {@code ? extends Object}.
+   * Returns a type that represents an unknown type that extends {@code bound}. For example, if
+   * {@code bound} is {@code CharSequence.class}, this returns {@code ? extends CharSequence}. If
+   * {@code bound} is {@code Object.class}, this returns {@code ?}, which is shorthand for {@code ?
+   * extends Object}.
    */
   public static WildcardType subtypeOf(Type bound) {
-    return new WildcardTypeImpl(new Type[] { bound }, MoreTypes.EMPTY_TYPE_ARRAY);
+    return new WildcardTypeImpl(new Type[] {bound}, MoreTypes.EMPTY_TYPE_ARRAY);
   }
 
   /**
-   * Returns a type that represents an unknown supertype of {@code bound}. For
-   * example, if {@code bound} is {@code String.class}, this returns {@code ?
-   * super String}.
+   * Returns a type that represents an unknown supertype of {@code bound}. For example, if {@code
+   * bound} is {@code String.class}, this returns {@code ? super String}.
    */
   public static WildcardType supertypeOf(Type bound) {
-    return new WildcardTypeImpl(new Type[] { Object.class }, new Type[] { bound });
+    return new WildcardTypeImpl(new Type[] {Object.class}, new Type[] {bound});
   }
 
   /**
-   * Returns a type modelling a {@link List} whose elements are of type
-   * {@code elementType}.
+   * Returns a type modelling a {@link List} whose elements are of type {@code elementType}.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
@@ -101,8 +97,16 @@
   }
 
   /**
-   * Returns a type modelling a {@link Set} whose elements are of type
-   * {@code elementType}.
+   * Returns a type modelling a {@link Collection} whose elements are of type {@code elementType}.
+   *
+   * @return a {@link java.io.Serializable serializable} parameterized type.
+   */
+  public static ParameterizedType collectionOf(Type elementType) {
+    return newParameterizedType(Collection.class, elementType);
+  }
+
+  /**
+   * Returns a type modelling a {@link Set} whose elements are of type {@code elementType}.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
@@ -111,8 +115,8 @@
   }
 
   /**
-   * Returns a type modelling a {@link Map} whose keys are of type
-   * {@code keyType} and whose values are of type {@code valueType}.
+   * Returns a type modelling a {@link Map} whose keys are of type {@code keyType} and whose values
+   * are of type {@code valueType}.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
@@ -123,12 +127,21 @@
   // for other custom collections types, use newParameterizedType()
 
   /**
-   * Returns a type modelling a {@link Provider} that provides elements of type
-   * {@code elementType}.
+   * Returns a type modelling a {@link Provider} that provides elements of type {@code elementType}.
    *
    * @return a {@link java.io.Serializable serializable} parameterized type.
    */
   public static ParameterizedType providerOf(Type providedType) {
     return newParameterizedType(Provider.class, providedType);
   }
-}
\ No newline at end of file
+
+  /**
+   * Returns a type modelling a {@link javax.inject.Provider} that provides elements of type {@code
+   * elementType}.
+   *
+   * @return a {@link java.io.Serializable serializable} parameterized type.
+   */
+  public static Type javaxProviderOf(Type type) {
+    return Types.newParameterizedType(javax.inject.Provider.class, type);
+  }
+}
diff --git a/core/src/com/google/inject/util/package-info.java b/core/src/com/google/inject/util/package-info.java
index 89c5de2..3ebb87c 100644
--- a/core/src/com/google/inject/util/package-info.java
+++ b/core/src/com/google/inject/util/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Helper methods for working with Guice.
- */
-package com.google.inject.util;
\ No newline at end of file
+/** Helper methods for working with Guice. */
+package com.google.inject.util;
diff --git a/core/test/com/google/inject/AllTests.java b/core/test/com/google/inject/AllTests.java
index f700608..8324708 100644
--- a/core/test/com/google/inject/AllTests.java
+++ b/core/test/com/google/inject/AllTests.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,6 +31,7 @@
 import com.google.inject.spi.HasDependenciesTest;
 import com.google.inject.spi.InjectionPointTest;
 import com.google.inject.spi.InjectorSpiTest;
+import com.google.inject.spi.MessageTest;
 import com.google.inject.spi.ModuleAnnotatedMethodScannerTest;
 import com.google.inject.spi.ModuleRewriterTest;
 import com.google.inject.spi.ModuleSourceTest;
@@ -41,24 +42,18 @@
 import com.google.inject.util.OverrideModuleTest;
 import com.google.inject.util.ProvidersTest;
 import com.google.inject.util.TypesTest;
-
 import com.googlecode.guice.GuiceTck;
 import com.googlecode.guice.Jsr330Test;
-
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
-import java.util.Set;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class AllTests {
 
-  private static final Set<String> SUPPRESSED_TEST_NAMES = ImmutableSet.of(
-      "testUnscopedProviderWorksOutsideOfRequestedScope(" + ScopesTest.class.getName() + ")",
-      "testCannotConvertUnannotatedBindings(" + TypeConversionTest.class.getName() + ")"
-  );
+  private static final ImmutableSet<String> SUPPRESSED_TEST_NAMES =
+      ImmutableSet.of(
+          "testUnscopedProviderWorksOutsideOfRequestedScope(" + ScopesTest.class.getName() + ")",
+          "testCannotConvertUnannotatedBindings(" + TypeConversionTest.class.getName() + ")");
 
   public static Test suite() {
     TestSuite suite = new TestSuite();
@@ -134,6 +129,7 @@
     suite.addTestSuite(ToolStageInjectorTest.class);
     suite.addTestSuite(ModuleSourceTest.class);
     suite.addTestSuite(ElementSourceTest.class);
+    suite.addTestSuite(MessageTest.class);
 
     // tools
     // suite.addTestSuite(JmxTest.class); not a testcase
@@ -154,6 +150,13 @@
     suite.addTestSuite(com.googlecode.guice.OSGiContainerTest.class);
     suite.addTestSuite(Jsr330Test.class);
 
+    // multibindings tests
+    suite.addTestSuite(com.google.inject.internal.MapBinderTest.class);
+    suite.addTestSuite(com.google.inject.internal.MultibinderTest.class);
+    suite.addTestSuite(com.google.inject.internal.OptionalBinderTest.class);
+    suite.addTestSuite(com.google.inject.internal.RealElementTest.class);
+    suite.addTestSuite(com.google.inject.multibindings.ProvidesIntoTest.class);
+
     return SuiteUtils.removeSuppressedTests(suite, SUPPRESSED_TEST_NAMES);
   }
 }
diff --git a/core/test/com/google/inject/Asserts.java b/core/test/com/google/inject/Asserts.java
index 6c63158..9b1b2e0 100644
--- a/core/test/com/google/inject/Asserts.java
+++ b/core/test/com/google/inject/Asserts.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-
 package com.google.inject;
 
-import static com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH;
+import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;
 import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
@@ -26,43 +26,51 @@
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.testing.GcFinalization;
-
-import junit.framework.Assert;
-
+import com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.NotSerializableException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import junit.framework.Assert;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class Asserts {
+
   private Asserts() {}
 
   /**
-   * Returns the String that would appear in an error message for this chain of classes 
-   * as modules.
+   * Returns the String that would appear in an error message for this chain of classes as modules.
    */
   public static String asModuleChain(Class... classes) {
-    return Joiner.on(" -> ").appendTo(new StringBuilder(" (via modules: "),
-        Iterables.transform(ImmutableList.copyOf(classes), new Function<Class, String>() {
-          @Override
-          public String apply(Class input) {
-            return input.getName();
-          }
-        })).append(")").toString();
+    return Joiner.on(" -> ")
+        .appendTo(
+            new StringBuilder(" (via modules: "),
+            Iterables.transform(
+                ImmutableList.copyOf(classes),
+                new Function<Class, String>() {
+                  @Override
+                  public String apply(Class input) {
+                    return input.getName();
+                  }
+                }))
+        .append(")")
+        .toString();
   }
 
   /**
-   * Returns the source file appears in error messages based on {@link 
+   * Returns the source file appears in error messages based on {@link
    * #getIncludeStackTraceOption()} value.
    */
   public static String getDeclaringSourcePart(Class clazz) {
@@ -89,9 +97,8 @@
   }
 
   /**
-   * Fails unless {@code expected.equals(actual)}, {@code
-   * actual.equals(expected)} and their hash codes are equal. This is useful
-   * for testing the equals method itself.
+   * Fails unless {@code expected.equals(actual)}, {@code actual.equals(expected)} and their hash
+   * codes are equal. This is useful for testing the equals method itself.
    */
   public static void assertEqualsBothWays(Object expected, Object actual) {
     assertNotNull(expected);
@@ -101,10 +108,16 @@
     assertEquals("hashCode", expected.hashCode(), actual.hashCode());
   }
 
-  /**
-   * Fails unless {@code text} includes all {@code substrings}, in order.
-   */
+  /** Fails unless {@code text} includes all {@code substrings}, in order, no duplicates */
   public static void assertContains(String text, String... substrings) {
+    assertContains(text, false, substrings);
+  }
+
+  /**
+   * Fails unless {@code text} includes all {@code substrings}, in order, and optionally {@code
+   * allowDuplicates}.
+   */
+  public static void assertContains(String text, boolean allowDuplicates, String... substrings) {
     /*if[NO_AOP]
     // when we strip out bytecode manipulation, we lose the ability to generate some source lines.
     if (text.contains("(Unknown Source)")) {
@@ -115,29 +128,29 @@
     int startingFrom = 0;
     for (String substring : substrings) {
       int index = text.indexOf(substring, startingFrom);
-      assertTrue(String.format("Expected \"%s\" to contain substring \"%s\"", text, substring),
+      assertTrue(
+          String.format("Expected \"%s\" to contain substring \"%s\"", text, substring),
           index >= startingFrom);
       startingFrom = index + substring.length();
     }
 
-    String lastSubstring = substrings[substrings.length - 1];
-    assertTrue(String.format("Expected \"%s\" to contain substring \"%s\" only once),",
-        text, lastSubstring), text.indexOf(lastSubstring, startingFrom) == -1);
+    if (!allowDuplicates) {
+      String lastSubstring = substrings[substrings.length - 1];
+      assertTrue(
+          String.format(
+              "Expected \"%s\" to contain substring \"%s\" only once),", text, lastSubstring),
+          text.indexOf(lastSubstring, startingFrom) == -1);
+    }
   }
 
-  /**
-   * Fails unless {@code object} doesn't equal itself when reserialized.
-   */
-  public static void assertEqualWhenReserialized(Object object)
-      throws IOException {
+  /** Fails unless {@code object} doesn't equal itself when reserialized. */
+  public static void assertEqualWhenReserialized(Object object) throws IOException {
     Object reserialized = reserialize(object);
     assertEquals(object, reserialized);
     assertEquals(object.hashCode(), reserialized.hashCode());
   }
 
-  /**
-   * Fails unless {@code object} has the same toString value when reserialized.
-   */
+  /** Fails unless {@code object} has the same toString value when reserialized. */
   public static void assertSimilarWhenReserialized(Object object) throws IOException {
     Object reserialized = reserialize(object);
     assertEquals(object.toString(), reserialized.toString());
@@ -167,8 +180,8 @@
   public static void awaitFullGc() {
     // GcFinalization *should* do it, but doesn't work well in practice...
     // so we put a second latch and wait for a ReferenceQueue to tell us.
-    ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
-    WeakReference ref = new WeakReference<Object>(new Object(), queue);
+    ReferenceQueue<Object> queue = new ReferenceQueue<>();
+    WeakReference<Object> ref = new WeakReference<>(new Object(), queue);
     GcFinalization.awaitFullGc();
     try {
       assertSame("queue didn't return ref in time", ref, queue.remove(5000));
@@ -186,8 +199,8 @@
     ReferenceQueue<Object> queue = null;
     WeakReference extraRef = null;
     if (data != null) {
-      queue = new ReferenceQueue<Object>();
-      extraRef = new WeakReference<Object>(data, queue);
+      queue = new ReferenceQueue<>();
+      extraRef = new WeakReference<>(data, queue);
       data = null;
     }
     GcFinalization.awaitClear(ref);
@@ -201,4 +214,27 @@
       }
     }
   }
+
+  /** Returns the URLs in the system class path. */
+  // TODO(https://github.com/google/guava/issues/2956): Use a common API once that's available.
+  public static URL[] getClassPathUrls() {
+    if (Asserts.class.getClassLoader() instanceof URLClassLoader) {
+      return ((URLClassLoader) Asserts.class.getClassLoader()).getURLs();
+    }
+    ImmutableList.Builder<URL> urls = ImmutableList.builder();
+    for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
+      try {
+        try {
+          urls.add(new File(entry).toURI().toURL());
+        } catch (SecurityException e) { // File.toURI checks to see if the file is a directory
+          urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
+        }
+      } catch (MalformedURLException e) {
+        AssertionError error = new AssertionError("malformed class path entry: " + entry);
+        error.initCause(e);
+        throw error;
+      }
+    }
+    return urls.build().toArray(new URL[0]);
+  }
 }
diff --git a/core/test/com/google/inject/BinderTest.java b/core/test/com/google/inject/BinderTest.java
index fb8f2c5..c7d489d 100644
--- a/core/test/com/google/inject/BinderTest.java
+++ b/core/test/com/google/inject/BinderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,17 +20,14 @@
 import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.Asserts.assertNotSerializable;
 import static com.google.inject.Asserts.getDeclaringSourcePart;
-import static com.google.inject.Asserts.isIncludeStackTraceOff;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import com.google.inject.internal.Annotations;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
 import com.google.inject.spi.Message;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Comparator;
 import java.util.Date;
@@ -39,48 +36,57 @@
 import java.util.logging.Handler;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class BinderTest extends TestCase {
 
   private final Logger loggerToWatch = Logger.getLogger(Guice.class.getName());
 
   private final List<LogRecord> logRecords = Lists.newArrayList();
-  private final Handler fakeHandler = new Handler() {
-    @Override
-    public void publish(LogRecord logRecord) {
-      logRecords.add(logRecord);
-    }
-    @Override
-    public void flush() {}
-    @Override
-    public void close() throws SecurityException {}
-  };
+  private final Handler fakeHandler =
+      new Handler() {
+        @Override
+        public void publish(LogRecord logRecord) {
+          logRecords.add(logRecord);
+        }
+
+        @Override
+        public void flush() {}
+
+        @Override
+        public void close() throws SecurityException {}
+      };
 
   Provider<Foo> fooProvider;
 
-  @Override protected void setUp() throws Exception {
+  @Override
+  protected void setUp() throws Exception {
     super.setUp();
     loggerToWatch.addHandler(fakeHandler);
   }
 
-  @Override protected void tearDown() throws Exception {
+  @Override
+  protected void tearDown() throws Exception {
     loggerToWatch.removeHandler(fakeHandler);
     super.tearDown();
   }
 
   public void testProviderFromBinder() {
-    Guice.createInjector(new Module() {
-      public void configure(Binder binder) {
-        fooProvider = binder.getProvider(Foo.class);
+    Guice.createInjector(
+        new Module() {
+          @Override
+          public void configure(Binder binder) {
+            fooProvider = binder.getProvider(Foo.class);
 
-        try {
-          fooProvider.get();
-        } catch (IllegalStateException e) { /* expected */ }
-      }
-    });
+            try {
+              fooProvider.get();
+              fail();
+            } catch (IllegalStateException e) {
+              /* expected */
+            }
+          }
+        });
 
     assertNotNull(fooProvider.get());
   }
@@ -89,55 +95,84 @@
 
   public void testMissingBindings() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        public void configure() {
-          getProvider(Runnable.class);
-          bind(Comparator.class);
-          requireBinding(Key.get(new TypeLiteral<Callable<String>>() {}));
-          bind(Date.class).annotatedWith(Names.named("date"));
-        }
-      });
+      Guice.createInjector(
+          // We put each binding in a separate module so the order of the error messages doesn't
+          // depend on line numbers
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              getProvider(Runnable.class);
+            }
+          },
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              bind(Comparator.class);
+            }
+          },
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              requireBinding(Key.get(new TypeLiteral<Callable<String>>() {}));
+            }
+          },
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              bind(Date.class).annotatedWith(Names.named("date"));
+            }
+          });
+      fail("Expected CreationException");
     } catch (CreationException e) {
       assertEquals(4, e.getErrorMessages().size());
-      String segment1 = "No implementation for " + Comparator.class.getName() + " was bound.";
-      String segment2 = "No implementation for java.util.Date annotated with @"
-          + Named.class.getName() + "(value=date) was bound.";
-      String segment3 = "No implementation for java.lang.Runnable was bound.";
-      String segment4 = " No implementation for java.util.concurrent.Callable<java.lang.String> was"
-          + " bound.";
+      String segment1 = "No implementation for java.lang.Runnable was bound.";
+      String segment2 = "No implementation for " + Comparator.class.getName() + " was bound.";
+      String segment3 =
+          "No implementation for java.util.concurrent.Callable<java.lang.String> was" + " bound.";
+      String segment4 =
+          "No implementation for java.util.Date annotated with @"
+              + Named.class.getName()
+              + "(value="
+              + Annotations.memberValueString("date")
+              + ") was bound.";
       String atSegment = "at " + getClass().getName();
       String sourceFileName = getDeclaringSourcePart(getClass());
-      if (isIncludeStackTraceOff()) {
-        assertContains(e.getMessage(),
-            segment1, atSegment, sourceFileName,
-            segment2, atSegment, sourceFileName,
-            segment3, atSegment, sourceFileName,
-            segment4, atSegment, sourceFileName);
-      } else {
-        assertContains(e.getMessage(),
-            segment3, atSegment, sourceFileName,
-            segment1, atSegment, sourceFileName,
-            segment4, atSegment, sourceFileName,
-            segment2, atSegment, sourceFileName);
-      }
+      assertContains(
+          e.getMessage(),
+          segment1,
+          atSegment,
+          sourceFileName,
+          segment2,
+          atSegment,
+          sourceFileName,
+          segment3,
+          atSegment,
+          sourceFileName,
+          segment4,
+          atSegment,
+          sourceFileName);
     }
   }
 
   public void testMissingDependency() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        public void configure() {
-          bind(NeedsRunnable.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              bind(NeedsRunnable.class);
+            }
+          });
+      fail("Expected CreationException");
     } catch (CreationException e) {
       assertEquals(1, e.getErrorMessages().size());
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "No implementation for java.lang.Runnable was bound.",
-          "for field at " + NeedsRunnable.class.getName(), ".runnable(BinderTest.java:",
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          "for field at " + NeedsRunnable.class.getName(),
+          ".runnable(BinderTest.java:",
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
@@ -147,14 +182,17 @@
 
   public void testDanglingConstantBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override public void configure() {
-          bindConstant();
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              bindConstant();
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Missing constant value. Please call to(...).",
           "at " + getClass().getName());
     }
@@ -162,31 +200,38 @@
 
   public void testRecursiveBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override public void configure() {
-          bind(Runnable.class).to(Runnable.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              bind(Runnable.class).to(Runnable.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Binding points to itself.",
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   public void testBindingNullConstant() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override public void configure() {
-          String none = null;
-          bindConstant().annotatedWith(Names.named("nullOne")).to(none);
-          bind(String.class).annotatedWith(Names.named("nullTwo")).toInstance(none);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              String none = null;
+              bindConstant().annotatedWith(Names.named("nullOne")).to(none);
+              bind(String.class).annotatedWith(Names.named("nullTwo")).toInstance(none);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Binding to null instances is not allowed. Use toProvider(Providers.of(null))",
           "2) Binding to null instances is not allowed. Use toProvider(Providers.of(null))");
     }
@@ -194,24 +239,29 @@
 
   public void testToStringOnBinderApi() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override public void configure() {
-          assertEquals("Binder", binder().toString());
-          assertEquals("Provider<java.lang.Integer>", getProvider(Integer.class).toString());
-          assertEquals("Provider<java.util.List<java.lang.String>>",
-              getProvider(Key.get(new TypeLiteral<List<String>>() {})).toString());
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              assertEquals("Binder", binder().toString());
+              assertEquals("Provider<java.lang.Integer>", getProvider(Integer.class).toString());
+              assertEquals(
+                  "Provider<java.util.List<java.lang.String>>",
+                  getProvider(Key.get(new TypeLiteral<List<String>>() {})).toString());
 
-          assertEquals("BindingBuilder<java.lang.Integer>",
-              bind(Integer.class).toString());
-          assertEquals("BindingBuilder<java.lang.Integer>",
-              bind(Integer.class).annotatedWith(Names.named("a")).toString());
-          assertEquals("ConstantBindingBuilder", bindConstant().toString());
-          assertEquals("ConstantBindingBuilder",
-              bindConstant().annotatedWith(Names.named("b")).toString());
-          assertEquals("AnnotatedElementBuilder",
-              binder().newPrivateBinder().expose(Integer.class).toString());
-        }
-      });
+              assertEquals("BindingBuilder<java.lang.Integer>", bind(Integer.class).toString());
+              assertEquals(
+                  "BindingBuilder<java.lang.Integer>",
+                  bind(Integer.class).annotatedWith(Names.named("a")).toString());
+              assertEquals("ConstantBindingBuilder", bindConstant().toString());
+              assertEquals(
+                  "ConstantBindingBuilder",
+                  bindConstant().annotatedWith(Names.named("b")).toString());
+              assertEquals(
+                  "AnnotatedElementBuilder",
+                  binder().newPrivateBinder().expose(Integer.class).toString());
+            }
+          });
       fail();
     } catch (CreationException ignored) {
     }
@@ -219,42 +269,45 @@
 
   public void testNothingIsSerializableInBinderApi() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override public void configure() {
-          try {
-            assertNotSerializable(binder());
-            assertNotSerializable(getProvider(Integer.class));
-            assertNotSerializable(getProvider(Key.get(new TypeLiteral<List<String>>() {})));
-            assertNotSerializable(bind(Integer.class));
-            assertNotSerializable(bind(Integer.class).annotatedWith(Names.named("a")));
-            assertNotSerializable(bindConstant());
-            assertNotSerializable(bindConstant().annotatedWith(Names.named("b")));
-          } catch (IOException e) {
-            fail(e.getMessage());
-          }
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            public void configure() {
+              try {
+                assertNotSerializable(binder());
+                assertNotSerializable(getProvider(Integer.class));
+                assertNotSerializable(getProvider(Key.get(new TypeLiteral<List<String>>() {})));
+                assertNotSerializable(bind(Integer.class));
+                assertNotSerializable(bind(Integer.class).annotatedWith(Names.named("a")));
+                assertNotSerializable(bindConstant());
+                assertNotSerializable(bindConstant().annotatedWith(Names.named("b")));
+              } catch (IOException e) {
+                fail(e.getMessage());
+              }
+            }
+          });
       fail();
     } catch (CreationException ignored) {
     }
   }
 
   /**
-   * Although {@code String[].class} isn't equal to {@code new
-   * GenericArrayTypeImpl(String.class)}, Guice should treat these two types
-   * interchangeably.
+   * Although {@code String[].class} isn't equal to {@code new GenericArrayTypeImpl(String.class)},
+   * Guice should treat these two types interchangeably.
    */
   public void testArrayTypeCanonicalization() {
-    final String[] strings = new String[] { "A" };
-    final Integer[] integers = new Integer[] { 1 };
+    final String[] strings = new String[] {"A"};
+    final Integer[] integers = new Integer[] {1};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String[].class).toInstance(strings);
-        bind(new TypeLiteral<Integer[]>() {}).toInstance(integers);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String[].class).toInstance(strings);
+                bind(new TypeLiteral<Integer[]>() {}).toInstance(integers);
+              }
+            });
 
     assertSame(integers, injector.getInstance(Key.get(new TypeLiteral<Integer[]>() {})));
     assertSame(integers, injector.getInstance(new Key<Integer[]>() {}));
@@ -264,154 +317,170 @@
     assertSame(strings, injector.getInstance(String[].class));
 
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(String[].class).toInstance(new String[] { "A" });
-          bind(new TypeLiteral<String[]>() {}).toInstance(new String[] { "B" });
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(String[].class).toInstance(new String[] {"A"});
+              bind(new TypeLiteral<String[]>() {}).toInstance(new String[] {"B"});
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) A binding to java.lang.String[] was already configured at " + getClass().getName(),
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
       assertContains(expected.getMessage(), "1 error");
     }
 
     // passes because duplicates are ignored
-    injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String[].class).toInstance(strings);
-        bind(new TypeLiteral<String[]>() {}).toInstance(strings);
-      }
-    });
+    injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String[].class).toInstance(strings);
+                bind(new TypeLiteral<String[]>() {}).toInstance(strings);
+              }
+            });
     assertSame(strings, injector.getInstance(Key.get(new TypeLiteral<String[]>() {})));
     assertSame(strings, injector.getInstance(new Key<String[]>() {}));
     assertSame(strings, injector.getInstance(String[].class));
   }
 
   static class ParentModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new FooModule());
       install(new BarModule());
     }
   }
+
   static class FooModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new ConstantModule("foo"));
     }
   }
+
   static class BarModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new ConstantModule("bar"));
     }
   }
+
   static class ConstantModule extends AbstractModule {
     private final String constant;
+
     ConstantModule(String constant) {
       this.constant = constant;
     }
-    @Override protected void configure() {
+
+    @Override
+    protected void configure() {
       bind(String.class).toInstance(constant);
     }
   }
 
-  /**
-   * Binding something to two different things should give an error.
-   */
+  /** Binding something to two different things should give an error. */
   public void testSettingBindingTwice() {
     try {
       Guice.createInjector(new ParentModule());
       fail();
-    } catch(CreationException expected) {
-      assertContains(expected.getMessage(),
-        "1) A binding to java.lang.String was already configured at " + ConstantModule.class.getName(),
-        asModuleChain(ParentModule.class, FooModule.class, ConstantModule.class),
-        "at " + ConstantModule.class.getName(), getDeclaringSourcePart(getClass()),
-        asModuleChain(ParentModule.class, BarModule.class, ConstantModule.class));
+    } catch (CreationException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) A binding to java.lang.String was already configured at "
+              + ConstantModule.class.getName(),
+          asModuleChain(ParentModule.class, FooModule.class, ConstantModule.class),
+          "at " + ConstantModule.class.getName(),
+          getDeclaringSourcePart(getClass()),
+          asModuleChain(ParentModule.class, BarModule.class, ConstantModule.class));
       assertContains(expected.getMessage(), "1 error");
     }
   }
 
-  /**
-   * Binding an @ImplementedBy thing to something else should also fail.
-   */
+  /** Binding an @ImplementedBy thing to something else should also fail. */
   public void testSettingAtImplementedByTwice() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(HasImplementedBy1.class);
-          bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(HasImplementedBy1.class);
+              bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
+            }
+          });
       fail();
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       expected.printStackTrace();
-      assertContains(expected.getMessage(),
-        "1) A binding to " + HasImplementedBy1.class.getName()
-        + " was already configured at " + getClass().getName(),
-        "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+      assertContains(
+          expected.getMessage(),
+          "1) A binding to "
+              + HasImplementedBy1.class.getName()
+              + " was already configured at "
+              + getClass().getName(),
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
       assertContains(expected.getMessage(), "1 error");
     }
   }
 
-  /**
-   * See issue 614, Problem One
-   * https://github.com/google/guice/issues/614
-   */
+  /** See issue 614, Problem One https://github.com/google/guice/issues/614 */
   public void testJitDependencyDoesntBlockOtherExplicitBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(HasImplementedByThatNeedsAnotherImplementedBy.class);
-        bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(HasImplementedByThatNeedsAnotherImplementedBy.class);
+                bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
+              }
+            });
     injector.getAllBindings(); // just validate it doesn't throw.
     // Also validate that we're using the explicit (and not @ImplementedBy) implementation
-    assertFalse(injector.getInstance(HasImplementedBy1.class) instanceof ImplementsHasImplementedBy1);
+    assertFalse(
+        injector.getInstance(HasImplementedBy1.class) instanceof ImplementsHasImplementedBy1);
   }
 
-  /**
-   * See issue 614, Problem Two
-   * https://github.com/google/guice/issues/id=614
-   */
+  /** See issue 614, Problem Two https://github.com/google/guice/issues/id=614 */
   public void testJitDependencyCanUseExplicitDependencies() {
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(HasImplementedByThatWantsExplicit.class);
-        bind(JustAnInterface.class).toInstance(new JustAnInterface() {});
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(HasImplementedByThatWantsExplicit.class);
+            bind(JustAnInterface.class).toInstance(new JustAnInterface() {});
+          }
+        });
   }
 
   /**
-   * Untargetted bindings should follow @ImplementedBy and @ProvidedBy
-   * annotations if they exist. Otherwise the class should be constructed
-   * directly.
+   * Untargetted bindings should follow @ImplementedBy and @ProvidedBy annotations if they exist.
+   * Otherwise the class should be constructed directly.
    */
   public void testUntargettedBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(HasProvidedBy1.class);
-        bind(HasImplementedBy1.class);
-        bind(HasProvidedBy2.class);
-        bind(HasImplementedBy2.class);
-        bind(JustAClass.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(HasProvidedBy1.class);
+                bind(HasImplementedBy1.class);
+                bind(HasProvidedBy2.class);
+                bind(HasImplementedBy2.class);
+                bind(JustAClass.class);
+              }
+            });
 
     assertNotNull(injector.getInstance(HasProvidedBy1.class));
     assertNotNull(injector.getInstance(HasImplementedBy1.class));
-    assertNotSame(HasProvidedBy2.class,
-        injector.getInstance(HasProvidedBy2.class).getClass());
-    assertSame(ExtendsHasImplementedBy2.class,
-        injector.getInstance(HasImplementedBy2.class).getClass());
+    assertNotSame(HasProvidedBy2.class, injector.getInstance(HasProvidedBy2.class).getClass());
+    assertSame(
+        ExtendsHasImplementedBy2.class, injector.getInstance(HasImplementedBy2.class).getClass());
     assertSame(JustAClass.class, injector.getInstance(JustAClass.class).getClass());
   }
 
@@ -421,21 +490,25 @@
       injector.getInstance(MissingParameter.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Could not find a suitable constructor in " + NoInjectConstructor.class.getName(),
-          "at " + MissingParameter.class.getName() + ".<init>(BinderTest.java:");
+          "for the 1st parameter of "
+              + MissingParameter.class.getName()
+              + ".<init>(BinderTest.java:");
     }
   }
 
   public void testUserReportedError() {
     final Message message = new Message(getClass(), "Whoops!");
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          addError(message);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              addError(message);
+            }
+          });
       fail();
     } catch (CreationException expected) {
       assertSame(message, Iterables.getOnlyElement(expected.getErrorMessages()));
@@ -444,48 +517,55 @@
 
   public void testUserReportedErrorsAreAlsoLogged() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          addError(new Message("Whoops!", new IllegalArgumentException()));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              addError(new Message("Whoops!", new IllegalArgumentException()));
+            }
+          });
       fail();
     } catch (CreationException expected) {
     }
 
     LogRecord logRecord = Iterables.getOnlyElement(this.logRecords);
-    assertContains(logRecord.getMessage(),
+    assertContains(
+        logRecord.getMessage(),
         "An exception was caught and reported. Message: java.lang.IllegalArgumentException");
   }
 
   public void testBindingToProvider() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(new TypeLiteral<Provider<String>>() {}).toInstance(Providers.of("A"));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(new TypeLiteral<Provider<String>>() {}).toInstance(Providers.of("A"));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Binding to Provider is not allowed.",
-          "at " + BinderTest.class.getName(), getDeclaringSourcePart(getClass()));
+          "at " + BinderTest.class.getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   static class OuterCoreModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerCoreModule());
     }
   }
+
   static class InnerCoreModule extends AbstractModule {
     final Named red = Names.named("red");
 
-    @Override protected void configure() {
-      bind(AbstractModule.class).annotatedWith(red)
-      .toProvider(Providers.<AbstractModule>of(null));
+    @Override
+    protected void configure() {
+      bind(AbstractModule.class).annotatedWith(red).toProvider(Providers.<AbstractModule>of(null));
       bind(Binder.class).annotatedWith(red).toProvider(Providers.<Binder>of(null));
       bind(Binding.class).annotatedWith(red).toProvider(Providers.<Binding>of(null));
       bind(Injector.class).annotatedWith(red).toProvider(Providers.<Injector>of(null));
@@ -498,52 +578,44 @@
       bind(new TypeLiteral<Key<String>>() {}).toProvider(Providers.<Key<String>>of(null));
     }
   }
+
   public void testCannotBindToGuiceTypes() {
     try {
       Guice.createInjector(new OuterCoreModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Binding to core guice framework type is not allowed: AbstractModule.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Binder.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Binding.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Injector.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Key.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Module.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to Provider is not allowed.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Scope.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Stage.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: TypeLiteral.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
-
           "Binding to core guice framework type is not allowed: Key.",
           "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterCoreModule.class, InnerCoreModule.class));
@@ -551,7 +623,8 @@
   }
 
   static class MissingParameter {
-    @Inject MissingParameter(NoInjectConstructor noInjectConstructor) {}
+    @Inject
+    MissingParameter(NoInjectConstructor noInjectConstructor) {}
   }
 
   static class NoInjectConstructor {
@@ -562,6 +635,7 @@
   interface HasProvidedBy1 {}
 
   static class HasProvidedBy1Provider implements Provider<HasProvidedBy1> {
+    @Override
     public HasProvidedBy1 get() {
       return new HasProvidedBy1() {};
     }
@@ -576,6 +650,7 @@
   static class HasProvidedBy2 {}
 
   static class HasProvidedBy2Provider implements Provider<HasProvidedBy2> {
+    @Override
     public HasProvidedBy2 get() {
       return new HasProvidedBy2() {};
     }
@@ -589,44 +664,46 @@
   static class JustAClass {}
 
   @ImplementedBy(ImplementsHasImplementedByThatNeedsAnotherImplementedBy.class)
-  static interface HasImplementedByThatNeedsAnotherImplementedBy {
-  }
+  static interface HasImplementedByThatNeedsAnotherImplementedBy {}
 
   static class ImplementsHasImplementedByThatNeedsAnotherImplementedBy
-    implements HasImplementedByThatNeedsAnotherImplementedBy {
+      implements HasImplementedByThatNeedsAnotherImplementedBy {
     @Inject
-    ImplementsHasImplementedByThatNeedsAnotherImplementedBy(
-        HasImplementedBy1 h1n1) {}
+    ImplementsHasImplementedByThatNeedsAnotherImplementedBy(HasImplementedBy1 h1n1) {}
   }
 
   @ImplementedBy(ImplementsHasImplementedByThatWantsExplicit.class)
-  static interface HasImplementedByThatWantsExplicit {
-  }
+  static interface HasImplementedByThatWantsExplicit {}
 
   static class ImplementsHasImplementedByThatWantsExplicit
       implements HasImplementedByThatWantsExplicit {
-    @Inject ImplementsHasImplementedByThatWantsExplicit(JustAnInterface jai) {}
+    @Inject
+    ImplementsHasImplementedByThatWantsExplicit(JustAnInterface jai) {}
   }
 
   static interface JustAnInterface {}
 
+  //  public void testBindInterfaceWithoutImplementation() {
+  //    Guice.createInjector(new AbstractModule() {
+  //      protected void configure() {
+  //        bind(Runnable.class);
+  //      }
+  //    }).getInstance(Runnable.class);
+  //  }
 
-//  public void testBindInterfaceWithoutImplementation() {
-//    Guice.createInjector(new AbstractModule() {
-//      protected void configure() {
-//        bind(Runnable.class);
-//      }
-//    }).getInstance(Runnable.class);
-//  }
-
-  enum Roshambo { ROCK, SCISSORS, PAPER }
+  enum Roshambo {
+    ROCK,
+    SCISSORS,
+    PAPER
+  }
 
   public void testInjectRawProvider() {
     try {
       Guice.createInjector().getInstance(Provider.class);
       fail();
     } catch (ConfigurationException expected) {
-      Asserts.assertContains(expected.getMessage(),
+      Asserts.assertContains(
+          expected.getMessage(),
           "1) Cannot inject a Provider that has no type parameter",
           "while locating " + Provider.class.getName());
     }
diff --git a/core/test/com/google/inject/BinderTestSuite.java b/core/test/com/google/inject/BinderTestSuite.java
index b34cfe0..5879835 100644
--- a/core/test/com/google/inject/BinderTestSuite.java
+++ b/core/test/com/google/inject/BinderTestSuite.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,20 +28,16 @@
 import com.google.inject.binder.ScopedBindingBuilder;
 import com.google.inject.name.Named;
 import com.google.inject.util.Providers;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class BinderTestSuite extends TestCase {
 
   public static Test suite() {
@@ -49,32 +45,39 @@
 
     new Builder()
         .name("bind A")
-        .module(new AbstractModule() {
-          protected void configure() {
-            bind(A.class);
-          }
-        })
+        .module(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class);
+              }
+            })
         .creationException("No implementation for %s was bound", A.class.getName())
         .addToSuite(suite);
 
     new Builder()
         .name("bind PlainA named apple")
-        .module(new AbstractModule() {
-          protected void configure() {
-            bind(PlainA.class).annotatedWith(named("apple"));
-          }
-        })
-        .creationException("No implementation for %s annotated with %s was bound",
+        .module(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(PlainA.class).annotatedWith(named("apple"));
+              }
+            })
+        .creationException(
+            "No implementation for %s annotated with %s was bound",
             PlainA.class.getName(), named("apple"))
         .addToSuite(suite);
 
     new Builder()
         .name("bind A to new PlainA(1)")
-        .module(new AbstractModule() {
-          protected void configure() {
-            bind(A.class).toInstance(new PlainA(1));
-          }
-        })
+        .module(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).toInstance(new PlainA(1));
+              }
+            })
         .creationTime(CreationTime.NONE)
         .expectedValues(new PlainA(1), new PlainA(1), new PlainA(1))
         .addToSuite(suite);
@@ -97,24 +100,27 @@
 
     new Builder()
         .name("no binding, AWithProvidedBy named apple")
-        .key(Key.get(AWithProvidedBy.class, named("apple")),
-            InjectsAWithProvidedByNamedApple.class)
-        .configurationException("No implementation for %s annotated with %s was bound",
+        .key(Key.get(AWithProvidedBy.class, named("apple")), InjectsAWithProvidedByNamedApple.class)
+        .configurationException(
+            "No implementation for %s annotated with %s was bound",
             AWithProvidedBy.class.getName(), named("apple"))
         .addToSuite(suite);
 
     new Builder()
         .name("no binding, AWithImplementedBy named apple")
-        .key(Key.get(AWithImplementedBy.class, named("apple")),
+        .key(
+            Key.get(AWithImplementedBy.class, named("apple")),
             InjectsAWithImplementedByNamedApple.class)
-        .configurationException("No implementation for %s annotated with %s was bound",
+        .configurationException(
+            "No implementation for %s annotated with %s was bound",
             AWithImplementedBy.class.getName(), named("apple"))
         .addToSuite(suite);
 
     new Builder()
         .name("no binding, ScopedA named apple")
         .key(Key.get(ScopedA.class, named("apple")), InjectsScopedANamedApple.class)
-        .configurationException("No implementation for %s annotated with %s was bound",
+        .configurationException(
+            "No implementation for %s annotated with %s was bound",
             ScopedA.class.getName(), named("apple"))
         .addToSuite(suite);
 
@@ -122,134 +128,161 @@
       new Builder()
           .name("bind PlainA")
           .key(Key.get(PlainA.class), InjectsPlainA.class)
-          .module(new AbstractModule() {
-            protected void configure() {
-              AnnotatedBindingBuilder<PlainA> abb = bind(PlainA.class);
-              scoper.configure(abb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  AnnotatedBindingBuilder<PlainA> abb = bind(PlainA.class);
+                  scoper.configure(abb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind A to PlainA")
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(A.class).to(PlainA.class);
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(A.class).to(PlainA.class);
+                  scoper.configure(sbb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind A to PlainAProvider.class")
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(A.class).toProvider(PlainAProvider.class);
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(A.class).toProvider(PlainAProvider.class);
+                  scoper.configure(sbb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind A to new PlainAProvider()")
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(A.class).toProvider(new PlainAProvider());
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(A.class).toProvider(new PlainAProvider());
+                  scoper.configure(sbb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind AWithProvidedBy")
           .key(Key.get(AWithProvidedBy.class), InjectsAWithProvidedBy.class)
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(AWithProvidedBy.class);
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(AWithProvidedBy.class);
+                  scoper.configure(sbb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind AWithImplementedBy")
           .key(Key.get(AWithImplementedBy.class), InjectsAWithImplementedBy.class)
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(AWithImplementedBy.class);
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(AWithImplementedBy.class);
+                  scoper.configure(sbb);
+                }
+              })
           .scoper(scoper)
           .addToSuite(suite);
 
       new Builder()
           .name("bind ScopedA")
           .key(Key.get(ScopedA.class), InjectsScopedA.class)
-          .module(new AbstractModule() {
-            protected void configure() {
-              ScopedBindingBuilder sbb = bind(ScopedA.class);
-              scoper.configure(sbb);
-            }
-          })
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ScopedBindingBuilder sbb = bind(ScopedA.class);
+                  scoper.configure(sbb);
+                }
+              })
           .expectedValues(new PlainA(201), new PlainA(201), new PlainA(202), new PlainA(202))
           .scoper(scoper)
           .addToSuite(suite);
 
-
       new Builder()
           .name("bind AWithProvidedBy named apple")
-          .module(new AbstractModule() {
-            protected void configure() {
-              scoper.configure(bind(AWithProvidedBy.class).annotatedWith(named("apple")));
-            }
-          })
-          .creationException("No implementation for %s annotated with %s was bound",
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  scoper.configure(bind(AWithProvidedBy.class).annotatedWith(named("apple")));
+                }
+              })
+          .creationException(
+              "No implementation for %s annotated with %s was bound",
               AWithProvidedBy.class.getName(), named("apple"))
           .addToSuite(suite);
 
       new Builder()
           .name("bind AWithImplementedBy named apple")
-          .module(new AbstractModule() {
-            protected void configure() {
-              scoper.configure(bind(AWithImplementedBy.class).annotatedWith(named("apple")));
-            }
-          })
-          .creationException("No implementation for %s annotated with %s was bound",
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  scoper.configure(bind(AWithImplementedBy.class).annotatedWith(named("apple")));
+                }
+              })
+          .creationException(
+              "No implementation for %s annotated with %s was bound",
               AWithImplementedBy.class.getName(), named("apple"))
           .addToSuite(suite);
 
       new Builder()
           .name("bind ScopedA named apple")
-          .module(new AbstractModule() {
-            protected void configure() {
-              scoper.configure(bind(ScopedA.class).annotatedWith(named("apple")));
-            }
-          })
-          .creationException("No implementation for %s annotated with %s was bound",
+          .module(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  scoper.configure(bind(ScopedA.class).annotatedWith(named("apple")));
+                }
+              })
+          .creationException(
+              "No implementation for %s annotated with %s was bound",
               ScopedA.class.getName(), named("apple"))
           .addToSuite(suite);
-
     }
-    
+
     return suite;
   }
-  
+
   enum Scoper {
     UNSCOPED {
+      @Override
       void configure(ScopedBindingBuilder sbb) {}
+
+      @Override
       void apply(Builder builder) {}
     },
 
     EAGER_SINGLETON {
+      @Override
       void configure(ScopedBindingBuilder sbb) {
         sbb.asEagerSingleton();
       }
+
+      @Override
       void apply(Builder builder) {
         builder.expectedValues(new PlainA(101), new PlainA(101), new PlainA(101));
         builder.creationTime(CreationTime.EAGER);
@@ -257,61 +290,79 @@
     },
 
     SCOPES_SINGLETON {
+      @Override
       void configure(ScopedBindingBuilder sbb) {
         sbb.in(Scopes.SINGLETON);
       }
+
+      @Override
       void apply(Builder builder) {
         builder.expectedValues(new PlainA(201), new PlainA(201), new PlainA(201));
       }
     },
 
     SINGLETON_DOT_CLASS {
+      @Override
       void configure(ScopedBindingBuilder sbb) {
         sbb.in(Singleton.class);
       }
+
+      @Override
       void apply(Builder builder) {
         builder.expectedValues(new PlainA(201), new PlainA(201), new PlainA(201));
       }
     },
 
     TWO_AT_A_TIME_SCOPED_DOT_CLASS {
+      @Override
       void configure(ScopedBindingBuilder sbb) {
         sbb.in(TwoAtATimeScoped.class);
       }
+
+      @Override
       void apply(Builder builder) {
         builder.expectedValues(new PlainA(201), new PlainA(201), new PlainA(202), new PlainA(202));
       }
     },
 
     TWO_AT_A_TIME_SCOPE {
+      @Override
       void configure(ScopedBindingBuilder sbb) {
         sbb.in(new TwoAtATimeScope());
       }
+
+      @Override
       void apply(Builder builder) {
         builder.expectedValues(new PlainA(201), new PlainA(201), new PlainA(202), new PlainA(202));
       }
     };
 
     abstract void configure(ScopedBindingBuilder sbb);
+
     abstract void apply(Builder builder);
   }
 
   /** When Guice creates a value, directly or via a provider */
   enum CreationTime {
-    NONE, EAGER, LAZY
+    NONE,
+    EAGER,
+    LAZY
   }
 
   public static class Builder {
     private String name = "test";
     private Key<?> key = Key.get(A.class);
     private Class<? extends Injectable> injectsKey = InjectsA.class;
-    private List<Module> modules = Lists.<Module>newArrayList(new AbstractModule() {
-      protected void configure() {
-        bindScope(TwoAtATimeScoped.class, new TwoAtATimeScope());
-      }
-    });
-    private List<Object> expectedValues = Lists.<Object>newArrayList(
-        new PlainA(201), new PlainA(202), new PlainA(203));
+    private List<Module> modules =
+        Lists.<Module>newArrayList(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(TwoAtATimeScoped.class, new TwoAtATimeScope());
+              }
+            });
+    private List<Object> expectedValues =
+        Lists.<Object>newArrayList(new PlainA(201), new PlainA(202), new PlainA(203));
     private CreationTime creationTime = CreationTime.LAZY;
     private String creationException;
     private String configurationException;
@@ -391,6 +442,7 @@
       expectedValues = ImmutableList.copyOf(builder.expectedValues);
     }
 
+    @Override
     public String getName() {
       return name;
     }
@@ -459,6 +511,7 @@
       creationException = builder.creationException;
     }
 
+    @Override
     public String getName() {
       return "creation errors:" + name;
     }
@@ -489,6 +542,7 @@
       configurationException = builder.configurationException;
     }
 
+    @Override
     public String getName() {
       return "provision errors:" + name;
     }
@@ -523,9 +577,12 @@
         newInjector().getInstance(injectsKey);
         fail();
       } catch (ConfigurationException expected) {
-        assertContains(expected.getMessage(),
-            configurationException, injectsKey.getName() + ".inject",
-            configurationException, injectsKey.getName() + ".inject",
+        assertContains(
+            expected.getMessage(),
+            configurationException,
+            injectsKey.getName() + ".inject",
+            configurationException,
+            injectsKey.getName() + ".inject",
             "2 errors");
       }
 
@@ -534,9 +591,12 @@
         newInjector().injectMembers(injectable);
         fail();
       } catch (ConfigurationException expected) {
-        assertContains(expected.getMessage(),
-            configurationException, injectsKey.getName() + ".inject",
-            configurationException, injectsKey.getName() + ".inject",
+        assertContains(
+            expected.getMessage(),
+            configurationException,
+            injectsKey.getName() + ".inject",
+            configurationException,
+            injectsKey.getName() + ".inject",
             "2 errors");
       }
     }
@@ -560,6 +620,7 @@
       creationTime = builder.creationTime;
     }
 
+    @Override
     public String getName() {
       return "provision errors:" + name;
     }
@@ -609,9 +670,12 @@
       try {
         nextId.set(-1);
         newInjector().getInstance(injectsKey);
+        fail("Expected ProvisionException");
       } catch (ProvisionException expected) {
-        assertContains(expected.getMessage(), "Illegal value: -1",
-            "for parameter 0 at " + injectsKey.getName() + ".inject");
+        assertContains(
+            expected.getMessage(),
+            "Illegal value: -1",
+            "for the 1st parameter of " + injectsKey.getName() + ".inject");
       }
 
       nextId.set(201);
@@ -620,8 +684,10 @@
         nextId.set(-1);
         newInjector().injectMembers(injectable);
       } catch (ProvisionException expected) {
-        assertContains(expected.getMessage(), "Illegal value: -1",
-            "for parameter 0 at " + injectsKey.getName() + ".inject");
+        assertContains(
+            expected.getMessage(),
+            "Illegal value: -1",
+            "for the 1st parameter of " + injectsKey.getName() + ".inject");
       }
 
       nextId.set(201);
@@ -630,6 +696,7 @@
       try {
         nextId.set(-1);
         hasProvider.provider.get();
+        // TODO(lukes): insert fail() call here
       } catch (ProvisionException expected) {
         assertContains(expected.getMessage(), "Illegal value: -1");
       }
@@ -643,15 +710,18 @@
   interface AWithProvidedBy {}
 
   static class InjectsAWithProvidedBy extends Injectable {
-    @Inject public void inject(AWithProvidedBy aWithProvidedBy,
-        Provider<AWithProvidedBy> aWithProvidedByProvider) {
+    @Inject
+    public void inject(
+        AWithProvidedBy aWithProvidedBy, Provider<AWithProvidedBy> aWithProvidedByProvider) {
       this.value = aWithProvidedBy;
       this.provider = aWithProvidedByProvider;
     }
   }
 
   static class InjectsAWithProvidedByNamedApple extends Injectable {
-    @Inject public void inject(@Named("apple") AWithProvidedBy aWithProvidedBy,
+    @Inject
+    public void inject(
+        @Named("apple") AWithProvidedBy aWithProvidedBy,
         @Named("apple") Provider<AWithProvidedBy> aWithProvidedByProvider) {
       this.value = aWithProvidedBy;
       this.provider = aWithProvidedByProvider;
@@ -662,7 +732,9 @@
   interface AWithImplementedBy {}
 
   static class InjectsAWithImplementedBy extends Injectable {
-    @Inject public void inject(AWithImplementedBy aWithImplementedBy,
+    @Inject
+    public void inject(
+        AWithImplementedBy aWithImplementedBy,
         Provider<AWithImplementedBy> aWithImplementedByProvider) {
       this.value = aWithImplementedBy;
       this.provider = aWithImplementedByProvider;
@@ -670,7 +742,9 @@
   }
 
   static class InjectsAWithImplementedByNamedApple extends Injectable {
-    @Inject public void inject(@Named("apple") AWithImplementedBy aWithImplementedBy,
+    @Inject
+    public void inject(
+        @Named("apple") AWithImplementedBy aWithImplementedBy,
         @Named("apple") Provider<AWithImplementedBy> aWithImplementedByProvider) {
       this.value = aWithImplementedBy;
       this.provider = aWithImplementedByProvider;
@@ -680,7 +754,8 @@
   interface A extends AWithProvidedBy, AWithImplementedBy {}
 
   static class InjectsA extends Injectable {
-    @Inject public void inject(A a, Provider<A> aProvider) {
+    @Inject
+    public void inject(A a, Provider<A> aProvider) {
       this.value = a;
       this.provider = aProvider;
     }
@@ -688,45 +763,57 @@
 
   static class PlainA implements A {
     final int value;
+
     PlainA() {
       value = nextId.getAndIncrement();
       if (value < 0) {
         throw new RuntimeException("Illegal value: " + value);
       }
     }
+
     PlainA(int value) {
       this.value = value;
     }
+
+    @Override
     public boolean equals(Object obj) {
-      return obj instanceof PlainA
-          && value == ((PlainA) obj).value;
+      return obj instanceof PlainA && value == ((PlainA) obj).value;
     }
+
+    @Override
     public int hashCode() {
       return value;
     }
+
+    @Override
     public String toString() {
       return "PlainA#" + value;
     }
   }
 
   static class PlainAProvider implements Provider<A> {
+    @Override
     public A get() {
       return new PlainA();
     }
   }
 
   static class InjectsPlainA extends Injectable {
-    @Inject public void inject(PlainA plainA, Provider<PlainA> plainAProvider) {
+    @Inject
+    public void inject(PlainA plainA, Provider<PlainA> plainAProvider) {
       this.value = plainA;
       this.provider = plainAProvider;
     }
   }
 
-  /** This scope hands out each value exactly twice  */
+  /** This scope hands out each value exactly twice */
   static class TwoAtATimeScope implements Scope {
+    @Override
     public <T> Provider<T> scope(Key<T> key, final Provider<T> unscoped) {
       return new Provider<T>() {
         T instance;
+
+        @Override
         public T get() {
           if (instance == null) {
             instance = unscoped.get();
@@ -741,22 +828,26 @@
     }
   }
 
-  @Target({ TYPE, METHOD }) @Retention(RUNTIME) @ScopeAnnotation
+  @Target({TYPE, METHOD})
+  @Retention(RUNTIME)
+  @ScopeAnnotation
   public @interface TwoAtATimeScoped {}
 
   @TwoAtATimeScoped
   static class ScopedA extends PlainA {}
 
   static class InjectsScopedA extends Injectable {
-    @Inject public void inject(ScopedA scopedA, Provider<ScopedA> scopedAProvider) {
+    @Inject
+    public void inject(ScopedA scopedA, Provider<ScopedA> scopedAProvider) {
       this.value = scopedA;
       this.provider = scopedAProvider;
     }
   }
 
   static class InjectsScopedANamedApple extends Injectable {
-    @Inject public void inject(@Named("apple") ScopedA scopedA,
-        @Named("apple") Provider<ScopedA> scopedAProvider) {
+    @Inject
+    public void inject(
+        @Named("apple") ScopedA scopedA, @Named("apple") Provider<ScopedA> scopedAProvider) {
       this.value = scopedA;
       this.provider = scopedAProvider;
     }
diff --git a/core/test/com/google/inject/BindingAnnotationTest.java b/core/test/com/google/inject/BindingAnnotationTest.java
index b119953..92b4536 100644
--- a/core/test/com/google/inject/BindingAnnotationTest.java
+++ b/core/test/com/google/inject/BindingAnnotationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,24 +20,23 @@
 import static com.google.inject.Asserts.getDeclaringSourcePart;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class BindingAnnotationTest extends TestCase {
 
   public void testAnnotationWithValueMatchesKeyWithTypeOnly() throws CreationException {
-    Injector c = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(Blue.class).to("foo");
-        bind(BlueFoo.class);
-      }
-    });
+    Injector c =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(Blue.class).to("foo");
+                bind(BlueFoo.class);
+              }
+            });
 
     BlueFoo foo = c.getInstance(BlueFoo.class);
 
@@ -46,47 +45,57 @@
 
   public void testRequireExactAnnotationsDisablesFallback() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExactBindingAnnotations();
-          bindConstant().annotatedWith(Blue.class).to("foo");
-          bind(BlueFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExactBindingAnnotations();
+              bindConstant().annotatedWith(Blue.class).to("foo");
+              bind(BlueFoo.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
+      assertContains(
+          expected.getMessage(),
+          true,
+          "No implementation for java.lang.String annotated with",
           "BindingAnnotationTest$Blue(value=5) was bound",
           "at " + BindingAnnotationTest.class.getName(),
           getDeclaringSourcePart(getClass()));
     }
   }
-  
+
   public void testRequireExactAnnotationsDoesntBreakIfDefaultsExist() {
-       Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExactBindingAnnotations();
-          bindConstant().annotatedWith(Red.class).to("foo");
-          bind(RedFoo.class);
-        }
-      }).getInstance(RedFoo.class);      
+    Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExactBindingAnnotations();
+                bindConstant().annotatedWith(Red.class).to("foo");
+                bind(RedFoo.class);
+              }
+            })
+        .getInstance(RedFoo.class);
   }
 
   public void testRequireExactAnnotationsRequireAllOptionals() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExactBindingAnnotations();
-          bindConstant().annotatedWith(Color.class).to("foo");
-          bind(ColorFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExactBindingAnnotations();
+              bindConstant().annotatedWith(Color.class).to("foo");
+              bind(ColorFoo.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
+      assertContains(
+          expected.getMessage(),
+          true,
+          "No implementation for java.lang.String annotated with",
           "BindingAnnotationTest$Color",
           "at " + BindingAnnotationTest.class.getName(),
           getDeclaringSourcePart(getClass()));
@@ -95,17 +104,21 @@
 
   public void testAnnotationWithValueThatDoesntMatch() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bindConstant().annotatedWith(createBlue(6)).to("six");
-          bind(String.class).toInstance("bar");
-          bind(BlueFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bindConstant().annotatedWith(createBlue(6)).to("six");
+              bind(String.class).toInstance("bar");
+              bind(BlueFoo.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
+      assertContains(
+          expected.getMessage(),
+          true,
+          "No implementation for java.lang.String annotated with",
           "BindingAnnotationTest$Blue(value=5) was bound",
           "at " + BindingAnnotationTest.class.getName(),
           getDeclaringSourcePart(getClass()));
@@ -113,15 +126,19 @@
   }
 
   static class BlueFoo {
-    @Inject @Blue(5) String s; 
+    @Inject
+    @Blue(5)
+    String s;
   }
-  
+
   static class RedFoo {
     @Inject @Red String s;
   }
-  
+
   static class ColorFoo {
-    @Inject @Color(b=2) String s;
+    @Inject
+    @Color(b = 2)
+    String s;
   }
 
   @Retention(RUNTIME)
@@ -129,39 +146,46 @@
   @interface Blue {
     int value();
   }
-  
+
   @Retention(RUNTIME)
   @BindingAnnotation
   @interface Red {
     int r() default 42;
+
     int g() default 42;
+
     int b() default 42;
   }
-  
+
   @Retention(RUNTIME)
   @BindingAnnotation
   @interface Color {
     int r() default 0;
+
     int g() default 0;
+
     int b();
   }
 
   public Blue createBlue(final int value) {
     return new Blue() {
+      @Override
       public int value() {
         return value;
       }
 
+      @Override
       public Class<? extends Annotation> annotationType() {
         return Blue.class;
       }
 
-      @Override public boolean equals(Object o) {
-        return o instanceof Blue
-            && ((Blue) o).value() == value;
+      @Override
+      public boolean equals(Object o) {
+        return o instanceof Blue && ((Blue) o).value() == value;
       }
 
-      @Override public int hashCode() {
+      @Override
+      public int hashCode() {
         return 127 * "value".hashCode() ^ value;
       }
     };
diff --git a/core/test/com/google/inject/BindingOrderTest.java b/core/test/com/google/inject/BindingOrderTest.java
index 6754cad..b9ca527 100644
--- a/core/test/com/google/inject/BindingOrderTest.java
+++ b/core/test/com/google/inject/BindingOrderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,41 +16,44 @@
 
 package com.google.inject;
 
-
-import junit.framework.TestCase;
-
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 
 public class BindingOrderTest extends TestCase {
 
   public void testBindingOutOfOrder() {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(BoundFirst.class);
-        bind(BoundSecond.class).to(BoundSecondImpl.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(BoundFirst.class);
+            bind(BoundSecond.class).to(BoundSecondImpl.class);
+          }
+        });
   }
 
   public static class BoundFirst {
-    @Inject public BoundFirst(BoundSecond boundSecond) { }
+    @Inject
+    public BoundFirst(BoundSecond boundSecond) {}
   }
 
-  interface BoundSecond { }
-  static class BoundSecondImpl implements BoundSecond { }
+  interface BoundSecond {}
+
+  static class BoundSecondImpl implements BoundSecond {}
 
   public void testBindingOrderAndScopes() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class);
-        bind(B.class).asEagerSingleton();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class);
+                bind(B.class).asEagerSingleton();
+              }
+            });
 
     assertSame(injector.getInstance(A.class).b, injector.getInstance(A.class).b);
   }
@@ -58,34 +61,39 @@
   public void testBindingWithExtraThreads() throws InterruptedException {
     final CountDownLatch ready = new CountDownLatch(1);
     final CountDownLatch done = new CountDownLatch(1);
-    final AtomicReference<B> ref = new AtomicReference<B>();
+    final AtomicReference<B> ref = new AtomicReference<>();
 
-    final Object createsAThread = new Object() {
-      @Inject void createAnotherThread(final Injector injector) {
-        new Thread() {
-          public void run() {
-            ready.countDown();
-            A a = injector.getInstance(A.class);
-            ref.set(a.b);
-            done.countDown();
+    final Object createsAThread =
+        new Object() {
+          @Inject
+          void createAnotherThread(final Injector injector) {
+            new Thread() {
+              @Override
+              public void run() {
+                ready.countDown();
+                A a = injector.getInstance(A.class);
+                ref.set(a.b);
+                done.countDown();
+              }
+            }.start();
+
+            // to encourage collisions, we make sure the other thread is running before returning
+            try {
+              ready.await();
+            } catch (InterruptedException e) {
+              throw new RuntimeException(e);
+            }
           }
-        }.start();
+        };
 
-        // to encourage collisions, we make sure the other thread is running before returning
-        try {
-          ready.await();
-        } catch (InterruptedException e) {
-          throw new RuntimeException(e);
-        }
-      }
-    };
-
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        requestInjection(createsAThread);
-        bind(A.class).toInstance(new A());
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestInjection(createsAThread);
+            bind(A.class).toInstance(new A());
+          }
+        });
 
     done.await();
     assertNotNull(ref.get());
@@ -95,5 +103,5 @@
     @Inject B b;
   }
 
-  static class B { }
+  static class B {}
 }
diff --git a/core/test/com/google/inject/BindingTest.java b/core/test/com/google/inject/BindingTest.java
index 7da597d..3876bab 100644
--- a/core/test/com/google/inject/BindingTest.java
+++ b/core/test/com/google/inject/BindingTest.java
@@ -22,7 +22,9 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.Runnables;
+import com.google.inject.internal.Annotations;
 import com.google.inject.matcher.Matchers;
+import com.google.inject.name.Named;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.TypeEncounter;
 import com.google.inject.spi.TypeListener;
@@ -35,6 +37,7 @@
 /*end[AOP]*/
 
 import java.lang.reflect.Constructor;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -54,12 +57,15 @@
   }
 
   public void testExplicitCyclicDependency() {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class);
-        bind(B.class);
-      }
-    }).getInstance(A.class);
+    Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class);
+                bind(B.class);
+              }
+            })
+        .getInstance(A.class);
   }
 
   static class A { @Inject B b; }
@@ -69,6 +75,7 @@
 
   static class MyModule extends AbstractModule {
 
+    @Override
     protected void configure() {
       // Linked.
       bind(Object.class).to(Runnable.class).in(Scopes.SINGLETON);
@@ -77,11 +84,15 @@
       bind(Runnable.class).toInstance(Runnables.doNothing());
 
       // Provider instance.
-      bind(Foo.class).toProvider(new Provider<Foo>() {
-        public Foo get() {
-          return new Foo();
-        }
-      }).in(Scopes.SINGLETON);
+      bind(Foo.class)
+          .toProvider(
+              new Provider<Foo>() {
+                @Override
+                public Foo get() {
+                  return new Foo();
+                }
+              })
+          .in(Scopes.SINGLETON);
 
       // Provider.
       bind(Foo.class)
@@ -99,6 +110,7 @@
   static class Foo {}
 
   public static class FooProvider implements Provider<Foo> {
+    @Override
     public Foo get() {
       throw new UnsupportedOperationException();
     }
@@ -108,11 +120,13 @@
 
   public void testBindToUnboundLinkedBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Collection.class).to(List.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Collection.class).to(List.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), "No implementation for java.util.List was bound.");
@@ -124,18 +138,22 @@
    * not to what the key is linked to.
    */
   public void testScopeIsAppliedToKeyNotTarget() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Integer.class).toProvider(Counter.class).asEagerSingleton();
-        bind(Number.class).toProvider(Counter.class).asEagerSingleton();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Integer.class).toProvider(Counter.class).asEagerSingleton();
+                bind(Number.class).toProvider(Counter.class).asEagerSingleton();
+              }
+            });
 
     assertNotSame(injector.getInstance(Integer.class), injector.getInstance(Number.class));
   }
 
   static class Counter implements Provider<Integer> {
     static AtomicInteger next = new AtomicInteger(1);
+    @Override
     public Integer get() {
       return next.getAndIncrement();
     }
@@ -219,19 +237,26 @@
     }
   }
 
+  @SuppressWarnings("InjectMultipleAtInjectConstructors")
   static class TooManyConstructors {
-    @Inject TooManyConstructors(Injector i) {}
-    @Inject TooManyConstructors() {}
+    @Inject
+    TooManyConstructors(Injector i) {}
+
+    @Inject
+    TooManyConstructors() {}
   }
 
   public void testToConstructorBinding() throws NoSuchMethodException {
     final Constructor<D> constructor = D.class.getConstructor(Stage.class);
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).toConstructor(constructor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Object.class).toConstructor(constructor);
+              }
+            });
 
     D d = (D) injector.getInstance(Object.class);
     assertEquals(Stage.DEVELOPMENT, d.stage);
@@ -242,12 +267,15 @@
     final Key<Object> s = new Key<Object>(named("s")) {};
     final Key<Object> i = new Key<Object>(named("i")) {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(s).toConstructor(constructor, new TypeLiteral<C<Stage>>() {});
-        bind(i).toConstructor(constructor, new TypeLiteral<C<Injector>>() {});
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(s).toConstructor(constructor, new TypeLiteral<C<Stage>>() {});
+                bind(i).toConstructor(constructor, new TypeLiteral<C<Injector>>() {});
+              }
+            });
 
     C<Stage> one = (C<Stage>) injector.getInstance(s);
     assertEquals(Stage.DEVELOPMENT, one.stage);
@@ -264,11 +292,13 @@
     final Constructor constructor = C.class.getConstructor(Stage.class, Object.class);
 
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Object.class).toConstructor(constructor);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Object.class).toConstructor(constructor);
+            }
+          });
       fail();
     } catch (CreationException expected) {
       assertContains(expected.getMessage(),
@@ -283,19 +313,24 @@
   public void testToConstructorAndMethodInterceptors() throws NoSuchMethodException {
     final Constructor<D> constructor = D.class.getConstructor(Stage.class);
     final AtomicInteger count = new AtomicInteger();
-    final MethodInterceptor countingInterceptor = new MethodInterceptor() {
-      public Object invoke(MethodInvocation methodInvocation) throws Throwable {
-        count.incrementAndGet();
-        return methodInvocation.proceed();
-      }
-    };
+    final MethodInterceptor countingInterceptor =
+        new MethodInterceptor() {
+          @Override
+          public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+            count.incrementAndGet();
+            return methodInvocation.proceed();
+          }
+        };
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).toConstructor(constructor);
-        bindInterceptor(Matchers.any(), Matchers.any(), countingInterceptor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Object.class).toConstructor(constructor);
+                bindInterceptor(Matchers.any(), Matchers.any(), countingInterceptor);
+              }
+            });
 
     D d = (D) injector.getInstance(Object.class);
     d.hashCode();
@@ -307,11 +342,14 @@
   public void testInaccessibleConstructor() throws NoSuchMethodException {
     final Constructor<E> constructor = E.class.getDeclaredConstructor(Stage.class);
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(E.class).toConstructor(constructor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(E.class).toConstructor(constructor);
+              }
+            });
 
     E e = injector.getInstance(E.class);
     assertEquals(Stage.DEVELOPMENT, e.stage);
@@ -325,14 +363,17 @@
     final Key<Object> n = Key.get(Object.class, named("N")); // "N" instances
     final Key<Object> r = Key.get(Object.class, named("R")); // a regular binding
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(d).toConstructor(constructor);
-        bind(s).toConstructor(constructor).in(Singleton.class);
-        bind(n).toConstructor(constructor).in(Scopes.NO_SCOPE);
-        bind(r).to(F.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(d).toConstructor(constructor);
+                bind(s).toConstructor(constructor).in(Singleton.class);
+                bind(n).toConstructor(constructor).in(Scopes.NO_SCOPE);
+                bind(r).to(F.class);
+              }
+            });
 
     assertDistinct(injector, 1, d, d, d, d);
     assertDistinct(injector, 1, s, s, s, s);
@@ -353,21 +394,25 @@
     final Set<TypeLiteral<?>> heardTypes = Sets.newHashSet();
 
     final Constructor<D> constructor = D.class.getConstructor(Stage.class);
-    final TypeListener listener = new TypeListener() {
-      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-        if (!heardTypes.add(type)) {
-          fail("Heard " + type + " multiple times!");
-        }
-      }
-    };
+    final TypeListener listener =
+        new TypeListener() {
+          @Override
+          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+            if (!heardTypes.add(type)) {
+              fail("Heard " + type + " multiple times!");
+            }
+          }
+        };
 
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).toConstructor(constructor);
-        bind(D.class).toConstructor(constructor);
-        bindListener(Matchers.any(), listener);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Object.class).toConstructor(constructor);
+            bind(D.class).toConstructor(constructor);
+            bindListener(Matchers.any(), listener);
+          }
+        });
     
     assertEquals(ImmutableSet.of(TypeLiteral.get(D.class)), heardTypes);
   }
@@ -375,11 +420,14 @@
   public void testInterfaceToImplementationConstructor() throws NoSuchMethodException {
     final Constructor<CFoo> constructor = CFoo.class.getDeclaredConstructor();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(IFoo.class).toConstructor(constructor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(IFoo.class).toConstructor(constructor);
+              }
+            });
 
     injector.getInstance(IFoo.class);
   }
@@ -388,13 +436,16 @@
   public static class CFoo implements IFoo {}
 
   public void testGetAllBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(D.class).toInstance(new D(Stage.PRODUCTION));
-        bind(Object.class).to(D.class);
-        getProvider(new Key<C<Stage>>() {});
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(D.class).toInstance(new D(Stage.PRODUCTION));
+                bind(Object.class).to(D.class);
+                getProvider(new Key<C<Stage>>() {});
+              }
+            });
 
     Map<Key<?>,Binding<?>> bindings = injector.getAllBindings();
     assertEquals(ImmutableSet.of(Key.get(Injector.class), Key.get(Stage.class), Key.get(D.class),
@@ -419,11 +470,14 @@
   }
 
   public void testGetAllServletBindings() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(F.class); // an explicit binding that uses a JIT binding for a constructor
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(F.class); // an explicit binding that uses a JIT binding for a constructor
+              }
+            });
     injector.getAllBindings();
   }
 
@@ -469,6 +523,7 @@
       public void configure() {
         bind(Bacon.class).to(UncookedBacon.class);
         bind(Bacon.class).annotatedWith(named("Turkey")).to(TurkeyBacon.class);
+        bind(Bacon.class).annotatedWith(named("Tofu")).to(TofuBacon.class);
         bind(Bacon.class).annotatedWith(named("Cooked")).toConstructor(
             (Constructor)InjectionPoint.forConstructorOf(Bacon.class).getMember());
       }
@@ -483,21 +538,129 @@
     
     Bacon cookedBacon = injector.getInstance(Key.get(Bacon.class, named("Cooked")));
     assertEquals(Food.PORK, cookedBacon.getMaterial());
-    assertTrue(cookedBacon.isCooked());    
+    assertTrue(cookedBacon.isCooked());
+
+    try {
+      // Turkey typo, missing a letter...
+      injector.getInstance(Key.get(Bacon.class, named("Turky")));
+      fail();
+    } catch (ConfigurationException e) {
+      String msg = e.getMessage();
+      assertContains(
+          msg,
+          "Guice configuration errors:",
+          "1) No implementation for"
+              + " com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("Turky")
+              + ") was bound.",
+          "Did you mean?",
+          "* com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("Turkey")
+              + ")",
+          "* com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("Tofu")
+              + ")",
+          "1 more binding with other annotations.",
+          "while locating com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("Turky")
+              + ")");
+    }
   }
-  
-  enum Food { TURKEY, PORK }
-  
+
+  public void testMissingAnnotationOneChoice() {
+    Injector injector = Guice.createInjector(new AbstractModule() {
+      @SuppressWarnings("unchecked")
+      @Override
+      public void configure() {
+        bind(Bacon.class).annotatedWith(named("Turkey")).to(TurkeyBacon.class);
+      }
+    });
+
+    try {
+      // turkey typo (should be Upper case)...
+      injector.getInstance(Key.get(Bacon.class, named("turkey")));
+      fail();
+    } catch (ConfigurationException e) {
+      String msg = e.getMessage();
+      assertContains(msg, "Guice configuration errors:");
+      assertContains(
+          msg,
+          "1) No implementation for com.google.inject.BindingTest$Bacon"
+              + " annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("turkey")
+              + ") was bound.",
+          "Did you mean?",
+          "* com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("Turkey")
+              + ")",
+          "while locating com.google.inject.BindingTest$Bacon annotated with"
+              + " @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("turkey")
+              + ")");
+    }
+  }
+
+  enum Food { TURKEY, PORK, TOFU }
+
   private static class Bacon {
     public Food getMaterial() { return Food.PORK; }
     public boolean isCooked() { return true; }
   }
 
   private static class TurkeyBacon extends Bacon {
+    @Override
     public Food getMaterial() { return Food.TURKEY; }
   }
 
+  private static class TofuBacon extends Bacon {
+    @Override
+    public Food getMaterial() { return Food.TOFU; }
+  }
+
   private static class UncookedBacon extends Bacon {
+    @Override
     public boolean isCooked() { return false; }
   }
+
+  public void testMissingAnnotationRelated() {
+    try {
+      final TypeLiteral<List<Butter>> list = new TypeLiteral<List<Butter>>() {};
+
+      Guice.createInjector(new AbstractModule() {
+        @SuppressWarnings("unchecked")
+        @Override
+        public void configure() {
+          bind(list).toInstance(butters);
+          bind(Sandwitch.class).to(ButterSandwitch.class);
+        }
+      });
+
+      fail();
+    } catch (CreationException e) {
+      final String msg = e.getMessage();
+      assertContains(msg, "Unable to create injector, see the following errors:",
+          "Did you mean?",
+          "java.util.List<com.google.inject.BindingTest$Butter> bound"
+          + "  at com.google.inject.BindingTest$24.configure");
+    }
+  }
+
+  private static List<Butter> butters = new ArrayList<>();
+
+  private static interface Sandwitch {};
+
+  private static interface Butter {};
+
+  private static class ButterSandwitch implements Sandwitch {
+    private ButterSandwitch() {};
+
+    @Inject
+    ButterSandwitch(@Named("unsalted") Butter butter) {};
+  }
 }
diff --git a/core/test/com/google/inject/BoundInstanceInjectionTest.java b/core/test/com/google/inject/BoundInstanceInjectionTest.java
index 59fe8b2..7aa942d 100644
--- a/core/test/com/google/inject/BoundInstanceInjectionTest.java
+++ b/core/test/com/google/inject/BoundInstanceInjectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,32 +22,32 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.name.Named;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class BoundInstanceInjectionTest extends TestCase {
 
   public void testInstancesAreInjected() throws CreationException {
     final O o = new O();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(O.class).toInstance(o);
-        bind(int.class).toInstance(5);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(O.class).toInstance(o);
+                bind(int.class).toInstance(5);
+              }
+            });
 
     assertEquals(5, o.fromMethod);
   }
 
   static class O {
     int fromMethod;
+
     @Inject
     void setInt(int i) {
       this.fromMethod = i;
@@ -55,65 +55,87 @@
   }
 
   public void testProvidersAreInjected() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(O.class).toProvider(new Provider<O>() {
-          @Inject int i;
-          public O get() {
-            O o = new O();
-            o.setInt(i);
-            return o;
-          }
-        });
-        bind(int.class).toInstance(5);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(O.class)
+                    .toProvider(
+                        new Provider<O>() {
+                          @Inject int i;
+
+                          @Override
+                          public O get() {
+                            O o = new O();
+                            o.setInt(i);
+                            return o;
+                          }
+                        });
+                bind(int.class).toInstance(5);
+              }
+            });
 
     assertEquals(5, injector.getInstance(O.class).fromMethod);
   }
 
   public void testMalformedInstance() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Object.class).toInstance(new MalformedInjectable());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Object.class).toInstance(new MalformedInjectable());
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      Asserts.assertContains(expected.getMessage(), MalformedInjectable.class.getName(),
-          ".doublyAnnotated() has more than one ", "annotation annotated with @BindingAnnotation: ",
+      Asserts.assertContains(
+          expected.getMessage(),
+          MalformedInjectable.class.getName(),
+          ".doublyAnnotated() has more than one ",
+          "annotation annotated with @BindingAnnotation: ",
           Named.class.getName() + " and " + Another.class.getName());
     }
   }
 
   public void testMalformedProvider() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(String.class).toProvider(new MalformedProvider());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(String.class).toProvider(new MalformedProvider());
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      Asserts.assertContains(expected.getMessage(), MalformedProvider.class.getName(),
-          ".doublyAnnotated() has more than one ", "annotation annotated with @BindingAnnotation: ",
+      Asserts.assertContains(
+          expected.getMessage(),
+          MalformedProvider.class.getName(),
+          ".doublyAnnotated() has more than one ",
+          "annotation annotated with @BindingAnnotation: ",
           Named.class.getName() + " and " + Another.class.getName());
     }
   }
 
   static class MalformedInjectable {
-    @Inject void doublyAnnotated(@Named("a") @Another String unused) {}
+    @Inject
+    void doublyAnnotated(@Named("a") @Another String unused) {}
   }
 
   static class MalformedProvider implements Provider<String> {
-    @Inject void doublyAnnotated(@Named("a") @Another String s) {}
+    @Inject
+    void doublyAnnotated(@Named("a") @Another String s) {}
 
+    @Override
     public String get() {
       return "a";
     }
   }
 
-  @BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
+  @BindingAnnotation
+  @Target({FIELD, PARAMETER, METHOD})
+  @Retention(RUNTIME)
   public @interface Another {}
 }
diff --git a/core/test/com/google/inject/BoundProviderTest.java b/core/test/com/google/inject/BoundProviderTest.java
index 5fc46f4..6c21f5f 100644
--- a/core/test/com/google/inject/BoundProviderTest.java
+++ b/core/test/com/google/inject/BoundProviderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,17 +18,18 @@
 
 import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class BoundProviderTest extends TestCase {
 
   public void testFooProvider() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toProvider(FooProvider.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(FooProvider.class);
+              }
+            });
 
     Foo a = injector.getInstance(Foo.class);
     Foo b = injector.getInstance(Foo.class);
@@ -41,11 +42,14 @@
   }
 
   public void testSingletonFooProvider() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toProvider(SingletonFooProvider.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(SingletonFooProvider.class);
+              }
+            });
 
     Foo a = injector.getInstance(Foo.class);
     Foo b = injector.getInstance(Foo.class);
@@ -79,6 +83,7 @@
       this.bar = bar;
     }
 
+    @Override
     public Foo get() {
       return new Foo(this.bar, count++);
     }
@@ -95,6 +100,7 @@
       this.bar = bar;
     }
 
+    @Override
     public Foo get() {
       return new Foo(this.bar, count++);
     }
diff --git a/core/test/com/google/inject/CircularDependencyTest.java b/core/test/com/google/inject/CircularDependencyTest.java
index 2b67f7b..4367873 100644
--- a/core/test/com/google/inject/CircularDependencyTest.java
+++ b/core/test/com/google/inject/CircularDependencyTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,88 +21,108 @@
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import junit.framework.TestCase;
 
 /**
  * @author crazybob@google.com (Bob Lee)
  * @author sameb@google.com (Sam Berlin)
  */
 public class CircularDependencyTest extends TestCase {
-  
+
   @Override
   protected void setUp() throws Exception {
     AImpl.nextId = 0;
     BImpl.nextId = 0;
   }
 
-  public void testCircularlyDependentConstructors()
-      throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).to(AImpl.class);
-        bind(B.class).to(BImpl.class);
-      }
-    });
+  public void testCircularlyDependentConstructors() throws CreationException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).to(AImpl.class);
+                bind(B.class).to(BImpl.class);
+              }
+            });
     assertCircularDependencies(injector);
   }
-  
-  public void testCircularlyDependentConstructorsWithProviderMethods()
-      throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {}
-      
-      @Provides @Singleton A a(B b) { return new AImpl(b); }
-      @Provides B b(A a) { return new BImpl(a); }
-    });
+
+  public void testCircularlyDependentConstructorsWithProviderMethods() throws CreationException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+
+              @Provides
+              @Singleton
+              A a(B b) {
+                return new AImpl(b);
+              }
+
+              @Provides
+              B b(A a) {
+                return new BImpl(a);
+              }
+            });
     assertCircularDependencies(injector);
   }
-  
-  public void testCircularlyDependentConstructorsWithProviderInstances()
-      throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).toProvider(new Provider<A>() {
-          @Inject Provider<B> bp;
-          public A get() {
-            return new AImpl(bp.get());
-          }
-        }).in(Singleton.class);
-        bind(B.class).toProvider(new Provider<B>() {
-          @Inject Provider<A> ap;
-          public B get() {
-            return new BImpl(ap.get());
-          }
-        });
-      }
-    });
+
+  public void testCircularlyDependentConstructorsWithProviderInstances() throws CreationException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class)
+                    .toProvider(
+                        new Provider<A>() {
+                          @Inject Provider<B> bp;
+
+                          @Override
+                          public A get() {
+                            return new AImpl(bp.get());
+                          }
+                        })
+                    .in(Singleton.class);
+                bind(B.class)
+                    .toProvider(
+                        new Provider<B>() {
+                          @Inject Provider<A> ap;
+
+                          @Override
+                          public B get() {
+                            return new BImpl(ap.get());
+                          }
+                        });
+              }
+            });
     assertCircularDependencies(injector);
   }
-  
-  public void testCircularlyDependentConstructorsWithProviderKeys()
-      throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).toProvider(AP.class).in(Singleton.class);
-        bind(B.class).toProvider(BP.class);
-      }
-    });
+
+  public void testCircularlyDependentConstructorsWithProviderKeys() throws CreationException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).toProvider(AP.class).in(Singleton.class);
+                bind(B.class).toProvider(BP.class);
+              }
+            });
     assertCircularDependencies(injector);
   }
-  
-  public void testCircularlyDependentConstructorsWithProvidedBy()
-      throws CreationException {
+
+  public void testCircularlyDependentConstructorsWithProvidedBy() throws CreationException {
     Injector injector = Guice.createInjector();
     assertCircularDependencies(injector);
   }
-  
+
   private void assertCircularDependencies(Injector injector) {
     A a = injector.getInstance(A.class);
     assertNotNull(a.getB().getA());
@@ -117,6 +137,7 @@
   @ProvidedBy(AutoAP.class)
   public interface A {
     B getB();
+
     int id();
   }
 
@@ -124,31 +145,40 @@
   static class AImpl implements A {
     static int nextId;
     int id = nextId++;
-    
+
     final B b;
-    @Inject public AImpl(B b) {
+
+    @Inject
+    public AImpl(B b) {
       this.b = b;
     }
+
+    @Override
     public int id() {
       return id;
     }
+
+    @Override
     public B getB() {
       return b;
     }
   }
-  
+
   static class AP implements Provider<A> {
     @Inject Provider<B> bp;
+
+    @Override
     public A get() {
       return new AImpl(bp.get());
     }
   }
-  
+
   @Singleton
   static class AutoAP implements Provider<A> {
     @Inject Provider<B> bp;
     A a;
-    
+
+    @Override
     public A get() {
       if (a == null) {
         a = new AImpl(bp.get());
@@ -160,30 +190,41 @@
   @ProvidedBy(BP.class)
   public interface B {
     A getA();
+
     int id();
   }
 
   static class BImpl implements B {
     static int nextId;
     int id = nextId++;
-    
+
     final A a;
-    @Inject public BImpl(A a) {
+
+    @Inject
+    public BImpl(A a) {
       this.a = a;
     }
+
+    @Override
     public int id() {
       return id;
     }
+
+    @Override
     public A getA() {
       return a;
     }
   }
-  
+
   static class BP implements Provider<B> {
     Provider<A> ap;
-    @Inject BP(Provider<A> ap) {
+
+    @Inject
+    BP(Provider<A> ap) {
       this.ap = ap;
     }
+
+    @Override
     public B get() {
       return new BImpl(ap.get());
     }
@@ -194,180 +235,242 @@
       Guice.createInjector().getInstance(C.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Tried proxying " + C.class.getName() + " to support a circular dependency, ",
           "but it is not an interface.");
     }
   }
-  
+
   public void testUnresolvableCircularDependenciesWithProviderInstances() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {}        
-        @Provides C c(D d) { return null; }
-        @Provides D d(C c) { return null; }
-      }).getInstance(C.class);
+      Guice.createInjector(
+              new AbstractModule() {
+
+                @Provides
+                C c(D d) {
+                  return null;
+                }
+
+                @Provides
+                D d(C c) {
+                  return null;
+                }
+              })
+          .getInstance(C.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Tried proxying " + C.class.getName() + " to support a circular dependency, ",
           "but it is not an interface.");
     }
   }
-  
+
   public void testUnresolvableCircularDependenciesWithProviderKeys() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(C2.class).toProvider(C2P.class);
-          bind(D2.class).toProvider(D2P.class);
-        }
-      }).getInstance(C2.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  bind(C2.class).toProvider(C2P.class);
+                  bind(D2.class).toProvider(D2P.class);
+                }
+              })
+          .getInstance(C2.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Tried proxying " + C2.class.getName() + " to support a circular dependency, ",
           "but it is not an interface.");
     }
   }
-  
+
   public void testUnresolvableCircularDependenciesWithProvidedBy() {
     try {
       Guice.createInjector().getInstance(C2.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Tried proxying " + C2.class.getName() + " to support a circular dependency, ",
           "but it is not an interface.");
     }
   }
 
   static class C {
-    @Inject C(D d) {}
+    @Inject
+    C(D d) {}
   }
+
   static class D {
-    @Inject D(C c) {}
+    @Inject
+    D(C c) {}
   }
-  
+
   static class C2P implements Provider<C2> {
     @Inject Provider<D2> dp;
+
+    @Override
     public C2 get() {
       dp.get();
       return null;
     }
   }
+
   static class D2P implements Provider<D2> {
     @Inject Provider<C2> cp;
+
+    @Override
     public D2 get() {
       cp.get();
       return null;
     }
   }
+
   @ProvidedBy(C2P.class)
   static class C2 {
-    @Inject C2(D2 d) {}
+    @Inject
+    C2(D2 d) {}
   }
+
   @ProvidedBy(D2P.class)
   static class D2 {
-    @Inject D2(C2 c) {}
+    @Inject
+    D2(C2 c) {}
   }
-  
+
   public void testDisabledCircularDependency() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().disableCircularProxies();
-        }
-      }).getInstance(C.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().disableCircularProxies();
+                }
+              })
+          .getInstance(C.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "Tried proxying " + C.class.getName() + " to support a circular dependency, ",
-          "but circular proxies are disabled.");
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + C.class.getName()
+              + ", and circular dependencies are disabled.");
     }
   }
-  
+
   public void testDisabledCircularDependenciesWithProviderInstances() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          binder().disableCircularProxies();
-        }        
-        @Provides C c(D d) { return null; }
-        @Provides D d(C c) { return null; }
-      }).getInstance(C.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().disableCircularProxies();
+                }
+
+                @Provides
+                C c(D d) {
+                  return null;
+                }
+
+                @Provides
+                D d(C c) {
+                  return null;
+                }
+              })
+          .getInstance(C.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "Tried proxying " + C.class.getName() + " to support a circular dependency, ",
-          "but circular proxies are disabled.");
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + C.class.getName()
+              + ", and circular dependencies are disabled.");
     }
   }
-  
+
   public void testDisabledCircularDependenciesWithProviderKeys() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          binder().disableCircularProxies();
-          bind(C2.class).toProvider(C2P.class);
-          bind(D2.class).toProvider(D2P.class);
-        }
-      }).getInstance(C2.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().disableCircularProxies();
+                  bind(C2.class).toProvider(C2P.class);
+                  bind(D2.class).toProvider(D2P.class);
+                }
+              })
+          .getInstance(C2.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "Tried proxying " + C2.class.getName() + " to support a circular dependency, ",
-          "but circular proxies are disabled.");
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + C2.class.getName()
+              + ", and circular dependencies are disabled.");
     }
   }
-  
+
   public void testDisabledCircularDependenciesWithProvidedBy() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().disableCircularProxies();
-        }
-      }).getInstance(C2.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().disableCircularProxies();
+                }
+              })
+          .getInstance(C2.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "Tried proxying " + C2.class.getName() + " to support a circular dependency, ",
-          "but circular proxies are disabled.");
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + C2.class.getName()
+              + ", and circular dependencies are disabled.");
     }
   }
 
   /**
-   * As reported by issue 349, we give a lousy trace when a class is circularly
-   * dependent on itself in multiple ways.
+   * As reported by issue 349, we give a lousy trace when a class is circularly dependent on itself
+   * in multiple ways.
    */
   public void testCircularlyDependentMultipleWays() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        binder.bind(A.class).to(E.class);
-        binder.bind(B.class).to(E.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder.bind(A.class).to(E.class);
+                binder.bind(B.class).to(E.class);
+              }
+            });
     injector.getInstance(A.class);
   }
-  
-  public void testDisablingCircularProxies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        binder().disableCircularProxies();
-        binder.bind(A.class).to(E.class);
-        binder.bind(B.class).to(E.class);
-      }
-    });
-    
+
+  public void testDisablingCircularDependencies() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().disableCircularProxies();
+                binder.bind(A.class).to(E.class);
+                binder.bind(B.class).to(E.class);
+              }
+            });
+
     try {
       injector.getInstance(A.class);
       fail("expected exception");
-    } catch(ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "Tried proxying " + A.class.getName() + " to support a circular dependency, but circular proxies are disabled", 
-          "Tried proxying " + B.class.getName() + " to support a circular dependency, but circular proxies are disabled");
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + A.class.getName()
+              + ", and circular dependencies are disabled.");
     }
   }
 
@@ -376,31 +479,35 @@
     @Inject
     public E(A a, B b) {}
 
+    @Override
     public B getB() {
       return this;
     }
 
+    @Override
     public A getA() {
       return this;
     }
-    
+
+    @Override
     public int id() {
       return 0;
     }
   }
 
-
   public void testCircularDependencyProxyDelegateNeverInitialized() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(F.class).to(RealF.class);
-        bind(G.class).to(RealG.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(F.class).to(RealF.class);
+                bind(G.class).to(RealG.class);
+              }
+            });
     F f = injector.getInstance(F.class);
     assertEquals("F", f.g().f().toString());
     assertEquals("G", f.g().f().g().toString());
-
   }
 
   public interface F {
@@ -410,15 +517,19 @@
   @Singleton
   public static class RealF implements F {
     private final G g;
-    @Inject RealF(G g) {
+
+    @Inject
+    RealF(G g) {
       this.g = g;
     }
 
+    @Override
     public G g() {
       return g;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "F";
     }
   }
@@ -430,109 +541,128 @@
   @Singleton
   public static class RealG implements G {
     private final F f;
-    @Inject RealG(F f) {
+
+    @Inject
+    RealG(F f) {
       this.f = f;
     }
 
+    @Override
     public F f() {
       return f;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "G";
     }
   }
-  
+
   /**
-   * Tests that ProviderInternalFactory can detect circular dependencies
-   * before it gets to Scopes.SINGLETON.  This is especially important
-   * because the failure in Scopes.SINGLETON doesn't have enough context to
-   * provide a decent error message.
+   * Tests that ProviderInternalFactory can detect circular dependencies before it gets to
+   * Scopes.SINGLETON. This is especially important because the failure in Scopes.SINGLETON doesn't
+   * have enough context to provide a decent error message.
    */
   public void testCircularDependenciesDetectedEarlyWhenDependenciesHaveDifferentTypes() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Number.class).to(Integer.class);
-      }
-      
-      @Provides @Singleton Integer provideInteger(List list) { 
-        return new Integer(2);
-      }
-      
-      @Provides List provideList(Integer integer) {
-        return new ArrayList();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Number.class).to(Integer.class);
+              }
+
+              @Provides
+              @Singleton
+              Integer provideInteger(List list) {
+                return 2;
+              }
+
+              @Provides
+              List provideList(Integer integer) {
+                return new ArrayList();
+              }
+            });
     try {
       injector.getInstance(Number.class);
       fail();
-    } catch(ProvisionException expected) {
-      assertContains(expected.getMessage(),
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
           "Tried proxying " + Integer.class.getName() + " to support a circular dependency, ",
-          "but it is not an interface.");      
+          "but it is not an interface.");
     }
   }
-  
+
   public void testPrivateModulesDontTriggerCircularErrorsInProviders() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new PrivateModule() {
-          @Override
-          protected void configure() {
-            bind(Foo.class);
-            expose(Foo.class);
-          }
-          @Provides String provideString(Bar bar) {
-            return new String("private 1, " + bar.string);
-          }
-        });
-        install(new PrivateModule() {
-          @Override
-          protected void configure() {
-            bind(Bar.class);
-            expose(Bar.class);
-          }
-          @Provides String provideString() {
-            return new String("private 2");
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new PrivateModule() {
+                      @Override
+                      protected void configure() {
+                        bind(Foo.class);
+                        expose(Foo.class);
+                      }
+
+                      @Provides
+                      String provideString(Bar bar) {
+                        return new String("private 1, " + bar.string);
+                      }
+                    });
+                install(
+                    new PrivateModule() {
+                      @Override
+                      protected void configure() {
+                        bind(Bar.class);
+                        expose(Bar.class);
+                      }
+
+                      @Provides
+                      String provideString() {
+                        return new String("private 2");
+                      }
+                    });
+              }
+            });
     Foo foo = injector.getInstance(Foo.class);
     assertEquals("private 1, private 2", foo.string);
   }
+
   static class Foo {
     @Inject String string;
   }
+
   static class Bar {
     @Inject String string;
   }
-  
+
   /**
-   * When Scope Providers call their unscoped Provider's get() methods are
-   * called, it's possible that the result is a circular proxy designed for one
-   * specific parameter (not for all possible parameters). But custom scopes
-   * typically cache the results without checking to see if the result is a
-   * proxy. This leads to caching a result that is unsuitable for reuse for
-   * other parameters.
-   * 
-   * This means that custom proxies have to do an
-   *   {@code if(Scopes.isCircularProxy(..))}
-   * in order to avoid exceptions.
+   * When Scope Providers call their unscoped Provider's get() methods are called, it's possible
+   * that the result is a circular proxy designed for one specific parameter (not for all possible
+   * parameters). But custom scopes typically cache the results without checking to see if the
+   * result is a proxy. This leads to caching a result that is unsuitable for reuse for other
+   * parameters.
+   *
+   * <p>This means that custom proxies have to do an {@code if(Scopes.isCircularProxy(..))} in order
+   * to avoid exceptions.
    */
   public void testCustomScopeCircularProxies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindScope(SimpleSingleton.class, new BasicSingleton());
-        bind(H.class).to(HImpl.class);
-        bind(I.class).to(IImpl.class);
-        bind(J.class).to(JImpl.class);
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(SimpleSingleton.class, new BasicSingleton());
+                bind(H.class).to(HImpl.class);
+                bind(I.class).to(IImpl.class);
+                bind(J.class).to(JImpl.class);
+              }
+            });
+
     // The reason this happens is because the Scope gets these requests, in order:
     // entry: Key<IImpl> (1 - from getInstance call)
     // entry: Key<HImpl>
@@ -540,47 +670,61 @@
     // result of 2nd Key<IImpl> - a com.google.inject.$Proxy, because it's a circular proxy
     // result of Key<HImpl> - an HImpl
     // entry: Key<JImpl>
-    // entry: Key<IImpl> (3 - another circular dependency, this time from JImpl)    
+    // entry: Key<IImpl> (3 - another circular dependency, this time from JImpl)
     // At this point, if the first Key<Impl> result was cached, our cache would have
     //  Key<IImpl> caching to an instanceof of I, but not an an instanceof of IImpl.
     // If returned this, it would result in cglib giving a ClassCastException or
     // java reflection giving an IllegalArgumentException when filling in parameters
     // for the constructor, because JImpl wants an IImpl, not an I.
-    
+
     try {
       injector.getInstance(IImpl.class);
       fail();
-    } catch(ProvisionException pe) {
-      assertContains(Iterables.getOnlyElement(pe.getErrorMessages()).getMessage(),
-          "Tried proxying " + IImpl.class.getName()
-          + " to support a circular dependency, but it is not an interface.");
+    } catch (ProvisionException pe) {
+      assertContains(
+          Iterables.getOnlyElement(pe.getErrorMessages()).getMessage(),
+          "Tried proxying "
+              + IImpl.class.getName()
+              + " to support a circular dependency, but it is not an interface.");
     }
   }
-  
+
   interface H {}
+
   interface I {}
+
   interface J {}
+
   @SimpleSingleton
   static class HImpl implements H {
-     @Inject HImpl(I i) {}     
+    @Inject
+    HImpl(I i) {}
   }
+
   @SimpleSingleton
   static class IImpl implements I {
-     @Inject IImpl(HImpl i, J j) {}
+    @Inject
+    IImpl(HImpl i, J j) {}
   }
+
   @SimpleSingleton
   static class JImpl implements J {
-     @Inject JImpl(IImpl i) {}
+    @Inject
+    JImpl(IImpl i) {}
   }
-  
-  @Target({ ElementType.TYPE, ElementType.METHOD })
+
+  @Target({ElementType.TYPE, ElementType.METHOD})
   @Retention(RUNTIME)
   @ScopeAnnotation
   public @interface SimpleSingleton {}
+
   public static class BasicSingleton implements Scope {
-    private static Map<Key, Object> cache = Maps.newHashMap();
+    private static Map<Key<?>, Object> cache = Maps.newHashMap();
+
+    @Override
     public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
       return new Provider<T>() {
+        @Override
         @SuppressWarnings("unchecked")
         public T get() {
           if (!cache.containsKey(key)) {
@@ -590,9 +734,51 @@
             }
             cache.put(key, t);
           }
-          return (T)cache.get(key);
+          return (T) cache.get(key);
         }
       };
     }
   }
+
+  public void testDisabledNonConstructorCircularDependencies() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().disableCircularProxies();
+              }
+            });
+
+    try {
+      injector.getInstance(K.class);
+      fail("expected exception");
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + K.class.getName()
+              + ", and circular dependencies are disabled.");
+    }
+
+    try {
+      injector.getInstance(L.class);
+      fail("expected exception");
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "Found a circular dependency involving "
+              + L.class.getName()
+              + ", and circular dependencies are disabled.");
+    }
+  }
+
+  static class K {
+    @Inject L l;
+  }
+
+  static class L {
+    @Inject
+    void inject(K k) {}
+  }
 }
diff --git a/core/test/com/google/inject/DuplicateBindingsTest.java b/core/test/com/google/inject/DuplicateBindingsTest.java
index 27a2fd1..fb0747e 100644
--- a/core/test/com/google/inject/DuplicateBindingsTest.java
+++ b/core/test/com/google/inject/DuplicateBindingsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,9 +25,6 @@
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.util.Arrays;
@@ -35,14 +32,15 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.logging.Logger;
+import junit.framework.TestCase;
 
 /**
  * A suite of tests for duplicate bindings.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 public class DuplicateBindingsTest extends TestCase {
-  
+
   private FooImpl foo = new FooImpl();
   private Provider<Foo> pFoo = Providers.<Foo>of(new FooImpl());
   private Class<? extends Provider<? extends Foo>> pclFoo = FooProvider.class;
@@ -50,13 +48,13 @@
   private Constructor<FooImpl> cFoo = FooImpl.cxtor();
 
   public void testDuplicateBindingsAreIgnored() {
-    Injector injector = Guice.createInjector(
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+    Injector injector =
+        Guice.createInjector(
+            new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
+            new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo));
     List<Key<?>> bindings = Lists.newArrayList(injector.getAllBindings().keySet());
     removeBasicBindings(bindings);
-    
+
     // Ensure only one binding existed for each type.
     assertTrue(bindings.remove(Key.get(Foo.class, named("instance"))));
     assertTrue(bindings.remove(Key.get(Foo.class, named("pInstance"))));
@@ -66,88 +64,119 @@
     assertTrue(bindings.remove(Key.get(Foo.class, named("constructor"))));
     assertTrue(bindings.remove(Key.get(FooProvider.class))); // JIT binding
     assertTrue(bindings.remove(Key.get(Foo.class, named("providerMethod"))));
-    
+
     assertEquals(bindings.toString(), 0, bindings.size());
   }
-  
+
   public void testElementsDeduplicate() {
-    List<Element> elements = Elements.getElements(
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+    List<Element> elements =
+        Elements.getElements(
+            new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
+            new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo));
     assertEquals(14, elements.size());
     assertEquals(7, new LinkedHashSet<Element>(elements).size());
   }
-  
+
   public void testProviderMethodsFailIfInstancesDiffer() {
     try {
       Guice.createInjector(new FailingProviderModule(), new FailingProviderModule());
       fail("should have failed");
-    } catch(CreationException ce) {
-      assertContains(ce.getMessage(),
-          "A binding to " + Foo.class.getName() + " was already configured " +
-          "at " + FailingProviderModule.class.getName(),
-          "at " + FailingProviderModule.class.getName()
-          );
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "A binding to "
+              + Foo.class.getName()
+              + " was already configured "
+              + "at "
+              + FailingProviderModule.class.getName(),
+          "at " + FailingProviderModule.class.getName());
     }
   }
-  
+
   public void testSameScopeInstanceIgnored() {
     Guice.createInjector(
         new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
-        new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
-    );
-    
+        new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo));
+
     Guice.createInjector(
         new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo),
-        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo));
   }
-  
+
   public void testSameScopeAnnotationIgnored() {
     Guice.createInjector(
         new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo),
-        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo));
   }
-  
+
   public void testMixedAnnotationAndScopeForSingletonIgnored() {
     Guice.createInjector(
         new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
-        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo));
   }
-  
+
   public void testMixedScopeAndUnscopedIgnored() {
     Guice.createInjector(
         new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo));
   }
 
   public void testMixedScopeFails() {
     try {
       Guice.createInjector(
           new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-          new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
-      );
+          new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo));
       fail("expected exception");
-    } catch(CreationException ce) {
-      String segment1 = "A binding to " + Foo.class.getName() + " annotated with "
-          + named("pInstance") + " was already configured at " + SimpleModule.class.getName();
-      String segment2 = "A binding to " + Foo.class.getName() + " annotated with " + named("pKey")
-          + " was already configured at " + SimpleModule.class.getName();
-      String segment3 = "A binding to " + Foo.class.getName() + " annotated with " 
-          + named("constructor") + " was already configured at " + SimpleModule.class.getName();
-      String segment4 = "A binding to " + FooImpl.class.getName() + " was already configured at "
-          + SimpleModule.class.getName();
+    } catch (CreationException ce) {
+      String segment1 =
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pInstance")
+              + " was already configured at "
+              + SimpleModule.class.getName();
+      String segment2 =
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pKey")
+              + " was already configured at "
+              + SimpleModule.class.getName();
+      String segment3 =
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("constructor")
+              + " was already configured at "
+              + SimpleModule.class.getName();
+      String segment4 =
+          "A binding to "
+              + FooImpl.class.getName()
+              + " was already configured at "
+              + SimpleModule.class.getName();
       String atSegment = "at " + ScopedModule.class.getName();
       if (isIncludeStackTraceOff()) {
-        assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment3,
-            atSegment, segment4, atSegment);
+        assertContains(
+            ce.getMessage(),
+            segment1,
+            atSegment,
+            segment2,
+            atSegment,
+            segment3,
+            atSegment,
+            segment4,
+            atSegment);
       } else {
-        assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment4,
-            atSegment, segment3, atSegment);
+        assertContains(
+            ce.getMessage(),
+            segment1,
+            atSegment,
+            segment2,
+            atSegment,
+            segment4,
+            atSegment,
+            segment3,
+            atSegment);
       }
     }
   }
@@ -157,90 +186,138 @@
     try {
       Guice.createInjector(
           new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-          new SimpleModule(new FooImpl(), Providers.<Foo>of(new FooImpl()), 
-              (Class)BarProvider.class, (Class)Bar.class, (Constructor)Bar.cxtor())
-      );
+          new SimpleModule(
+              new FooImpl(),
+              Providers.<Foo>of(new FooImpl()),
+              (Class) BarProvider.class,
+              (Class) Bar.class,
+              (Constructor) Bar.cxtor()));
       fail("expected exception");
-    } catch(CreationException ce) {
-      assertContains(ce.getMessage(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
-          "at " + SimpleModule.class.getName(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
-          "at " + SimpleModule.class.getName(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pInstance")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
           "at " + SimpleModule.class.getName(),
-          "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pKey")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
+          "at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("linkedKey")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
+          "at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("constructor")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
           "at " + SimpleModule.class.getName());
     }
   }
-  
+
   public void testExceptionInEqualsThrowsCreationException() {
     try {
       Guice.createInjector(new ThrowingModule(), new ThrowingModule());
       fail("expected exception");
-    } catch(CreationException ce) {
-      assertContains(ce.getMessage(),
-          "A binding to " + Foo.class.getName() + " was already configured at " + ThrowingModule.class.getName(),
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "A binding to "
+              + Foo.class.getName()
+              + " was already configured at "
+              + ThrowingModule.class.getName(),
           "and an error was thrown while checking duplicate bindings.  Error: java.lang.RuntimeException: Boo!",
           "at " + ThrowingModule.class.getName());
     }
   }
-  
+
   public void testChildInjectorDuplicateParentFail() {
-    Injector injector = Guice.createInjector(
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
-    );
-    
+    Injector injector = Guice.createInjector(new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo));
+
     try {
-      injector.createChildInjector(
-          new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
-      );
+      injector.createChildInjector(new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo));
       fail("expected exception");
-    } catch(CreationException ce) {
-      assertContains(ce.getMessage(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
-          "at " + SimpleModule.class.getName(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
-          "at " + SimpleModule.class.getName(), 
-          "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pInstance")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
           "at " + SimpleModule.class.getName(),
-          "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("pKey")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
           "at " + SimpleModule.class.getName(),
-          "A binding to " + Foo.class.getName() + " annotated with " + named("providerMethod") + " was already configured at " + SimpleProviderModule.class.getName(),
-          "at " + SimpleProviderModule.class.getName()
-          );
-    } 
-    
-    
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("linkedKey")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
+          "at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("constructor")
+              + " was already configured at "
+              + SimpleModule.class.getName(),
+          "at " + SimpleModule.class.getName(),
+          "A binding to "
+              + Foo.class.getName()
+              + " annotated with "
+              + named("providerMethod")
+              + " was already configured at "
+              + SimpleProviderModule.class.getName(),
+          "at " + SimpleProviderModule.class.getName());
+    }
   }
-  
+
   public void testDuplicatesSolelyInChildIgnored() {
     Injector injector = Guice.createInjector();
     injector.createChildInjector(
         new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
-        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
-    );
+        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo));
   }
-  
+
   public void testDifferentBindingTypesFail() {
-    List<Element> elements = Elements.getElements(
-        new FailedModule(foo, pFoo, pclFoo, clFoo, cFoo)
-    );
-    
+    List<Element> elements = Elements.getElements(new FailedModule(foo, pFoo, pclFoo, clFoo, cFoo));
+
     // Make sure every combination of the elements with another element fails.
     // This ensures that duplication checks the kind of binding also.
-    for(Element e1 : elements) {
-      for(Element e2: elements) {
+    for (Element e1 : elements) {
+      for (Element e2 : elements) {
         // if they're the same, this shouldn't fail.
         try {
           Guice.createInjector(Elements.getModule(Arrays.asList(e1, e2)));
-          if(e1 != e2) {
+          if (e1 != e2) {
             fail("must fail!");
           }
-        } catch(CreationException expected) {
-          if(e1 != e2) {
-            assertContains(expected.getMessage(),
-                "A binding to " + Foo.class.getName() + " was already configured at " + FailedModule.class.getName(),
+        } catch (CreationException expected) {
+          if (e1 != e2) {
+            assertContains(
+                expected.getMessage(),
+                "A binding to "
+                    + Foo.class.getName()
+                    + " was already configured at "
+                    + FailedModule.class.getName(),
                 "at " + FailedModule.class.getName());
           } else {
             throw expected;
@@ -249,155 +326,180 @@
       }
     }
   }
-  
+
   public void testJitBindingsAreCheckedAfterConversions() {
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(A.class);
-       bind(A.class).to(RealA.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(A.class);
+            bind(A.class).to(RealA.class);
+          }
+        });
   }
-  
+
   public void testEqualsNotCalledByDefaultOnInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnEquals = true;
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(HashEqualsTester.class).toInstance(a);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class);
+            bind(HashEqualsTester.class).toInstance(a);
+          }
+        });
   }
-  
+
   public void testEqualsNotCalledByDefaultOnProvider() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnEquals = true;
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(Object.class).toProvider(a);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class);
+            bind(Object.class).toProvider(a);
+          }
+        });
   }
-  
+
   public void testHashcodeNeverCalledOnInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnHashcode = true;
     a.equality = "test";
-    
+
     final HashEqualsTester b = new HashEqualsTester();
     b.throwOnHashcode = true;
     b.equality = "test";
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(HashEqualsTester.class).toInstance(a);
-       bind(HashEqualsTester.class).toInstance(b);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class);
+            bind(HashEqualsTester.class).toInstance(a);
+            bind(HashEqualsTester.class).toInstance(b);
+          }
+        });
   }
-  
+
   public void testHashcodeNeverCalledOnProviderInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnHashcode = true;
     a.equality = "test";
-    
+
     final HashEqualsTester b = new HashEqualsTester();
     b.throwOnHashcode = true;
     b.equality = "test";
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(Object.class).toProvider(a);
-       bind(Object.class).toProvider(b);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class);
+            bind(Object.class).toProvider(a);
+            bind(Object.class).toProvider(b);
+          }
+        });
   }
 
   private static class RealA extends A {}
-  @ImplementedBy(RealA.class) private static class A {}
-  
+
+  @ImplementedBy(RealA.class)
+  private static class A {}
+
   private void removeBasicBindings(Collection<Key<?>> bindings) {
     bindings.remove(Key.get(Injector.class));
     bindings.remove(Key.get(Logger.class));
     bindings.remove(Key.get(Stage.class));
   }
-  
+
   private static class ThrowingModule extends AbstractModule {
     @Override
     protected void configure() {
-      bind(Foo.class).toInstance(new Foo() {
-        @Override
-        public boolean equals(Object obj) {
-          throw new RuntimeException("Boo!");
-        }
-      });
+      bind(Foo.class)
+          .toInstance(
+              new Foo() {
+                @Override
+                public boolean equals(Object obj) {
+                  throw new RuntimeException("Boo!");
+                }
+
+                @Override
+                public int hashCode() {
+                  throw new RuntimeException("Boo!");
+                }
+              });
     }
   }
-  
-  private static abstract class FooModule extends AbstractModule {
+
+  private abstract static class FooModule extends AbstractModule {
     protected final FooImpl foo;
     protected final Provider<Foo> pFoo;
     protected final Class<? extends Provider<? extends Foo>> pclFoo;
     protected final Class<? extends Foo> clFoo;
     protected final Constructor<FooImpl> cFoo;
-    
-    FooModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
-        Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
+
+    FooModule(
+        FooImpl foo,
+        Provider<Foo> pFoo,
+        Class<? extends Provider<? extends Foo>> pclFoo,
+        Class<? extends Foo> clFoo,
+        Constructor<FooImpl> cFoo) {
       this.foo = foo;
       this.pFoo = pFoo;
       this.pclFoo = pclFoo;
       this.clFoo = clFoo;
       this.cFoo = cFoo;
-    }    
+    }
   }
-  
+
   private static class FailedModule extends FooModule {
-    FailedModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
-        Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
+    FailedModule(
+        FooImpl foo,
+        Provider<Foo> pFoo,
+        Class<? extends Provider<? extends Foo>> pclFoo,
+        Class<? extends Foo> clFoo,
+        Constructor<FooImpl> cFoo) {
       super(foo, pFoo, pclFoo, clFoo, cFoo);
     }
-    
+
+    @Override
     protected void configure() {
       // InstanceBinding
       bind(Foo.class).toInstance(foo);
-      
+
       // ProviderInstanceBinding
       bind(Foo.class).toProvider(pFoo);
-      
+
       // ProviderKeyBinding
       bind(Foo.class).toProvider(pclFoo);
-      
+
       // LinkedKeyBinding
       bind(Foo.class).to(clFoo);
-      
+
       // ConstructorBinding
       bind(Foo.class).toConstructor(cFoo);
     }
-    
-    @Provides Foo foo() {
+
+    @Provides
+    Foo foo() {
       return null;
     }
   }
-  
-  private static class FailingProviderModule extends AbstractModule {
-    @Override protected void configure() {}
 
-    @Provides Foo foo() {
+  private static class FailingProviderModule extends AbstractModule {
+
+    @Provides
+    Foo foo() {
       return null;
     }
   }
 
   private static class SimpleProviderModule extends AbstractModule {
-    @Override protected void configure() {}
 
-    @Provides @Named("providerMethod") Foo foo() {
+    @Provides
+    @Named("providerMethod")
+    Foo foo() {
       return null;
     }
 
@@ -405,30 +507,35 @@
     public boolean equals(Object obj) {
       return obj.getClass() == getClass();
     }
-  }  
-  
+  }
+
   private static class SimpleModule extends FooModule {
-    SimpleModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
-        Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
+    SimpleModule(
+        FooImpl foo,
+        Provider<Foo> pFoo,
+        Class<? extends Provider<? extends Foo>> pclFoo,
+        Class<? extends Foo> clFoo,
+        Constructor<FooImpl> cFoo) {
       super(foo, pFoo, pclFoo, clFoo, cFoo);
     }
-    
+
+    @Override
     protected void configure() {
       // InstanceBinding
       bind(Foo.class).annotatedWith(named("instance")).toInstance(foo);
-      
+
       // ProviderInstanceBinding
       bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo);
-      
+
       // ProviderKeyBinding
       bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo);
-      
+
       // LinkedKeyBinding
       bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo);
-      
+
       // UntargettedBinding / ConstructorBinding
       bind(FooImpl.class);
-      
+
       // ConstructorBinding
       bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo);
 
@@ -438,68 +545,79 @@
       install(Elements.getModule(Elements.getElements(new SimpleProviderModule())));
     }
   }
-  
+
   private static class ScopedModule extends FooModule {
     private final Scope scope;
 
-    ScopedModule(Scope scope, FooImpl foo, Provider<Foo> pFoo,
-        Class<? extends Provider<? extends Foo>> pclFoo, Class<? extends Foo> clFoo,
+    ScopedModule(
+        Scope scope,
+        FooImpl foo,
+        Provider<Foo> pFoo,
+        Class<? extends Provider<? extends Foo>> pclFoo,
+        Class<? extends Foo> clFoo,
         Constructor<FooImpl> cFoo) {
       super(foo, pFoo, pclFoo, clFoo, cFoo);
       this.scope = scope;
     }
-    
+
+    @Override
     protected void configure() {
       // ProviderInstanceBinding
       bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
-      
+
       // ProviderKeyBinding
       bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
-      
+
       // LinkedKeyBinding
       bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
-      
+
       // UntargettedBinding / ConstructorBinding
       bind(FooImpl.class).in(scope);
-      
+
       // ConstructorBinding
       bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
     }
   }
-  
+
   private static class AnnotatedScopeModule extends FooModule {
     private final Class<? extends Annotation> scope;
 
-    AnnotatedScopeModule(Class<? extends Annotation> scope, FooImpl foo, Provider<Foo> pFoo,
-        Class<? extends Provider<? extends Foo>> pclFoo, Class<? extends Foo> clFoo,
+    AnnotatedScopeModule(
+        Class<? extends Annotation> scope,
+        FooImpl foo,
+        Provider<Foo> pFoo,
+        Class<? extends Provider<? extends Foo>> pclFoo,
+        Class<? extends Foo> clFoo,
         Constructor<FooImpl> cFoo) {
       super(foo, pFoo, pclFoo, clFoo, cFoo);
       this.scope = scope;
     }
-    
-    
+
+    @Override
     protected void configure() {
       // ProviderInstanceBinding
       bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
-      
+
       // ProviderKeyBinding
       bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
-      
+
       // LinkedKeyBinding
       bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
-      
+
       // UntargettedBinding / ConstructorBinding
       bind(FooImpl.class).in(scope);
-      
+
       // ConstructorBinding
       bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
     }
-  }  
-  
+  }
+
   private static interface Foo {}
+
   private static class FooImpl implements Foo {
-    @Inject public FooImpl() {}
-    
+    @Inject
+    public FooImpl() {}
+
     private static Constructor<FooImpl> cxtor() {
       try {
         return FooImpl.class.getConstructor();
@@ -509,16 +627,19 @@
         throw new RuntimeException(e);
       }
     }
-  }  
+  }
+
   private static class FooProvider implements Provider<Foo> {
+    @Override
     public Foo get() {
       return new FooImpl();
     }
   }
-  
+
   private static class Bar implements Foo {
-    @Inject public Bar() {}
-    
+    @Inject
+    public Bar() {}
+
     private static Constructor<Bar> cxtor() {
       try {
         return Bar.class.getConstructor();
@@ -528,28 +649,30 @@
         throw new RuntimeException(e);
       }
     }
-  }  
+  }
+
   private static class BarProvider implements Provider<Foo> {
+    @Override
     public Foo get() {
       return new Bar();
     }
   }
-  
+
   private static class HashEqualsTester implements Provider<Object> {
     private String equality;
     private boolean throwOnEquals;
     private boolean throwOnHashcode;
-    
+
     @Override
     public boolean equals(Object obj) {
       if (throwOnEquals) {
         throw new RuntimeException();
       } else if (obj instanceof HashEqualsTester) {
-        HashEqualsTester o = (HashEqualsTester)obj;
-        if(o.throwOnEquals) {
+        HashEqualsTester o = (HashEqualsTester) obj;
+        if (o.throwOnEquals) {
           throw new RuntimeException();
         }
-        if(equality == null && o.equality == null) {
+        if (equality == null && o.equality == null) {
           return this == o;
         } else {
           return Objects.equal(equality, o.equality);
@@ -558,19 +681,19 @@
         return false;
       }
     }
-    
+
     @Override
     public int hashCode() {
-      if(throwOnHashcode) {
+      if (throwOnHashcode) {
         throw new RuntimeException();
       } else {
         return super.hashCode();
       }
     }
-    
+
+    @Override
     public Object get() {
       return new Object();
     }
   }
-  
 }
diff --git a/core/test/com/google/inject/EagerSingletonTest.java b/core/test/com/google/inject/EagerSingletonTest.java
index d18f194..f7a32cf 100644
--- a/core/test/com/google/inject/EagerSingletonTest.java
+++ b/core/test/com/google/inject/EagerSingletonTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,37 +16,49 @@
 
 package com.google.inject;
 
+import static com.google.inject.Asserts.getClassPathUrls;
+
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class EagerSingletonTest extends TestCase {
 
-  @Override public void setUp() {
+  @Override
+  public void setUp() {
     A.instanceCount = 0;
     B.instanceCount = 0;
     C.instanceCount = 0;
   }
 
   public void testJustInTimeEagerSingletons() {
-    Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
-      protected void configure() {
-        // create a just-in-time binding for A
-        getProvider(A.class);
+    Guice.createInjector(
+        Stage.PRODUCTION,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            // create a just-in-time binding for A
+            getProvider(A.class);
 
-        // create a just-in-time binding for C
-        requestInjection(new Object() {
-          @Inject void inject(Injector injector) {
-            injector.getInstance(C.class);
+            // create a just-in-time binding for C
+            requestInjection(
+                new Object() {
+                  @Inject
+                  void inject(Injector injector) {
+                    injector.getInstance(C.class);
+                  }
+                });
           }
         });
-      }
-    });
 
     assertEquals(1, A.instanceCount);
-    assertEquals("Singletons discovered when creating singletons should not be built eagerly",
-        0, B.instanceCount);
+    assertEquals(
+        "Singletons discovered when creating singletons should not be built eagerly",
+        0,
+        B.instanceCount);
     assertEquals(1, C.instanceCount);
   }
 
@@ -58,28 +70,121 @@
 
   public void testChildEagerSingletons() {
     Injector parent = Guice.createInjector(Stage.PRODUCTION);
-    parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(D.class).to(C.class);
-      }
-    });
+    parent.createChildInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(D.class).to(C.class);
+          }
+        });
 
     assertEquals(1, C.instanceCount);
   }
 
+  // there used to be a bug that caused a concurrent modification exception if jit bindings were
+  // loaded during eager singleton creation due to failur to apply the lock when iterating over
+  // all bindings.
+
+  public void testJustInTimeEagerSingletons_multipleThreads() throws Exception {
+    // in order to make the data race more likely we need a lot of jit bindings.  The easiest thing
+    // is just to 'copy' out class for B a bunch of times.
+    final List<Class<?>> jitBindings = new ArrayList<>();
+    for (int i = 0; i < 1000; i++) {
+      jitBindings.add(copyClass(B.class));
+    }
+    Guice.createInjector(
+        Stage.PRODUCTION,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            // create a just-in-time binding for A
+            getProvider(A.class);
+
+            // create a just-in-time binding for C
+            requestInjection(
+                new Object() {
+                  @Inject
+                  void inject(final Injector injector) throws Exception {
+                    final CountDownLatch latch = new CountDownLatch(1);
+                    new Thread() {
+                      @Override
+                      public void run() {
+                        latch.countDown();
+                        for (Class<?> jitBinding : jitBindings) {
+                          // this causes the binding to be created
+                          injector.getProvider(jitBinding);
+                        }
+                      }
+                    }.start();
+                    latch.await(); // make sure the thread is running before returning
+                  }
+                });
+          }
+        });
+
+    assertEquals(1, A.instanceCount);
+    // our thread runs in parallel with eager singleton loading so some there should be some number
+    // N such that 0<=N <jitBindings.size() and all classes in jitBindings with an index < N will
+    // have been initialized.  Assert that!
+    int prev = -1;
+    int index = 0;
+    for (Class<?> jitBinding : jitBindings) {
+      int instanceCount = (Integer) jitBinding.getDeclaredField("instanceCount").get(null);
+      if (instanceCount != 0 && instanceCount != 1) {
+        fail("Should only have created zero or one instances, got " + instanceCount);
+      }
+      if (prev == -1) {
+        prev = instanceCount;
+      } else if (prev != instanceCount) {
+        if (prev != 1 && instanceCount != 0) {
+          fail("initialized later JIT bindings before earlier ones at index " + index);
+        }
+        prev = instanceCount;
+      }
+      index++;
+    }
+  }
+
+  /** Creates a copy of a class in a child classloader. */
+  private static Class<?> copyClass(final Class<?> cls) {
+    // To create a copy of a class we create a new child class loader with the same data as our
+    // parent and override loadClass to always load a new copy of cls.
+    try {
+      return new URLClassLoader(getClassPathUrls(), EagerSingletonTest.class.getClassLoader()) {
+        @Override
+        public Class<?> loadClass(String name) throws ClassNotFoundException {
+          // This means for every class besides cls we delegate to our parent (so things like
+          // @Singleton and Object are well defined), but for this one class we load a new one in
+          // this loader.
+          if (name.equals(cls.getName())) {
+            Class<?> c = findLoadedClass(name);
+            if (c == null) {
+              return super.findClass(name);
+            }
+            return c;
+          }
+          return super.loadClass(name);
+        }
+      }.loadClass(cls.getName());
+    } catch (ClassNotFoundException cnfe) {
+      throw new AssertionError(cnfe);
+    }
+  }
+
   @Singleton
   static class A {
     static int instanceCount = 0;
     int instanceId = instanceCount++;
 
-    @Inject A(Injector injector) {
+    @Inject
+    A(Injector injector) {
       injector.getProvider(B.class);
     }
   }
 
   @Singleton
-  static class B {
-    static int instanceCount = 0;
+  public static class B {
+    public static int instanceCount = 0;
     int instanceId = instanceCount++;
   }
 
diff --git a/core/test/com/google/inject/ErrorHandlingTest.java b/core/test/com/google/inject/ErrorHandlingTest.java
index 19161ca..1c71b2b 100644
--- a/core/test/com/google/inject/ErrorHandlingTest.java
+++ b/core/test/com/google/inject/ErrorHandlingTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,46 +20,46 @@
 
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.List;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ErrorHandlingTest {
 
   public static void main(String[] args) throws CreationException {
     try {
       Guice.createInjector(new MyModule());
-    }
-    catch (CreationException e) {
+    } catch (CreationException e) {
       e.printStackTrace();
       System.err.println("--");
     }
 
-    Injector bad = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toProvider(new Provider<String>() {
-          public String get() {
-            return null;
-          }
-        });
-      }
-    });
+    Injector bad =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class)
+                    .toProvider(
+                        new Provider<String>() {
+                          @Override
+                          public String get() {
+                            return null;
+                          }
+                        });
+              }
+            });
     try {
       bad.getInstance(String.class);
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
       e.printStackTrace();
       System.err.println("--");
     }
     try {
       bad.getInstance(NeedsString.class);
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
       e.printStackTrace();
       System.err.println("--");
     }
@@ -69,29 +69,34 @@
     @Inject String mofo;
   }
 
-  @Inject @Named("missing")
+  @Inject
+  @Named("missing")
   static List<String> missing = null;
 
   static class Foo {
     @Inject
     public Foo(Runnable r) {}
 
-    @Inject void setNames(List<String> names) {}
+    @Inject
+    void setNames(List<String> names) {}
   }
 
   static class Bar {
     // Invalid constructor.
     Bar(String s) {}
 
-    @Inject void setNumbers(@Named("numbers") List<Integer> numbers) {}
+    @Inject
+    void setNumbers(@Named("numbers") List<Integer> numbers) {}
 
-    @Inject void bar(@Named("foo") String s) {}
+    @Inject
+    void bar(@Named("foo") String s) {}
   }
 
   static class Tee {
     @Inject String s;
 
-    @Inject void tee(String s, int i) {}
+    @Inject
+    void tee(String s, int i) {}
 
     @Inject Invalid invalid;
   }
@@ -100,11 +105,11 @@
     Invalid(String s) {}
   }
 
-  @SuppressWarnings("MoreThanOneScopeAnnotationOnClass") // suppress compiler error to test
-  @Singleton 
+  // suppress compiler error to test
+  @SuppressWarnings({"MoreThanOneScopeAnnotationOnClass", "multiple-scope"})
+  @Singleton
   @GoodScope
-  static class TooManyScopes {
-  }
+  static class TooManyScopes {}
 
   @Target(ElementType.TYPE)
   @Retention(RUNTIME)
@@ -117,6 +122,7 @@
   interface I {}
 
   static class MyModule extends AbstractModule {
+    @Override
     protected void configure() {
       bind(Runnable.class);
       bind(Foo.class);
@@ -127,15 +133,18 @@
       bind(Key.get(Runnable.class)).to(Key.get(Runnable.class));
       bind(TooManyScopes.class);
       bindScope(BadScope.class, Scopes.SINGLETON);
-      bind(Object.class).toInstance(new Object() {
-        @Inject void foo() {
-          throw new RuntimeException();
-        }
-      });
+      bind(Object.class)
+          .toInstance(
+              new Object() {
+                @Inject
+                void foo() {
+                  throw new RuntimeException();
+                }
+              });
       requestStaticInjection(ErrorHandlingTest.class);
 
       addError("I don't like %s", "you");
-      
+
       Object o = "2";
       try {
         Integer i = (Integer) o;
diff --git a/core/test/com/google/inject/GenericInjectionTest.java b/core/test/com/google/inject/GenericInjectionTest.java
index 51a1cb1..1ea5f30 100644
--- a/core/test/com/google/inject/GenericInjectionTest.java
+++ b/core/test/com/google/inject/GenericInjectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,28 +19,28 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.util.Modules;
-
-import junit.framework.TestCase;
-
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class GenericInjectionTest extends TestCase {
 
   public void testGenericInjection() throws CreationException {
     final List<String> names = Arrays.asList("foo", "bar", "bob");
 
-    Injector injector = Guice.createInjector((Module) new AbstractModule() {
-      protected void configure() {
-        bind(new TypeLiteral<List<String>>() {}).toInstance(names);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            (Module)
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(new TypeLiteral<List<String>>() {}).toInstance(names);
+                  }
+                });
 
     Foo foo = injector.getInstance(Foo.class);
     assertEquals(names, foo.names);
@@ -51,108 +51,130 @@
   }
 
   /**
-   * Although we may not have intended to support this behaviour, this test
-   * passes under Guice 1.0. The workaround is to add an explicit binding for
-   * the parameterized type. See {@link #testExplicitBindingOfGenericType()}.
+   * Although we may not have intended to support this behaviour, this test passes under Guice 1.0.
+   * The workaround is to add an explicit binding for the parameterized type. See {@link
+   * #testExplicitBindingOfGenericType()}.
    */
   public void testImplicitBindingOfGenericType() {
-    Parameterized<String> parameterized
-        = Guice.createInjector().getInstance(Key.get(new TypeLiteral<Parameterized<String>>() {}));
+    Parameterized<String> parameterized =
+        Guice.createInjector().getInstance(Key.get(new TypeLiteral<Parameterized<String>>() {}));
     assertNotNull(parameterized);
   }
 
   public void testExplicitBindingOfGenericType() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Key.get(new TypeLiteral<Parameterized<String>>() {}))
-            .to((Class) Parameterized.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Key.get(new TypeLiteral<Parameterized<String>>() {}))
+                    .to((Class) Parameterized.class);
+              }
+            });
 
-    Parameterized<String> parameterized
-        = injector.getInstance(Key.get(new TypeLiteral<Parameterized<String>>() { }));
+    Parameterized<String> parameterized =
+        injector.getInstance(Key.get(new TypeLiteral<Parameterized<String>>() {}));
     assertNotNull(parameterized);
   }
 
   static class Parameterized<T> {
     @Inject
-    Parameterized() { }
+    Parameterized() {}
   }
 
   public void testInjectingParameterizedDependenciesForImplicitBinding() {
-    assertParameterizedDepsInjected(new Key<ParameterizedDeps<String, Integer>>() {},
-        Modules.EMPTY_MODULE);
+    assertParameterizedDepsInjected(
+        new Key<ParameterizedDeps<String, Integer>>() {}, Modules.EMPTY_MODULE);
   }
 
   public void testInjectingParameterizedDependenciesForBindingTarget() {
-    final TypeLiteral<ParameterizedDeps<String, Integer>> type
-        = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
+    final TypeLiteral<ParameterizedDeps<String, Integer>> type =
+        new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
 
-    assertParameterizedDepsInjected(Key.get(Object.class), new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).to(type);
-      }
-    });
+    assertParameterizedDepsInjected(
+        Key.get(Object.class),
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Object.class).to(type);
+          }
+        });
   }
 
   public void testInjectingParameterizedDependenciesForBindingSource() {
-    final TypeLiteral<ParameterizedDeps<String, Integer>> type
-        = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
+    final TypeLiteral<ParameterizedDeps<String, Integer>> type =
+        new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
 
-    assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
-      protected void configure() {
-        bind(type);
-      }
-    });
+    assertParameterizedDepsInjected(
+        Key.get(type),
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(type);
+          }
+        });
   }
 
   public void testBindingToSubtype() {
-    final TypeLiteral<ParameterizedDeps<String, Integer>> type
-        = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
+    final TypeLiteral<ParameterizedDeps<String, Integer>> type =
+        new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
 
-    assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
-      protected void configure() {
-        bind(type).to(new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {});
-      }
-    });
+    assertParameterizedDepsInjected(
+        Key.get(type),
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(type).to(new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {});
+          }
+        });
   }
 
   public void testBindingSubtype() {
-    final TypeLiteral<SubParameterizedDeps<String, Long, Integer>> type
-        = new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {};
+    final TypeLiteral<SubParameterizedDeps<String, Long, Integer>> type =
+        new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {};
 
-    assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
-      protected void configure() {
-        bind(type);
-      }
-    });
+    assertParameterizedDepsInjected(
+        Key.get(type),
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(type);
+          }
+        });
   }
 
   @SuppressWarnings("unchecked")
   public void assertParameterizedDepsInjected(Key<?> key, Module bindingModule) {
-    Module bindDataModule = new AbstractModule() {
-      protected void configure() {}
-      @Provides Map<String, Integer> provideMap() {
-        return ImmutableMap.of("one", 1, "two", 2);
-      }
-      @Provides Set<String> provideSet(Map<String, Integer> map) {
-        return map.keySet();
-      }
-      @Provides Collection<Integer> provideCollection(Map<String, Integer> map) {
-        return map.values();
-      }
-    };
+    Module bindDataModule =
+        new AbstractModule() {
+
+          @Provides
+          Map<String, Integer> provideMap() {
+            return ImmutableMap.of("one", 1, "two", 2);
+          }
+
+          @Provides
+          Set<String> provideSet(Map<String, Integer> map) {
+            return map.keySet();
+          }
+
+          @Provides
+          Collection<Integer> provideCollection(Map<String, Integer> map) {
+            return map.values();
+          }
+        };
 
     Injector injector = Guice.createInjector(bindDataModule, bindingModule);
-    ParameterizedDeps<String, Integer> parameterizedDeps
-        = (ParameterizedDeps<String, Integer>) injector.getInstance(key);
+    ParameterizedDeps<String, Integer> parameterizedDeps =
+        (ParameterizedDeps<String, Integer>) injector.getInstance(key);
     assertEquals(ImmutableMap.of("one", 1, "two", 2), parameterizedDeps.map);
     assertEquals(ImmutableSet.of("one", "two"), parameterizedDeps.keys);
     assertEquals(ImmutableSet.of(1, 2), ImmutableSet.copyOf(parameterizedDeps.values));
   }
 
   static class SubParameterizedDeps<A, B, C> extends ParameterizedDeps<A, C> {
-    @Inject SubParameterizedDeps(Set<A> keys) {
+    @Inject
+    SubParameterizedDeps(Set<A> keys) {
       super(keys);
     }
   }
@@ -162,21 +184,26 @@
     private Set<K> keys;
     private Collection<V> values;
 
-    @Inject ParameterizedDeps(Set<K> keys) {
+    @Inject
+    ParameterizedDeps(Set<K> keys) {
       this.keys = keys;
     }
 
-    @Inject void method(Collection<V> values) {
+    @Inject
+    void method(Collection<V> values) {
       this.values = values;
     }
   }
 
   public void testImmediateTypeVariablesAreInjected() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("tee");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("tee");
+              }
+            });
     InjectsT<String> injectsT = injector.getInstance(new Key<InjectsT<String>>() {});
     assertEquals("tee", injectsT.t);
   }
diff --git a/core/test/com/google/inject/ImplicitBindingTest.java b/core/test/com/google/inject/ImplicitBindingTest.java
index eb47e49..5b1876a 100644
--- a/core/test/com/google/inject/ImplicitBindingTest.java
+++ b/core/test/com/google/inject/ImplicitBindingTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,17 +17,14 @@
 package com.google.inject;
 
 import com.google.common.collect.Iterables;
+import com.google.inject.internal.Annotations;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
 import com.google.inject.spi.Message;
-
+import java.util.List;
 import junit.framework.TestCase;
 
-import java.util.List;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ImplicitBindingTest extends TestCase {
 
   public void testCircularDependency() throws CreationException {
@@ -42,6 +39,7 @@
 
   static class Bar {
     final Foo foo;
+
     @Inject
     public Bar(Foo foo) {
       this.foo = foo;
@@ -60,10 +58,12 @@
   }
 
   static class IImpl implements I {
+    @Override
     public void go() {}
   }
 
   static class AlternateImpl implements I {
+    @Override
     public void go() {}
   }
 
@@ -74,12 +74,14 @@
   }
 
   public void testBindingOverridesImplementedBy() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(I.class).to(AlternateImpl.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(I.class).to(AlternateImpl.class);
+              }
+            });
     assertEquals(AlternateImpl.class, injector.getInstance(I.class).getClass());
   }
 
@@ -93,17 +95,28 @@
       Guice.createInjector().getInstance(Key.get(I.class, Names.named("i")));
       fail();
     } catch (ConfigurationException expected) {
-      Asserts.assertContains(expected.getMessage(),
+      Asserts.assertContains(
+          expected.getMessage(),
           "1) No implementation for " + I.class.getName(),
-          "annotated with @" + Named.class.getName() + "(value=i) was bound.",
+          "annotated with @"
+              + Named.class.getName()
+              + "(value="
+              + Annotations.memberValueString("i")
+              + ") was bound.",
           "while locating " + I.class.getName(),
-          " annotated with @" + Named.class.getName() + "(value=i)");
+          " annotated with @"
+              + Named.class.getName()
+              + "(value="
+              + Annotations.memberValueString("i")
+              + ")");
     }
   }
 
   static class ProvidedProvider implements Provider<Provided> {
+    @Override
     public Provided get() {
       return new Provided() {
+        @Override
         public void go() {}
       };
     }
@@ -113,20 +126,22 @@
    * When we're building the binding for A, we temporarily insert that binding to support circular
    * dependencies. And so we can successfully create a binding for B. But later, when the binding
    * for A ultimately fails, we need to clean up the dependent binding for B.
-   * 
-   * The test loops through linked bindings & bindings with constructor & member injections,
-   * to make sure that all are cleaned up and traversed.  It also makes sure we don't touch
-   * explicit bindings.
+   *
+   * <p>The test loops through linked bindings & bindings with constructor & member injections, to
+   * make sure that all are cleaned up and traversed. It also makes sure we don't touch explicit
+   * bindings.
    */
   public void testCircularJitBindingsLeaveNoResidue() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Valid.class);
-        bind(Valid2.class);
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Valid.class);
+                bind(Valid2.class);
+              }
+            });
+
     // Capture good bindings.
     Binding v1 = injector.getBinding(Valid.class);
     Binding v2 = injector.getBinding(Valid2.class);
@@ -144,205 +159,230 @@
     assertFailure(injector, InvalidProvidedBy2.class);
     assertFailure(injector, InvalidProvidedBy2Provider.class);
     assertFailure(injector, Invalid2.class);
-    
+
     // Validate we didn't do anything to the valid explicit bindings.
     assertSame(v1, injector.getBinding(Valid.class));
     assertSame(v2, injector.getBinding(Valid2.class));
-    
+
     // Validate that we didn't erase the valid JIT bindings
     assertSame(jv1, injector.getBinding(JitValid.class));
     assertSame(jv2, injector.getBinding(JitValid2.class));
   }
-  
+
   @SuppressWarnings("unchecked")
   private void assertFailure(Injector injector, Class clazz) {
     try {
       injector.getBinding(clazz);
       fail("Shouldn't have been able to get binding of: " + clazz);
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       Message msg = Iterables.getOnlyElement(expected.getErrorMessages());
-      assertEquals("No implementation for " + InvalidInterface.class.getName() + " was bound.",
-          msg.getMessage());
+      Asserts.assertContains(
+          msg.getMessage(),
+          "No implementation for " + InvalidInterface.class.getName() + " was bound.");
       List<Object> sources = msg.getSources();
       // Assert that the first item in the sources if the key for the class we're looking up,
       // ensuring that each lookup is "new".
       assertEquals(Key.get(clazz).toString(), sources.get(0).toString());
       // Assert that the last item in each lookup contains the InvalidInterface class
-      Asserts.assertContains(sources.get(sources.size()-1).toString(),
-          Key.get(InvalidInterface.class).toString());
+      Asserts.assertContains(
+          sources.get(sources.size() - 1).toString(), Key.get(InvalidInterface.class).toString());
     }
   }
 
   static class Invalid {
     @Inject Valid a;
-    @Inject JitValid b;    
-    @Inject InvalidProvidedBy c; 
-    @Inject Invalid(InvalidLinked a) {}    
-    @Inject void foo(InvalidInterface a) {}
-    
+    @Inject JitValid b;
+    @Inject InvalidProvidedBy c;
+
+    @Inject
+    Invalid(InvalidLinked a) {}
+
+    @Inject
+    void foo(InvalidInterface a) {}
   }
 
   @ImplementedBy(InvalidLinkedImpl.class)
   static interface InvalidLinked {}
+
   static class InvalidLinkedImpl implements InvalidLinked {
     @Inject InvalidLinked2 a;
   }
-  
+
   @ImplementedBy(InvalidLinked2Impl.class)
   static interface InvalidLinked2 {}
+
   static class InvalidLinked2Impl implements InvalidLinked2 {
-    @Inject InvalidLinked2Impl(Invalid2 a) {}
+    @Inject
+    InvalidLinked2Impl(Invalid2 a) {}
   }
-  
+
   @ProvidedBy(InvalidProvidedByProvider.class)
   static interface InvalidProvidedBy {}
+
   static class InvalidProvidedByProvider implements Provider<InvalidProvidedBy> {
     @Inject InvalidProvidedBy2 a;
+
+    @Override
     public InvalidProvidedBy get() {
       return null;
     }
   }
-  
+
   @ProvidedBy(InvalidProvidedBy2Provider.class)
   static interface InvalidProvidedBy2 {}
+
   static class InvalidProvidedBy2Provider implements Provider<InvalidProvidedBy2> {
     @Inject Invalid2 a;
+
+    @Override
     public InvalidProvidedBy2 get() {
       return null;
     }
-  }  
-  
+  }
+
   static class Invalid2 {
     @Inject Invalid a;
   }
 
   interface InvalidInterface {}
-  
-  static class Valid { @Inject Valid2 a; }
+
+  static class Valid {
+    @Inject Valid2 a;
+  }
+
   static class Valid2 {}
-  
-  static class JitValid { @Inject JitValid2 a; }
+
+  static class JitValid {
+    @Inject JitValid2 a;
+  }
+
   static class JitValid2 {}
-  
+
   /**
    * Regression test for https://github.com/google/guice/issues/319
-   * 
-   * The bug is that a class that asks for a provider for itself during injection time, 
-   * where any one of the other types required to fulfill the object creation was bound 
-   * in a child constructor, explodes when the injected Provider is called.
-   * 
-   * It works just fine when the other types are bound in a main injector.
-   */  
-  public void testInstancesRequestingProvidersForThemselvesWithChildInjectors() {       
-    final Module testModule = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class)
-          .toProvider(TestStringProvider.class);
-      }            
-    };    
-    
+   *
+   * <p>The bug is that a class that asks for a provider for itself during injection time, where any
+   * one of the other types required to fulfill the object creation was bound in a child
+   * constructor, explodes when the injected Provider is called.
+   *
+   * <p>It works just fine when the other types are bound in a main injector.
+   */
+  public void testInstancesRequestingProvidersForThemselvesWithChildInjectors() {
+    final Module testModule =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toProvider(TestStringProvider.class);
+          }
+        };
+
     // Verify it works when the type is setup in the parent.
     Injector parentSetupRootInjector = Guice.createInjector(testModule);
     Injector parentSetupChildInjector = parentSetupRootInjector.createChildInjector();
-    assertEquals(TestStringProvider.TEST_VALUE, 
-        parentSetupChildInjector.getInstance(
-            RequiresProviderForSelfWithOtherType.class).getValue());
-        
+    assertEquals(
+        TestStringProvider.TEST_VALUE,
+        parentSetupChildInjector
+            .getInstance(RequiresProviderForSelfWithOtherType.class)
+            .getValue());
+
     // Verify it works when the type is setup in the child, not the parent.
     // If it still occurs, the bug will explode here.
     Injector childSetupRootInjector = Guice.createInjector();
-    Injector childSetupChildInjector = childSetupRootInjector.createChildInjector(testModule);      
-    assertEquals(TestStringProvider.TEST_VALUE, 
-        childSetupChildInjector.getInstance(
-            RequiresProviderForSelfWithOtherType.class).getValue());
+    Injector childSetupChildInjector = childSetupRootInjector.createChildInjector(testModule);
+    assertEquals(
+        TestStringProvider.TEST_VALUE,
+        childSetupChildInjector.getInstance(RequiresProviderForSelfWithOtherType.class).getValue());
   }
-  
+
   static class TestStringProvider implements Provider<String> {
     static final String TEST_VALUE = "This is to verify it all works";
-    
+
+    @Override
     public String get() {
       return TEST_VALUE;
-    }    
-  }    
-  
+    }
+  }
+
   static class RequiresProviderForSelfWithOtherType {
     private final Provider<RequiresProviderForSelfWithOtherType> selfProvider;
     private final String providedStringValue;
-    
-    @Inject    
+
+    @Inject
     RequiresProviderForSelfWithOtherType(
-        String providedStringValue,
-        Provider<RequiresProviderForSelfWithOtherType> selfProvider
-        ) {
+        String providedStringValue, Provider<RequiresProviderForSelfWithOtherType> selfProvider) {
       this.providedStringValue = providedStringValue;
-      this.selfProvider = selfProvider;      
+      this.selfProvider = selfProvider;
     }
-    
+
     public String getValue() {
       // Attempt to get another instance of ourself. This pattern
-      // is possible for recursive processing. 
+      // is possible for recursive processing.
       selfProvider.get();
-      
+
       return providedStringValue;
     }
   }
 
   /**
-   * Ensure that when we cleanup failed JIT bindings, we don't break.
-   * The test here requires a sequence of JIT bindings:
-   *   A-> B 
-   *   B -> C, A
-   *   C -> A, D
-   *   D not JITable
-   * The problem was that C cleaned up A's binding and then handed control back to B,
-   * which tried to continue processing A.. but A was removed from the jitBindings Map,
-   * so it attempts to create a new JIT binding for A, but we haven't yet finished
-   * constructing the first JIT binding for A, so we get a recursive
-   * computation exception from ComputingConcurrentHashMap.
-   * 
-   * We also throw in a valid JIT binding, E, to guarantee that if
-   * something fails in this flow, it can be recreated later if it's
-   * not from a failed sequence.
+   * Ensure that when we cleanup failed JIT bindings, we don't break. The test here requires a
+   * sequence of JIT bindings:
+   *
+   * <ol>
+   * <li> A-> B
+   * <li> B -> C, A
+   * <li> C -> A, D
+   * <li> D not JITable
+   * </ol>
+   *
+   * <p>The problem was that C cleaned up A's binding and then handed control back to B, which tried
+   * to continue processing A.. but A was removed from the jitBindings Map, so it attempts to create
+   * a new JIT binding for A, but we haven't yet finished constructing the first JIT binding for A,
+   * so we get a recursive computation exception from ComputingConcurrentHashMap.
+   *
+   * <p>We also throw in a valid JIT binding, E, to guarantee that if something fails in this flow,
+   * it can be recreated later if it's not from a failed sequence.
    */
   public void testRecursiveJitBindingsCleanupCorrectly() throws Exception {
     Injector injector = Guice.createInjector();
     try {
       injector.getInstance(A.class);
       fail("Expected failure");
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       Message msg = Iterables.getOnlyElement(expected.getErrorMessages());
-      Asserts.assertContains(msg.getMessage(),
-          "Could not find a suitable constructor in " + D.class.getName());
+      Asserts.assertContains(
+          msg.getMessage(), "Could not find a suitable constructor in " + D.class.getName());
     }
     // Assert that we've removed all the bindings.
     assertNull(injector.getExistingBinding(Key.get(A.class)));
     assertNull(injector.getExistingBinding(Key.get(B.class)));
     assertNull(injector.getExistingBinding(Key.get(C.class)));
     assertNull(injector.getExistingBinding(Key.get(D.class)));
-    
+
     // Confirm that we didn't prevent 'E' from working.
     assertNotNull(injector.getBinding(Key.get(E.class)));
   }
 
   static class A {
-    @Inject public A(B b) {}
+    @Inject
+    public A(B b) {}
   }
 
   static class B {
-    @Inject public B(C c, A a) {}
+    @Inject
+    public B(C c, A a) {}
   }
 
   static class C {
-    @Inject public C(A a, D d, E e) {}
+    @Inject
+    public C(A a, D d, E e) {}
   }
 
   static class D {
     public D(int i) {}
   }
-  
+
   // Valid JITable binding
-  static class E { }
+  static class E {}
 
   public void testProvidedByNonEmptyEnum() {
     NonEmptyEnum cardSuit = Guice.createInjector().getInstance(NonEmptyEnum.class);
@@ -356,7 +396,12 @@
   }
 
   @ProvidedBy(NonEmptyEnumProvider.class)
-  enum NonEmptyEnum { HEARTS, DIAMONDS, CLUBS, SPADES }
+  enum NonEmptyEnum {
+    HEARTS,
+    DIAMONDS,
+    CLUBS,
+    SPADES
+  }
 
   static final class NonEmptyEnumProvider implements Provider<NonEmptyEnum> {
     @Override
@@ -382,14 +427,24 @@
     try {
       injector.getInstance(EnumWithImplementedBy.class);
       fail("Expected failure");
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       Message msg = Iterables.getOnlyElement(expected.getErrorMessages());
-      Asserts.assertContains(msg.getMessage(),
+      Asserts.assertContains(
+          msg.getMessage(),
           "No implementation for " + EnumWithImplementedBy.class.getName() + " was bound.");
     }
   }
 
   @ImplementedBy(EnumWithImplementedByEnum.class)
   enum EnumWithImplementedBy {}
+
   private static class EnumWithImplementedByEnum {}
+
+  public void testImplicitJdkBindings() {
+    Injector injector = Guice.createInjector();
+    // String has a public nullary constructor, so Guice will call it.
+    assertEquals("", injector.getInstance(String.class));
+    // InetAddress has a package private constructor.  We probably shouldn't be calling it :(
+    assertNotNull(injector.getInstance(java.net.InetAddress.class));
+  }
 }
diff --git a/core/test/com/google/inject/InjectorTest.java b/core/test/com/google/inject/InjectorTest.java
index a71eb18..7ecae17 100644
--- a/core/test/com/google/inject/InjectorTest.java
+++ b/core/test/com/google/inject/InjectorTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,9 +20,6 @@
 import static com.google.inject.Asserts.assertNotSerializable;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.util.concurrent.Callable;
@@ -31,21 +28,23 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 
 public class InjectorTest extends TestCase {
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface Other {}
+  @BindingAnnotation
+  @interface Other {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface S {}
+  @BindingAnnotation
+  @interface S {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface I {}
+  @BindingAnnotation
+  @interface I {}
 
   public void testToStringDoesNotInfinitelyRecurse() {
     Injector injector = Guice.createInjector(Stage.TOOL);
@@ -57,21 +56,20 @@
     final SampleSingleton singleton = new SampleSingleton();
     final SampleSingleton other = new SampleSingleton();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(SampleSingleton.class).toInstance(singleton);
-        bind(SampleSingleton.class)
-            .annotatedWith(Other.class)
-            .toInstance(other);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(SampleSingleton.class).toInstance(singleton);
+                bind(SampleSingleton.class).annotatedWith(Other.class).toInstance(other);
+              }
+            });
 
-    assertSame(singleton,
-        injector.getInstance(Key.get(SampleSingleton.class)));
+    assertSame(singleton, injector.getInstance(Key.get(SampleSingleton.class)));
     assertSame(singleton, injector.getInstance(SampleSingleton.class));
 
-    assertSame(other,
-        injector.getInstance(Key.get(SampleSingleton.class, Other.class)));
+    assertSame(other, injector.getInstance(Key.get(SampleSingleton.class, Other.class)));
   }
 
   static class SampleSingleton {}
@@ -91,14 +89,16 @@
   }
 
   private Injector createFooInjector() throws CreationException {
-    return Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Bar.class).to(BarImpl.class);
-        bind(Tee.class).to(TeeImpl.class);
-        bindConstant().annotatedWith(S.class).to("test");
-        bindConstant().annotatedWith(I.class).to(5);
-      }
-    });
+    return Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Bar.class).to(BarImpl.class);
+            bind(Tee.class).to(TeeImpl.class);
+            bindConstant().annotatedWith(S.class).to("test");
+            bindConstant().annotatedWith(I.class).to(5);
+          }
+        });
   }
 
   public void testGetInstance() throws CreationException {
@@ -109,13 +109,15 @@
     assertEquals(5, bar.getI());
   }
 
-  public void testIntAndIntegerAreInterchangeable()
-      throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindConstant().annotatedWith(I.class).to(5);
-      }
-    });
+  public void testIntAndIntegerAreInterchangeable() throws CreationException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(I.class).to(5);
+              }
+            });
 
     IntegerWrapper iw = injector.getInstance(IntegerWrapper.class);
     assertEquals(5, (int) iw.i);
@@ -153,6 +155,7 @@
   interface Bar {
 
     Tee getTee();
+
     int getI();
   }
 
@@ -168,10 +171,12 @@
       this.tee = tee;
     }
 
+    @Override
     public Tee getTee() {
       return tee;
     }
 
+    @Override
     public int getI() {
       return i;
     }
@@ -180,6 +185,7 @@
   interface Tee {
 
     String getS();
+
     Bar getBar();
   }
 
@@ -193,23 +199,27 @@
       this.s = s;
     }
 
+    @Override
     public String getS() {
       return s;
     }
 
+    @Override
     public Bar getBar() {
       return bar;
     }
   }
 
   public void testInjectStatics() throws CreationException {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindConstant().annotatedWith(S.class).to("test");
-        bindConstant().annotatedWith(I.class).to(5);
-        requestStaticInjection(Static.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(S.class).to("test");
+            bindConstant().annotatedWith(I.class).to(5);
+            requestStaticInjection(Static.class);
+          }
+        });
 
     assertEquals("test", Static.s);
     assertEquals(5, Static.i);
@@ -217,17 +227,20 @@
 
   public void testInjectStaticInterface() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          requestStaticInjection(Interface.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestStaticInjection(Interface.class);
+            }
+          });
       fail();
-    } catch(CreationException ce) {
+    } catch (CreationException ce) {
       assertEquals(1, ce.getErrorMessages().size());
       Asserts.assertContains(
           ce.getMessage(),
-          "1) " + Interface.class.getName()
+          "1) "
+              + Interface.class.getName()
               + " is an interface, but interfaces have no static injection points.",
           "at " + InjectorTest.class.getName(),
           "configure");
@@ -242,18 +255,22 @@
 
     static String s;
 
-    @Inject static void setS(@S String s) {
+    @Inject
+    static void setS(@S String s) {
       Static.s = s;
     }
   }
 
   public void testPrivateInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("foo");
-        bind(int.class).toInstance(5);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("foo");
+                bind(int.class).toInstance(5);
+              }
+            });
 
     Private p = injector.getInstance(Private.class);
     assertEquals("foo", p.fromConstructor);
@@ -276,12 +293,15 @@
   }
 
   public void testProtectedInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("foo");
-        bind(int.class).toInstance(5);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("foo");
+                bind(int.class).toInstance(5);
+              }
+            });
 
     Protected p = injector.getInstance(Protected.class);
     assertEquals("foo", p.fromConstructor);
@@ -304,15 +324,19 @@
   }
 
   public void testInstanceInjectionHappensAfterFactoriesAreSetUp() {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).toInstance(new Object() {
-          @Inject Runnable r;
-        });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Object.class)
+                .toInstance(
+                    new Object() {
+                      @Inject Runnable r;
+                    });
 
-        bind(Runnable.class).to(MyRunnable.class);
-      }
-    });
+            bind(Runnable.class).to(MyRunnable.class);
+          }
+        });
   }
 
   public void testSubtypeNotProvided() {
@@ -320,10 +344,13 @@
       Guice.createInjector().getInstance(Money.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           Tree.class.getName() + " doesn't provide instances of " + Money.class.getName(),
-          "while locating ", Tree.class.getName(),
-          "while locating ", Money.class.getName());
+          "while locating ",
+          Tree.class.getName(),
+          "while locating ",
+          Money.class.getName());
     }
   }
 
@@ -332,9 +359,11 @@
       Guice.createInjector().getInstance(PineTree.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           Tree.class.getName() + " doesn't extend " + PineTree.class.getName(),
-          "while locating ", PineTree.class.getName());
+          "while locating ",
+          PineTree.class.getName());
     }
   }
 
@@ -343,9 +372,11 @@
       Guice.createInjector().getInstance(SeaHorse.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "@ImplementedBy points to the same class it annotates.",
-          "while locating ", SeaHorse.class.getName());
+          "while locating ",
+          SeaHorse.class.getName());
     }
   }
 
@@ -354,20 +385,24 @@
       Guice.createInjector().getInstance(Chicken.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "@ProvidedBy points to the same class it annotates",
-          "while locating ", Chicken.class.getName());
+          "while locating ",
+          Chicken.class.getName());
     }
   }
 
   static class MyRunnable implements Runnable {
-   public void run() {}
+    @Override
+    public void run() {}
   }
 
   @ProvidedBy(Tree.class)
   static class Money {}
 
   static class Tree implements Provider<Object> {
+    @Override
     public Object get() {
       return "Money doesn't grow on trees";
     }
@@ -381,6 +416,7 @@
 
   @ProvidedBy(Chicken.class)
   static class Chicken implements Provider<Chicken> {
+    @Override
     public Chicken get() {
       return this;
     }
@@ -388,23 +424,30 @@
 
   public void testJitBindingFromAnotherThreadDuringInjection() {
     final ExecutorService executorService = Executors.newSingleThreadExecutor();
-    final AtomicReference<JustInTime> got = new AtomicReference<JustInTime>();
+    final AtomicReference<JustInTime> got = new AtomicReference<>();
 
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        requestInjection(new Object() {
-          @Inject void initialize(final Injector injector)
-              throws ExecutionException, InterruptedException {
-            Future<JustInTime> future = executorService.submit(new Callable<JustInTime>() {
-              public JustInTime call() throws Exception {
-                return injector.getInstance(JustInTime.class);
-              }
-            });
-            got.set(future.get());
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestInjection(
+                new Object() {
+                  @Inject
+                  void initialize(final Injector injector)
+                      throws ExecutionException, InterruptedException {
+                    Future<JustInTime> future =
+                        executorService.submit(
+                            new Callable<JustInTime>() {
+                              @Override
+                              public JustInTime call() throws Exception {
+                                return injector.getInstance(JustInTime.class);
+                              }
+                            });
+                    got.set(future.get());
+                  }
+                });
           }
         });
-      }
-    });
 
     assertNotNull(got.get());
   }
diff --git a/core/test/com/google/inject/IntegrationTest.java b/core/test/com/google/inject/IntegrationTest.java
index ceff0ad..f1f924c 100644
--- a/core/test/com/google/inject/IntegrationTest.java
+++ b/core/test/com/google/inject/IntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,24 +19,24 @@
 import static com.google.inject.matcher.Matchers.any;
 
 import junit.framework.TestCase;
-
 import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class IntegrationTest extends TestCase {
 
   public void testIntegration() throws CreationException {
     final CountingInterceptor counter = new CountingInterceptor();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class);
-        bindInterceptor(any(), any(), counter);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class);
+                bindInterceptor(any(), any(), counter);
+              }
+            });
 
     Foo foo = injector.getInstance(Key.get(Foo.class));
     foo.foo();
@@ -51,6 +51,7 @@
 
   static class Foo {
     boolean invoked;
+
     public void foo() {
       invoked = true;
     }
@@ -60,10 +61,10 @@
 
     int count;
 
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       count++;
       return methodInvocation.proceed();
     }
   }
-
 }
diff --git a/core/test/com/google/inject/JitBindingsTest.java b/core/test/com/google/inject/JitBindingsTest.java
index 243c53e..706f64e 100644
--- a/core/test/com/google/inject/JitBindingsTest.java
+++ b/core/test/com/google/inject/JitBindingsTest.java
@@ -21,21 +21,20 @@
 import static com.google.inject.JitBindingsTest.GetBindingCheck.ALLOW_BINDING;
 import static com.google.inject.JitBindingsTest.GetBindingCheck.FAIL_ALL;
 
-import junit.framework.TestCase;
-
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * Some tests for {@link Binder#requireExplicitBindings()}
- * 
+ *
  * @author sberlin@gmail.com (Sam Berlin)
  */
 public class JitBindingsTest extends TestCase {
-  
+
   private String jitFailed(Class<?> clazz) {
     return jitFailed(TypeLiteral.get(clazz));
   }
-  
+
   private String jitFailed(TypeLiteral<?> clazz) {
     return "Explicit bindings are required and " + clazz + " is not explicitly bound.";
   }
@@ -47,21 +46,23 @@
   private String jitInParentFailed(TypeLiteral<?> clazz) {
     return "Explicit bindings are required and " + clazz + " would be bound in a parent injector.";
   }
-  
+
   private String inChildMessage(Class<?> clazz) {
     return "Unable to create binding for "
         + clazz.getName()
         + ". It was already configured on one or more child injectors or private modules";
   }
-  
+
   public void testLinkedBindingWorks() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(FooImpl.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(FooImpl.class);
+              }
+            });
     // Foo was explicitly bound
     ensureWorks(injector, Foo.class);
     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
@@ -69,33 +70,37 @@
     // of the binding
     ensureFails(injector, ALLOW_BINDING, FooImpl.class);
   }
-  
+
   public void testMoreBasicsWork() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(FooImpl.class);
-        bind(Bar.class);
-        bind(FooBar.class);
-      }
-    });
-    // Foo, Bar & FooBar was explicitly bound    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(FooImpl.class);
+                bind(Bar.class);
+                bind(FooBar.class);
+              }
+            });
+    // Foo, Bar & FooBar was explicitly bound
     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
     // It is OK to call getBinding for introspection, but an error to get the provider
-    // of the binding    
-    ensureFails(injector, ALLOW_BINDING,  FooImpl.class);    
+    // of the binding
+    ensureFails(injector, ALLOW_BINDING, FooImpl.class);
   }
-  
+
   public void testLinkedEagerSingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(FooImpl.class).asEagerSingleton();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(FooImpl.class).asEagerSingleton();
+              }
+            });
     // Foo was explicitly bound
     ensureWorks(injector, Foo.class);
     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
@@ -103,116 +108,128 @@
     // of the binding
     ensureFails(injector, ALLOW_BINDING, FooImpl.class);
   }
-  
+
   public void testBasicsWithEagerSingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(FooImpl.class).asEagerSingleton();
-        bind(Bar.class);
-        bind(FooBar.class);
-      }
-    });
-    // Foo, Bar & FooBar was explicitly bound    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(FooImpl.class).asEagerSingleton();
+                bind(Bar.class);
+                bind(FooBar.class);
+              }
+            });
+    // Foo, Bar & FooBar was explicitly bound
     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
     // It is OK to call getBinding for introspection, but an error to get the provider
-    // of the binding    
-    ensureFails(injector, ALLOW_BINDING,  FooImpl.class);    
-  }  
-  
+    // of the binding
+    ensureFails(injector, ALLOW_BINDING, FooImpl.class);
+  }
+
   public void testLinkedToScoped() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder.requireExplicitBindings();
-        bind(Foo.class).to(ScopedFooImpl.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder.requireExplicitBindings();
+                bind(Foo.class).to(ScopedFooImpl.class);
+              }
+            });
     // Foo was explicitly bound
     ensureWorks(injector, Foo.class);
     // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
     // It is OK to call getBinding for introspection, but an error to get the provider
     // of the binding
-    ensureFails(injector, ALLOW_BINDING, ScopedFooImpl.class);    
+    ensureFails(injector, ALLOW_BINDING, ScopedFooImpl.class);
   }
-  
+
   public void testBasicsWithScoped() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(ScopedFooImpl.class);
-        bind(Bar.class);
-        bind(FooBar.class);
-      }
-    });
-    // Foo, Bar & FooBar was explicitly bound    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(ScopedFooImpl.class);
+                bind(Bar.class);
+                bind(FooBar.class);
+              }
+            });
+    // Foo, Bar & FooBar was explicitly bound
     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
     // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
     // It is OK to call getBinding for introspection, but an error to get the provider
-    // of the binding    
-    ensureFails(injector, ALLOW_BINDING,  ScopedFooImpl.class);   
+    // of the binding
+    ensureFails(injector, ALLOW_BINDING, ScopedFooImpl.class);
   }
-  
+
   public void testFailsIfInjectingScopedDirectlyWhenItIsntBound() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExplicitBindings();
-          bind(Foo.class).to(ScopedFooImpl.class);
-          bind(WantsScopedFooImpl.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExplicitBindings();
+              bind(Foo.class).to(ScopedFooImpl.class);
+              bind(WantsScopedFooImpl.class);
+            }
+          });
       fail();
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(ScopedFooImpl.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
   }
-  
+
   public void testLinkedProviderBindingWorks() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).toProvider(FooProvider.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).toProvider(FooProvider.class);
+              }
+            });
     // Foo was explicitly bound
     ensureWorks(injector, Foo.class);
     // FooImpl was not bound at all (even implicitly), it is an error
     // to call getInstance, getProvider, or getBinding.
     ensureFails(injector, FAIL_ALL, FooImpl.class);
   }
-  
+
   public void testJitGetFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-         binder().requireExplicitBindings(); 
-        }
-      }).getInstance(Bar.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().requireExplicitBindings();
+                }
+              })
+          .getInstance(Bar.class);
       fail("should have failed");
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
   }
-  
+
   public void testJitInjectionFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExplicitBindings();
-          bind(Foo.class).to(FooImpl.class);
-          bind(FooBar.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExplicitBindings();
+              bind(Foo.class).to(FooImpl.class);
+              bind(FooBar.class);
+            }
+          });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
@@ -222,12 +239,14 @@
 
   public void testJitProviderGetFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExplicitBindings(); 
-        }
-      }).getProvider(Bar.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  binder().requireExplicitBindings();
+                }
+              })
+          .getProvider(Bar.class);
       fail("should have failed");
     } catch (ConfigurationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
@@ -237,97 +256,117 @@
 
   public void testJitProviderInjectionFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExplicitBindings();
-          bind(Foo.class).to(FooImpl.class);
-          bind(ProviderFooBar.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExplicitBindings();
+              bind(Foo.class).to(FooImpl.class);
+              bind(ProviderFooBar.class);
+            }
+          });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
   }
-  
+
   public void testImplementedBy() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(ImplBy.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(ImplBy.class);
+              }
+            });
     ensureWorks(injector, ImplBy.class);
     ensureFails(injector, ALLOW_BINDING, ImplByImpl.class);
   }
-  
+
   public void testImplementedBySomethingThatIsAnnotated() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(ImplByScoped.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(ImplByScoped.class);
+              }
+            });
     ensureWorks(injector, ImplByScoped.class);
-    ensureFails(injector, ALLOW_BINDING, ImplByScopedImpl.class);    
+    ensureFails(injector, ALLOW_BINDING, ImplByScopedImpl.class);
   }
-  
+
   public void testProvidedBy() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(ProvBy.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(ProvBy.class);
+              }
+            });
     ensureWorks(injector, ProvBy.class);
     ensureFails(injector, ALLOW_BINDING, ProvByProvider.class);
   }
-  
+
   public void testProviderMethods() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        binder().requireExplicitBindings();
-      }
-      @SuppressWarnings("unused") @Provides Foo foo() { return new FooImpl(); }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+              }
+
+              @SuppressWarnings("unused")
+              @Provides
+              Foo foo() {
+                return new FooImpl();
+              }
+            });
     ensureWorks(injector, Foo.class);
   }
-  
+
   public void testChildInjectorInheritsOption() {
-    Injector parent = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Bar.class);
-      }
-    });
+    Injector parent =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Bar.class);
+              }
+            });
     ensureWorks(parent, Bar.class);
     ensureFails(parent, FAIL_ALL, FooImpl.class, FooBar.class, Foo.class);
-    
+
     try {
-      parent.createChildInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(FooBar.class);
-        }
-      });
+      parent.createChildInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(FooBar.class);
+            }
+          });
       fail("should have failed");
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Foo.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
-    
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Foo.class).to(FooImpl.class);
-      }
-    });
+
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).to(FooImpl.class);
+              }
+            });
     ensureWorks(child, Foo.class, Bar.class);
     ensureFails(child, ALLOW_BINDING, FooImpl.class);
     ensureInChild(parent, FooImpl.class, Foo.class);
@@ -337,62 +376,71 @@
     // FooBar was succesfully inserted into the child injector (and parent blacklist), but then
     // JIT bindings it depended on failed, making the child injector invalid.
 
-    Injector grandchild = child.createChildInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(FooBar.class);
-      }
-    });
+    Injector grandchild =
+        child.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(FooBar.class);
+              }
+            });
     ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
     ensureFails(grandchild, ALLOW_BINDING, FooImpl.class);
     ensureFails(child, ALLOW_BINDING, FooImpl.class);
     ensureInChild(parent, FooImpl.class, FooBar.class, Foo.class);
   }
-  
+
   public void testChildInjectorAddsOption() {
-    Injector parent = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Bar.class);
-      }
-    });
+    Injector parent =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Bar.class);
+              }
+            });
     int totalParentBindings = parent.getAllBindings().size();
-    
+
     try {
-      parent.createChildInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireExplicitBindings();
-          bind(FooBar.class);
-        }
-      });
+      parent.createChildInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExplicitBindings();
+              bind(FooBar.class);
+            }
+          });
       fail("should have failed");
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Foo.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
     assertEquals(totalParentBindings, parent.getAllBindings().size());
-    
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class).to(FooImpl.class);
-        bind(FooImpl.class);
-      }
-    });
+
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class).to(FooImpl.class);
+                bind(FooImpl.class);
+              }
+            });
     assertEquals(totalParentBindings, parent.getAllBindings().size());
     ensureWorks(child, Foo.class, Bar.class);
-    
-    Injector grandchild = child.createChildInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(FooBar.class);
-      }
-    });
-    assertEquals(totalParentBindings, parent.getAllBindings().size());    
+
+    Injector grandchild =
+        child.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(FooBar.class);
+              }
+            });
+    assertEquals(totalParentBindings, parent.getAllBindings().size());
     ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
-    
+
     // Make sure siblings of children don't inherit each others settings...
     // a new child should be able to get FooImpl.
     child = parent.createChildInjector();
@@ -401,114 +449,140 @@
 
   public void testPrivateModulesInheritOptions() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          binder().requireExplicitBindings();
-          bind(Foo.class).to(FooImpl.class);
-  
-          install(new PrivateModule() {
-            public void configure() {
-              bind(FooBar.class);
-              expose(FooBar.class);
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              binder().requireExplicitBindings();
+              bind(Foo.class).to(FooImpl.class);
+
+              install(
+                  new PrivateModule() {
+                    @Override
+                    public void configure() {
+                      bind(FooBar.class);
+                      expose(FooBar.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
-    
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        binder().requireExplicitBindings();
 
-        install(new PrivateModule() {
-          public void configure() {
-            bind(Foo.class).to(FooImpl.class);
-            expose(Foo.class);
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        bind(Foo.class).to(FooImpl.class);
+                        expose(Foo.class);
+                      }
+                    });
+              }
+            });
     ensureInChild(injector, FooImpl.class);
   }
-  
+
   public void testPrivateModuleAddsOption() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Foo.class).to(FooImpl.class);
-  
-          // Fails because FooBar is in the private module,
-          // and it wants Bar, but Bar would be JIT.
-          install(new PrivateModule() {
-            public void configure() {
-              binder().requireExplicitBindings();
-              bind(FooBar.class);
-              expose(FooBar.class);
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Foo.class).to(FooImpl.class);
+
+              // Fails because FooBar is in the private module,
+              // and it wants Bar, but Bar would be JIT.
+              install(
+                  new PrivateModule() {
+                    @Override
+                    public void configure() {
+                      binder().requireExplicitBindings();
+                      bind(FooBar.class);
+                      expose(FooBar.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitFailed(Bar.class));
       assertEquals(1, expected.getErrorMessages().size());
     }
   }
 
   public void testPrivateModuleSiblingsDontShareOption() {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).to(FooImpl.class);
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Foo.class).to(FooImpl.class);
 
-        install(new PrivateModule() {
-          public void configure() {
-            binder().requireExplicitBindings();
+            install(
+                new PrivateModule() {
+                  @Override
+                  public void configure() {
+                    binder().requireExplicitBindings();
+                  }
+                });
+
+            // This works, even though Bar is JIT,
+            // because the requireExplicitBindings isn't shared
+            // between sibling private modules.
+            install(
+                new PrivateModule() {
+                  @Override
+                  public void configure() {
+                    bind(FooBar.class);
+                    expose(FooBar.class);
+                  }
+                });
           }
         });
-
-        // This works, even though Bar is JIT,
-        // because the requireExplicitBindings isn't shared
-        // between sibling private modules.
-        install(new PrivateModule() {
-          public void configure() {
-            bind(FooBar.class);
-            expose(FooBar.class);
-          }
-        });
-      }
-    });
-  }  
+  }
 
   public void testTypeLiteralsCanBeInjected() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          binder().requireExplicitBindings();
-          bind(new TypeLiteral<WantsTypeLiterals<String>>() {});
-          bind(new TypeLiteral<Set<String>>() {}).toInstance(of("bar"));
-        }
-      });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(new TypeLiteral<WantsTypeLiterals<String>>() {});
+                bind(new TypeLiteral<Set<String>>() {}).toInstance(of("bar"));
+              }
+            });
 
     WantsTypeLiterals<String> foo = injector.getInstance(new Key<WantsTypeLiterals<String>>() {});
     assertEquals(foo.literal.getRawType(), String.class);
     assertEquals(of("bar"), foo.set);
   }
-  
+
   public void testMembersInjectorsCanBeInjected() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        binder().requireExplicitBindings();
-      }
-      
-      @Provides String data(MembersInjector<String> mi) {
-        String data = "foo";
-        mi.injectMembers(data);
-        return data;
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+              }
+
+              @Provides
+              String data(MembersInjector<String> mi) {
+                String data = "foo";
+                mi.injectMembers(data);
+                return data;
+              }
+            });
 
     String data = injector.getInstance(String.class);
     assertEquals("foo", data);
@@ -516,18 +590,20 @@
 
   public void testJitLinkedBindingInParentFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
-              binder().requireExplicitBindings();
-              bind(Foo.class).to(FooImpl.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      binder().requireExplicitBindings();
+                      bind(Foo.class).to(FooImpl.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitInParentFailed(FooImpl.class));
@@ -537,18 +613,20 @@
 
   public void testJitProviderBindingInParentFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
-              binder().requireExplicitBindings();
-              bind(Foo.class).toProvider(FooProvider.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      binder().requireExplicitBindings();
+                      bind(Foo.class).toProvider(FooProvider.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitInParentFailed(FooProvider.class));
@@ -558,18 +636,20 @@
 
   public void testJitImplementedByBindingInParentFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
-              binder().requireExplicitBindings();
-              bind(ImplBy.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      binder().requireExplicitBindings();
+                      bind(ImplBy.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitInParentFailed(ImplByImpl.class));
@@ -579,18 +659,20 @@
 
   public void testJitProvidedByBindingInParentFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
-              binder().requireExplicitBindings();
-              bind(ProvBy.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      binder().requireExplicitBindings();
+                      bind(ProvBy.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("should have failed");
     } catch (CreationException expected) {
       assertContains(expected.getMessage(), jitInParentFailed(ProvByProvider.class));
@@ -599,32 +681,37 @@
   }
 
   private void ensureWorks(Injector injector, Class<?>... classes) {
-    for(int i = 0; i < classes.length; i++) {
+    for (int i = 0; i < classes.length; i++) {
       injector.getInstance(classes[i]);
       injector.getProvider(classes[i]).get();
       injector.getBinding(classes[i]).getProvider().get();
     }
   }
-  
-  enum GetBindingCheck { FAIL_ALL, ALLOW_BINDING, ALLOW_BINDING_PROVIDER }
+
+  enum GetBindingCheck {
+    FAIL_ALL,
+    ALLOW_BINDING,
+    ALLOW_BINDING_PROVIDER
+  }
+
   private void ensureFails(Injector injector, GetBindingCheck getBinding, Class<?>... classes) {
-    for(int i = 0; i < classes.length; i++) {      
-      try { 
+    for (int i = 0; i < classes.length; i++) {
+      try {
         injector.getInstance(classes[i]);
         fail("should have failed tring to retrieve class: " + classes[i]);
-      } catch(ConfigurationException expected) {
+      } catch (ConfigurationException expected) {
         assertContains(expected.getMessage(), jitFailed(classes[i]));
         assertEquals(1, expected.getErrorMessages().size());
       }
-      
-      try { 
+
+      try {
         injector.getProvider(classes[i]);
         fail("should have failed tring to retrieve class: " + classes[i]);
-      } catch(ConfigurationException expected) {
+      } catch (ConfigurationException expected) {
         assertContains(expected.getMessage(), jitFailed(classes[i]));
         assertEquals(1, expected.getErrorMessages().size());
       }
-      
+
       if (getBinding == GetBindingCheck.ALLOW_BINDING
           || getBinding == GetBindingCheck.ALLOW_BINDING_PROVIDER) {
         Binding<?> binding = injector.getBinding(classes[i]);
@@ -633,7 +720,7 @@
           if (getBinding != GetBindingCheck.ALLOW_BINDING_PROVIDER) {
             fail("should have failed trying to retrieve class: " + classes[i]);
           }
-        } catch(ConfigurationException expected) {
+        } catch (ConfigurationException expected) {
           if (getBinding == GetBindingCheck.ALLOW_BINDING_PROVIDER) {
             throw expected;
           }
@@ -643,59 +730,80 @@
       } else {
         try {
           injector.getBinding(classes[i]);
-          fail("should have failed tring to retrieve class: " + classes[i]);          
-        } catch(ConfigurationException expected) {
+          fail("should have failed tring to retrieve class: " + classes[i]);
+        } catch (ConfigurationException expected) {
           assertContains(expected.getMessage(), jitFailed(classes[i]));
           assertEquals(1, expected.getErrorMessages().size());
         }
       }
     }
   }
-  
+
   private void ensureInChild(Injector injector, Class<?>... classes) {
-    for(int i = 0; i < classes.length; i++) {      
-      try { 
+    for (int i = 0; i < classes.length; i++) {
+      try {
         injector.getInstance(classes[i]);
         fail("should have failed tring to retrieve class: " + classes[i]);
-      } catch(ConfigurationException expected) {
+      } catch (ConfigurationException expected) {
         assertContains(expected.getMessage(), inChildMessage(classes[i]));
         assertEquals(1, expected.getErrorMessages().size());
       }
-      
-      try { 
+
+      try {
         injector.getProvider(classes[i]);
         fail("should have failed tring to retrieve class: " + classes[i]);
-      } catch(ConfigurationException expected) {
+      } catch (ConfigurationException expected) {
         assertContains(expected.getMessage(), inChildMessage(classes[i]));
         assertEquals(1, expected.getErrorMessages().size());
       }
-      
+
       try {
         injector.getBinding(classes[i]);
-        fail("should have failed tring to retrieve class: " + classes[i]);          
-      } catch(ConfigurationException expected) {
+        fail("should have failed tring to retrieve class: " + classes[i]);
+      } catch (ConfigurationException expected) {
         assertContains(expected.getMessage(), inChildMessage(classes[i]));
         assertEquals(1, expected.getErrorMessages().size());
       }
     }
   }
-  
+
   private static interface Foo {}
+
   private static class FooImpl implements Foo {}
-  @Singleton private static class ScopedFooImpl implements Foo {}
+
+  @Singleton
+  private static class ScopedFooImpl implements Foo {}
+
   private static class WantsScopedFooImpl {
-    @SuppressWarnings("unused") @Inject ScopedFooImpl scopedFoo;
+    @SuppressWarnings("unused")
+    @Inject
+    ScopedFooImpl scopedFoo;
   }
+
   private static class Bar {}
+
   private static class FooBar {
-    @SuppressWarnings("unused") @Inject Foo foo;
-    @SuppressWarnings("unused") @Inject Bar bar;
+    @SuppressWarnings("unused")
+    @Inject
+    Foo foo;
+
+    @SuppressWarnings("unused")
+    @Inject
+    Bar bar;
   }
+
   private static class ProviderFooBar {
-    @SuppressWarnings("unused") @Inject Provider<Foo> foo;
-    @SuppressWarnings("unused") @Inject Provider<Bar> bar;
+    @SuppressWarnings("unused")
+    @Inject
+    Provider<Foo> foo;
+
+    @SuppressWarnings("unused")
+    @Inject
+    Provider<Bar> bar;
   }
+
   private static class FooProvider implements Provider<Foo> {
+    @Override
     public Foo get() {
       return new FooImpl();
     }
@@ -703,29 +811,33 @@
 
   @ImplementedBy(ImplByImpl.class)
   private static interface ImplBy {}
+
   private static class ImplByImpl implements ImplBy {}
-  
+
   @ImplementedBy(ImplByScopedImpl.class)
   private static interface ImplByScoped {}
+
   @Singleton
-  private static class ImplByScopedImpl implements ImplByScoped {}  
+  private static class ImplByScopedImpl implements ImplByScoped {}
 
   @ProvidedBy(ProvByProvider.class)
   private static interface ProvBy {}
+
   private static class ProvByProvider implements Provider<ProvBy> {
+    @Override
     public ProvBy get() {
       return new ProvBy() {};
     }
   }
-  
+
   private static class WantsTypeLiterals<T> {
     TypeLiteral<T> literal;
     Set<T> set;
-    
-    @Inject WantsTypeLiterals(TypeLiteral<T> literal, Set<T> set) {
+
+    @Inject
+    WantsTypeLiterals(TypeLiteral<T> literal, Set<T> set) {
       this.literal = literal;
       this.set = set;
-      
     }
   }
 }
diff --git a/core/test/com/google/inject/KeyTest.java b/core/test/com/google/inject/KeyTest.java
index d9dd943..858c981 100644
--- a/core/test/com/google/inject/KeyTest.java
+++ b/core/test/com/google/inject/KeyTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,9 +26,6 @@
 import com.google.inject.name.Names;
 import com.google.inject.spi.Dependency;
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -42,14 +39,15 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class KeyTest extends TestCase {
 
   public void foo(List<String> a, List<String> b) {}
+
   public void bar(Provider<List<String>> a) {}
+
   @Foo String baz;
   List<? extends CharSequence> wildcardExtends;
 
@@ -67,10 +65,11 @@
   }
 
   public void testProviderKey() throws NoSuchMethodException {
-    Key<?> actual = Key.get(getClass().getMethod("foo", List.class, List.class)
-        .getGenericParameterTypes()[0]).providerKey();
-    Key<?> expected = Key.get(getClass().getMethod("bar", Provider.class)
-        .getGenericParameterTypes()[0]);
+    Key<?> actual =
+        Key.get(getClass().getMethod("foo", List.class, List.class).getGenericParameterTypes()[0])
+            .providerKey();
+    Key<?> expected =
+        Key.get(getClass().getMethod("bar", Provider.class).getGenericParameterTypes()[0]);
     assertEqualsBothWays(expected, actual);
     assertEquals(expected.toString(), actual.toString());
   }
@@ -81,23 +80,37 @@
     assertEquals(types[0], types[1]);
     Key<List<String>> k = new Key<List<String>>() {};
     assertEquals(types[0], k.getTypeLiteral().getType());
-    assertFalse(types[0].equals(
-        new Key<List<Integer>>() {}.getTypeLiteral().getType()));
+    assertFalse(types[0].equals(new Key<List<Integer>>() {}.getTypeLiteral().getType()));
   }
 
   /**
-   * Key canonicalizes {@link int.class} to {@code Integer.class}, and
-   * won't expose wrapper types.
+   * Key canonicalizes {@link int.class} to {@code Integer.class}, and won't expose wrapper types.
    */
   public void testPrimitivesAndWrappersAreEqual() {
-    Class[] primitives = new Class[] {
-        boolean.class, byte.class, short.class, int.class, long.class,
-        float.class, double.class, char.class, void.class
-    };
-    Class[] wrappers = new Class[] {
-        Boolean.class, Byte.class, Short.class, Integer.class, Long.class,
-        Float.class, Double.class, Character.class, Void.class
-    };
+    Class[] primitives =
+        new Class[] {
+          boolean.class,
+          byte.class,
+          short.class,
+          int.class,
+          long.class,
+          float.class,
+          double.class,
+          char.class,
+          void.class
+        };
+    Class[] wrappers =
+        new Class[] {
+          Boolean.class,
+          Byte.class,
+          Short.class,
+          Integer.class,
+          Long.class,
+          Float.class,
+          Double.class,
+          Character.class,
+          Void.class
+        };
 
     for (int t = 0; t < primitives.length; t++) {
       @SuppressWarnings("unchecked")
@@ -154,7 +167,9 @@
       Key.get(String.class, Deprecated.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(), "java.lang.Deprecated is not a binding annotation. ",
+      assertContains(
+          expected.getMessage(),
+          "java.lang.Deprecated is not a binding annotation. ",
           "Please annotate it with @BindingAnnotation.");
     }
   }
@@ -164,7 +179,9 @@
       Key.get(String.class, Bar.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(), Bar.class.getName() + " is not retained at runtime.",
+      assertContains(
+          expected.getMessage(),
+          Bar.class.getName() + " is not retained at runtime.",
           "Please annotate it with @Retention(RUNTIME).");
     }
   }
@@ -173,16 +190,20 @@
 
   /** Test for issue 186 */
   public void testCannotCreateKeysWithTypeVariables() throws NoSuchMethodException {
-    ParameterizedType listOfTType = (ParameterizedType) getClass().getDeclaredMethod(
-        "parameterizedWithVariable", List.class).getGenericParameterTypes()[0];
+    ParameterizedType listOfTType =
+        (ParameterizedType)
+            getClass()
+                    .getDeclaredMethod("parameterizedWithVariable", List.class)
+                    .getGenericParameterTypes()[
+                0];
 
     TypeLiteral<?> listOfT = TypeLiteral.get(listOfTType);
     try {
       Key.get(listOfT);
       fail("Guice should not allow keys for java.util.List<T>");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
-          "java.util.List<T> cannot be used as a key; It is not fully specified.");
+      assertContains(
+          e.getMessage(), "java.util.List<T> cannot be used as a key; It is not fully specified.");
     }
 
     TypeVariable tType = (TypeVariable) listOfTType.getActualTypeArguments()[0];
@@ -191,8 +212,7 @@
       Key.get(t);
       fail("Guice should not allow keys for T");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
-          "T cannot be used as a key; It is not fully specified.");
+      assertContains(e.getMessage(), "T cannot be used as a key; It is not fully specified.");
     }
   }
 
@@ -202,8 +222,7 @@
       Key.get(typeLiteral);
       fail("Guice should not allow keys for T");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
-          "T cannot be used as a key; It is not fully specified.");
+      assertContains(e.getMessage(), "T cannot be used as a key; It is not fully specified.");
     }
   }
 
@@ -216,8 +235,7 @@
       KeyTest.<Integer>createKey();
       fail("Guice should not allow keys for T");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
-          "T cannot be used as a key; It is not fully specified.");
+      assertContains(e.getMessage(), "T cannot be used as a key; It is not fully specified.");
     }
   }
 
@@ -228,14 +246,18 @@
   interface B {}
 
   @Retention(RUNTIME)
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
-  @BindingAnnotation @interface Foo {}
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+  @BindingAnnotation
+  @interface Foo {}
 
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
-  @BindingAnnotation @interface Bar {}
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+  @BindingAnnotation
+  @interface Bar {}
 
-  class HasTypeParameters<A, B extends List<A> & Runnable, C extends Runnable> {
-    A a; B b; C c;
+  static class HasTypeParameters<A, B extends List<A> & Runnable, C extends Runnable> {
+    A a;
+    B b;
+    C c;
   }
 
   public void testKeysWithDefaultAnnotations() {
@@ -255,67 +277,79 @@
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface AllDefaults {
+  @BindingAnnotation
+  @interface AllDefaults {
     int v1() default 1;
+
     String v2() default "foo";
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface SomeDefaults {
+  @BindingAnnotation
+  @interface SomeDefaults {
     int v1() default 1;
+
     String v2() default "foo";
+
     Class<?> clazz();
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface NoDefaults {
+  @BindingAnnotation
+  @interface NoDefaults {
     int value();
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface Marker {
-  }
+  @BindingAnnotation
+  @interface Marker {}
 
   @AllDefaults
   @Marker
-  class HasAnnotations {}
+  static class HasAnnotations {}
 
   public void testAnonymousClassesDontHoldRefs() {
     final AtomicReference<Provider<List<String>>> stringProvider =
         new AtomicReference<Provider<List<String>>>();
     final AtomicReference<Provider<List<Integer>>> intProvider =
         new AtomicReference<Provider<List<Integer>>>();
-    final Object foo = new Object() {
-      @SuppressWarnings("unused") @Inject List<String> list;
-    };
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        bind(new Key<List<String>>() {}).toInstance(new ArrayList<String>());
-        bind(new TypeLiteral<List<Integer>>() {}).toInstance(new ArrayList<Integer>());
+    final Object foo =
+        new Object() {
+          @SuppressWarnings("unused")
+          @Inject
+          List<String> list;
+        };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(new Key<List<String>>() {}).toInstance(new ArrayList<String>());
+            bind(new TypeLiteral<List<Integer>>() {}).toInstance(new ArrayList<Integer>());
 
-        stringProvider.set(getProvider(new Key<List<String>>() {}));
-        intProvider.set(binder().getProvider(Dependency.get(new Key<List<Integer>>() {})));
+            stringProvider.set(getProvider(new Key<List<String>>() {}));
+            intProvider.set(binder().getProvider(Dependency.get(new Key<List<Integer>>() {})));
 
-        binder().requestInjection(new TypeLiteral<Object>() {}, foo);
-      }
-    };
-    WeakReference<Module> moduleRef = new WeakReference<Module>(module);
+            binder().requestInjection(new TypeLiteral<Object>() {}, foo);
+          }
+        };
+    WeakReference<Module> moduleRef = new WeakReference<>(module);
     final Injector injector = Guice.createInjector(module);
     module = null;
     awaitClear(moduleRef); // Make sure anonymous keys & typeliterals don't hold the module.
 
-    Runnable runner = new Runnable() {
-      @Override public void run() {
-        injector.getInstance(new Key<Typed<String>>() {});
-        injector.getInstance(Key.get(new TypeLiteral<Typed<Integer>>() {}));
-      }
-    };
-    WeakReference<Runnable> runnerRef = new WeakReference<Runnable>(runner);
+    Runnable runner =
+        new Runnable() {
+          @Override
+          public void run() {
+            injector.getInstance(new Key<Typed<String>>() {});
+            injector.getInstance(Key.get(new TypeLiteral<Typed<Integer>>() {}));
+          }
+        };
+    WeakReference<Runnable> runnerRef = new WeakReference<>(runner);
     runner.run();
     runner = null;
     awaitClear(runnerRef); // also make sure anonymous keys & typeliterals don't hold for JITs
   }
 
   static class Typed<T> {}
-
 }
diff --git a/core/test/com/google/inject/LoggerInjectionTest.java b/core/test/com/google/inject/LoggerInjectionTest.java
index 36e5b22..6573181 100644
--- a/core/test/com/google/inject/LoggerInjectionTest.java
+++ b/core/test/com/google/inject/LoggerInjectionTest.java
@@ -3,10 +3,8 @@
 import static com.google.inject.Asserts.assertContains;
 
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.util.logging.Logger;
+import junit.framework.TestCase;
 
 /**
  * Test built-in injection of loggers.
@@ -22,21 +20,23 @@
     injector.injectMembers(this);
     assertEquals("com.google.inject.LoggerInjectionTest", logger.getName());
   }
-  
+
   public void testLoggerInConstructor() {
     Injector injector = Guice.createInjector();
     Foo foo = injector.getInstance(Foo.class);
     assertEquals("com.google.inject.LoggerInjectionTest$Foo", foo.logger.getName());
   }
-  
+
   private static class Foo {
     Logger logger;
+
     @SuppressWarnings("unused")
-    @Inject Foo(Logger logger) {
+    @Inject
+    Foo(Logger logger) {
       this.logger = logger;
     }
   }
-  
+
   public void testLoggerWithoutMember() {
     Injector injector = Guice.createInjector();
     assertNull(injector.getInstance(Logger.class).getName());
@@ -46,28 +46,33 @@
   }
 
   public void testCanBindAnnotatedLogger() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Logger.class)
-            .annotatedWith(Names.named("anonymous"))
-            .toInstance(Logger.getAnonymousLogger());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Logger.class)
+                    .annotatedWith(Names.named("anonymous"))
+                    .toInstance(Logger.getAnonymousLogger());
+              }
+            });
 
     assertNull(injector.getInstance(Key.get(Logger.class, Names.named("anonymous"))).getName());
   }
-  
+
   public void testCannotBindLogger() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Logger.class).toInstance(Logger.getAnonymousLogger());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Logger.class).toInstance(Logger.getAnonymousLogger());
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "A binding to java.util.logging.Logger was already configured");
+      assertContains(
+          expected.getMessage(), "A binding to java.util.logging.Logger was already configured");
     }
   }
 }
diff --git a/core/test/com/google/inject/MembersInjectorTest.java b/core/test/com/google/inject/MembersInjectorTest.java
index 4bb32dd..3c07127 100644
--- a/core/test/com/google/inject/MembersInjectorTest.java
+++ b/core/test/com/google/inject/MembersInjectorTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,70 +18,84 @@
 
 import static com.google.inject.Asserts.assertContains;
 
+import com.google.inject.internal.Annotations;
 import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
-
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.inject.Inject;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class MembersInjectorTest extends TestCase {
 
-  private static final A<C> uninjectableA = new A<C>() {
-    @Override void doNothing() {
-      throw new AssertionFailedError();
-    }
-  };
+  private static final long DEADLOCK_TIMEOUT_SECONDS = 1;
 
-  private static final B uninjectableB = new B() {
-    @Override void doNothing() {
-      throw new AssertionFailedError();
-    }
-  };
+  private static final A<C> uninjectableA =
+      new A<C>() {
+        @Inject
+        @Override
+        void doNothing() {
+          throw new AssertionFailedError();
+        }
+      };
+
+  private static final B uninjectableB =
+      new B() {
+        @Inject
+        @Override
+        void doNothing() {
+          throw new AssertionFailedError();
+        }
+      };
 
   private static final C myFavouriteC = new C();
 
   public void testMembersInjectorFromBinder() {
-    final AtomicReference<MembersInjector<A<C>>> aMembersInjectorReference
-        = new AtomicReference<MembersInjector<A<C>>>();
-    final AtomicReference<MembersInjector<B>> bMembersInjectorReference
-        = new AtomicReference<MembersInjector<B>>();
+    final AtomicReference<MembersInjector<A<C>>> aMembersInjectorReference =
+        new AtomicReference<MembersInjector<A<C>>>();
+    final AtomicReference<MembersInjector<B>> bMembersInjectorReference =
+        new AtomicReference<MembersInjector<B>>();
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MembersInjector<A<C>> aMembersInjector = getMembersInjector(new TypeLiteral<A<C>>() {});
-        try {
-          aMembersInjector.injectMembers(uninjectableA);
-          fail();
-        } catch (IllegalStateException expected) {
-          assertContains(expected.getMessage(),
-              "This MembersInjector cannot be used until the Injector has been created.");
-        }
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MembersInjector<A<C>> aMembersInjector = getMembersInjector(new TypeLiteral<A<C>>() {});
+            try {
+              aMembersInjector.injectMembers(uninjectableA);
+              fail();
+            } catch (IllegalStateException expected) {
+              assertContains(
+                  expected.getMessage(),
+                  "This MembersInjector cannot be used until the Injector has been created.");
+            }
 
-        MembersInjector<B> bMembersInjector = getMembersInjector(B.class);
-        try {
-          bMembersInjector.injectMembers(uninjectableB);
-          fail();
-        } catch (IllegalStateException expected) {
-          assertContains(expected.getMessage(),
-              "This MembersInjector cannot be used until the Injector has been created.");
-        }
+            MembersInjector<B> bMembersInjector = getMembersInjector(B.class);
+            try {
+              bMembersInjector.injectMembers(uninjectableB);
+              fail();
+            } catch (IllegalStateException expected) {
+              assertContains(
+                  expected.getMessage(),
+                  "This MembersInjector cannot be used until the Injector has been created.");
+            }
 
-        aMembersInjectorReference.set(aMembersInjector);
-        bMembersInjectorReference.set(bMembersInjector);
+            aMembersInjectorReference.set(aMembersInjector);
+            bMembersInjectorReference.set(bMembersInjector);
 
-        assertEquals("MembersInjector<java.lang.String>",
-            getMembersInjector(String.class).toString());
+            assertEquals(
+                "MembersInjector<java.lang.String>", getMembersInjector(String.class).toString());
 
-        bind(C.class).toInstance(myFavouriteC);
-      }
-    });
+            bind(C.class).toInstance(myFavouriteC);
+          }
+        });
 
-    A<C> injectableA = new A<C>();
+    A<C> injectableA = new A<>();
     aMembersInjectorReference.get().injectMembers(injectableA);
     assertSame(myFavouriteC, injectableA.t);
     assertSame(myFavouriteC, injectableA.b.c);
@@ -96,17 +110,20 @@
   }
 
   public void testMembersInjectorFromInjector() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(C.class).toInstance(myFavouriteC);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(C.class).toInstance(myFavouriteC);
+              }
+            });
 
-    MembersInjector<A<C>> aMembersInjector
-        = injector.getMembersInjector(new TypeLiteral<A<C>>() {});
+    MembersInjector<A<C>> aMembersInjector =
+        injector.getMembersInjector(new TypeLiteral<A<C>>() {});
     MembersInjector<B> bMembersInjector = injector.getMembersInjector(B.class);
 
-    A<C> injectableA = new A<C>();
+    A<C> injectableA = new A<>();
     aMembersInjector.injectMembers(injectableA);
     assertSame(myFavouriteC, injectableA.t);
     assertSame(myFavouriteC, injectableA.b.c);
@@ -119,15 +136,15 @@
     bMembersInjector.injectMembers(anotherInjectableB);
     assertSame(myFavouriteC, anotherInjectableB.c);
 
-    assertEquals("MembersInjector<java.lang.String>",
-        injector.getMembersInjector(String.class).toString());
+    assertEquals(
+        "MembersInjector<java.lang.String>", injector.getMembersInjector(String.class).toString());
   }
 
   public void testMembersInjectorWithNonInjectedTypes() {
     Injector injector = Guice.createInjector();
 
-    MembersInjector<NoInjectedMembers> membersInjector
-        = injector.getMembersInjector(NoInjectedMembers.class);
+    MembersInjector<NoInjectedMembers> membersInjector =
+        injector.getMembersInjector(NoInjectedMembers.class);
 
     membersInjector.injectMembers(new NoInjectedMembers());
     membersInjector.injectMembers(new NoInjectedMembers());
@@ -136,14 +153,15 @@
   public void testInjectionFailure() {
     Injector injector = Guice.createInjector();
 
-    MembersInjector<InjectionFailure> membersInjector
-        = injector.getMembersInjector(InjectionFailure.class);
+    MembersInjector<InjectionFailure> membersInjector =
+        injector.getMembersInjector(InjectionFailure.class);
 
     try {
       membersInjector.injectMembers(new InjectionFailure());
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error injecting method, java.lang.ClassCastException: whoops, failure #1");
     }
   }
@@ -156,13 +174,17 @@
   }
 
   public void testInjectingMembersInjector() {
-    InjectsMembersInjector injectsMembersInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(C.class).toInstance(myFavouriteC);
-      }
-    }).getInstance(InjectsMembersInjector.class);
+    InjectsMembersInjector injectsMembersInjector =
+        Guice.createInjector(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(C.class).toInstance(myFavouriteC);
+                  }
+                })
+            .getInstance(InjectsMembersInjector.class);
 
-    A<C> a = new A<C>();
+    A<C> a = new A<>();
     injectsMembersInjector.aMembersInjector.injectMembers(a);
     assertSame(myFavouriteC, a.t);
     assertSame(myFavouriteC, a.b.c);
@@ -170,27 +192,33 @@
 
   public void testCannotBindMembersInjector() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(MembersInjector.class).toProvider(Providers.<MembersInjector>of(null));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(MembersInjector.class).toProvider(Providers.<MembersInjector>of(null));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Binding to core guice framework type is not allowed: MembersInjector.");
     }
 
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(new TypeLiteral<MembersInjector<A<C>>>() {})
-              .toProvider(Providers.<MembersInjector<A<C>>>of(null));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(new TypeLiteral<MembersInjector<A<C>>>() {})
+                  .toProvider(Providers.<MembersInjector<A<C>>>of(null));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Binding to core guice framework type is not allowed: MembersInjector.");
     }
   }
@@ -200,7 +228,8 @@
       Guice.createInjector().getInstance(InjectsBrokenMembersInjector.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for " + Unimplemented.class.getName() + " was bound.",
           "while locating " + Unimplemented.class.getName(),
           "for field at " + A.class.getName() + ".t(MembersInjectorTest.java:",
@@ -211,20 +240,24 @@
   }
 
   public void testLookupMembersInjectorBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(C.class).toInstance(myFavouriteC);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(C.class).toInstance(myFavouriteC);
+              }
+            });
     MembersInjector<A<C>> membersInjector =
         injector.getInstance(new Key<MembersInjector<A<C>>>() {});
 
-    A<C> a = new A<C>();
+    A<C> a = new A<>();
     membersInjector.injectMembers(a);
     assertSame(myFavouriteC, a.t);
     assertSame(myFavouriteC, a.b.c);
 
-    assertEquals("MembersInjector<java.lang.String>",
+    assertEquals(
+        "MembersInjector<java.lang.String>",
         injector.getInstance(new Key<MembersInjector<String>>() {}).toString());
   }
 
@@ -234,8 +267,8 @@
       injector.getInstance(MembersInjector.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
-          "Cannot inject a MembersInjector that has no type parameter");
+      assertContains(
+          expected.getMessage(), "Cannot inject a MembersInjector that has no type parameter");
     }
   }
 
@@ -245,21 +278,144 @@
       injector.getInstance(new Key<MembersInjector<String>>(Names.named("foo")) {});
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for com.google.inject.MembersInjector<java.lang.String> "
-              + "annotated with @com.google.inject.name.Named(value=foo) was bound.");
+              + "annotated with @com.google.inject.name.Named(value="
+              + Annotations.memberValueString("foo")
+              + ") was bound.");
     }
   }
 
+  /** Callback for member injection. Uses a static type to be referable by getInstance(). */
+  abstract static class AbstractParallelMemberInjectionCallback {
+
+    volatile boolean called = false;
+
+    private final Thread mainThread;
+    private final Class<? extends AbstractParallelMemberInjectionCallback> otherCallbackClass;
+
+    AbstractParallelMemberInjectionCallback(
+        Class<? extends AbstractParallelMemberInjectionCallback> otherCallbackClass) {
+      this.mainThread = Thread.currentThread();
+      this.otherCallbackClass = otherCallbackClass;
+    }
+
+    @Inject
+    void callback(final Injector injector) throws Exception {
+      called = true;
+      if (mainThread != Thread.currentThread()) {
+        // only execute logic on the main thread
+        return;
+      }
+      // verify that other callback can be finished on a separate thread
+      AbstractParallelMemberInjectionCallback otherCallback =
+          Executors.newSingleThreadExecutor()
+              .submit(
+                  new Callable<AbstractParallelMemberInjectionCallback>() {
+                    @Override
+                    public AbstractParallelMemberInjectionCallback call() throws Exception {
+                      return injector.getInstance(otherCallbackClass);
+                    }
+                  })
+              .get(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+      assertTrue(otherCallback.called);
+
+      try {
+        // other thread would wait for callback to finish on this thread first
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Object>() {
+                  @Override
+                  public Object call() throws Exception {
+                    return injector.getInstance(
+                        AbstractParallelMemberInjectionCallback.this.getClass());
+                  }
+                })
+            .get(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        fail();
+      } catch (TimeoutException expected) {
+        // recursive call from another thread should time out
+        // as it would be waiting for this thread to finish
+      }
+    }
+  }
+
+  static class ParallelMemberInjectionCallback1 extends AbstractParallelMemberInjectionCallback {
+
+    ParallelMemberInjectionCallback1() {
+      super(ParallelMemberInjectionCallback2.class);
+    }
+  }
+
+  static class ParallelMemberInjectionCallback2 extends AbstractParallelMemberInjectionCallback {
+
+    ParallelMemberInjectionCallback2() {
+      super(ParallelMemberInjectionCallback1.class);
+    }
+  }
+
+  /**
+   * Tests that member injections could happen in parallel.
+   *
+   * <p>Additional check that when member injection happen other threads would wait for it to finish
+   * to provide proper resolution order semantics.
+   */
+
+  public void testMemberInjectorParallelization() throws Exception {
+    final ParallelMemberInjectionCallback1 c1 = new ParallelMemberInjectionCallback1();
+    final ParallelMemberInjectionCallback2 c2 = new ParallelMemberInjectionCallback2();
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(ParallelMemberInjectionCallback1.class).toInstance(c1);
+            bind(ParallelMemberInjectionCallback2.class).toInstance(c2);
+          }
+        });
+    assertTrue(c1.called);
+    assertTrue(c2.called);
+  }
+
+  /** Member injection callback that injects itself. */
+  static class RecursiveMemberInjection {
+    boolean called = false;
+
+    @Inject
+    void callback(RecursiveMemberInjection recursiveMemberInjection) {
+      if (called) {
+        fail("Should not be called twice");
+      }
+      called = true;
+    }
+  }
+
+  /** Verifies that member injection injecting itself would get a non initialized instance. */
+  public void testRecursiveMemberInjector() throws Exception {
+    final RecursiveMemberInjection rmi = new RecursiveMemberInjection();
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(RecursiveMemberInjection.class).toInstance(rmi);
+          }
+        });
+    assertTrue("Member injection should happen", rmi.called);
+  }
+
   static class A<T> {
     @Inject B b;
     @Inject T t;
-    @Inject void doNothing() {}
+
+    @Inject
+    void doNothing() {}
   }
 
   static class B {
     @Inject C c;
-    @Inject void doNothing() {}
+
+    @Inject
+    void doNothing() {}
   }
 
   static class C {}
@@ -269,7 +425,8 @@
   static class InjectionFailure {
     int failures = 0;
 
-    @Inject void fail() {
+    @Inject
+    void fail() {
       throw new ClassCastException("whoops, failure #" + (++failures));
     }
   }
diff --git a/core/test/com/google/inject/MethodInterceptionTest.java b/core/test/com/google/inject/MethodInterceptionTest.java
index de39bd9..85ba987 100644
--- a/core/test/com/google/inject/MethodInterceptionTest.java
+++ b/core/test/com/google/inject/MethodInterceptionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,100 +25,121 @@
 import com.google.inject.matcher.AbstractMatcher;
 import com.google.inject.matcher.Matchers;
 import com.google.inject.spi.ConstructorBinding;
-
-import junit.framework.TestCase;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Queue;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class MethodInterceptionTest extends TestCase {
 
   private AtomicInteger count = new AtomicInteger();
 
   private final class CountingInterceptor implements MethodInterceptor {
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       count.incrementAndGet();
       return methodInvocation.proceed();
     }
   }
 
-  private final class ReturnNullInterceptor implements MethodInterceptor {
+  private static final class ReturnNullInterceptor implements MethodInterceptor {
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       return null;
     }
   }
-  
-  private final class NoOpInterceptor implements MethodInterceptor {
+
+  private static final class NoOpInterceptor implements MethodInterceptor {
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       return methodInvocation.proceed();
     }
   }
 
   public void testSharedProxyClasses() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.returns(only(Foo.class)),
-            new ReturnNullInterceptor());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.returns(only(Foo.class)), new ReturnNullInterceptor());
+              }
+            });
 
-    Injector childOne = injector.createChildInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Interceptable.class);
-      }
-    });
+    Injector childOne =
+        injector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Interceptable.class);
+              }
+            });
 
     Interceptable nullFoosOne = childOne.getInstance(Interceptable.class);
     assertNotNull(nullFoosOne.bar());
     assertNull(nullFoosOne.foo()); // confirm it's being intercepted
 
-    Injector childTwo = injector.createChildInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Interceptable.class);
-      }
-    });
+    Injector childTwo =
+        injector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Interceptable.class);
+              }
+            });
 
     Interceptable nullFoosTwo = childTwo.getInstance(Interceptable.class);
     assertNull(nullFoosTwo.foo()); // confirm it's being intercepted
 
-    assertSame("Child injectors should share proxy classes, otherwise memory leaks!",
-        nullFoosOne.getClass(), nullFoosTwo.getClass());
-    
-    Injector injector2 = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.returns(only(Foo.class)),
-            new ReturnNullInterceptor());
-      }
-    });
+    assertSame(
+        "Child injectors should share proxy classes, otherwise memory leaks!",
+        nullFoosOne.getClass(),
+        nullFoosTwo.getClass());
+
+    Injector injector2 =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.returns(only(Foo.class)), new ReturnNullInterceptor());
+              }
+            });
     Interceptable separateNullFoos = injector2.getInstance(Interceptable.class);
     assertNull(separateNullFoos.foo()); // confirm it's being intercepted
-    assertSame("different injectors should share proxy classes, otherwise memory leaks!",
-        nullFoosOne.getClass(), separateNullFoos.getClass());
+    assertSame(
+        "different injectors should share proxy classes, otherwise memory leaks!",
+        nullFoosOne.getClass(),
+        separateNullFoos.getClass());
   }
 
   public void testGetThis() {
-    final AtomicReference<Object> lastTarget = new AtomicReference<Object>();
+    final AtomicReference<Object> lastTarget = new AtomicReference<>();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), new MethodInterceptor() {
-          public Object invoke(MethodInvocation methodInvocation) throws Throwable {
-            lastTarget.set(methodInvocation.getThis());
-            return methodInvocation.proceed();
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(),
+                    Matchers.any(),
+                    new MethodInterceptor() {
+                      @Override
+                      public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+                        lastTarget.set(methodInvocation.getThis());
+                        return methodInvocation.proceed();
+                      }
+                    });
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     interceptable.foo();
@@ -126,22 +147,31 @@
   }
 
   public void testInterceptingFinalClass() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), new MethodInterceptor() {
-          public Object invoke(MethodInvocation methodInvocation) throws Throwable {
-            return methodInvocation.proceed();
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(),
+                    Matchers.any(),
+                    new MethodInterceptor() {
+                      @Override
+                      public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+                        return methodInvocation.proceed();
+                      }
+                    });
+              }
+            });
     try {
       injector.getInstance(NotInterceptable.class);
       fail();
-    } catch(ConfigurationException ce) {
-      assertEquals("Unable to method intercept: " + NotInterceptable.class.getName(),
+    } catch (ConfigurationException ce) {
+      assertEquals(
+          "Unable to method intercept: " + NotInterceptable.class.getName(),
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage().toString());
-      assertEquals("Cannot subclass final class class " + NotInterceptable.class.getName(),
+      assertEquals(
+          "Cannot subclass final class " + NotInterceptable.class.getName(),
           ce.getCause().getMessage());
     }
   }
@@ -149,27 +179,34 @@
   public void testSpiAccessToInterceptors() throws NoSuchMethodException {
     final MethodInterceptor countingInterceptor = new CountingInterceptor();
     final MethodInterceptor returnNullInterceptor = new ReturnNullInterceptor();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(),Matchers.returns(only(Foo.class)),
-            countingInterceptor);
-        bindInterceptor(Matchers.any(), Matchers.returns(only(Foo.class).or(only(Bar.class))),
-            returnNullInterceptor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.returns(only(Foo.class)), countingInterceptor);
+                bindInterceptor(
+                    Matchers.any(),
+                    Matchers.returns(only(Foo.class).or(only(Bar.class))),
+                    returnNullInterceptor);
+              }
+            });
 
-    ConstructorBinding<?> interceptedBinding
-        = (ConstructorBinding<?>) injector.getBinding(Interceptable.class);
+    ConstructorBinding<?> interceptedBinding =
+        (ConstructorBinding<?>) injector.getBinding(Interceptable.class);
     Method barMethod = Interceptable.class.getMethod("bar");
     Method fooMethod = Interceptable.class.getMethod("foo");
-    assertEquals(ImmutableMap.<Method, List<MethodInterceptor>>of(
-        fooMethod, ImmutableList.of(countingInterceptor, returnNullInterceptor),
-        barMethod, ImmutableList.of(returnNullInterceptor)),
+    assertEquals(
+        ImmutableMap.<Method, List<MethodInterceptor>>of(
+            fooMethod, ImmutableList.of(countingInterceptor, returnNullInterceptor),
+            barMethod, ImmutableList.of(returnNullInterceptor)),
         interceptedBinding.getMethodInterceptors());
 
-    ConstructorBinding<?> nonInterceptedBinding
-        = (ConstructorBinding<?>) injector.getBinding(Foo.class);
-    assertEquals(ImmutableMap.<Method, List<MethodInterceptor>>of(),
+    ConstructorBinding<?> nonInterceptedBinding =
+        (ConstructorBinding<?>) injector.getBinding(Foo.class);
+    assertEquals(
+        ImmutableMap.<Method, List<MethodInterceptor>>of(),
         nonInterceptedBinding.getMethodInterceptors());
 
     injector.getInstance(Interceptable.class).foo();
@@ -177,12 +214,15 @@
   }
 
   public void testInterceptedMethodThrows() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), new CountingInterceptor());
-        bindInterceptor(Matchers.any(), Matchers.any(), new CountingInterceptor());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(Matchers.any(), Matchers.any(), new CountingInterceptor());
+                bindInterceptor(Matchers.any(), Matchers.any(), new CountingInterceptor());
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     try {
@@ -199,14 +239,17 @@
       }
     }
   }
-  
+
   public void testNotInterceptedMethodsInInterceptedClassDontAddFrames() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.returns(only(Foo.class)),
-            new NoOpInterceptor());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.returns(only(Foo.class)), new NoOpInterceptor());
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     assertNull(interceptable.lastElements);
@@ -220,7 +263,7 @@
     }
     assertTrue(Arrays.toString(interceptable.lastElements), cglibFound);
     cglibFound = false;
-    
+
     interceptable.bar();
     for (int i = 0; i < interceptable.lastElements.length; i++) {
       if (interceptable.lastElements[i].toString().contains("cglib")) {
@@ -232,19 +275,22 @@
   }
 
   static class Foo {}
+
   static class Bar {}
 
   public static class Interceptable {
-    StackTraceElement[] lastElements; 
-    
+    StackTraceElement[] lastElements;
+
     public Foo foo() {
       lastElements = Thread.currentThread().getStackTrace();
       return new Foo() {};
     }
+
     public Bar bar() {
       lastElements = Thread.currentThread().getStackTrace();
       return new Bar() {};
     }
+
     public String explode() throws Exception {
       lastElements = Thread.currentThread().getStackTrace();
       throw new Exception("kaboom!", new RuntimeException("boom!"));
@@ -252,76 +298,96 @@
   }
 
   public static final class NotInterceptable {}
-  
+
   public void testInterceptingNonBridgeWorks() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Interface.class).to(Impl.class);
-        bindInterceptor(Matchers.any(), new AbstractMatcher<Method>() {
-          public boolean matches(Method t) {
-            return !t.isBridge() && t.getDeclaringClass() != Object.class;
-          }
-        }, new CountingInterceptor());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Interface.class).to(Impl.class);
+                bindInterceptor(
+                    Matchers.any(),
+                    new AbstractMatcher<Method>() {
+                      @Override
+                      public boolean matches(Method t) {
+                        return !t.isBridge() && t.getDeclaringClass() != Object.class;
+                      }
+                    },
+                    new CountingInterceptor());
+              }
+            });
     Interface intf = injector.getInstance(Interface.class);
     assertEquals(0, count.get());
     intf.aMethod(null);
     assertEquals(1, count.get());
   }
-  
+
   static class ErasedType {}
-  static class RetType extends ErasedType {}  
-  static abstract class Superclass<T extends ErasedType> {
-      public T aMethod(T t) { return null; }
+
+  static class RetType extends ErasedType {}
+
+  abstract static class Superclass<T extends ErasedType> {
+    public T aMethod(T t) {
+      return null;
+    }
   }
+
   public interface Interface {
-      RetType aMethod(RetType obj);
+    RetType aMethod(RetType obj);
   }
-  public static class Impl extends Superclass<RetType> implements Interface {
-  }
-  
+
+  public static class Impl extends Superclass<RetType> implements Interface {}
+
   public void testInterceptionOrder() {
     final List<String> callList = Lists.newArrayList();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), 
-          new NamedInterceptor("a", callList),
-          new NamedInterceptor("b", callList),
-          new NamedInterceptor("c", callList));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(),
+                    Matchers.any(),
+                    new NamedInterceptor("a", callList),
+                    new NamedInterceptor("b", callList),
+                    new NamedInterceptor("c", callList));
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     assertEquals(0, callList.size());
     interceptable.foo();
     assertEquals(Arrays.asList("a", "b", "c"), callList);
   }
-  
-  private final class NamedInterceptor implements MethodInterceptor {
+
+  private static final class NamedInterceptor implements MethodInterceptor {
     private final String name;
     final List<String> called;
-    
+
     NamedInterceptor(String name, List<String> callList) {
       this.name = name;
       this.called = callList;
     }
-    
+
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       called.add(name);
       return methodInvocation.proceed();
     }
   }
-  
+
   public void testDeDuplicateInterceptors() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        CountingInterceptor interceptor = new CountingInterceptor();
-        bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
-        bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                CountingInterceptor interceptor = new CountingInterceptor();
+                bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
+                bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     interceptable.foo();
@@ -330,11 +396,14 @@
 
   public void testCallLater() {
     final Queue<Runnable> queue = Lists.newLinkedList();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), new CallLaterInterceptor(queue));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(Matchers.any(), Matchers.any(), new CallLaterInterceptor(queue));
+              }
+            });
 
     Interceptable interceptable = injector.getInstance(Interceptable.class);
     interceptable.foo();
@@ -345,24 +414,26 @@
     assertNotNull(interceptable.lastElements);
   }
 
-  private final class CallLaterInterceptor implements MethodInterceptor {
+  private static final class CallLaterInterceptor implements MethodInterceptor {
     private final Queue<Runnable> queue;
 
     public CallLaterInterceptor(Queue<Runnable> queue) {
       this.queue = queue;
     }
 
+    @Override
     public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
-      queue.add(new Runnable() {
-        @Override
-        public void run() {
-          try {
-            methodInvocation.proceed();
-          } catch (Throwable t) {
-            throw new RuntimeException(t);
-          }
-        }
-      });
+      queue.add(
+          new Runnable() {
+            @Override
+            public void run() {
+              try {
+                methodInvocation.proceed();
+              } catch (Throwable t) {
+                throw new RuntimeException(t);
+              }
+            }
+          });
       return null;
     }
   }
diff --git a/core/test/com/google/inject/ModuleTest.java b/core/test/com/google/inject/ModuleTest.java
index e938da5..db32723 100644
--- a/core/test/com/google/inject/ModuleTest.java
+++ b/core/test/com/google/inject/ModuleTest.java
@@ -12,6 +12,7 @@
 public class ModuleTest extends TestCase {
 
   static class A implements Module {
+    @Override
     public void configure(Binder binder) {
       binder.bind(X.class);
       binder.install(new B());
@@ -20,6 +21,7 @@
   }
 
   static class B implements Module {
+    @Override
     public void configure(Binder binder) {
       binder.bind(Y.class);
       binder.install(new D());
@@ -27,6 +29,7 @@
   }
 
   static class C implements Module {
+    @Override
     public void configure(Binder binder) {
       binder.bind(Z.class);
       binder.install(new D());
@@ -34,20 +37,28 @@
   }
 
   static class D implements Module {
+    @Override
     public void configure(Binder binder) {
       binder.bind(W.class);
     }
-    @Override public boolean equals(Object obj) {
+
+    @Override
+    public boolean equals(Object obj) {
       return obj.getClass() == D.class; // we're all equal in the eyes of guice
     }
-    @Override public int hashCode() {
+
+    @Override
+    public int hashCode() {
       return D.class.hashCode();
     }
   }
 
   static class X {}
+
   static class Y {}
+
   static class Z {}
+
   static class W {}
 
   public void testDiamond() throws Exception {
diff --git a/core/test/com/google/inject/ModulesTest.java b/core/test/com/google/inject/ModulesTest.java
index b32e4f6..71c2dc1 100644
--- a/core/test/com/google/inject/ModulesTest.java
+++ b/core/test/com/google/inject/ModulesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,14 +19,10 @@
 import com.google.common.collect.ImmutableList;
 import com.google.inject.spi.ElementSource;
 import com.google.inject.util.Modules;
-
+import java.util.Arrays;
 import junit.framework.TestCase;
 
-import java.util.Arrays;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class ModulesTest extends TestCase {
 
   public void testCombineVarargs() {
@@ -36,7 +32,7 @@
     assertEquals(2L, injector.getInstance(Long.class).longValue());
     assertEquals(3, injector.getInstance(Short.class).shortValue());
   }
-  
+
   public void testCombineIterable() {
     Iterable<Module> modules = Arrays.asList(newModule(1), newModule(2L), newModule((short) 3));
     Injector injector = Guice.createInjector(Modules.combine(modules));
@@ -45,31 +41,36 @@
     assertEquals(3, injector.getInstance(Short.class).shortValue());
   }
 
-  /**
-   * The module returned by Modules.combine shouldn't show up in binder sources.
-   */
+  /** The module returned by Modules.combine shouldn't show up in binder sources. */
   public void testCombineSources() {
     final Module m1 = newModule(1);
     final Module m2 = newModule(2L);
     final Module combined1 = Modules.combine(m1, m2);
-    Module skipSourcesModule = new AbstractModule() {
-      @Override protected void configure() {
-        install(combined1);
-      }
-    };
+    Module skipSourcesModule =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(combined1);
+          }
+        };
     final Module combined2 = Modules.combine(skipSourcesModule);
     Injector injector = Guice.createInjector(combined2);
     ElementSource source = (ElementSource) injector.getBinding(Integer.class).getSource();
-    assertEquals(source.getModuleClassNames().size(), 4);
-    assertEquals(ImmutableList.of(m1.getClass().getName(),
-        combined1.getClass().getName(), skipSourcesModule.getClass().getName(),
-        combined2.getClass().getName()), source.getModuleClassNames());
+    assertEquals(4, source.getModuleClassNames().size());
+    assertEquals(
+        ImmutableList.of(
+            m1.getClass().getName(),
+            combined1.getClass().getName(),
+            skipSourcesModule.getClass().getName(),
+            combined2.getClass().getName()),
+        source.getModuleClassNames());
     StackTraceElement stackTraceElement = (StackTraceElement) source.getDeclaringSource();
     assertEquals(skipSourcesModule.getClass().getName(), stackTraceElement.getClassName());
   }
 
   private <T> Module newModule(final T toBind) {
     return new AbstractModule() {
+      @Override
       protected void configure() {
         @SuppressWarnings("unchecked") // getClass always needs a cast
         Class<T> tClass = (Class<T>) toBind.getClass();
diff --git a/core/test/com/google/inject/NullableInjectionPointTest.java b/core/test/com/google/inject/NullableInjectionPointTest.java
index 9cf22cc..9f7c07a 100644
--- a/core/test/com/google/inject/NullableInjectionPointTest.java
+++ b/core/test/com/google/inject/NullableInjectionPointTest.java
@@ -3,28 +3,31 @@
 import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.Asserts.getDeclaringSourcePart;
 
-import junit.framework.TestCase;
-
+import com.google.common.base.Optional;
+import com.google.inject.multibindings.OptionalBinder;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import com.google.inject.util.Providers;
 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;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class NullableInjectionPointTest extends TestCase {
 
   public void testInjectNullIntoNotNullableConstructor() {
     try {
       createInjector().getInstance(FooConstructor.class);
       fail("Injecting null should fail with an error");
-    }
-    catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
           "null returned by binding at " + getClass().getName(),
-          "parameter 0 of " + FooConstructor.class.getName() + ".<init>() is not @Nullable");
+          "the 1st parameter of " + FooConstructor.class.getName() + ".<init>(",
+          "is not @Nullable");
     }
   }
 
@@ -32,11 +35,12 @@
     try {
       createInjector().getInstance(FooMethod.class);
       fail("Injecting null should fail with an error");
-    }
-    catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
           "null returned by binding at " + getClass().getName(),
-          "parameter 0 of " + FooMethod.class.getName() + ".setFoo() is not @Nullable");
+          "the 1st parameter of " + FooMethod.class.getName() + ".setFoo(",
+          "is not @Nullable");
     }
   }
 
@@ -44,195 +48,222 @@
     try {
       createInjector().getInstance(FooField.class);
       fail("Injecting null should fail with an error");
-    }
-    catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
           "null returned by binding at " + getClass().getName(),
-          " but " + FooField.class.getName() + ".foo is not @Nullable");
+          " but " + FooField.class.getName() + ".foo",
+          " is not @Nullable");
     }
   }
 
-  /**
-   * Provider.getInstance() is allowed to return null via direct calls to
-   * getInstance().
-   */
+  /** Provider.getInstance() is allowed to return null via direct calls to getInstance(). */
   public void testGetInstanceOfNull() {
     assertNull(createInjector().getInstance(Foo.class));
   }
 
   public void testInjectNullIntoNullableConstructor() {
-    NullableFooConstructor nfc
-        = createInjector().getInstance(NullableFooConstructor.class);
+    NullableFooConstructor nfc = createInjector().getInstance(NullableFooConstructor.class);
     assertNull(nfc.foo);
   }
 
   public void testInjectNullIntoNullableMethod() {
-    NullableFooMethod nfm
-        = createInjector().getInstance(NullableFooMethod.class);
+    NullableFooMethod nfm = createInjector().getInstance(NullableFooMethod.class);
     assertNull(nfm.foo);
   }
 
   public void testInjectNullIntoNullableField() {
-    NullableFooField nff
-        = createInjector().getInstance(NullableFooField.class);
+    NullableFooField nff = createInjector().getInstance(NullableFooField.class);
     assertNull(nff.foo);
   }
-  
+
   public void testInjectNullIntoCustomNullableConstructor() {
-    CustomNullableFooConstructor nfc
-        = createInjector().getInstance(CustomNullableFooConstructor.class);
+    CustomNullableFooConstructor nfc =
+        createInjector().getInstance(CustomNullableFooConstructor.class);
     assertNull(nfc.foo);
   }
 
   public void testInjectNullIntoCustomNullableMethod() {
-    CustomNullableFooMethod nfm
-        = createInjector().getInstance(CustomNullableFooMethod.class);
+    CustomNullableFooMethod nfm = createInjector().getInstance(CustomNullableFooMethod.class);
     assertNull(nfm.foo);
   }
 
   public void testInjectNullIntoCustomNullableField() {
-    CustomNullableFooField nff
-        = createInjector().getInstance(CustomNullableFooField.class);
+    CustomNullableFooField nff = createInjector().getInstance(CustomNullableFooField.class);
     assertNull(nff.foo);
-  }  
+  }
 
   private Injector createInjector() {
     return Guice.createInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
-            bind(Foo.class).toProvider(new Provider<Foo>() {
-              public Foo get() {
-                return null;
-              }
-            });
+            bind(Foo.class).toProvider(Providers.<Foo>of(null));
           }
         });
   }
 
-  /**
-   * We haven't decided on what the desired behaviour of this test should be...
-   */
+  /** We haven't decided on what the desired behaviour of this test should be... */
   public void testBindNullToInstance() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(Foo.class).toInstance(null);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Foo.class).toInstance(null);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Binding to null instances is not allowed.",
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   public void testBindNullToProvider() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toProvider(new Provider<Foo>() {
-          public Foo get() {
-            return null;
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(Providers.<Foo>of(null));
+              }
+            });
     assertNull(injector.getInstance(NullableFooField.class).foo);
     assertNull(injector.getInstance(CustomNullableFooField.class).foo);
 
     try {
       injector.getInstance(FooField.class);
-    }
-    catch(ProvisionException expected) {
+      fail("Expected ProvisionException");
+    } catch (ProvisionException expected) {
       assertContains(expected.getMessage(), "null returned by binding at");
     }
   }
 
   public void testBindScopedNull() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toProvider(new Provider<Foo>() {
-          public Foo get() {
-            return null;
-          }
-        }).in(Scopes.SINGLETON);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(Providers.<Foo>of(null)).in(Scopes.SINGLETON);
+              }
+            });
     assertNull(injector.getInstance(NullableFooField.class).foo);
     assertNull(injector.getInstance(CustomNullableFooField.class).foo);
 
     try {
       injector.getInstance(FooField.class);
-    }
-    catch(ProvisionException expected) {
+      fail("Expected ProvisionException");
+    } catch (ProvisionException expected) {
       assertContains(expected.getMessage(), "null returned by binding at");
     }
   }
 
   public void testBindNullAsEagerSingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toProvider(new Provider<Foo>() {
-          public Foo get() {
-            return null;
-          }
-        }).asEagerSingleton();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(Providers.<Foo>of(null)).asEagerSingleton();
+              }
+            });
     assertNull(injector.getInstance(NullableFooField.class).foo);
     assertNull(injector.getInstance(CustomNullableFooField.class).foo);
 
     try {
       injector.getInstance(FooField.class);
       fail();
-    } catch(ProvisionException expected) {
-      assertContains(expected.getMessage(), "null returned by binding "
-          + "at com.google.inject.NullableInjectionPointTest");
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "null returned by binding " + "at com.google.inject.NullableInjectionPointTest");
     }
   }
 
-  static class Foo { }
+  /**
+   * Tests for a regression where dependency objects were not updated properly and OptionalBinder
+   * was rejecting nulls from its dependencies.
+   */
+  public void testBindNullAndLinkFromOptionalBinder() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toProvider(Providers.<Foo>of(null));
+                OptionalBinder.newOptionalBinder(binder(), Foo.class);
+              }
+
+              @Provides
+              @Named("throughProvidesMethod")
+              Foo provideFoo(Optional<Foo> foo) {
+                return foo.orNull();
+              }
+            });
+    assertNull(injector.getInstance(Key.get(Foo.class, Names.named("throughProvidesMethod"))));
+  }
+
+  static class Foo {}
 
   static class FooConstructor {
-    @Inject FooConstructor(Foo foo) { }
+    @Inject
+    FooConstructor(Foo foo) {}
   }
+
   static class FooField {
     @Inject Foo foo;
   }
+
   static class FooMethod {
     @Inject
-    void setFoo(Foo foo) { }
+    void setFoo(Foo foo) {}
   }
 
   static class NullableFooConstructor {
     Foo foo;
-    @Inject NullableFooConstructor(@Nullable Foo foo) {
+
+    @Inject
+    NullableFooConstructor(@Nullable Foo foo) {
       this.foo = foo;
     }
   }
+
   static class NullableFooField {
     @Inject @Nullable Foo foo;
   }
+
   static class NullableFooMethod {
     Foo foo;
-    @Inject void setFoo(@Nullable Foo foo) {
+
+    @Inject
+    void setFoo(@Nullable Foo foo) {
       this.foo = foo;
     }
   }
-  
+
   static class CustomNullableFooConstructor {
     Foo foo;
-    @Inject CustomNullableFooConstructor(@Namespace.Nullable Foo foo) {
+
+    @Inject
+    CustomNullableFooConstructor(@Namespace.Nullable Foo foo) {
       this.foo = foo;
     }
   }
-  
+
   static class CustomNullableFooField {
     @Inject @Namespace.Nullable Foo foo;
   }
+
   static class CustomNullableFooMethod {
     Foo foo;
-    @Inject void setFoo(@Namespace.Nullable Foo foo) {
+
+    @Inject
+    void setFoo(@Namespace.Nullable Foo foo) {
       this.foo = foo;
     }
   }
@@ -240,12 +271,12 @@
   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target({ElementType.PARAMETER, ElementType.FIELD})
-  @interface Nullable { }
-  
+  @interface Nullable {}
+
   static interface Namespace {
     @Documented
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.PARAMETER, ElementType.FIELD})
-    @interface Nullable { }
+    @interface Nullable {}
   }
 }
diff --git a/core/test/com/google/inject/OptionalBindingTest.java b/core/test/com/google/inject/OptionalBindingTest.java
index a62191c..a526c93 100644
--- a/core/test/com/google/inject/OptionalBindingTest.java
+++ b/core/test/com/google/inject/OptionalBindingTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,21 +14,18 @@
  * limitations under the License.
  */
 
-
 package com.google.inject;
 
 import static com.google.inject.Asserts.assertContains;
 
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
 import junit.framework.TestCase;
 
 /**
- * This test verifies the ways things are injected (ie. getInstance(),
- * injectMembers(), bind to instance, and bind to provider instance) for all
- * states of optional bindings (fields, methods, multiple-argument methods,
- * provider fields, provider methods, constructors).
+ * This test verifies the ways things are injected (ie. getInstance(), injectMembers(), bind to
+ * instance, and bind to provider instance) for all states of optional bindings (fields, methods,
+ * multiple-argument methods, provider fields, provider methods, constructors).
  *
  * @author jessewilson@google.com (Jesse Wilson)
  */
@@ -42,44 +39,51 @@
   private static final F injectF = new F() {};
   private static final G injectG = new G() {};
 
-  private Module everythingModule = new AbstractModule() {
-    protected void configure() {
-      bind(A.class).toInstance(injectA);
-      bind(B.class).toInstance(injectB);
-      bind(C.class).toInstance(injectC);
-      bind(D.class).toInstance(injectD);
-      bind(E.class).annotatedWith(Names.named("e")).toInstance(injectE);
-      bind(F.class).toInstance(injectF);
-      bind(G.class).toInstance(injectG);
-    }
-  };
+  private Module everythingModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(A.class).toInstance(injectA);
+          bind(B.class).toInstance(injectB);
+          bind(C.class).toInstance(injectC);
+          bind(D.class).toInstance(injectD);
+          bind(E.class).annotatedWith(Names.named("e")).toInstance(injectE);
+          bind(F.class).toInstance(injectF);
+          bind(G.class).toInstance(injectG);
+        }
+      };
 
-  private Module partialModule = new AbstractModule() {
-    protected void configure() {
-      bind(C.class).toInstance(new C() {});
-    }
-  };
+  private Module partialModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(C.class).toInstance(new C() {});
+        }
+      };
 
-  private Module toInstanceModule = new AbstractModule() {
-    protected void configure() {
-      bind(HasOptionalInjections.class)
-          .toInstance(new HasOptionalInjections());
-    }
-  };
+  private Module toInstanceModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(HasOptionalInjections.class).toInstance(new HasOptionalInjections());
+        }
+      };
 
-  private Module toProviderInstanceModule = new AbstractModule() {
-    protected void configure() {
-      bind(HasOptionalInjections.class)
-          .toProvider(new HasOptionalInjectionsProvider());
-    }
-  };
+  private Module toProviderInstanceModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(HasOptionalInjections.class).toProvider(new HasOptionalInjectionsProvider());
+        }
+      };
 
-  private Module toProviderModule = new AbstractModule() {
-    protected void configure() {
-      bind(HasOptionalInjections.class)
-          .toProvider(HasOptionalInjectionsProvider.class);
-    }
-  };
+  private Module toProviderModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(HasOptionalInjections.class).toProvider(HasOptionalInjectionsProvider.class);
+        }
+      };
 
   public void testEverythingInjectorGetInstance() {
     Guice.createInjector(everythingModule)
@@ -94,9 +98,7 @@
   }
 
   public void testNothingInjectorGetInstance() {
-    Guice.createInjector()
-        .getInstance(HasOptionalInjections.class)
-        .assertNothingInjected();
+    Guice.createInjector().getInstance(HasOptionalInjections.class).assertNothingInjected();
   }
 
   public void testEverythingInjectorInjectMembers() {
@@ -134,7 +136,7 @@
         .getInstance(HasOptionalInjections.class)
         .assertNothingInjected();
   }
-  
+
   public void testEverythingInjectorToProviderInstance() {
     Guice.createInjector(everythingModule, toProviderInstanceModule)
         .getInstance(HasOptionalInjections.class)
@@ -173,36 +175,47 @@
 
   static class HasOptionalInjections {
     A originalA = new A() {};
-    @Inject(optional=true) A a = originalA; // field injection
+
+    @Inject(optional = true)
+    A a = originalA; // field injection
+
     B b; // method injection with one argument
     C c; // method injection with two arguments
     D d; // method injection with two arguments
     E e; // annotated injection
-    @Inject(optional=true) Provider<F> fProvider; // provider
+
+    @Inject(optional = true)
+    Provider<F> fProvider; // provider
+
     Provider<G> gProvider; // method injection of provider
     boolean invoked0, invoked1, invoked2, invokedAnnotated, invokeProvider;
 
-    @Inject(optional=true) void methodInjectZeroArguments() {
+    @Inject(optional = true)
+    void methodInjectZeroArguments() {
       invoked0 = true;
     }
 
-    @Inject(optional=true) void methodInjectOneArgument(B b) {
+    @Inject(optional = true)
+    void methodInjectOneArgument(B b) {
       this.b = b;
       invoked1 = true;
     }
 
-    @Inject(optional=true) void methodInjectTwoArguments(C c, D d) {
+    @Inject(optional = true)
+    void methodInjectTwoArguments(C c, D d) {
       this.c = c;
       this.d = d;
       invoked2 = true;
     }
 
-    @Inject(optional=true) void methodInjectAnnotated(@Named("e") E e) {
+    @Inject(optional = true)
+    void methodInjectAnnotated(@Named("e") E e) {
       this.e = e;
       invokedAnnotated = true;
     }
 
-    @Inject(optional=true) void methodInjectProvider(Provider<G> gProvider) {
+    @Inject(optional = true)
+    void methodInjectProvider(Provider<G> gProvider) {
       this.gProvider = gProvider;
       invokeProvider = true;
     }
@@ -237,8 +250,9 @@
     }
   }
 
-  static class HasOptionalInjectionsProvider
-      extends HasOptionalInjections implements Provider<HasOptionalInjections> {
+  static class HasOptionalInjectionsProvider extends HasOptionalInjections
+      implements Provider<HasOptionalInjections> {
+    @Override
     public HasOptionalInjections get() {
       return this;
     }
@@ -249,8 +263,10 @@
       Guice.createInjector().getInstance(HasOptionalConstructor.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), "OptionalBindingTest$HasOptionalConstructor.<init>() "
-          + "is annotated @Inject(optional=true), but constructors cannot be optional.");
+      assertContains(
+          expected.getMessage(),
+          "OptionalBindingTest$HasOptionalConstructor.<init>() "
+              + "is annotated @Inject(optional=true), but constructors cannot be optional.");
     }
   }
 
@@ -258,25 +274,27 @@
     // Suppress compiler errors by the error-prone checker InjectedConstructorAnnotations,
     // which catches optional injected constructors.
     @SuppressWarnings("InjectedConstructorAnnotations")
-    @Inject(optional=true)
+    @Inject(optional = true)
     HasOptionalConstructor() {}
   }
 
-  @Inject(optional=true) static A staticInjectA;
+  @Inject(optional = true)
+  static A staticInjectA;
 
   public void testStaticInjection() {
     staticInjectA = injectA;
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        requestStaticInjection(OptionalBindingTest.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestStaticInjection(OptionalBindingTest.class);
+          }
+        });
     assertSame(staticInjectA, injectA);
   }
 
   /**
-   * Test for bug 107, where we weren't doing optional injection properly for
-   * indirect injections.
+   * Test for bug 107, where we weren't doing optional injection properly for indirect injections.
    */
   public void testIndirectOptionalInjection() {
     Indirect indirect = Guice.createInjector().getInstance(Indirect.class);
@@ -289,10 +307,16 @@
   }
 
   interface A {}
+
   interface B {}
+
   interface C {}
+
   interface D {}
+
   interface E {}
+
   interface F {}
+
   interface G {}
 }
diff --git a/core/test/com/google/inject/ParentInjectorTest.java b/core/test/com/google/inject/ParentInjectorTest.java
index 4940b77..f519122 100644
--- a/core/test/com/google/inject/ParentInjectorTest.java
+++ b/core/test/com/google/inject/ParentInjectorTest.java
@@ -26,16 +26,12 @@
 import com.google.inject.matcher.Matchers;
 import com.google.inject.name.Names;
 import com.google.inject.spi.TypeConverter;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.List;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class ParentInjectorTest extends TestCase {
 
   public void testParentAndChildCannotShareExplicitBindings() {
@@ -44,9 +40,17 @@
       parent.createChildInjector(bindsA);
       fail("Created the same explicit binding on both parent and child");
     } catch (CreationException e) {
-      assertContains(e.getMessage(), "A binding to ", A.class.getName(), " was already configured",
-          " at ", getClass().getName(), getDeclaringSourcePart(getClass()),
-          " at ", getClass().getName(), getDeclaringSourcePart(getClass()));
+      assertContains(
+          e.getMessage(),
+          "A binding to ",
+          A.class.getName(),
+          " was already configured",
+          " at ",
+          getClass().getName(),
+          getDeclaringSourcePart(getClass()),
+          " at ",
+          getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
@@ -57,7 +61,8 @@
       parent.getInstance(A.class);
       fail("Created a just-in-time binding on the parent that's the same as a child's binding");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Unable to create binding for " + A.class.getName(),
           "It was already configured on one or more child injectors or private modules",
           "bound at " + bindsA.getClass().getName() + ".configure(",
@@ -65,17 +70,20 @@
           "while locating " + A.class.getName());
     }
   }
-  
+
   public void testChildCannotBindToAParentJitBinding() {
     Injector parent = Guice.createInjector();
     parent.getInstance(A.class);
     try {
       parent.createChildInjector(bindsA);
       fail();
-    } catch(CreationException ce) {
-      assertContains(Iterables.getOnlyElement(ce.getErrorMessages()).getMessage(),
-          "A just-in-time binding to " + A.class.getName() + " was already configured on a parent injector.");
-    }    
+    } catch (CreationException ce) {
+      assertContains(
+          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage(),
+          "A just-in-time binding to "
+              + A.class.getName()
+              + " was already configured on a parent injector.");
+    }
   }
 
   public void testJustInTimeBindingsAreSharedWithParentIfPossible() {
@@ -116,40 +124,55 @@
   }
 
   public void testScopesInherited() {
-    Injector parent = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(MyScope.class, Scopes.SINGLETON);
-      }
-    });
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(A.class).in(MyScope.class);
-      }
-    });
+    Injector parent =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(MyScope.class, Scopes.SINGLETON);
+              }
+            });
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).in(MyScope.class);
+              }
+            });
     assertSame(child.getInstance(A.class), child.getInstance(A.class));
   }
 
   /*if[AOP]*/
-  private final org.aopalliance.intercept.MethodInterceptor returnNullInterceptor
-      = new org.aopalliance.intercept.MethodInterceptor() {
-    public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
-      return null;
-    }
-  };
+  private final org.aopalliance.intercept.MethodInterceptor returnNullInterceptor =
+      new org.aopalliance.intercept.MethodInterceptor() {
+        @Override
+        public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
+          return null;
+        }
+      };
 
   public void testInterceptorsInherited() {
-    Injector parent = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        super.bindInterceptor(Matchers.any(), Matchers.returns(Matchers.identicalTo(A.class)),
-            returnNullInterceptor);
-      }
-    });
+    Injector parent =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                super.bindInterceptor(
+                    Matchers.any(),
+                    Matchers.returns(Matchers.identicalTo(A.class)),
+                    returnNullInterceptor);
+              }
+            });
 
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(C.class);
-      }
-    });
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(C.class);
+              }
+            });
 
     assertNull(child.getInstance(C.class).interceptedMethod());
   }
@@ -176,11 +199,14 @@
 
   public void testInjectorInjectionSpanningInjectors() {
     Injector parent = Guice.createInjector();
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(D.class);
-      }
-    });
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(D.class);
+              }
+            });
 
     D d = child.getInstance(D.class);
     assertSame(d.injector, child);
@@ -194,7 +220,7 @@
     Injector left = top.createChildInjector();
     Injector leftLeft = left.createChildInjector(bindsD);
     Injector right = top.createChildInjector(bindsD);
-    
+
     assertSame(leftLeft, leftLeft.getInstance(D.class).injector);
     assertSame(right, right.getInstance(D.class).injector);
     assertSame(top, leftLeft.getInstance(E.class).injector);
@@ -218,33 +244,40 @@
 
   public void testScopeBoundInChildInjectorOnly() {
     Injector parent = Guice.createInjector();
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(MyScope.class, Scopes.SINGLETON);
-      }
-    });
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(MyScope.class, Scopes.SINGLETON);
+              }
+            });
 
     try {
       parent.getProvider(F.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "No scope is bound to com.google.inject.ParentInjectorTest$MyScope.",
           "at " + F.class.getName() + ".class(ParentInjectorTest.java",
           "  while locating " + F.class.getName());
     }
-    
+
     assertNotNull(child.getProvider(F.class).get());
   }
 
   public void testErrorInParentButOkayInChild() {
     Injector parent = Guice.createInjector();
-    Injector childInjector = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(MyScope.class, Scopes.SINGLETON);
-        bind(Object.class).to(F.class);
-      }
-    });
+    Injector childInjector =
+        parent.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(MyScope.class, Scopes.SINGLETON);
+                bind(Object.class).to(F.class);
+              }
+            });
     Object one = childInjector.getInstance(Object.class);
     Object two = childInjector.getInstance(Object.class);
     assertSame(one, two);
@@ -257,8 +290,10 @@
     try {
       childInjector.getInstance(G.class);
       fail();
-    } catch(ConfigurationException expected) {
-      assertContains(expected.getMessage(), "No scope is bound to " + MyScope.class.getName(),
+    } catch (ConfigurationException expected) {
+      assertContains(
+          expected.getMessage(),
+          "No scope is bound to " + MyScope.class.getName(),
           "at " + F.class.getName() + ".class(ParentInjectorTest.java:",
           "  while locating " + G.class.getName());
     }
@@ -267,41 +302,54 @@
   @Singleton
   static class A {}
 
-  private final Module bindsA = new AbstractModule() {
-    @Override protected void configure() {
-      bind(A.class).toInstance(new A());
-    }
-  };
+  private final Module bindsA =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(A.class).toInstance(new A());
+        }
+      };
 
   interface B {}
+
   static class RealB implements B {}
 
-  private final Module bindsB = new AbstractModule() {
-    @Override protected void configure() {
-      bind(B.class).to(RealB.class);
-    }
-  };
+  private final Module bindsB =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(B.class).to(RealB.class);
+        }
+      };
 
-  @Target(TYPE) @Retention(RUNTIME) @ScopeAnnotation
+  @Target(TYPE)
+  @Retention(RUNTIME)
+  @ScopeAnnotation
   public @interface MyScope {}
 
-  private final TypeConverter listConverter = new TypeConverter() {
-    public Object convert(String value, TypeLiteral<?> toType) {
-      return ImmutableList.of();
-    }
-  };
+  private final TypeConverter listConverter =
+      new TypeConverter() {
+        @Override
+        public Object convert(String value, TypeLiteral<?> toType) {
+          return ImmutableList.of();
+        }
+      };
 
-  private final Module bindListConverterModule = new AbstractModule() {
-    @Override protected void configure() {
-      convertToTypes(Matchers.any(), listConverter);
-    }
-  };
+  private final Module bindListConverterModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          convertToTypes(Matchers.any(), listConverter);
+        }
+      };
 
-  private final Module bindStringNamedB = new AbstractModule() {
-    @Override protected void configure() {
-      bind(String.class).annotatedWith(Names.named("B")).toInstance("buzz");
-    }
-  };
+  private final Module bindStringNamedB =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(String.class).annotatedWith(Names.named("B")).toInstance("buzz");
+        }
+      };
 
   public static class C {
     public A interceptedMethod() {
@@ -317,11 +365,13 @@
     @Inject Injector injector;
   }
 
-  private final Module bindsD = new AbstractModule() {
-    @Override protected void configure() {
-      bind(D.class);
-    }
-  };
+  private final Module bindsD =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(D.class);
+        }
+      };
 
   @MyScope
   static class F implements G {}
diff --git a/core/test/com/google/inject/PerformanceComparison.java b/core/test/com/google/inject/PerformanceComparison.java
index a6351a3..c2adbfa 100644
--- a/core/test/com/google/inject/PerformanceComparison.java
+++ b/core/test/com/google/inject/PerformanceComparison.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,21 +20,19 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertSame;
 
+import java.lang.annotation.Retention;
+import java.text.DecimalFormat;
+import java.util.concurrent.Callable;
 import org.springframework.beans.MutablePropertyValues;
 import org.springframework.beans.factory.config.ConstructorArgumentValues;
 import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 
-import java.lang.annotation.Retention;
-import java.text.DecimalFormat;
-import java.util.concurrent.Callable;
-
 /**
- * A semi-useless microbenchmark. Spring and Guice constuct the same object
- * graph a bunch of times, and we see who can construct the most per second.
- * As of this writing Guice is more than 50X faster. Also useful for comparing 
- * pure Java configuration options.
+ * A semi-useless microbenchmark. Spring and Guice constuct the same object graph a bunch of times,
+ * and we see who can construct the most per second. As of this writing Guice is more than 50X
+ * faster. Also useful for comparing pure Java configuration options.
  *
  * @author crazybob@google.com (Bob Lee)
  */
@@ -49,7 +47,7 @@
 
     for (int i2 = 0; i2 < 10; i2++) {
       iterate(springFactory, "Spring:  ");
-      iterate(juiceFactory,  "Guice:   ");
+      iterate(juiceFactory, "Guice:   ");
       iterate(byHandFactory, "By Hand: ");
 
       System.err.println();
@@ -59,88 +57,99 @@
 
     for (int i2 = 0; i2 < 10; i2++) {
       concurrentlyIterate(springFactory, "Spring:  ");
-      concurrentlyIterate(juiceFactory,  "Guice:   ");
+      concurrentlyIterate(juiceFactory, "Guice:   ");
       concurrentlyIterate(byHandFactory, "By Hand: ");
 
       System.err.println();
     }
   }
 
-  static final Callable<Foo> springFactory = new Callable<Foo>() {
+  static final Callable<Foo> springFactory =
+      new Callable<Foo>() {
 
-    final DefaultListableBeanFactory beanFactory;
+        final DefaultListableBeanFactory beanFactory;
 
-    {
-      beanFactory = new DefaultListableBeanFactory();
+        {
+          beanFactory = new DefaultListableBeanFactory();
 
-      RootBeanDefinition tee = new RootBeanDefinition(TeeImpl.class, true);
-      tee.setLazyInit(true);
-      ConstructorArgumentValues teeValues = new ConstructorArgumentValues();
-      teeValues.addGenericArgumentValue("test");
-      tee.setConstructorArgumentValues(teeValues);
+          RootBeanDefinition tee = new RootBeanDefinition(TeeImpl.class, true);
+          tee.setLazyInit(true);
+          ConstructorArgumentValues teeValues = new ConstructorArgumentValues();
+          teeValues.addGenericArgumentValue("test");
+          tee.setConstructorArgumentValues(teeValues);
 
-      RootBeanDefinition bar = new RootBeanDefinition(BarImpl.class, false);
-      ConstructorArgumentValues barValues = new ConstructorArgumentValues();
-      barValues.addGenericArgumentValue(new RuntimeBeanReference("tee"));
-      barValues.addGenericArgumentValue(5);
-      bar.setConstructorArgumentValues(barValues);
+          RootBeanDefinition bar = new RootBeanDefinition(BarImpl.class, false);
+          ConstructorArgumentValues barValues = new ConstructorArgumentValues();
+          barValues.addGenericArgumentValue(new RuntimeBeanReference("tee"));
+          barValues.addGenericArgumentValue(5);
+          bar.setConstructorArgumentValues(barValues);
 
-      RootBeanDefinition foo = new RootBeanDefinition(Foo.class, false);
-      MutablePropertyValues fooValues = new MutablePropertyValues();
-      fooValues.addPropertyValue("i", 5);
-      fooValues.addPropertyValue("bar", new RuntimeBeanReference("bar"));
-      fooValues.addPropertyValue("copy", new RuntimeBeanReference("bar"));
-      fooValues.addPropertyValue("s", "test");
-      foo.setPropertyValues(fooValues);
+          RootBeanDefinition foo = new RootBeanDefinition(Foo.class, false);
+          MutablePropertyValues fooValues = new MutablePropertyValues();
+          fooValues.addPropertyValue("i", 5);
+          fooValues.addPropertyValue("bar", new RuntimeBeanReference("bar"));
+          fooValues.addPropertyValue("copy", new RuntimeBeanReference("bar"));
+          fooValues.addPropertyValue("s", "test");
+          foo.setPropertyValues(fooValues);
 
-      beanFactory.registerBeanDefinition("foo", foo);
-      beanFactory.registerBeanDefinition("bar", bar);
-      beanFactory.registerBeanDefinition("tee", tee);
-    }
+          beanFactory.registerBeanDefinition("foo", foo);
+          beanFactory.registerBeanDefinition("bar", bar);
+          beanFactory.registerBeanDefinition("tee", tee);
+        }
 
-    public Foo call() throws Exception {
-      return (Foo) beanFactory.getBean("foo");
-    }
-  };
+        @Override
+        public Foo call() throws Exception {
+          return (Foo) beanFactory.getBean("foo");
+        }
+      };
 
-  static final Callable<Foo> juiceFactory = new Callable<Foo>() {
-    final Provider<Foo> fooProvider;
-    {
-      Injector injector;
-      try {
-        injector = Guice.createInjector(new AbstractModule() {
-          protected void configure() {
-            bind(Tee.class).to(TeeImpl.class);
-            bind(Bar.class).to(BarImpl.class);
-            bind(Foo.class);
-            bindConstant().annotatedWith(I.class).to(5);
-            bindConstant().annotatedWith(S.class).to("test");
+  static final Callable<Foo> juiceFactory =
+      new Callable<Foo>() {
+        final Provider<Foo> fooProvider;
+
+        {
+          Injector injector;
+          try {
+            injector =
+                Guice.createInjector(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        bind(Tee.class).to(TeeImpl.class);
+                        bind(Bar.class).to(BarImpl.class);
+                        bind(Foo.class);
+                        bindConstant().annotatedWith(I.class).to(5);
+                        bindConstant().annotatedWith(S.class).to("test");
+                      }
+                    });
+          } catch (CreationException e) {
+            throw new RuntimeException(e);
           }
-        });
-      } catch (CreationException e) {
-        throw new RuntimeException(e);
-      }
-      fooProvider = injector.getProvider(Foo.class);
-    }
+          fooProvider = injector.getProvider(Foo.class);
+        }
 
-    public Foo call() throws Exception {
-      return fooProvider.get();
-    }
-  };
+        @Override
+        public Foo call() throws Exception {
+          return fooProvider.get();
+        }
+      };
 
-  static final Callable<Foo> byHandFactory = new Callable<Foo>() {
-    final Tee tee = new TeeImpl("test");
-    public Foo call() throws Exception {
-      Foo foo = new Foo();
-      foo.setI(5);
-      foo.setS("test");
-      Bar bar = new BarImpl(tee, 5);
-      Bar copy = new BarImpl(tee, 5);
-      foo.setBar(bar);
-      foo.setCopy(copy);
-      return foo;
-    }
-  };
+  static final Callable<Foo> byHandFactory =
+      new Callable<Foo>() {
+        final Tee tee = new TeeImpl("test");
+
+        @Override
+        public Foo call() throws Exception {
+          Foo foo = new Foo();
+          foo.setI(5);
+          foo.setS("test");
+          Bar bar = new BarImpl(tee, 5);
+          Bar copy = new BarImpl(tee, 5);
+          foo.setBar(bar);
+          foo.setCopy(copy);
+          return foo;
+        }
+      };
 
   static void validate(Callable<Foo> t) throws Exception {
     Foo foo = t.call();
@@ -161,16 +170,14 @@
     for (int i = 0; i < count; i++) {
       try {
         callable.call();
-      }
-      catch (Exception e) {
+      } catch (Exception e) {
         throw new RuntimeException(e);
       }
     }
 
     time = System.currentTimeMillis() - time;
 
-    System.err.println(label
-        + format.format(count * 1000 / time) + " creations/s");
+    System.err.println(label + format.format(count * 1000 / time) + " creations/s");
   }
 
   static void concurrentlyIterate(final Callable<Foo> callable, String label) {
@@ -180,21 +187,21 @@
     Thread[] threads = new Thread[threadCount];
 
     for (int i = 0; i < threadCount; i++) {
-      threads[i] = new Thread() {
-        public void run() {
-          for (int i = 0; i < count; i++) {
-            try {
-              validate(callable);
+      threads[i] =
+          new Thread() {
+            @Override
+            public void run() {
+              for (int i = 0; i < count; i++) {
+                try {
+                  validate(callable);
+                } catch (Exception e) {
+                  throw new RuntimeException(e);
+                }
+              }
             }
-            catch (Exception e) {
-              throw new RuntimeException(e);
-            }
-          }
-        }
-      };
+          };
     }
 
-
     long time = System.currentTimeMillis();
 
     for (int i = 0; i < threadCount; i++) {
@@ -204,16 +211,14 @@
     for (int i = 0; i < threadCount; i++) {
       try {
         threads[i].join();
-      }
-      catch (InterruptedException e) {
+      } catch (InterruptedException e) {
         throw new RuntimeException(e);
       }
     }
 
     time = System.currentTimeMillis() - time;
 
-    System.err.println(label
-        + format.format(count * 1000 / time) + " creations/s");
+    System.err.println(label + format.format(count * 1000 / time) + " creations/s");
   }
 
   public static class Foo {
@@ -247,6 +252,7 @@
   interface Bar {
 
     Tee getTee();
+
     int getI();
   }
 
@@ -261,10 +267,12 @@
       this.i = i;
     }
 
+    @Override
     public Tee getTee() {
       return tee;
     }
 
+    @Override
     public int getI() {
       return i;
     }
@@ -285,14 +293,17 @@
       this.s = s;
     }
 
+    @Override
     public String getS() {
       return s;
     }
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface I {}
+  @BindingAnnotation
+  @interface I {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface S {}
+  @BindingAnnotation
+  @interface S {}
 }
diff --git a/core/test/com/google/inject/PrivateModuleTest.java b/core/test/com/google/inject/PrivateModuleTest.java
index 05db62b..576c9ad 100644
--- a/core/test/com/google/inject/PrivateModuleTest.java
+++ b/core/test/com/google/inject/PrivateModuleTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,48 +22,52 @@
 import static com.google.inject.name.Names.named;
 
 import com.google.common.collect.ImmutableSet;
+import com.google.inject.internal.Annotations;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.ExposedBinding;
 import com.google.inject.spi.PrivateElements;
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class PrivateModuleTest extends TestCase {
 
   public void testBasicUsage() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).annotatedWith(named("a")).toInstance("public");
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).annotatedWith(named("a")).toInstance("public");
 
-        install(new PrivateModule() {
-          @Override public void configure() {
-            bind(String.class).annotatedWith(named("b")).toInstance("i");
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        bind(String.class).annotatedWith(named("b")).toInstance("i");
 
-            bind(AB.class).annotatedWith(named("one")).to(AB.class);
-            expose(AB.class).annotatedWith(named("one"));
-          }
-        });
+                        bind(AB.class).annotatedWith(named("one")).to(AB.class);
+                        expose(AB.class).annotatedWith(named("one"));
+                      }
+                    });
 
-        install(new PrivateModule() {
-          @Override public void configure() {
-            bind(String.class).annotatedWith(named("b")).toInstance("ii");
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        bind(String.class).annotatedWith(named("b")).toInstance("ii");
 
-            bind(AB.class).annotatedWith(named("two")).to(AB.class);
-            expose(AB.class).annotatedWith(named("two"));
-          }
-        });
-      }
-    });
+                        bind(AB.class).annotatedWith(named("two")).to(AB.class);
+                        expose(AB.class).annotatedWith(named("two"));
+                      }
+                    });
+              }
+            });
 
     AB ab1 = injector.getInstance(Key.get(AB.class, named("one")));
     assertEquals("public", ab1.a);
@@ -73,21 +77,24 @@
     assertEquals("public", ab2.a);
     assertEquals("ii", ab2.b);
   }
-  
-  public void testWithoutPrivateModules() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        PrivateBinder bindA = binder().newPrivateBinder();
-        bindA.bind(String.class).annotatedWith(named("a")).toInstance("i");
-        bindA.expose(String.class).annotatedWith(named("a"));
-        bindA.bind(String.class).annotatedWith(named("c")).toInstance("private to A");
 
-        PrivateBinder bindB = binder().newPrivateBinder();
-        bindB.bind(String.class).annotatedWith(named("b")).toInstance("ii");
-        bindB.expose(String.class).annotatedWith(named("b"));
-        bindB.bind(String.class).annotatedWith(named("c")).toInstance("private to B");
-      }
-    });
+  public void testWithoutPrivateModules() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                PrivateBinder bindA = binder().newPrivateBinder();
+                bindA.bind(String.class).annotatedWith(named("a")).toInstance("i");
+                bindA.expose(String.class).annotatedWith(named("a"));
+                bindA.bind(String.class).annotatedWith(named("c")).toInstance("private to A");
+
+                PrivateBinder bindB = binder().newPrivateBinder();
+                bindB.bind(String.class).annotatedWith(named("b")).toInstance("ii");
+                bindB.expose(String.class).annotatedWith(named("b"));
+                bindB.bind(String.class).annotatedWith(named("c")).toInstance("private to B");
+              }
+            });
 
     assertEquals("i", injector.getInstance(Key.get(String.class, named("a"))));
     assertEquals("ii", injector.getInstance(Key.get(String.class, named("b"))));
@@ -95,80 +102,105 @@
 
   public void testMisplacedExposedAnnotation() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {}
+      Guice.createInjector(
+          new AbstractModule() {
 
-        @Provides @Exposed
-        String provideString() {
-          return "i";
-        }
-      });
+            @Provides
+            @Exposed
+            String provideString() {
+              return "i";
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "Cannot expose java.lang.String on a standard binder. ",
+      assertContains(
+          expected.getMessage(),
+          "Cannot expose java.lang.String on a standard binder. ",
           "Exposed bindings are only applicable to private binders.",
-          " at " + PrivateModuleTest.class.getName(), "provideString(PrivateModuleTest.java:");
+          " at " + PrivateModuleTest.class.getName(),
+          "provideString(PrivateModuleTest.java:");
     }
   }
 
   public void testMisplacedExposeStatement() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          ((PrivateBinder) binder()).expose(String.class).annotatedWith(named("a"));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ((PrivateBinder) binder()).expose(String.class).annotatedWith(named("a"));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "Cannot expose java.lang.String on a standard binder. ",
+      assertContains(
+          expected.getMessage(),
+          "Cannot expose java.lang.String on a standard binder. ",
           "Exposed bindings are only applicable to private binders.",
-          " at " + PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass()));
+          " at " + PrivateModuleTest.class.getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   public void testPrivateModulesAndProvidesMethods() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new PrivateModule() {
-          @Override public void configure() {
-            expose(String.class).annotatedWith(named("a"));
-          }
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        expose(String.class).annotatedWith(named("a"));
+                      }
 
-          @Provides @Named("a") String providePublicA() {
-            return "i";
-          }
+                      @Provides
+                      @Named("a")
+                      String providePublicA() {
+                        return "i";
+                      }
 
-          @Provides @Named("b") String providePrivateB() {
-            return "private";
-          }
-        });
+                      @Provides
+                      @Named("b")
+                      String providePrivateB() {
+                        return "private";
+                      }
+                    });
 
-        install(new PrivateModule() {
-          @Override public void configure() {}
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {}
 
-          @Provides @Named("c") String providePrivateC() {
-            return "private";
-          }
+                      @Provides
+                      @Named("c")
+                      String providePrivateC() {
+                        return "private";
+                      }
 
-          @Provides @Exposed @Named("d") String providePublicD() {
-            return "ii";
-          }
-        });
-      }
-    });
+                      @Provides
+                      @Exposed
+                      @Named("d")
+                      String providePublicD() {
+                        return "ii";
+                      }
+                    });
+              }
+            });
 
     assertEquals("i", injector.getInstance(Key.get(String.class, named("a"))));
 
     try {
       injector.getInstance(Key.get(String.class, named("b")));
       fail();
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
     }
 
     try {
       injector.getInstance(Key.get(String.class, named("c")));
       fail();
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
     }
 
     assertEquals("ii", injector.getInstance(Key.get(String.class, named("d"))));
@@ -176,139 +208,181 @@
 
   public void testCannotBindAKeyExportedByASibling() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          install(new PrivateModule() {
-            @Override public void configure() {
-              bind(String.class).toInstance("public");
-              expose(String.class);
-            }
-          });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(
+                  new PrivateModule() {
+                    @Override
+                    public void configure() {
+                      bind(String.class).toInstance("public");
+                      expose(String.class);
+                    }
+                  });
 
-          install(new PrivateModule() {
-            @Override public void configure() {
-              bind(String.class).toInstance("private");
+              install(
+                  new PrivateModule() {
+                    @Override
+                    public void configure() {
+                      bind(String.class).toInstance("private");
+                    }
+                  });
             }
           });
-        }
-      });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "A binding to java.lang.String was already configured at ",
-          getClass().getName(), getDeclaringSourcePart(getClass()),
-          " at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          getClass().getName(),
+          getDeclaringSourcePart(getClass()),
+          " at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   public void testExposeButNoBind() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(String.class).annotatedWith(named("a")).toInstance("a");
-          bind(String.class).annotatedWith(named("b")).toInstance("b");
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(String.class).annotatedWith(named("a")).toInstance("a");
+              bind(String.class).annotatedWith(named("b")).toInstance("b");
 
-          install(new PrivateModule() {
-            @Override public void configure() {
-              expose(AB.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    public void configure() {
+                      expose(AB.class);
+                    }
+                  });
             }
           });
-        }
-      });
       fail("AB was exposed but not bound");
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Could not expose() " + AB.class.getName() + ", it must be explicitly bound",
           getDeclaringSourcePart(getClass()));
     }
   }
 
   /**
-   * Ensure that when we've got errors in different private modules, Guice presents all errors
-   * in a unified message.
+   * Ensure that when we've got errors in different private modules, Guice presents all errors in a
+   * unified message.
    */
   public void testMessagesFromPrivateModulesAreNicelyIntegrated() {
     try {
       Guice.createInjector(
           new PrivateModule() {
-            @Override public void configure() {
+            @Override
+            public void configure() {
               bind(C.class);
             }
           },
           new PrivateModule() {
-            @Override public void configure() {
+            @Override
+            public void configure() {
               bind(AB.class);
             }
-          }
-      );
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for " + C.class.getName() + " was bound.",
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()),
-          "2) No implementation for " + String.class.getName(), "Named(value=a) was bound.",
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()),
+          "2) No implementation for " + String.class.getName(),
+          "Named(value=" + Annotations.memberValueString("a") + ") was bound.",
           "for field at " + AB.class.getName() + ".a(PrivateModuleTest.java:",
-          "3) No implementation for " + String.class.getName(), "Named(value=b) was bound.",
+          "3) No implementation for " + String.class.getName(),
+          "Named(value=" + Annotations.memberValueString("b") + ") was bound.",
           "for field at " + AB.class.getName() + ".b(PrivateModuleTest.java:",
           "3 errors");
     }
   }
 
   public void testNestedPrivateInjectors() {
-    Injector injector = Guice.createInjector(new PrivateModule() {
-      @Override public void configure() {
-        expose(String.class);
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              public void configure() {
+                expose(String.class);
 
-        install(new PrivateModule() {
-          @Override public void configure() {
-            bind(String.class).toInstance("nested");
-            expose(String.class);
-          }
-        });
-      }
-    });
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        bind(String.class).toInstance("nested");
+                        expose(String.class);
+                      }
+                    });
+              }
+            });
 
     assertEquals("nested", injector.getInstance(String.class));
   }
 
   public void testInstallingRegularModulesFromPrivateModules() {
-    Injector injector = Guice.createInjector(new PrivateModule() {
-      @Override public void configure() {
-        expose(String.class);
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              public void configure() {
+                expose(String.class);
 
-        install(new AbstractModule() {
-          @Override protected void configure() {
-            bind(String.class).toInstance("nested");
-          }
-        });
-      }
-    });
+                install(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        bind(String.class).toInstance("nested");
+                      }
+                    });
+              }
+            });
 
     assertEquals("nested", injector.getInstance(String.class));
   }
 
   public void testNestedPrivateModulesWithSomeKeysUnexposed() {
-    Injector injector = Guice.createInjector(new PrivateModule() {
-      @Override public void configure() {
-        bind(String.class).annotatedWith(named("bound outer, exposed outer")).toInstance("boeo");
-        expose(String.class).annotatedWith(named("bound outer, exposed outer"));
-        bind(String.class).annotatedWith(named("bound outer, exposed none")).toInstance("boen");
-        expose(String.class).annotatedWith(named("bound inner, exposed both"));
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              public void configure() {
+                bind(String.class)
+                    .annotatedWith(named("bound outer, exposed outer"))
+                    .toInstance("boeo");
+                expose(String.class).annotatedWith(named("bound outer, exposed outer"));
+                bind(String.class)
+                    .annotatedWith(named("bound outer, exposed none"))
+                    .toInstance("boen");
+                expose(String.class).annotatedWith(named("bound inner, exposed both"));
 
-        install(new PrivateModule() {
-          @Override public void configure() {
-            bind(String.class).annotatedWith(named("bound inner, exposed both")).toInstance("bieb");
-            expose(String.class).annotatedWith(named("bound inner, exposed both"));
-            bind(String.class).annotatedWith(named("bound inner, exposed none")).toInstance("bien");
-          }
-        });
-      }
-    });
+                install(
+                    new PrivateModule() {
+                      @Override
+                      public void configure() {
+                        bind(String.class)
+                            .annotatedWith(named("bound inner, exposed both"))
+                            .toInstance("bieb");
+                        expose(String.class).annotatedWith(named("bound inner, exposed both"));
+                        bind(String.class)
+                            .annotatedWith(named("bound inner, exposed none"))
+                            .toInstance("bien");
+                      }
+                    });
+              }
+            });
 
-    assertEquals("boeo",
-        injector.getInstance(Key.get(String.class, named("bound outer, exposed outer"))));
-    assertEquals("bieb",
-        injector.getInstance(Key.get(String.class, named("bound inner, exposed both"))));
+    assertEquals(
+        "boeo", injector.getInstance(Key.get(String.class, named("bound outer, exposed outer"))));
+    assertEquals(
+        "bieb", injector.getInstance(Key.get(String.class, named("bound inner, exposed both"))));
 
     try {
       injector.getInstance(Key.get(String.class, named("bound outer, exposed none")));
@@ -324,145 +398,204 @@
   }
 
   public void testDependenciesBetweenPrivateAndPublic() {
-    Injector injector = Guice.createInjector(
-        new PrivateModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              protected void configure() {}
 
-          @Provides @Exposed @Named("a") String provideA() {
-            return "A";
-          }
+              @Provides
+              @Exposed
+              @Named("a")
+              String provideA() {
+                return "A";
+              }
 
-          @Provides @Exposed @Named("abc") String provideAbc(@Named("ab") String ab) {
-            return ab + "C";
-          }
-        },
-        new AbstractModule() {
-          @Override protected void configure() {}
+              @Provides
+              @Exposed
+              @Named("abc")
+              String provideAbc(@Named("ab") String ab) {
+                return ab + "C";
+              }
+            },
+            new AbstractModule() {
 
-          @Provides @Named("ab") String provideAb(@Named("a") String a) {
-            return a + "B";
-          }
+              @Provides
+              @Named("ab")
+              String provideAb(@Named("a") String a) {
+                return a + "B";
+              }
 
-          @Provides @Named("abcd") String provideAbcd(@Named("abc") String abc) {
-            return abc + "D";
-          }
-        }
-    );
+              @Provides
+              @Named("abcd")
+              String provideAbcd(@Named("abc") String abc) {
+                return abc + "D";
+              }
+            });
 
     assertEquals("ABCD", injector.getInstance(Key.get(String.class, named("abcd"))));
   }
 
   public void testDependenciesBetweenPrivateAndPublicWithPublicEagerSingleton() {
-    Injector injector = Guice.createInjector(
-        new PrivateModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              protected void configure() {}
 
-          @Provides @Exposed @Named("a") String provideA() {
-            return "A";
-          }
-
-          @Provides @Exposed @Named("abc") String provideAbc(@Named("ab") String ab) {
-            return ab + "C";
-          }
-        },
-        new AbstractModule() {
-          @Override protected void configure() {
-            bind(String.class).annotatedWith(named("abcde")).toProvider(new Provider<String>() {
-              @Inject @Named("abcd") String abcd;
-
-              public String get() {
-                return abcd + "E";
+              @Provides
+              @Exposed
+              @Named("a")
+              String provideA() {
+                return "A";
               }
-            }).asEagerSingleton();
-          }
 
-          @Provides @Named("ab") String provideAb(@Named("a") String a) {
-            return a + "B";
-          }
+              @Provides
+              @Exposed
+              @Named("abc")
+              String provideAbc(@Named("ab") String ab) {
+                return ab + "C";
+              }
+            },
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class)
+                    .annotatedWith(named("abcde"))
+                    .toProvider(
+                        new Provider<String>() {
+                          @Inject
+                          @Named("abcd")
+                          String abcd;
 
-          @Provides @Named("abcd") String provideAbcd(@Named("abc") String abc) {
-            return abc + "D";
-          }
-        }
-    );
+                          @Override
+                          public String get() {
+                            return abcd + "E";
+                          }
+                        })
+                    .asEagerSingleton();
+              }
+
+              @Provides
+              @Named("ab")
+              String provideAb(@Named("a") String a) {
+                return a + "B";
+              }
+
+              @Provides
+              @Named("abcd")
+              String provideAbcd(@Named("abc") String abc) {
+                return abc + "D";
+              }
+            });
 
     assertEquals("ABCDE", injector.getInstance(Key.get(String.class, named("abcde"))));
   }
 
   public void testDependenciesBetweenPrivateAndPublicWithPrivateEagerSingleton() {
-    Injector injector = Guice.createInjector(
-        new AbstractModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
 
-          @Provides @Named("ab") String provideAb(@Named("a") String a) {
-            return a + "B";
-          }
-
-          @Provides @Named("abcd") String provideAbcd(@Named("abc") String abc) {
-            return abc + "D";
-          }
-        },
-        new PrivateModule() {
-          @Override protected void configure() {
-            bind(String.class).annotatedWith(named("abcde")).toProvider(new Provider<String>() {
-              @Inject @Named("abcd") String abcd;
-
-              public String get() {
-                return abcd + "E";
+              @Provides
+              @Named("ab")
+              String provideAb(@Named("a") String a) {
+                return a + "B";
               }
-            }).asEagerSingleton();
-            expose(String.class).annotatedWith(named("abcde"));
-          }
 
-          @Provides @Exposed @Named("a") String provideA() {
-            return "A";
-          }
+              @Provides
+              @Named("abcd")
+              String provideAbcd(@Named("abc") String abc) {
+                return abc + "D";
+              }
+            },
+            new PrivateModule() {
+              @Override
+              protected void configure() {
+                bind(String.class)
+                    .annotatedWith(named("abcde"))
+                    .toProvider(
+                        new Provider<String>() {
+                          @Inject
+                          @Named("abcd")
+                          String abcd;
 
-          @Provides @Exposed @Named("abc") String provideAbc(@Named("ab") String ab) {
-            return ab + "C";
-          }
-        }
-    );
+                          @Override
+                          public String get() {
+                            return abcd + "E";
+                          }
+                        })
+                    .asEagerSingleton();
+                expose(String.class).annotatedWith(named("abcde"));
+              }
+
+              @Provides
+              @Exposed
+              @Named("a")
+              String provideA() {
+                return "A";
+              }
+
+              @Provides
+              @Exposed
+              @Named("abc")
+              String provideAbc(@Named("ab") String ab) {
+                return ab + "C";
+              }
+            });
 
     assertEquals("ABCDE", injector.getInstance(Key.get(String.class, named("abcde"))));
   }
 
   static class AB {
-    @Inject @Named("a") String a;
-    @Inject @Named("b") String b;
+    @Inject
+    @Named("a")
+    String a;
+
+    @Inject
+    @Named("b")
+    String b;
   }
 
   interface C {}
 
   public void testSpiAccess() {
-    Injector injector = Guice.createInjector(new PrivateModule() {
-          @Override public void configure() {
-            bind(String.class).annotatedWith(named("a")).toInstance("private");
-            bind(String.class).annotatedWith(named("b")).toInstance("exposed");
-            expose(String.class).annotatedWith(named("b"));
-          }
-        });
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              public void configure() {
+                bind(String.class).annotatedWith(named("a")).toInstance("private");
+                bind(String.class).annotatedWith(named("b")).toInstance("exposed");
+                expose(String.class).annotatedWith(named("b"));
+              }
+            });
 
-    ExposedBinding<?> binding
-        = (ExposedBinding<?>) injector.getBinding(Key.get(String.class, Names.named("b")));
-    assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))),
+    ExposedBinding<?> binding =
+        (ExposedBinding<?>) injector.getBinding(Key.get(String.class, Names.named("b")));
+    assertEquals(
+        ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))),
         binding.getDependencies());
     PrivateElements privateElements = binding.getPrivateElements();
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))),
+    assertEquals(
+        ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))),
         privateElements.getExposedKeys());
-    assertContains(privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(),
-        PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass()));
+    assertContains(
+        privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(),
+        PrivateModuleTest.class.getName(),
+        getDeclaringSourcePart(getClass()));
     Injector privateInjector = privateElements.getInjector();
     assertEquals("private", privateInjector.getInstance(Key.get(String.class, Names.named("a"))));
   }
-  
+
   public void testParentBindsSomethingInPrivate() {
     try {
       Guice.createInjector(new FailingModule());
       fail();
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      assertContains(expected.toString(),
+      assertContains(
+          expected.toString(),
           "Unable to create binding for java.util.List.",
           "It was already configured on one or more child injectors or private modules",
           "bound at " + FailingPrivateModule.class.getName() + ".configure(",
@@ -474,15 +607,16 @@
           "at " + FailingModule.class.getName() + ".configure(");
     }
   }
-  
+
   public void testParentBindingToPrivateLinkedJitBinding() {
     Injector injector = Guice.createInjector(new ManyPrivateModules());
     try {
       injector.getBinding(Key.get(Types.providerOf(List.class)));
       fail();
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      assertContains(expected.toString(),
+      assertContains(
+          expected.toString(),
           "Unable to create binding for com.google.inject.Provider<java.util.List>.",
           "It was already configured on one or more child injectors or private modules",
           "bound at " + FailingPrivateModule.class.getName() + ".configure(",
@@ -493,15 +627,16 @@
           "while locating com.google.inject.Provider<java.util.List>");
     }
   }
-  
+
   public void testParentBindingToPrivateJitBinding() {
     Injector injector = Guice.createInjector(new ManyPrivateModules());
     try {
       injector.getBinding(PrivateFoo.class);
       fail();
-    } catch(ConfigurationException expected) {
+    } catch (ConfigurationException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      assertContains(expected.toString(),
+      assertContains(
+          expected.toString(),
           "Unable to create binding for " + PrivateFoo.class.getName(),
           "It was already configured on one or more child injectors or private modules",
           "(bound by a just-in-time binding)",
@@ -511,14 +646,16 @@
   }
 
   private static class FailingModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bind(Collection.class).to(List.class);
       install(new ManyPrivateModules());
     }
   }
 
   private static class ManyPrivateModules extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       // make sure duplicate sources are collapsed
       install(new FailingPrivateModule());
       install(new FailingPrivateModule());
@@ -528,37 +665,39 @@
   }
 
   private static class FailingPrivateModule extends PrivateModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bind(List.class).toInstance(new ArrayList());
-      
+
       // Add the Provider<List> binding, created just-in-time,
       // to make sure our linked JIT bindings have the correct source.
       getProvider(Key.get(Types.providerOf(List.class)));
-      
+
       // Request a JIT binding for PrivateFoo, which can only
       // be created in the private module because it depends
       // on List.
       getProvider(PrivateFoo.class);
     }
   }
-  
+
   /** A second class, so we can see another name in the source list. */
   private static class SecondFailingPrivateModule extends PrivateModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bind(List.class).toInstance(new ArrayList());
-      
+
       // Add the Provider<List> binding, created just-in-time,
       // to make sure our linked JIT bindings have the correct source.
       getProvider(Key.get(Types.providerOf(List.class)));
-      
+
       // Request a JIT binding for PrivateFoo, which can only
       // be created in the private module because it depends
       // on List.
       getProvider(PrivateFoo.class);
     }
   }
-  
+
   private static class PrivateFoo {
     @Inject List list;
-  } 
+  }
 }
diff --git a/core/test/com/google/inject/ProviderInjectionTest.java b/core/test/com/google/inject/ProviderInjectionTest.java
index 755ff97..85e5641 100644
--- a/core/test/com/google/inject/ProviderInjectionTest.java
+++ b/core/test/com/google/inject/ProviderInjectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,24 +19,23 @@
 import static com.google.inject.name.Names.named;
 
 import com.google.inject.name.Named;
-
-import junit.framework.TestCase;
-
 import java.util.Arrays;
 import java.util.List;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ProviderInjectionTest extends TestCase {
 
   public void testProviderInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Bar.class);
-        bind(SampleSingleton.class).in(Scopes.SINGLETON);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Bar.class);
+                bind(SampleSingleton.class).in(Scopes.SINGLETON);
+              }
+            });
 
     Foo foo = injector.getInstance(Foo.class);
 
@@ -51,107 +50,143 @@
 
   /** Test for bug 155. */
   public void testProvidersAreInjectedWhenBound() {
-    Module m = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Bar.class).toProvider(new Provider<Bar>() {
-          @SuppressWarnings("unused")
-          @Inject void cantBeCalled(Baz baz) {
-            fail("Can't have called this method since Baz is not bound.");
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Bar.class)
+                .toProvider(
+                    new Provider<Bar>() {
+                      @SuppressWarnings("unused")
+                      @Inject
+                      void cantBeCalled(Baz baz) {
+                        fail("Can't have called this method since Baz is not bound.");
+                      }
+
+                      @Override
+                      public Bar get() {
+                        return new Bar() {};
+                      }
+                    });
           }
-          public Bar get() {
-            return new Bar() {};
-          }
-        });
-      }
-    };
+        };
 
     try {
       Guice.createInjector(m);
       fail("Should have thrown a CreationException");
-    }
-    catch (CreationException expected) {
+    } catch (CreationException expected) {
     }
   }
 
   /**
-   * When custom providers are used at injector creation time, they should be
-   * injected before use. In this testcase, we verify that a provider for
-   * List.class is injected before it is used.
+   * When custom providers are used at injector creation time, they should be injected before use.
+   * In this testcase, we verify that a provider for List.class is injected before it is used.
    */
   public void testProvidersAreInjectedBeforeTheyAreUsed() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      public void configure() {
-        // should bind String to "[true]"
-        bind(String.class).toProvider(new Provider<String>() {
-          private String value;
-          @Inject void initialize(List list) {
-            value = list.toString();
-          }
-          public String get() {
-            return value;
-          }
-        });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              public void configure() {
+                // should bind String to "[true]"
+                bind(String.class)
+                    .toProvider(
+                        new Provider<String>() {
+                          private String value;
 
-        // should bind List to [true]
-        bind(List.class).toProvider(new Provider<List>() {
-          @Inject Boolean injectedYet = Boolean.FALSE;
-          public List get() {
-            return Arrays.asList(injectedYet);
-          }
-        });
+                          @Inject
+                          void initialize(List list) {
+                            value = list.toString();
+                          }
 
-        // should bind Boolean to true
-        bind(Boolean.class).toInstance(Boolean.TRUE);
-      }
-    });
+                          @Override
+                          public String get() {
+                            return value;
+                          }
+                        });
 
-    assertEquals("Providers not injected before use",
-        "[true]",
-        injector.getInstance(String.class));
+                // should bind List to [true]
+                bind(List.class)
+                    .toProvider(
+                        new Provider<List>() {
+                          @Inject Boolean injectedYet = Boolean.FALSE;
+
+                          @Override
+                          public List get() {
+                            return Arrays.asList(injectedYet);
+                          }
+                        });
+
+                // should bind Boolean to true
+                bind(Boolean.class).toInstance(Boolean.TRUE);
+              }
+            });
+
+    assertEquals("Providers not injected before use", "[true]", injector.getInstance(String.class));
   }
 
   /**
-   * This test ensures that regardless of binding order, instances are injected
-   * before they are used. It injects mutable Count objects and records their
-   * value at the time that they're injected.
+   * This test ensures that regardless of binding order, instances are injected before they are
+   * used. It injects mutable Count objects and records their value at the time that they're
+   * injected.
    */
   public void testCreationTimeInjectionOrdering() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        // instance injection
-        bind(Count.class).annotatedWith(named("a")).toInstance(new Count(0) {
-          @Inject void initialize(@Named("b") Count bCount) {
-            value = bCount.value + 1;
-          }
-        });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                // instance injection
+                bind(Count.class)
+                    .annotatedWith(named("a"))
+                    .toInstance(
+                        new Count(0) {
+                          @Inject
+                          void initialize(@Named("b") Count bCount) {
+                            value = bCount.value + 1;
+                          }
+                        });
 
-        // provider injection
-        bind(Count.class).annotatedWith(named("b")).toProvider(new Provider<Count>() {
-          Count count;
-          @Inject void initialize(@Named("c") Count cCount) {
-            count = new Count(cCount.value + 2);
-          }
-          public Count get() {
-            return count;
-          }
-        });
+                // provider injection
+                bind(Count.class)
+                    .annotatedWith(named("b"))
+                    .toProvider(
+                        new Provider<Count>() {
+                          Count count;
 
-        // field and method injection, fields first
-        bind(Count.class).annotatedWith(named("c")).toInstance(new Count(0) {
-          @Inject @Named("d") Count dCount;
-          @Inject void initialize(@Named("e") Count eCount) {
-            value = dCount.value + eCount.value + 4;
-          }
-        });
+                          @Inject
+                          void initialize(@Named("c") Count cCount) {
+                            count = new Count(cCount.value + 2);
+                          }
 
-        // static injection
-        requestStaticInjection(StaticallyInjectable.class);
+                          @Override
+                          public Count get() {
+                            return count;
+                          }
+                        });
 
-        bind(Count.class).annotatedWith(named("d")).toInstance(new Count(8));
-        bind(Count.class).annotatedWith(named("e")).toInstance(new Count(16));
-      }
-    });
+                // field and method injection, fields first
+                bind(Count.class)
+                    .annotatedWith(named("c"))
+                    .toInstance(
+                        new Count(0) {
+                          @Inject
+                          @Named("d")
+                          Count dCount;
+
+                          @Inject
+                          void initialize(@Named("e") Count eCount) {
+                            value = dCount.value + eCount.value + 4;
+                          }
+                        });
+
+                // static injection
+                requestStaticInjection(StaticallyInjectable.class);
+
+                bind(Count.class).annotatedWith(named("d")).toInstance(new Count(8));
+                bind(Count.class).annotatedWith(named("e")).toInstance(new Count(16));
+              }
+            });
 
     assertEquals(28, injector.getInstance(Key.get(Count.class, named("c"))).value);
     assertEquals(30, injector.getInstance(Key.get(Count.class, named("b"))).value);
@@ -161,6 +196,7 @@
 
   static class Count {
     int value;
+
     Count(int value) {
       this.value = value;
     }
@@ -168,7 +204,9 @@
 
   static class StaticallyInjectable {
     static int cCountAtInjectionTime;
-    @Inject static void initialize(@Named("c") Count cCount) {
+
+    @Inject
+    static void initialize(@Named("c") Count cCount) {
       cCountAtInjectionTime = cCount.value;
     }
   }
@@ -182,6 +220,5 @@
 
   static class SampleSingleton {}
 
-  interface Baz { }
-
+  interface Baz {}
 }
diff --git a/core/test/com/google/inject/ProvisionExceptionTest.java b/core/test/com/google/inject/ProvisionExceptionTest.java
index 962794f..35a4f47 100644
--- a/core/test/com/google/inject/ProvisionExceptionTest.java
+++ b/core/test/com/google/inject/ProvisionExceptionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,28 +25,29 @@
 import static java.lang.annotation.ElementType.PARAMETER;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
-import junit.framework.TestCase;
-
+import com.google.common.base.Throwables;
+import com.google.inject.spi.Message;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 @SuppressWarnings("UnusedDeclaration")
 public class ProvisionExceptionTest extends TestCase {
 
   public void testExceptionsCollapsed() {
     try {
       Guice.createInjector().getInstance(A.class);
-      fail(); 
+      fail();
     } catch (ProvisionException e) {
       assertTrue(e.getCause() instanceof UnsupportedOperationException);
-      assertContains(e.getMessage(), "Error injecting constructor",
-          "for parameter 0 at com.google.inject.ProvisionExceptionTest$C.setD",
+      assertContains(
+          e.getMessage(),
+          "Error injecting constructor",
+          "for the 1st parameter of com.google.inject.ProvisionExceptionTest$C.setD",
           "for field at com.google.inject.ProvisionExceptionTest$B.c",
-          "for parameter 0 at com.google.inject.ProvisionExceptionTest$A");
+          "for the 1st parameter of com.google.inject.ProvisionExceptionTest$A");
     }
   }
 
@@ -56,19 +57,24 @@
    */
   public void testExceptionsCollapsedWithScopes() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(B.class).in(Scopes.SINGLETON);
-        }
-      }).getInstance(A.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  bind(B.class).in(Scopes.SINGLETON);
+                }
+              })
+          .getInstance(A.class);
       fail();
     } catch (ProvisionException e) {
       assertTrue(e.getCause() instanceof UnsupportedOperationException);
       assertFalse(e.getMessage().contains("custom provider"));
-      assertContains(e.getMessage(), "Error injecting constructor",
-          "for parameter 0 at com.google.inject.ProvisionExceptionTest$C.setD",
+      assertContains(
+          e.getMessage(),
+          "Error injecting constructor",
+          "for the 1st parameter of com.google.inject.ProvisionExceptionTest$C.setD",
           "for field at com.google.inject.ProvisionExceptionTest$B.c",
-          "for parameter 0 at com.google.inject.ProvisionExceptionTest$A");
+          "for the 1st parameter of com.google.inject.ProvisionExceptionTest$A");
     }
   }
 
@@ -78,22 +84,28 @@
       fail();
     } catch (ProvisionException e) {
       assertTrue(e.getCause() instanceof UnsupportedOperationException);
-      assertContains(e.getMessage(), "Error injecting method",
+      assertContains(
+          e.getMessage(),
+          "Error injecting method",
           "at " + E.class.getName() + ".setObject(ProvisionExceptionTest.java:");
     }
   }
 
   public void testBindToProviderInstanceExceptions() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(D.class).toProvider(new DProvider());
-        }
-      }).getInstance(D.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  bind(D.class).toProvider(new DProvider());
+                }
+              })
+          .getInstance(D.class);
       fail();
     } catch (ProvisionException e) {
       assertTrue(e.getCause() instanceof UnsupportedOperationException);
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error in custom provider, java.lang.UnsupportedOperationException",
           "at " + ProvisionExceptionTest.class.getName(),
           getDeclaringSourcePart(getClass()));
@@ -108,36 +120,50 @@
       Guice.createInjector().getInstance(F.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(), "1) User Exception",
+      assertContains(
+          e.getMessage(),
+          "1) User Exception",
           "at " + F.class.getName() + ".<init>(ProvisionExceptionTest.java:");
     }
   }
 
   public void testProvisionExceptionsAreWrappedForBindToProviderType() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(F.class).toProvider(FProvider.class);
-        }
-      }).getInstance(F.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  bind(F.class).toProvider(FProvider.class);
+                }
+              })
+          .getInstance(F.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(), "1) User Exception",
-          "while locating ", FProvider.class.getName(),
-          "while locating ", F.class.getName());
+      assertContains(
+          e.getMessage(),
+          "1) User Exception",
+          "while locating ",
+          FProvider.class.getName(),
+          "while locating ",
+          F.class.getName());
     }
   }
 
   public void testProvisionExceptionsAreWrappedForBindToProviderInstance() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(F.class).toProvider(new FProvider());
-        }
-      }).getInstance(F.class);
+      Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  bind(F.class).toProvider(new FProvider());
+                }
+              })
+          .getInstance(F.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(), "1) User Exception",
+      assertContains(
+          e.getMessage(),
+          "1) User Exception",
           "at " + ProvisionExceptionTest.class.getName(),
           getDeclaringSourcePart(getClass()));
     }
@@ -149,29 +175,47 @@
       fail();
     } catch (ProvisionException expected) {
       ProvisionException reserialized = reserialize(expected);
-      assertContains(reserialized.getMessage(),
+      assertContains(
+          reserialized.getMessage(),
           "1) Error injecting constructor, java.lang.UnsupportedOperationException",
-              "at com.google.inject.ProvisionExceptionTest$RealD.<init>()",
-              "at Key[type=com.google.inject.ProvisionExceptionTest$RealD, annotation=[none]]",
-              "@com.google.inject.ProvisionExceptionTest$C.setD()[0]",
-              "at Key[type=com.google.inject.ProvisionExceptionTest$C, annotation=[none]]",
-              "@com.google.inject.ProvisionExceptionTest$B.c",
-              "at Key[type=com.google.inject.ProvisionExceptionTest$B, annotation=[none]]",
-              "@com.google.inject.ProvisionExceptionTest$A.<init>()[0]",
-              "at Key[type=com.google.inject.ProvisionExceptionTest$A, annotation=[none]]");
+          "at com.google.inject.ProvisionExceptionTest$RealD.<init>()",
+          "at Key[type=com.google.inject.ProvisionExceptionTest$RealD, annotation=[none]]",
+          "@com.google.inject.ProvisionExceptionTest$C.setD()[0]",
+          "at Key[type=com.google.inject.ProvisionExceptionTest$C, annotation=[none]]",
+          "@com.google.inject.ProvisionExceptionTest$B.c",
+          "at Key[type=com.google.inject.ProvisionExceptionTest$B, annotation=[none]]",
+          "@com.google.inject.ProvisionExceptionTest$A.<init>()[0]",
+          "at Key[type=com.google.inject.ProvisionExceptionTest$A, annotation=[none]]");
     }
   }
 
+  // The only way to trigger an exception with _multiple_ user controlled throwables is by
+  // triggering errors during injector creation.
   public void testMultipleCauses() {
     try {
-      Guice.createInjector().getInstance(G.class);
+      Guice.createInjector(
+          Stage.PRODUCTION,
+          new AbstractModule() {
+            @Provides
+            @Singleton
+            String injectFirst() {
+              throw new IllegalArgumentException(new UnsupportedOperationException("Unsupported"));
+            }
+
+            @Provides
+            @Singleton
+            Object injectSecond() {
+              throw new NullPointerException("can't inject second either");
+            }
+          });
       fail();
-    } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
-          "1) Error injecting method, java.lang.IllegalArgumentException",
+    } catch (CreationException e) {
+      assertContains(
+          e.getMessage(),
+          "1) Error in custom provider, java.lang.IllegalArgumentException",
           "Caused by: java.lang.IllegalArgumentException: java.lang.UnsupportedOperationException",
           "Caused by: java.lang.UnsupportedOperationException: Unsupported",
-          "2) Error injecting method, java.lang.NullPointerException: can't inject second either",
+          "2) Error in custom provider, java.lang.NullPointerException: can't inject second either",
           "Caused by: java.lang.NullPointerException: can't inject second either",
           "2 errors");
     }
@@ -183,7 +227,8 @@
       injector.getInstance(InnerClass.class);
       fail();
     } catch (Exception expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Injecting into inner classes is not supported.",
           "while locating " + InnerClass.class.getName());
     }
@@ -197,7 +242,8 @@
       injector.getInstance(LocalClass.class);
       fail();
     } catch (Exception expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Injecting into inner classes is not supported.",
           "while locating " + LocalClass.class.getName());
     }
@@ -209,8 +255,10 @@
       injector.getInstance(MethodWithBindingAnnotation.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), MethodWithBindingAnnotation.class.getName()
-          + ".injectMe() is annotated with @", Green.class.getName() + "(), ",
+      assertContains(
+          expected.getMessage(),
+          MethodWithBindingAnnotation.class.getName() + ".injectMe() is annotated with @",
+          Green.class.getName() + "(), ",
           "but binding annotations should be applied to its parameters instead.",
           "while locating " + MethodWithBindingAnnotation.class.getName());
     }
@@ -219,8 +267,10 @@
       Guice.createInjector().getInstance(ConstructorWithBindingAnnotation.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), ConstructorWithBindingAnnotation.class.getName()
-          + ".<init>() is annotated with @", Green.class.getName() + "(), ",
+      assertContains(
+          expected.getMessage(),
+          ConstructorWithBindingAnnotation.class.getName() + ".<init>() is annotated with @",
+          Green.class.getName() + "(), ",
           "but binding annotations should be applied to its parameters instead.",
           "at " + ConstructorWithBindingAnnotation.class.getName() + ".class",
           "while locating " + ConstructorWithBindingAnnotation.class.getName());
@@ -228,26 +278,33 @@
   }
 
   public void testBindingAnnotationWarningForScala() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).annotatedWith(Green.class).toInstance("lime!");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).annotatedWith(Green.class).toInstance("lime!");
+              }
+            });
     injector.getInstance(LikeScala.class);
   }
 
   public void testLinkedBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(D.class).to(RealD.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(D.class).to(RealD.class);
+              }
+            });
 
     try {
       injector.getInstance(D.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "at " + RealD.class.getName() + ".<init>(ProvisionExceptionTest.java:",
           "while locating " + RealD.class.getName(),
           "while locating " + D.class.getName());
@@ -255,50 +312,118 @@
   }
 
   public void testProviderKeyBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(D.class).toProvider(DProvider.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(D.class).toProvider(DProvider.class);
+              }
+            });
 
     try {
       injector.getInstance(D.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "while locating " + DProvider.class.getName(),
           "while locating " + D.class.getName());
     }
   }
 
+  public void testDuplicateCausesCollapsed() {
+    final RuntimeException sharedException = new RuntimeException("fail");
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              addError(sharedException);
+              addError(sharedException);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(sharedException, ce.getCause());
+      assertEquals(2, ce.getErrorMessages().size());
+      for (Message message : ce.getErrorMessages()) {
+        assertEquals(sharedException, message.getCause());
+      }
+    }
+  }
+
+  public void testMultipleDuplicates() {
+    final RuntimeException exception1 = new RuntimeException("fail");
+    final RuntimeException exception2 = new RuntimeException("abort");
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              addError(exception1);
+              addError(exception1);
+              addError(exception2);
+              addError(exception2);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertNull(ce.getCause());
+      assertEquals(4, ce.getErrorMessages().size());
+
+      String e1 = Throwables.getStackTraceAsString(exception1);
+      String e2 = Throwables.getStackTraceAsString(exception2);
+      assertContains(
+          ce.getMessage(),
+          "\n1) ",
+          e1,
+          "\n2) ",
+          "(same stack trace as error #1)",
+          "\n3) ",
+          e2,
+          "\n4) ",
+          "(same stack trace as error #3)");
+    }
+  }
+
+  @SuppressWarnings("ClassCanBeStatic")
   private class InnerClass {}
 
   static class A {
     @Inject
-    A(B b) { }
+    A(B b) {}
   }
+
   static class B {
     @Inject C c;
   }
+
   static class C {
     @Inject
-    void setD(RealD d) { }
+    void setD(RealD d) {}
   }
+
   static class E {
-    @Inject void setObject(Object o) {
+    @Inject
+    void setObject(Object o) {
       throw new UnsupportedOperationException();
     }
   }
 
   static class MethodWithBindingAnnotation {
-    @Inject @Green void injectMe(String greenString) {}
+    @Inject
+    @Green
+    void injectMe(String greenString) {}
   }
 
   static class ConstructorWithBindingAnnotation {
     // Suppress compiler errors by the error-prone checker InjectedConstructorAnnotations,
     // which catches injected constructors with binding annotations.
     @SuppressWarnings("InjectedConstructorAnnotations")
-    @Inject @Green ConstructorWithBindingAnnotation(String greenString) {}
+    @Inject
+    @Green
+    ConstructorWithBindingAnnotation(String greenString) {}
   }
 
   /**
@@ -307,46 +432,46 @@
    */
   static class LikeScala {
     @Inject @Green String green;
-    @Inject @Green String green() { return green; }
+
+    @Inject
+    @Green
+    String green() {
+      return green;
+    }
   }
 
   @Retention(RUNTIME)
-  @Target({ FIELD, PARAMETER, CONSTRUCTOR, METHOD })
+  @Target({FIELD, PARAMETER, CONSTRUCTOR, METHOD})
   @BindingAnnotation
   @interface Green {}
 
   interface D {}
 
   static class RealD implements D {
-    @Inject RealD() {
+    @Inject
+    RealD() {
       throw new UnsupportedOperationException();
     }
   }
 
   static class DProvider implements Provider<D> {
+    @Override
     public D get() {
       throw new UnsupportedOperationException();
     }
   }
 
   static class F {
-    @Inject public F() {
+    @Inject
+    public F() {
       throw new ProvisionException("User Exception", new RuntimeException());
     }
   }
 
   static class FProvider implements Provider<F> {
+    @Override
     public F get() {
       return new F();
     }
   }
-
-  static class G {
-    @Inject void injectFirst() {
-      throw new IllegalArgumentException(new UnsupportedOperationException("Unsupported"));
-    }
-    @Inject void injectSecond() {
-      throw new NullPointerException("can't inject second either");
-    }
-  }
 }
diff --git a/core/test/com/google/inject/ProvisionExceptionsTest.java b/core/test/com/google/inject/ProvisionExceptionsTest.java
index 23c323c..024e998 100644
--- a/core/test/com/google/inject/ProvisionExceptionsTest.java
+++ b/core/test/com/google/inject/ProvisionExceptionsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,13 +16,11 @@
 
 package com.google.inject;
 
-import com.google.inject.internal.Errors;
+import com.google.inject.internal.Messages;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
+import junit.framework.TestCase;
 
 /**
  * Tests that ProvisionExceptions are readable and clearly indicate to the user what went wrong with
@@ -31,148 +29,174 @@
  * @author sameb@google.com (Sam Berlin)
  */
 public class ProvisionExceptionsTest extends TestCase {
-  
+
   public void testConstructorRuntimeException() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(Names.named("runtime")).to(true);
-        bind(Exploder.class).to(Explosion.class);
-        bind(Tracer.class).to(TracerImpl.class);        
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(Names.named("runtime")).to(true);
+                bind(Exploder.class).to(Explosion.class);
+                bind(Tracer.class).to(TracerImpl.class);
+              }
+            });
     try {
       injector.getInstance(Tracer.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       // Make sure our initial error message gives the user exception.
-      Asserts.assertContains(pe.getMessage(),
-          "1) Error injecting constructor", "java.lang.IllegalStateException: boom!");
+      Asserts.assertContains(
+          pe.getMessage(),
+          "1) Error injecting constructor",
+          "java.lang.IllegalStateException: boom!");
       assertEquals(1, pe.getErrorMessages().size());
       assertEquals(IllegalStateException.class, pe.getCause().getClass());
-      assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
+      assertEquals(
+          IllegalStateException.class, Messages.getOnlyCause(pe.getErrorMessages()).getClass());
     }
   }
-  
+
   public void testConstructorCheckedException() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(Names.named("runtime")).to(false);
-        bind(Exploder.class).to(Explosion.class);
-        bind(Tracer.class).to(TracerImpl.class);        
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(Names.named("runtime")).to(false);
+                bind(Exploder.class).to(Explosion.class);
+                bind(Tracer.class).to(TracerImpl.class);
+              }
+            });
     try {
       injector.getInstance(Tracer.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       // Make sure our initial error message gives the user exception.
-      Asserts.assertContains(pe.getMessage(),
-          "1) Error injecting constructor", "java.io.IOException: boom!");
+      Asserts.assertContains(
+          pe.getMessage(), "1) Error injecting constructor", "java.io.IOException: boom!");
       assertEquals(1, pe.getErrorMessages().size());
       assertEquals(IOException.class, pe.getCause().getClass());
-      assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
+      assertEquals(IOException.class, Messages.getOnlyCause(pe.getErrorMessages()).getClass());
     }
   }
-  
+
   public void testCustomProvidersRuntimeException() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Exploder.class).toProvider(new Provider<Exploder>() {
-          public Exploder get() {
-            return Explosion.createRuntime();
-          }
-        });
-        bind(Tracer.class).to(TracerImpl.class);        
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Exploder.class)
+                    .toProvider(
+                        new Provider<Exploder>() {
+                          @Override
+                          public Exploder get() {
+                            return Explosion.createRuntime();
+                          }
+                        });
+                bind(Tracer.class).to(TracerImpl.class);
+              }
+            });
     try {
       injector.getInstance(Tracer.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       // Make sure our initial error message gives the user exception.
-      Asserts.assertContains(pe.getMessage(),
-          "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
+      Asserts.assertContains(
+          pe.getMessage(), "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
       assertEquals(1, pe.getErrorMessages().size());
       assertEquals(IllegalStateException.class, pe.getCause().getClass());
-      assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
+      assertEquals(
+          IllegalStateException.class, Messages.getOnlyCause(pe.getErrorMessages()).getClass());
     }
   }
-  
+
   public void testProviderMethodRuntimeException() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Tracer.class).to(TracerImpl.class);        
-      }
-      @Provides Exploder exploder() {
-        return Explosion.createRuntime();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Tracer.class).to(TracerImpl.class);
+              }
+
+              @Provides
+              Exploder exploder() {
+                return Explosion.createRuntime();
+              }
+            });
     try {
       injector.getInstance(Tracer.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       // Make sure our initial error message gives the user exception.
-      Asserts.assertContains(pe.getMessage(),
-          "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
+      Asserts.assertContains(
+          pe.getMessage(), "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
       assertEquals(1, pe.getErrorMessages().size());
       assertEquals(IllegalStateException.class, pe.getCause().getClass());
-      assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
+      assertEquals(
+          IllegalStateException.class, Messages.getOnlyCause(pe.getErrorMessages()).getClass());
     }
   }
-  
+
   public void testProviderMethodCheckedException() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Tracer.class).to(TracerImpl.class);        
-      }
-      @Provides Exploder exploder() throws IOException {
-        return Explosion.createChecked();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Tracer.class).to(TracerImpl.class);
+              }
+
+              @Provides
+              Exploder exploder() throws IOException {
+                return Explosion.createChecked();
+              }
+            });
     try {
       injector.getInstance(Tracer.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       pe.printStackTrace();
       // Make sure our initial error message gives the user exception.
-      Asserts.assertContains(pe.getMessage(),
-          "1) Error in custom provider", "java.io.IOException: boom!");
+      Asserts.assertContains(
+          pe.getMessage(), "1) Error in custom provider", "java.io.IOException: boom!");
       assertEquals(1, pe.getErrorMessages().size());
       assertEquals(IOException.class, pe.getCause().getClass());
-      assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
+      assertEquals(IOException.class, Messages.getOnlyCause(pe.getErrorMessages()).getClass());
     }
   }
-  
+
   private static interface Exploder {}
+
   public static class Explosion implements Exploder {
-    @Inject public Explosion(@Named("runtime") boolean runtime) throws IOException {
-      if(runtime) {
+    @Inject
+    public Explosion(@Named("runtime") boolean runtime) throws IOException {
+      if (runtime) {
         throw new IllegalStateException("boom!");
       } else {
         throw new IOException("boom!");
       }
     }
-    
+
     public static Explosion createRuntime() {
       try {
         return new Explosion(true);
-      } catch(IOException iox) {
+      } catch (IOException iox) {
         throw new RuntimeException();
-      }      
+      }
     }
-    
+
     public static Explosion createChecked() throws IOException {
       return new Explosion(false);
     }
   }
+
   private static interface Tracer {}
+
   private static class TracerImpl implements Tracer {
-    @Inject TracerImpl(Exploder explosion) {
-    }
+    @Inject
+    TracerImpl(Exploder explosion) {}
   }
 }
diff --git a/core/test/com/google/inject/ProvisionListenerTest.java b/core/test/com/google/inject/ProvisionListenerTest.java
index 6e1be84..85e85e7 100644
--- a/core/test/com/google/inject/ProvisionListenerTest.java
+++ b/core/test/com/google/inject/ProvisionListenerTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,130 +17,151 @@
 package com.google.inject;
 
 import static com.google.common.collect.ImmutableList.of;
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.name.Names.named;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.inject.matcher.AbstractMatcher;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.matcher.Matchers;
 import com.google.inject.name.Named;
-import com.google.inject.spi.DependencyAndSource;
 import com.google.inject.spi.InstanceBinding;
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link Binder#bindListener(Matcher, ProvisionListener...)}
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 // TODO(sameb): Add some tests for private modules & child injectors.
 public class ProvisionListenerTest extends TestCase {
 
   public void testExceptionInListenerBeforeProvisioning() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new FailBeforeProvision());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), new FailBeforeProvision());
+              }
+            });
     try {
       injector.getInstance(Foo.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
-          "1) Error notifying ProvisionListener " + FailBeforeProvision.class.getName()
-          + " of " + Foo.class.getName(),
+      assertContains(
+          pe.getMessage(),
+          "1) Error notifying ProvisionListener "
+              + FailBeforeProvision.class.getName()
+              + " of "
+              + Foo.class.getName(),
           "Reason: java.lang.RuntimeException: boo",
           "while locating " + Foo.class.getName());
       assertEquals("boo", pe.getCause().getMessage());
     }
   }
-  
+
   public void testExceptionInListenerAfterProvisioning() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new FailAfterProvision());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), new FailAfterProvision());
+              }
+            });
     try {
       injector.getInstance(Foo.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
-          "1) Error notifying ProvisionListener " + FailAfterProvision.class.getName()
-          + " of " + Foo.class.getName(),
+      assertContains(
+          pe.getMessage(),
+          "1) Error notifying ProvisionListener "
+              + FailAfterProvision.class.getName()
+              + " of "
+              + Foo.class.getName(),
           "Reason: java.lang.RuntimeException: boo",
           "while locating " + Foo.class.getName());
       assertEquals("boo", pe.getCause().getMessage());
     }
   }
-  
+
   public void testExceptionInProvisionExplicitlyCalled() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new JustProvision());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), new JustProvision());
+              }
+            });
     try {
       injector.getInstance(FooBomb.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
+      assertContains(
+          pe.getMessage(),
           "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
           " at " + FooBomb.class.getName(),
           " while locating " + FooBomb.class.getName());
       assertEquals("Retry, Abort, Fail", pe.getCause().getMessage());
     }
   }
-  
+
   public void testExceptionInProvisionAutomaticallyCalled() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new NoProvision());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), new NoProvision());
+              }
+            });
     try {
       injector.getInstance(FooBomb.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
+      assertContains(
+          pe.getMessage(),
           "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
           " at " + FooBomb.class.getName(),
           " while locating " + FooBomb.class.getName());
       assertEquals("Retry, Abort, Fail", pe.getCause().getMessage());
     }
   }
-  
+
   public void testExceptionInFieldProvision() throws Exception {
     final CountAndCaptureExceptionListener listener = new CountAndCaptureExceptionListener();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(new AbstractMatcher<Binding<?>>() {
-          @Override public boolean matches(Binding<?> binding) {
-            return binding.getKey().getRawType().equals(DependsOnFooBombInField.class);
-          }
-        }, listener);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    new AbstractMatcher<Binding<?>>() {
+                      @Override
+                      public boolean matches(Binding<?> binding) {
+                        return binding.getKey().getRawType().equals(DependsOnFooBombInField.class);
+                      }
+                    },
+                    listener);
+              }
+            });
     assertEquals(0, listener.beforeProvision);
     String expectedMsg = null;
     try {
@@ -148,29 +169,48 @@
       fail();
     } catch (ProvisionException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      expectedMsg = expected.getMessage();
-      assertContains(listener.capture.get().getMessage(),
+      expectedMsg = Iterables.getOnlyElement(expected.getErrorMessages()).getMessage();
+      assertContains(
+          expected.getMessage(),
           "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
           " at " + FooBomb.class.getName(),
           " while locating " + FooBomb.class.getName(),
           " while locating " + DependsOnFooBombInField.class.getName());
+      assertContains(
+          listener.capture.get().getMessage(),
+          "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
+          " at " + FooBomb.class.getName(),
+          " while locating " + FooBomb.class.getName());
+      // The message that is captures by the provision listener does not show what is depending on
+      // the thing being listened to.
+      assertThat(listener.capture.get().getMessage())
+          .doesNotContain(" while locating " + DependsOnFooBombInField.class.getName());
     }
     assertEquals(1, listener.beforeProvision);
-    assertEquals(expectedMsg, listener.capture.get().getMessage());
+    assertEquals(
+        expectedMsg,
+        Iterables.getOnlyElement(((ProvisionException) listener.capture.get()).getErrorMessages())
+            .getMessage());
     assertEquals(0, listener.afterProvision);
   }
-  
+
   public void testExceptionInCxtorProvision() throws Exception {
     final CountAndCaptureExceptionListener listener = new CountAndCaptureExceptionListener();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(new AbstractMatcher<Binding<?>>() {
-          @Override public boolean matches(Binding<?> binding) {
-            return binding.getKey().getRawType().equals(DependsOnFooBombInCxtor.class);
-          }
-        }, listener);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    new AbstractMatcher<Binding<?>>() {
+                      @Override
+                      public boolean matches(Binding<?> binding) {
+                        return binding.getKey().getRawType().equals(DependsOnFooBombInCxtor.class);
+                      }
+                    },
+                    listener);
+              }
+            });
     assertEquals(0, listener.beforeProvision);
     String expectedMsg = null;
     try {
@@ -178,177 +218,215 @@
       fail();
     } catch (ProvisionException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      expectedMsg = expected.getMessage();
-      assertContains(listener.capture.get().getMessage(),
+      expectedMsg = Iterables.getOnlyElement(expected.getErrorMessages()).getMessage();
+      assertContains(
+          expected.getMessage(),
           "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
           " at " + FooBomb.class.getName(),
           " while locating " + FooBomb.class.getName(),
           " while locating " + DependsOnFooBombInCxtor.class.getName());
+      assertContains(
+          listener.capture.get().getMessage(),
+          "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
+          " at " + FooBomb.class.getName(),
+          " while locating " + FooBomb.class.getName());
+      // The message that is captures by the provision listener does not show what is depending on
+      // the thing being listened to.
+      assertThat(listener.capture.get().getMessage())
+          .doesNotContain(" while locating " + DependsOnFooBombInField.class.getName());
     }
     assertEquals(1, listener.beforeProvision);
-    assertEquals(expectedMsg, listener.capture.get().getMessage());
+    assertEquals(
+        expectedMsg,
+        Iterables.getOnlyElement(((ProvisionException) listener.capture.get()).getErrorMessages())
+            .getMessage());
     assertEquals(0, listener.afterProvision);
   }
 
   public void testListenerCallsProvisionTwice() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new ProvisionTwice());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), new ProvisionTwice());
+              }
+            });
     try {
       injector.getInstance(Foo.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
-          "1) Error notifying ProvisionListener " + ProvisionTwice.class.getName()
-          + " of " + Foo.class.getName(),
+      assertContains(
+          pe.getMessage(),
+          "1) Error notifying ProvisionListener "
+              + ProvisionTwice.class.getName()
+              + " of "
+              + Foo.class.getName(),
           "Reason: java.lang.IllegalStateException: Already provisioned in this listener.",
           "while locating " + Foo.class.getName());
-      assertEquals("Already provisioned in this listener.", pe.getCause().getMessage());  
+      assertEquals("Already provisioned in this listener.", pe.getCause().getMessage());
     }
   }
-  
+
   public void testCachedInScopePreventsProvisionNotify() {
     final Counter count1 = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), count1);
-        bind(Foo.class).in(Scopes.SINGLETON);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), count1);
+                bind(Foo.class).in(Scopes.SINGLETON);
+              }
+            });
     Foo foo = injector.getInstance(Foo.class);
     assertNotNull(foo);
     assertEquals(1, count1.count);
-    
+
     // not notified the second time because nothing is provisioned
     // (it's cached in the scope)
     count1.count = 0;
     assertSame(foo, injector.getInstance(Foo.class));
     assertEquals(0, count1.count);
   }
-  
+
   public void testCombineAllBindListenerCalls() {
     final Counter count1 = new Counter();
     final Counter count2 = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), count1);
-        bindListener(Matchers.any(), count2);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), count1);
+                bindListener(Matchers.any(), count2);
+              }
+            });
     assertNotNull(injector.getInstance(Foo.class));
     assertEquals(1, count1.count);
     assertEquals(1, count2.count);
   }
-  
+
   public void testNotifyEarlyListenersIfFailBeforeProvision() {
     final Counter count1 = new Counter();
     final Counter count2 = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), count1, new FailBeforeProvision(), count2);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), count1, new FailBeforeProvision(), count2);
+              }
+            });
     try {
       injector.getInstance(Foo.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
-          "1) Error notifying ProvisionListener " + FailBeforeProvision.class.getName()
-          + " of " + Foo.class.getName(),
+      assertContains(
+          pe.getMessage(),
+          "1) Error notifying ProvisionListener "
+              + FailBeforeProvision.class.getName()
+              + " of "
+              + Foo.class.getName(),
           "Reason: java.lang.RuntimeException: boo",
           "while locating " + Foo.class.getName());
       assertEquals("boo", pe.getCause().getMessage());
-      
+
       assertEquals(1, count1.count);
       assertEquals(0, count2.count);
     }
   }
-  
+
   public void testNotifyLaterListenersIfFailAfterProvision() {
     final Counter count1 = new Counter();
     final Counter count2 = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), count1, new FailAfterProvision(), count2);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), count1, new FailAfterProvision(), count2);
+              }
+            });
     try {
       injector.getInstance(Foo.class);
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertEquals(1, pe.getErrorMessages().size());
-      assertContains(pe.getMessage(),
-          "1) Error notifying ProvisionListener " + FailAfterProvision.class.getName()
-          + " of " + Foo.class.getName(),
+      assertContains(
+          pe.getMessage(),
+          "1) Error notifying ProvisionListener "
+              + FailAfterProvision.class.getName()
+              + " of "
+              + Foo.class.getName(),
           "Reason: java.lang.RuntimeException: boo",
           "while locating " + Foo.class.getName());
       assertEquals("boo", pe.getCause().getMessage());
-      
+
       assertEquals(1, count1.count);
       assertEquals(1, count2.count);
     }
   }
-  
+
   public void testNotifiedKeysOfAllBindTypes() {
     final Capturer capturer = new Capturer();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), capturer);
-        bind(Foo.class).annotatedWith(named("pk")).toProvider(FooP.class);
-        try {
-          bind(Foo.class).annotatedWith(named("cxtr")).toConstructor(Foo.class.getDeclaredConstructor());
-        } catch (Exception ex) {
-          throw new RuntimeException(ex);
-        }
-        bind(LinkedFoo.class).to(Foo.class);
-        bind(Interface.class).toInstance(new Implementation());
-        bindConstant().annotatedWith(named("constant")).to("MyConstant");
-      }
-      
-      @Provides @Named("pi") Foo provideFooBar() {
-        return new Foo();
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), capturer);
+                bind(Foo.class).annotatedWith(named("pk")).toProvider(FooP.class);
+                try {
+                  bind(Foo.class)
+                      .annotatedWith(named("cxtr"))
+                      .toConstructor(Foo.class.getDeclaredConstructor());
+                } catch (Exception ex) {
+                  throw new RuntimeException(ex);
+                }
+                bind(LinkedFoo.class).to(Foo.class);
+                bind(Interface.class).toInstance(new Implementation());
+                bindConstant().annotatedWith(named("constant")).to("MyConstant");
+              }
+
+              @Provides
+              @Named("pi")
+              Foo provideFooBar() {
+                return new Foo();
+              }
+            });
+
     // toInstance & constant bindings are notified in random order, at the very beginning.
     assertEquals(
         ImmutableSet.of(Key.get(Interface.class), Key.get(String.class, named("constant"))),
         capturer.getAsSetAndClear());
-    
+
     // simple binding
     assertNotNull(injector.getInstance(Foo.class));
     assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
-    
+
     // provider key binding -- notifies about provider & the object, always
     assertNotNull(injector.getInstance(Key.get(Foo.class, named("pk"))));
     assertEquals(of(Key.get(FooP.class), Key.get(Foo.class, named("pk"))), capturer.getAndClear());
     assertNotNull(injector.getInstance(Key.get(Foo.class, named("pk"))));
     assertEquals(of(Key.get(FooP.class), Key.get(Foo.class, named("pk"))), capturer.getAndClear());
-    
+
     // JIT provider key binding -- notifies about provider & the object, always
     assertNotNull(injector.getInstance(JitFoo2.class));
     assertEquals(of(Key.get(JitFoo2P.class), Key.get(JitFoo2.class)), capturer.getAndClear());
     assertNotNull(injector.getInstance(JitFoo2.class));
     assertEquals(of(Key.get(JitFoo2P.class), Key.get(JitFoo2.class)), capturer.getAndClear());
-    
+
     // provider instance binding -- just the object (not the provider)
     assertNotNull(injector.getInstance(Key.get(Foo.class, named("pi"))));
     assertEquals(of(Key.get(Foo.class, named("pi"))), capturer.getAndClear());
-    
+
     // toConstructor binding
     assertNotNull(injector.getInstance(Key.get(Foo.class, named("cxtr"))));
     assertEquals(of(Key.get(Foo.class, named("cxtr"))), capturer.getAndClear());
-    
+
     // linked binding -- notifies about the target (that's what's provisioned), not the link
     assertNotNull(injector.getInstance(LinkedFoo.class));
     assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
@@ -357,20 +435,24 @@
     assertNotNull(injector.getInstance(JitFoo.class));
     assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
   }
-  
+
   public void testSingletonMatcher() {
     final Counter counter = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(new AbstractMatcher<Binding<?>>() {
-          @Override
-          public boolean matches(Binding<?> t) {
-            return Scopes.isSingleton(t);
-          }
-        }, counter);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    new AbstractMatcher<Binding<?>>() {
+                      @Override
+                      public boolean matches(Binding<?> t) {
+                        return Scopes.isSingleton(t);
+                      }
+                    },
+                    counter);
+              }
+            });
     assertEquals(0, counter.count);
     // no increment for getting Many.
     injector.getInstance(Many.class);
@@ -379,81 +461,102 @@
     injector.getInstance(Sole.class);
     assertEquals(1, counter.count);
   }
-  
+
   public void testCallingBindingDotGetProviderDotGet() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new ProvisionListener() {
-          @Override
-          public <T> void onProvision(ProvisionInvocation<T> provision) {
-            provision.getBinding().getProvider().get(); // AGH!
-          }
-        });
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    Matchers.any(),
+                    new ProvisionListener() {
+                      @Override
+                      public <T> void onProvision(ProvisionInvocation<T> provision) {
+                        provision.getBinding().getProvider().get(); // AGH!
+                      }
+                    });
+              }
+            });
+
     try {
       injector.getInstance(Sole.class);
       fail();
-    } catch(ProvisionException expected) {
+    } catch (ProvisionException expected) {
       // We don't really care what kind of error you get, we only care you get an error.
     }
-    
+
     try {
       injector.getInstance(Many.class);
       fail();
-    } catch(ProvisionException expected) {
+    } catch (ProvisionException expected) {
       // We don't really care what kind of error you get, we only care you get an error.
     }
   }
-  
+
   interface Interface {}
-  class Implementation implements Interface {}
-  
-  @Singleton static class Sole {}
+
+  static class Implementation implements Interface {}
+
+  @Singleton
+  static class Sole {}
+
   static class Many {}
-  
-  @ImplementedBy(Foo.class) static interface JitFoo {}  
-  @ProvidedBy(JitFoo2P.class) static class JitFoo2 {}  
+
+  @ImplementedBy(Foo.class)
+  static interface JitFoo {}
+
+  @ProvidedBy(JitFoo2P.class)
+  static class JitFoo2 {}
+
   static interface LinkedFoo {}
+
   static class Foo implements JitFoo, LinkedFoo {}
+
   static class FooP implements Provider<Foo> {
+    @Override
     public Foo get() {
       return new Foo();
     }
   }
+
   static class JitFoo2P implements Provider<JitFoo2> {
+    @Override
     public JitFoo2 get() {
       return new JitFoo2();
     }
   }
-  
+
   static class FooBomb {
     FooBomb() {
       throw new RuntimeException("Retry, Abort, Fail");
     }
   }
-  
+
   static class DependsOnFooBombInField {
     @Inject FooBomb fooBomb;
   }
-  
+
   static class DependsOnFooBombInCxtor {
-    @Inject DependsOnFooBombInCxtor(FooBomb fooBomb) {}
+    @Inject
+    DependsOnFooBombInCxtor(FooBomb fooBomb) {}
   }
-  
+
   private static class Counter implements ProvisionListener {
     int count = 0;
+
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       count++;
     }
   }
-  
+
   private static class CountAndCaptureExceptionListener implements ProvisionListener {
     int beforeProvision = 0;
     int afterProvision = 0;
-    AtomicReference<RuntimeException> capture = new AtomicReference<RuntimeException>();
+    AtomicReference<RuntimeException> capture = new AtomicReference<>();
+
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       beforeProvision++;
       try {
@@ -465,9 +568,11 @@
       afterProvision++;
     }
   }
-  
+
   private static class Capturer implements ProvisionListener {
-    List<Key> keys = Lists.newArrayList(); 
+    List<Key> keys = Lists.newArrayList();
+
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       keys.add(provision.getBinding().getKey());
       T provisioned = provision.provision();
@@ -477,19 +582,20 @@
       // with a toConstructor binding... but we don't use that in our tests.
       if (provision.getBinding() instanceof InstanceBinding) {
         Class<? super T> expected = provision.getBinding().getKey().getRawType();
-        assertTrue("expected instanceof: " + expected + ", but was: " + provisioned,
+        assertTrue(
+            "expected instanceof: " + expected + ", but was: " + provisioned,
             expected.isInstance(provisioned));
       } else {
         assertEquals(provision.getBinding().getKey().getRawType(), provisioned.getClass());
       }
     }
-    
+
     Set<Key> getAsSetAndClear() {
       Set<Key> copy = ImmutableSet.copyOf(keys);
       keys.clear();
       return copy;
     }
-    
+
     List<Key> getAndClear() {
       List<Key> copy = ImmutableList.copyOf(keys);
       keys.clear();
@@ -498,51 +604,62 @@
   }
 
   private static class FailBeforeProvision implements ProvisionListener {
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       throw new RuntimeException("boo");
     }
-  }  
+  }
+
   private static class FailAfterProvision implements ProvisionListener {
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       provision.provision();
       throw new RuntimeException("boo");
     }
-  }  
+  }
+
   private static class JustProvision implements ProvisionListener {
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       provision.provision();
     }
-  }  
+  }
+
   private static class NoProvision implements ProvisionListener {
-    public <T> void onProvision(ProvisionInvocation<T> provision) {
-    }
+    @Override
+    public <T> void onProvision(ProvisionInvocation<T> provision) {}
   }
+
   private static class ProvisionTwice implements ProvisionListener {
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       provision.provision();
       provision.provision();
     }
   }
-  
+
   private static class ChainAsserter implements ProvisionListener {
     private final List<Class<?>> provisionList;
+
     private final List<Class<?>> expected;
-    
+
     public ChainAsserter(List<Class<?>> provisionList, Iterable<Class<?>> expected) {
       this.provisionList = provisionList;
       this.expected = ImmutableList.copyOf(expected);
     }
-    
+
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       List<Class<?>> actual = Lists.newArrayList();
-      for (DependencyAndSource dep : provision.getDependencyChain()) {
+      for (com.google.inject.spi.DependencyAndSource dep : provision.getDependencyChain()) {
         actual.add(dep.getDependency().getKey().getRawType());
       }
       assertEquals(expected, actual);
+
       provisionList.add(provision.getBinding().getKey().getRawType());
     }
   }
-  
+
   private static Matcher<Binding<?>> keyMatcher(final Class<?> clazz) {
     return new AbstractMatcher<Binding<?>>() {
       @Override
@@ -551,55 +668,62 @@
       }
     };
   }
-  
+
   @SuppressWarnings("unchecked")
   public void testDependencyChain() {
     final List<Class<?>> pList = Lists.newArrayList();
     final List<Class<?>> totalList = Lists.newArrayList();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Instance.class).toInstance(new Instance());
-        bind(B.class).to(BImpl.class);
-        bind(D.class).toProvider(DP.class);
-        
-        bindListener(Matchers.any(), new ProvisionListener() {
-          public <T> void onProvision(ProvisionInvocation<T> provision) {
-            totalList.add(provision.getBinding().getKey().getRawType());
-          }
-        });
-        
-        // Build up a list of asserters for our dependency chains.
-        ImmutableList.Builder<Class<?>> chain = ImmutableList.builder();
-        chain.add(Instance.class);
-        bindListener(keyMatcher(Instance.class), new ChainAsserter(pList, chain.build()));
-        
-        chain.add(A.class);
-        bindListener(keyMatcher(A.class), new ChainAsserter(pList, chain.build()));
-        
-        chain.add(B.class).add(BImpl.class);
-        bindListener(keyMatcher(BImpl.class), new ChainAsserter(pList, chain.build()));
-        
-        chain.add(C.class);
-        bindListener(keyMatcher(C.class), new ChainAsserter(pList, chain.build()));
-        
-        // the chain has D before DP even though DP is provisioned & notified first
-        // because we do DP because of D, and need DP to provision D.
-        chain.add(D.class).add(DP.class);
-        bindListener(keyMatcher(D.class), new ChainAsserter(pList, chain.build()));
-        bindListener(keyMatcher(DP.class), new ChainAsserter(pList, chain.build()));
-        
-        chain.add(E.class);
-        bindListener(keyMatcher(E.class), new ChainAsserter(pList, chain.build()));
-        
-        chain.add(F.class);
-        bindListener(keyMatcher(F.class), new ChainAsserter(pList, chain.build()));
-      }
-      @Provides C c(D d) {
-        return new C() {};
-      }
-    });
-    Instance instance = injector.getInstance(Instance.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Instance.class).toInstance(new Instance());
+                bind(B.class).to(BImpl.class);
+                bind(D.class).toProvider(DP.class);
+
+                bindListener(
+                    Matchers.any(),
+                    new ProvisionListener() {
+                      @Override
+                      public <T> void onProvision(ProvisionInvocation<T> provision) {
+                        totalList.add(provision.getBinding().getKey().getRawType());
+                      }
+                    });
+
+                // Build up a list of asserters for our dependency chains.
+                ImmutableList.Builder<Class<?>> chain = ImmutableList.builder();
+                chain.add(Instance.class);
+                bindListener(keyMatcher(Instance.class), new ChainAsserter(pList, chain.build()));
+
+                chain.add(A.class);
+                bindListener(keyMatcher(A.class), new ChainAsserter(pList, chain.build()));
+
+                chain.add(B.class).add(BImpl.class);
+                bindListener(keyMatcher(BImpl.class), new ChainAsserter(pList, chain.build()));
+
+                chain.add(C.class);
+                bindListener(keyMatcher(C.class), new ChainAsserter(pList, chain.build()));
+
+                // the chain has D before DP even though DP is provisioned & notified first
+                // because we do DP because of D, and need DP to provision D.
+                chain.add(D.class).add(DP.class);
+                bindListener(keyMatcher(D.class), new ChainAsserter(pList, chain.build()));
+                bindListener(keyMatcher(DP.class), new ChainAsserter(pList, chain.build()));
+
+                chain.add(E.class);
+                bindListener(keyMatcher(E.class), new ChainAsserter(pList, chain.build()));
+
+                chain.add(F.class);
+                bindListener(keyMatcher(F.class), new ChainAsserter(pList, chain.build()));
+              }
+
+              @Provides
+              C c(D d) {
+                return new C() {};
+              }
+            });
+    injector.getInstance(Instance.class);
     // make sure we're checking all of the chain asserters..
     assertEquals(
         of(Instance.class, A.class, BImpl.class, C.class, DP.class, D.class, E.class, F.class),
@@ -607,116 +731,147 @@
     // and make sure that nothing else was notified that we didn't expect.
     assertEquals(totalList, pList);
   }
-  
+
   public void testModuleRequestInjection() {
-    final AtomicBoolean notified = new AtomicBoolean();    
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        requestInjection(new Object() {
-          @Inject Foo foo;
-        });
-        bindListener(Matchers.any(),
-            new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
-      }
-    });
-    assertTrue(notified.get());
-  }
-  
-  public void testToProviderInstance() {
-    final AtomicBoolean notified = new AtomicBoolean();    
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Object.class).toProvider(new Provider<Object>() {
-          @Inject Foo foo;
-          public Object get() {
-            return null;
+    final AtomicBoolean notified = new AtomicBoolean();
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestInjection(
+                new Object() {
+                  @Inject Foo foo;
+                });
+            bindListener(
+                Matchers.any(),
+                new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
           }
         });
-        bindListener(Matchers.any(),
-            new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
-      }
-    });
     assertTrue(notified.get());
   }
-  
+
+  public void testToProviderInstance() {
+    final AtomicBoolean notified = new AtomicBoolean();
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Object.class)
+                .toProvider(
+                    new Provider<Object>() {
+                      @Inject Foo foo;
+
+                      @Override
+                      public Object get() {
+                        return null;
+                      }
+                    });
+            bindListener(
+                Matchers.any(),
+                new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
+          }
+        });
+    assertTrue(notified.get());
+  }
+
   public void testInjectorInjectMembers() {
-    final Object object = new Object() {
-      @Inject Foo foo;
-    };
-    final AtomicBoolean notified = new AtomicBoolean();    
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(),
-            new SpecialChecker(Foo.class, object.getClass().getName(), notified));
-      }
-    }).injectMembers(object);
+    final Object object =
+        new Object() {
+          @Inject Foo foo;
+        };
+    final AtomicBoolean notified = new AtomicBoolean();
+    Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    Matchers.any(),
+                    new SpecialChecker(Foo.class, object.getClass().getName(), notified));
+              }
+            })
+        .injectMembers(object);
     assertTrue(notified.get());
   }
-  
+
   private static class SpecialChecker implements ProvisionListener {
     private final Class<?> notifyType;
+
     private final String firstSource;
+
     private final AtomicBoolean notified;
-    
+
     public SpecialChecker(Class<?> notifyType, String firstSource, AtomicBoolean notified) {
       this.notifyType = notifyType;
       this.firstSource = firstSource;
       this.notified = notified;
     }
-    
+
+    @Override
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       notified.set(true);
-      assertEquals(notifyType, provision.getBinding().getKey().getRawType());            
+      assertEquals(notifyType, provision.getBinding().getKey().getRawType());
       assertEquals(2, provision.getDependencyChain().size());
-      
+
       assertNull(provision.getDependencyChain().get(0).getDependency());
       assertContains(provision.getDependencyChain().get(0).getBindingSource(), firstSource);
-      
-      assertEquals(notifyType,
-          provision.getDependencyChain().get(1).getDependency().getKey().getRawType());
-      assertContains(provision.getDependencyChain().get(1).getBindingSource(),
+
+      assertEquals(
+          notifyType, provision.getDependencyChain().get(1).getDependency().getKey().getRawType());
+      assertContains(
+          provision.getDependencyChain().get(1).getBindingSource(),
           notifyType.getName() + ".class(");
+
     }
   }
-  
+
   private static class Instance {
     @Inject A a;
   }
+
   private static class A {
-    @Inject A(B b) {}
+    @Inject
+    A(B b) {}
   }
+
   private interface B {}
+
   private static class BImpl implements B {
-    @Inject void inject(C c) {}
+    @Inject
+    void inject(C c) {}
   }
+
   private interface C {}
+
   private interface D {}
+
   private static class DP implements Provider<D> {
     @Inject Provider<E> ep;
+
+    @Override
     public D get() {
       ep.get();
       return new D() {};
     }
   }
+
   private static class E {
     @SuppressWarnings("unused")
-    @Inject F f;
+    @Inject
+    F f;
   }
-  private static class F {
-  }
+
+  private static class F {}
 
   public void testBindToInjectorWithListeningGivesSaneException() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bindListener(Matchers.any(), new Counter());
-          bind(Injector.class).toProvider(Providers.<Injector>of(null));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bindListener(Matchers.any(), new Counter());
+              bind(Injector.class).toProvider(Providers.<Injector>of(null));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertContains(
@@ -725,39 +880,44 @@
   }
 
   public void testProvisionIsNotifiedAfterContextsClear() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), new ProvisionListener() {
-          @Override
-          public <T> void onProvision(ProvisionInvocation<T> provision) {
-            Object provisioned = provision.provision();
-            if (provisioned instanceof X) {
-              ((X)provisioned).init();
-            } else if (provisioned instanceof Y) {
-              X.createY = false;
-              ((Y)provisioned).init();
-            }
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    Matchers.any(),
+                    new ProvisionListener() {
+                      @Override
+                      public <T> void onProvision(ProvisionInvocation<T> provision) {
+                        Object provisioned = provision.provision();
+                        if (provisioned instanceof X) {
+                          ((X) provisioned).init();
+                        } else if (provisioned instanceof Y) {
+                          X.createY = false;
+                          ((Y) provisioned).init();
+                        }
+                      }
+                    });
+              }
+            });
 
     X.createY = true;
     X x = injector.getInstance(X.class);
     assertNotSame(x, x.y.x);
-    assertFalse("x.ID: " + x.ID + ", x.y.x.iD: " + x.y.x.ID, x.ID == x.y.x.ID);
+    assertFalse("x.id: " + x.id + ", x.y.x.id: " + x.y.x.id, x.id == x.y.x.id);
   }
 
   private static class X {
-    final static AtomicInteger COUNTER = new AtomicInteger();
+    static final AtomicInteger COUNTER = new AtomicInteger();
     static boolean createY;
 
-    final int ID = COUNTER.getAndIncrement();
+    final int id = COUNTER.getAndIncrement();
     final Provider<Y> yProvider;
     Y y;
 
-    @Inject X(Provider<Y> yProvider) {
+    @Inject
+    X(Provider<Y> yProvider) {
       this.yProvider = yProvider;
     }
 
@@ -772,7 +932,8 @@
     final Provider<X> xProvider;
     X x;
 
-    @Inject Y(Provider<X> xProvider) {
+    @Inject
+    Y(Provider<X> xProvider) {
       this.xProvider = xProvider;
     }
 
@@ -780,16 +941,18 @@
       this.x = xProvider.get();
     }
   }
-  
+
   public void testDeDuplicateProvisionListeners() {
     final Counter counter = new Counter();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(Matchers.any(), counter);
-        bindListener(Matchers.any(), counter);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(Matchers.any(), counter);
+                bindListener(Matchers.any(), counter);
+              }
+            });
     injector.getInstance(Many.class);
     assertEquals("ProvisionListener not de-duplicated", 1, counter.count);
   }
diff --git a/core/test/com/google/inject/ReflectionTest.java b/core/test/com/google/inject/ReflectionTest.java
index 610f099..9821551 100644
--- a/core/test/com/google/inject/ReflectionTest.java
+++ b/core/test/com/google/inject/ReflectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,27 +19,27 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.spi.ElementSource;
-
+import java.lang.annotation.Retention;
 import junit.framework.TestCase;
 
-import java.lang.annotation.Retention;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ReflectionTest extends TestCase {
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface I {}
+  @BindingAnnotation
+  @interface I {}
 
   public void testNormalBinding() throws CreationException {
     final Foo foo = new Foo();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class).toInstance(foo);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class).toInstance(foo);
+              }
+            });
 
     Binding<Foo> fooBinding = injector.getBinding(Key.get(Foo.class));
     assertSame(foo, fooBinding.getProvider().get());
@@ -49,11 +49,14 @@
   }
 
   public void testConstantBinding() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindConstant().annotatedWith(I.class).to(5);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(I.class).to(5);
+              }
+            });
 
     Binding<?> i = injector.getBinding(Key.get(int.class, I.class));
     assertEquals(5, i.getProvider().get());
@@ -65,12 +68,15 @@
   public void testLinkedBinding() throws CreationException {
     final Bar bar = new Bar();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Bar.class).toInstance(bar);
-        bind(Key.get(Foo.class)).to(Key.get(Bar.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Bar.class).toInstance(bar);
+                bind(Key.get(Foo.class)).to(Key.get(Bar.class));
+              }
+            });
 
     Binding<Foo> fooBinding = injector.getBinding(Key.get(Foo.class));
     assertSame(bar, fooBinding.getProvider().get());
diff --git a/core/test/com/google/inject/RequestInjectionTest.java b/core/test/com/google/inject/RequestInjectionTest.java
index dfd0f77..488c12c 100644
--- a/core/test/com/google/inject/RequestInjectionTest.java
+++ b/core/test/com/google/inject/RequestInjectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,21 +23,19 @@
 import com.google.inject.matcher.Matchers;
 import com.google.inject.spi.TypeEncounter;
 import com.google.inject.spi.TypeListener;
-
+import java.lang.annotation.Retention;
 import junit.framework.TestCase;
 
-import java.lang.annotation.Retention;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class RequestInjectionTest extends TestCase {
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface ForField {}
+  @BindingAnnotation
+  @interface ForField {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface ForMethod {}
+  @BindingAnnotation
+  @interface ForMethod {}
 
   @Override
   protected void setUp() throws Exception {
@@ -49,14 +47,15 @@
   public void testInjectMembers() {
     final HasInjections hi = new HasInjections();
 
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(ForMethod.class).to("test");
-        bindConstant().annotatedWith(ForField.class).to(5);
-        requestInjection(hi);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(ForMethod.class).to("test");
+            bindConstant().annotatedWith(ForField.class).to(5);
+            requestInjection(hi);
+          }
+        });
 
     assertEquals("test", hi.instanceMethod);
     assertEquals(5, hi.instanceField);
@@ -65,31 +64,33 @@
   }
 
   public void testInjectStatics() throws CreationException {
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(ForMethod.class).to("test");
-        bindConstant().annotatedWith(ForField.class).to(5);
-        requestStaticInjection(HasInjections.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(ForMethod.class).to("test");
+            bindConstant().annotatedWith(ForField.class).to(5);
+            requestStaticInjection(HasInjections.class);
+          }
+        });
 
     assertEquals("test", HasInjections.staticMethod);
     assertEquals(5, HasInjections.staticField);
   }
-  
+
   public void testInjectMembersAndStatics() {
     final HasInjections hi = new HasInjections();
 
-    Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindConstant().annotatedWith(ForMethod.class).to("test");
-        bindConstant().annotatedWith(ForField.class).to(5);
-        requestStaticInjection(HasInjections.class);
-        requestInjection(hi);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(ForMethod.class).to("test");
+            bindConstant().annotatedWith(ForField.class).to(5);
+            requestStaticInjection(HasInjections.class);
+            requestInjection(hi);
+          }
+        });
 
     assertEquals("test", hi.instanceMethod);
     assertEquals(5, hi.instanceField);
@@ -99,51 +100,63 @@
 
   public void testValidationErrorOnInjectedMembers() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          requestInjection(new NeedsRunnable());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestInjection(new NeedsRunnable());
+            }
+          });
+      fail("Expected CreationException");
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for java.lang.Runnable was bound",
-          "at " + NeedsRunnable.class.getName(), ".runnable(RequestInjectionTest.java:");
+          "at " + NeedsRunnable.class.getName(),
+          ".runnable(RequestInjectionTest.java:");
     }
   }
 
   public void testInjectionErrorOnInjectedMembers() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(Runnable.class).toProvider(new Provider<Runnable>() {
-            public Runnable get() {
-              throw new UnsupportedOperationException();
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Runnable.class)
+                  .toProvider(
+                      new Provider<Runnable>() {
+                        @Override
+                        public Runnable get() {
+                          throw new UnsupportedOperationException();
+                        }
+                      });
+              requestInjection(new NeedsRunnable());
             }
           });
-          requestInjection(new NeedsRunnable());
-        }
-      });
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error in custom provider, java.lang.UnsupportedOperationException",
           "for field at " + NeedsRunnable.class.getName() + ".runnable(RequestInjectionTest.java:",
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   public void testUserExceptionWhileInjectingInstance() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          requestInjection(new BlowsUpOnInject());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestInjection(new BlowsUpOnInject());
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error injecting method, java.lang.UnsupportedOperationException: Pop",
           "at " + BlowsUpOnInject.class.getName() + ".injectInstance(RequestInjectionTest.java:");
     }
@@ -151,15 +164,17 @@
 
   public void testUserExceptionWhileInjectingStatically() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          requestStaticInjection(BlowsUpOnInject.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestStaticInjection(BlowsUpOnInject.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error injecting method, java.lang.UnsupportedOperationException: Snap",
           "at " + BlowsUpOnInject.class.getName() + ".injectStatically(RequestInjectionTest.java:");
     }
@@ -177,59 +192,72 @@
     static String staticMethod;
     String instanceMethod;
 
-    @Inject static void setStaticMethod(@ForMethod String staticMethod) {
+    @Inject
+    static void setStaticMethod(@ForMethod String staticMethod) {
       HasInjections.staticMethod = staticMethod;
     }
 
-    @Inject void setInstanceS(@ForMethod String instanceS) {
+    @Inject
+    void setInstanceS(@ForMethod String instanceS) {
       this.instanceMethod = instanceS;
     }
   }
 
   static class BlowsUpOnInject {
-    @Inject void injectInstance() {
+    @Inject
+    void injectInstance() {
       throw new UnsupportedOperationException("Pop");
     }
 
-    @Inject static void injectStatically() {
+    @Inject
+    static void injectStatically() {
       throw new UnsupportedOperationException("Snap");
     }
   }
-  
+
   /*
    * Tests that initializables of the same instance don't clobber
    * membersInjectors in InitializableReference, so that they ultimately
    * can be requested in any order.
    */
   public void testEarlyInjectableReferencesWithSameIdentity() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        // Add a listener to trigger all toInstance bindings to get an Initializable.
-        bindListener(Matchers.any(), new TypeListener() {
-          @Override
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-          }
-        });
-        
-        // Bind two different Keys to the IDENTITICAL object
-        // ORDER MATTERS! We want the String binding to push out the Object one
-        String fail = new String("better not fail!");
-        bind(Object.class).toInstance(fail);
-        bind(String.class).toInstance(fail);
-        
-        // Then try to inject those objects in a requestInjection,
-        // letting us get into InjectableReference.get before it has
-        // finished running through all its injections.
-        // Each of these technically has its own InjectableReference internally.
-        // ORDER MATTERS!.. because Object is injected first, that InjectableReference
-        // attempts to process its members injector, but it wasn't initialized,
-        // because String pushed it out of the queue!
-        requestInjection(new Object() {
-          @SuppressWarnings("unused") @Inject Object obj;
-          @SuppressWarnings("unused") @Inject String str;
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                // Add a listener to trigger all toInstance bindings to get an Initializable.
+                bindListener(
+                    Matchers.any(),
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {}
+                    });
+
+                // Bind two different Keys to the IDENTITICAL object
+                // ORDER MATTERS! We want the String binding to push out the Object one
+                String fail = new String("better not fail!");
+                bind(Object.class).toInstance(fail);
+                bind(String.class).toInstance(fail);
+
+                // Then try to inject those objects in a requestInjection,
+                // letting us get into InjectableReference.get before it has
+                // finished running through all its injections.
+                // Each of these technically has its own InjectableReference internally.
+                // ORDER MATTERS!.. because Object is injected first, that InjectableReference
+                // attempts to process its members injector, but it wasn't initialized,
+                // because String pushed it out of the queue!
+                requestInjection(
+                    new Object() {
+                      @SuppressWarnings("unused")
+                      @Inject
+                      Object obj;
+
+                      @SuppressWarnings("unused")
+                      @Inject
+                      String str;
+                    });
+              }
+            });
   }
 }
diff --git a/core/test/com/google/inject/RequireAtInjectOnConstructorsTest.java b/core/test/com/google/inject/RequireAtInjectOnConstructorsTest.java
index e5f90c2..e61febd 100644
--- a/core/test/com/google/inject/RequireAtInjectOnConstructorsTest.java
+++ b/core/test/com/google/inject/RequireAtInjectOnConstructorsTest.java
@@ -14,189 +14,230 @@
  * limitations under the License.
  */
 
-
 package com.google.inject;
 
 import junit.framework.TestCase;
 
 /**
  * Tests for {@link Binder#requireAtInjectOnConstructors()}
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 public class RequireAtInjectOnConstructorsTest extends TestCase {
-  
+
   public void testNoCxtors_explicitBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(NoCxtors.class);
-          binder().requireAtInjectOnConstructors();
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(NoCxtors.class);
+              binder().requireAtInjectOnConstructors();
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertEquals(1, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
+      Asserts.assertContains(
+          ce.getMessage(),
           "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
     }
   }
-  
+
   public void testNoCxtors_jitBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        binder().requireAtInjectOnConstructors();
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireAtInjectOnConstructors();
+              }
+            });
     try {
       injector.getInstance(NoCxtors.class);
       fail();
     } catch (ConfigurationException ce) {
-      Asserts.assertContains(ce.getMessage(),
+      Asserts.assertContains(
+          ce.getMessage(),
           "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
           "while locating " + NoCxtors.class.getName());
     }
   }
-  
+
   public void testNoCxtors_implicitBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(Interface.class).to(NoCxtors.class);
-          binder().requireAtInjectOnConstructors();
-        }
-      });
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
-          "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
-    }
-  }
-  
-  public void testNoCxtors_inheritedByPrivateModules() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          binder().requireAtInjectOnConstructors();
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
-              bind(NoCxtors.class);
+              bind(Interface.class).to(NoCxtors.class);
+              binder().requireAtInjectOnConstructors();
             }
           });
-        }
-      });
       fail();
     } catch (CreationException ce) {
       assertEquals(1, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
+      Asserts.assertContains(
+          ce.getMessage(),
           "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
     }
   }
-  
-  public void testNoCxtors_accumulatesAllErrors() {
+
+  public void testNoCxtors_inheritedByPrivateModules() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(NoCxtors.class);
-          bind(AnotherNoCxtors.class);
-          binder().requireAtInjectOnConstructors();
-        }
-      });
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(2, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
-          "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure",
-          "2) Explicit @Inject annotations are required on constructors, but "
-          + AnotherNoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
-    }
-  }
-  
-  public void testNoCxtors_separateOptionsForPrivateModules() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(AnotherNoCxtors.class);
-          install(new PrivateModule() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
             protected void configure() {
               binder().requireAtInjectOnConstructors();
-              bind(NoCxtors.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      bind(NoCxtors.class);
+                    }
+                  });
             }
           });
-        }
-      });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      Asserts.assertContains(
+          ce.getMessage(),
+          "1) Explicit @Inject annotations are required on constructors, but "
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
+    }
+  }
+
+  public void testNoCxtors_accumulatesAllErrors() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(NoCxtors.class);
+              bind(AnotherNoCxtors.class);
+              binder().requireAtInjectOnConstructors();
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(2, ce.getErrorMessages().size());
+      Asserts.assertContains(
+          ce.getMessage(),
+          "1) Explicit @Inject annotations are required on constructors, but "
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure",
+          "2) Explicit @Inject annotations are required on constructors, but "
+              + AnotherNoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
+    }
+  }
+
+  public void testNoCxtors_separateOptionsForPrivateModules() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(AnotherNoCxtors.class);
+              install(
+                  new PrivateModule() {
+                    @Override
+                    protected void configure() {
+                      binder().requireAtInjectOnConstructors();
+                      bind(NoCxtors.class);
+                    }
+                  });
+            }
+          });
       fail();
     } catch (CreationException ce) {
       // This is testing that the parent module doesn't fail because it isn't included
       // in the error message.
       assertEquals(1, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
+      Asserts.assertContains(
+          ce.getMessage(),
           "1) Explicit @Inject annotations are required on constructors, but "
-          + NoCxtors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
+              + NoCxtors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
     }
   }
-  
+
   public void testManyConstructorsButNoneWithAtInject() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(ManyConstructors.class);
-          binder().requireAtInjectOnConstructors();
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(ManyConstructors.class);
+              binder().requireAtInjectOnConstructors();
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertEquals(1, ce.getErrorMessages().size());
-      Asserts.assertContains(ce.getMessage(),
+      Asserts.assertContains(
+          ce.getMessage(),
           "1) Explicit @Inject annotations are required on constructors, but "
-          + ManyConstructors.class.getName() + " has no constructors annotated with @Inject",
-          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$", "configure");
+              + ManyConstructors.class.getName()
+              + " has no constructors annotated with @Inject",
+          "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
+          "configure");
     }
   }
-  
+
   public void testRequireAtInjectStillAllowsToConstructorBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          try {
-            bind(ManyConstructors.class)
-                .toConstructor(ManyConstructors.class.getDeclaredConstructor());
-          } catch (Exception e) {
-            throw new RuntimeException(e);
-          }
-          binder().requireAtInjectOnConstructors();
-        }
-      });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                try {
+                  bind(ManyConstructors.class)
+                      .toConstructor(ManyConstructors.class.getDeclaredConstructor());
+                } catch (Exception e) {
+                  throw new RuntimeException(e);
+                }
+                binder().requireAtInjectOnConstructors();
+              }
+            });
     injector.getInstance(ManyConstructors.class);
   }
-  
+
   private static interface Interface {}
-  private static class NoCxtors implements Interface {}  
+
+  private static class NoCxtors implements Interface {}
+
   private static class AnotherNoCxtors {}
+
   private static class ManyConstructors {
-    @SuppressWarnings("unused") ManyConstructors() {}
-    @SuppressWarnings("unused") ManyConstructors(String a) {}
-    @SuppressWarnings("unused") ManyConstructors(int a) {}
+    @SuppressWarnings("unused")
+    ManyConstructors() {}
+
+    @SuppressWarnings("unused")
+    ManyConstructors(String a) {}
+
+    @SuppressWarnings("unused")
+    ManyConstructors(int a) {}
   }
 }
diff --git a/core/test/com/google/inject/ScopesTest.java b/core/test/com/google/inject/ScopesTest.java
index 15c2d2e..83c36a6 100644
--- a/core/test/com/google/inject/ScopesTest.java
+++ b/core/test/com/google/inject/ScopesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,26 +22,27 @@
 import static com.google.inject.name.Names.named;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
+import com.google.common.base.Joiner;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Maps;
+import com.google.inject.matcher.Matchers;
 import com.google.inject.name.Named;
+import com.google.inject.spi.DefaultBindingScopingVisitor;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
+import com.google.inject.spi.Message;
 import com.google.inject.spi.PrivateElements;
+import com.google.inject.spi.ProvisionListener;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -50,29 +51,32 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ScopesTest extends TestCase {
 
   static final long DEADLOCK_TIMEOUT_SECONDS = 1;
 
-  private final AbstractModule singletonsModule = new AbstractModule() {
-    @Override protected void configure() {
-      bind(BoundAsSingleton.class).in(Scopes.SINGLETON);
-      bind(AnnotatedSingleton.class);
-      bind(EagerSingleton.class).asEagerSingleton();
-      bind(LinkedSingleton.class).to(RealLinkedSingleton.class);
-      bind(DependsOnJustInTimeSingleton.class);
-      bind(NotASingleton.class);
-      bind(ImplementedBySingleton.class).in(Scopes.SINGLETON);
-      bind(ProvidedBySingleton.class).in(Scopes.SINGLETON);
-    }
-  };
+  private final AbstractModule singletonsModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bind(BoundAsSingleton.class).in(Scopes.SINGLETON);
+          bind(AnnotatedSingleton.class);
+          bind(EagerSingleton.class).asEagerSingleton();
+          bind(LinkedSingleton.class).to(RealLinkedSingleton.class);
+          bind(DependsOnJustInTimeSingleton.class);
+          bind(NotASingleton.class);
+          bind(ImplementedBySingleton.class).in(Scopes.SINGLETON);
+          bind(ProvidedBySingleton.class).in(Scopes.SINGLETON);
+        }
+      };
 
-  @Override protected void setUp() throws Exception {
+  @Override
+  protected void setUp() throws Exception {
     AnnotatedSingleton.nextInstanceId = 0;
     BoundAsSingleton.nextInstanceId = 0;
     EagerSingleton.nextInstanceId = 0;
@@ -88,28 +92,24 @@
     Injector injector = Guice.createInjector(singletonsModule);
 
     assertSame(
-        injector.getInstance(BoundAsSingleton.class),
-        injector.getInstance(BoundAsSingleton.class));
+        injector.getInstance(BoundAsSingleton.class), injector.getInstance(BoundAsSingleton.class));
 
     assertSame(
         injector.getInstance(AnnotatedSingleton.class),
         injector.getInstance(AnnotatedSingleton.class));
 
     assertSame(
-        injector.getInstance(EagerSingleton.class),
-        injector.getInstance(EagerSingleton.class));
+        injector.getInstance(EagerSingleton.class), injector.getInstance(EagerSingleton.class));
 
     assertSame(
-        injector.getInstance(LinkedSingleton.class),
-        injector.getInstance(LinkedSingleton.class));
+        injector.getInstance(LinkedSingleton.class), injector.getInstance(LinkedSingleton.class));
 
     assertSame(
         injector.getInstance(JustInTimeSingleton.class),
         injector.getInstance(JustInTimeSingleton.class));
 
     assertNotSame(
-        injector.getInstance(NotASingleton.class),
-        injector.getInstance(NotASingleton.class));
+        injector.getInstance(NotASingleton.class), injector.getInstance(NotASingleton.class));
 
     assertSame(
         injector.getInstance(ImplementedBySingleton.class),
@@ -135,11 +135,14 @@
   }
 
   public void testOverriddingAnnotation() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(AnnotatedSingleton.class).in(Scopes.NO_SCOPE);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(AnnotatedSingleton.class).in(Scopes.NO_SCOPE);
+              }
+            });
 
     assertNotSame(
         injector.getInstance(AnnotatedSingleton.class),
@@ -148,14 +151,17 @@
 
   public void testScopingAnnotationsOnAbstractTypeViaBind() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(A.class).to(AImpl.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(A.class).to(AImpl.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           A.class.getName() + " is annotated with " + Singleton.class.getName(),
           "but scope annotations are not supported for abstract types.",
           "at " + A.class.getName() + ".class(ScopesTest.java:");
@@ -164,6 +170,7 @@
 
   @Singleton
   interface A {}
+
   static class AImpl implements A {}
 
   @Retention(RUNTIME)
@@ -172,14 +179,17 @@
   @Component
   @Singleton
   interface ComponentAnnotationTest {}
+
   static class ComponentAnnotationTestImpl implements ComponentAnnotationTest {}
 
   public void testScopingAnnotationsOnAbstractTypeIsValidForComponent() {
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(ComponentAnnotationTest.class).to(ComponentAnnotationTestImpl.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(ComponentAnnotationTest.class).to(ComponentAnnotationTestImpl.class);
+          }
+        });
   }
 
   public void testScopingAnnotationsOnAbstractTypeViaImplementedBy() {
@@ -187,15 +197,18 @@
       Guice.createInjector().getInstance(D.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           D.class.getName() + " is annotated with " + Singleton.class.getName(),
           "but scope annotations are not supported for abstract types.",
           "at " + D.class.getName() + ".class(ScopesTest.java:");
     }
   }
 
-  @Singleton @ImplementedBy(DImpl.class)
+  @Singleton
+  @ImplementedBy(DImpl.class)
   interface D {}
+
   static class DImpl implements D {}
 
   public void testScopingAnnotationsOnAbstractTypeViaProvidedBy() {
@@ -203,16 +216,20 @@
       Guice.createInjector().getInstance(E.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           E.class.getName() + " is annotated with " + Singleton.class.getName(),
           "but scope annotations are not supported for abstract types.",
           "at " + E.class.getName() + ".class(ScopesTest.java:");
     }
   }
 
-  @Singleton @ProvidedBy(EProvider.class)
+  @Singleton
+  @ProvidedBy(EProvider.class)
   interface E {}
+
   static class EProvider implements Provider<E> {
+    @Override
     public E get() {
       return null;
     }
@@ -220,17 +237,21 @@
 
   public void testScopeUsedButNotBound() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(B.class).in(CustomScoped.class);
-          bind(C.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(B.class).in(CustomScoped.class);
+              bind(C.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No scope is bound to " + CustomScoped.class.getName(),
-          "at " + getClass().getName(), getDeclaringSourcePart(getClass()),
+          "at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()),
           "2) No scope is bound to " + CustomScoped.class.getName(),
           "at " + C.class.getName() + ".class");
     }
@@ -274,12 +295,15 @@
   public void testUnscopedProviderWorksOutsideOfRequestedScope() {
     final RememberProviderScope scope = new RememberProviderScope();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(CustomScoped.class, scope);
-        bind(List.class).to(ArrayList.class).in(CustomScoped.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(CustomScoped.class, scope);
+                bind(List.class).to(ArrayList.class).in(CustomScoped.class);
+              }
+            });
 
     injector.getInstance(List.class);
     Provider<?> listProvider = scope.providers.get(Key.get(List.class));
@@ -290,22 +314,28 @@
   }
 
   static class OuterRuntimeModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerRuntimeModule());
     }
   }
+
   static class InnerRuntimeModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindScope(NotRuntimeRetainedScoped.class, Scopes.NO_SCOPE);
     }
   }
+
   public void testScopeAnnotationWithoutRuntimeRetention() {
     try {
       Guice.createInjector(new OuterRuntimeModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "1) Please annotate " + NotRuntimeRetainedScoped.class.getName()
+      assertContains(
+          expected.getMessage(),
+          "1) Please annotate "
+              + NotRuntimeRetainedScoped.class.getName()
               + " with @Retention(RUNTIME).",
           "at " + InnerRuntimeModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterRuntimeModule.class, InnerRuntimeModule.class));
@@ -313,21 +343,26 @@
   }
 
   static class OuterDeprecatedModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerDeprecatedModule());
     }
   }
+
   static class InnerDeprecatedModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindScope(Deprecated.class, Scopes.NO_SCOPE);
     }
   }
+
   public void testBindScopeToAnnotationWithoutScopeAnnotation() {
     try {
       Guice.createInjector(new OuterDeprecatedModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Please annotate " + Deprecated.class.getName() + " with @ScopeAnnotation.",
           "at " + InnerDeprecatedModule.class.getName() + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterDeprecatedModule.class, InnerDeprecatedModule.class));
@@ -335,18 +370,23 @@
   }
 
   static class OuterScopeModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new CustomNoScopeModule());
       install(new CustomSingletonModule());
     }
   }
+
   static class CustomNoScopeModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindScope(CustomScoped.class, Scopes.NO_SCOPE);
     }
   }
+
   static class CustomSingletonModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindScope(CustomScoped.class, Scopes.SINGLETON);
     }
   }
@@ -356,23 +396,31 @@
       Guice.createInjector(new OuterScopeModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "1) Scope Scopes.NO_SCOPE is already bound to " + CustomScoped.class.getName()
-              + " at " + CustomNoScopeModule.class.getName() + getDeclaringSourcePart(getClass()),
+      assertContains(
+          expected.getMessage(),
+          "1) Scope Scopes.NO_SCOPE is already bound to "
+              + CustomScoped.class.getName()
+              + " at "
+              + CustomNoScopeModule.class.getName()
+              + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterScopeModule.class, CustomNoScopeModule.class),
           "Cannot bind Scopes.SINGLETON.",
-          "at " + ScopesTest.class.getName(), getDeclaringSourcePart(getClass()),
+          "at " + ScopesTest.class.getName(),
+          getDeclaringSourcePart(getClass()),
           asModuleChain(OuterScopeModule.class, CustomSingletonModule.class));
     }
   }
 
   public void testBindDuplicateScope() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(CustomScoped.class, Scopes.SINGLETON);
-        bindScope(CustomScoped.class, Scopes.SINGLETON);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(CustomScoped.class, Scopes.SINGLETON);
+                bindScope(CustomScoped.class, Scopes.SINGLETON);
+              }
+            });
 
     assertSame(
         injector.getInstance(AnnotatedCustomScoped.class),
@@ -380,33 +428,39 @@
   }
 
   public void testDuplicateScopeAnnotations() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(CustomScoped.class, Scopes.NO_SCOPE);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(CustomScoped.class, Scopes.NO_SCOPE);
+              }
+            });
 
     try {
       injector.getInstance(SingletonAndCustomScoped.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) More than one scope annotation was found: ",
           "while locating " + SingletonAndCustomScoped.class.getName());
     }
   }
 
   public void testNullScopedAsASingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
 
-      final Iterator<String> values = Arrays.asList(null, "A").iterator();
+              final Iterator<String> values = Arrays.asList(null, "A").iterator();
 
-      @Provides @Singleton String provideString() {
-         return values.next();
-      }
-    });
+              @Provides
+              @Singleton
+              String provideString() {
+                return values.next();
+              }
+            });
 
     assertNull(injector.getInstance(String.class));
     assertNull(injector.getInstance(String.class));
@@ -415,6 +469,8 @@
 
   class RememberProviderScope implements Scope {
     final Map<Key<?>, Provider<?>> providers = Maps.newHashMap();
+
+    @Override
     public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
       providers.put(key, unscoped);
       return unscoped;
@@ -423,27 +479,34 @@
 
   public void testSingletonAnnotationOnParameterizedType() {
     Injector injector = Guice.createInjector();
-    assertSame(injector.getInstance(new Key<Injected<String>>() {}),
+    assertSame(
+        injector.getInstance(new Key<Injected<String>>() {}),
         injector.getInstance(new Key<Injected<String>>() {}));
-    assertSame(injector.getInstance(new Key<In<Integer>>() {}),
+    assertSame(
+        injector.getInstance(new Key<In<Integer>>() {}),
         injector.getInstance(new Key<In<Short>>() {}));
   }
 
-  @ImplementedBy(Injected.class) public interface In<T> {}
-  @Singleton public static class Injected<T>  implements In<T> {}
+  @ImplementedBy(Injected.class)
+  public interface In<T> {}
 
-  @Target({ ElementType.TYPE, ElementType.METHOD })
+  @Singleton
+  public static class Injected<T> implements In<T> {}
+
+  @Target({ElementType.TYPE, ElementType.METHOD})
   @Retention(RUNTIME)
   @ScopeAnnotation
   public @interface CustomScoped {}
 
-  static final Scope CUSTOM_SCOPE = new Scope() {
-    public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
-      return Scopes.SINGLETON.scope(key, unscoped);
-    }
-  };
+  static final Scope CUSTOM_SCOPE =
+      new Scope() {
+        @Override
+        public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
+          return Scopes.SINGLETON.scope(key, unscoped);
+        }
+      };
 
-  @Target({ ElementType.TYPE, ElementType.METHOD })
+  @Target({ElementType.TYPE, ElementType.METHOD})
   @ScopeAnnotation
   public @interface NotRuntimeRetainedScoped {}
 
@@ -489,7 +552,8 @@
     final int instanceId = nextInstanceId++;
   }
 
-  @SuppressWarnings("MoreThanOneScopeAnnotationOnClass") // suppress compiler error for testing
+  // suppress compiler error for testing
+  @SuppressWarnings({"MoreThanOneScopeAnnotationOnClass", "multiple-scope"})
   @Singleton
   @CustomScoped
   static class SingletonAndCustomScoped {}
@@ -509,21 +573,25 @@
   }
 
   static class ImplementationProvider implements Provider<ProvidedBySingleton> {
+    @Override
     public ProvidedBySingleton get() {
       return new ProvidedBySingleton();
     }
   }
 
   public void testScopeThatGetsAnUnrelatedObject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(B.class);
-        bind(C.class);
-        ProviderGetScope providerGetScope = new ProviderGetScope();
-        requestInjection(providerGetScope);
-        bindScope(CustomScoped.class, providerGetScope);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class);
+                bind(C.class);
+                ProviderGetScope providerGetScope = new ProviderGetScope();
+                requestInjection(providerGetScope);
+                bindScope(CustomScoped.class, providerGetScope);
+              }
+            });
 
     injector.getInstance(C.class);
   }
@@ -531,8 +599,10 @@
   class ProviderGetScope implements Scope {
     @Inject Provider<B> bProvider;
 
+    @Override
     public <T> Provider<T> scope(Key<T> key, final Provider<T> unscoped) {
       return new Provider<T>() {
+        @Override
         public T get() {
           bProvider.get();
           return unscoped.get();
@@ -552,27 +622,34 @@
     final Key<Object> h = Key.get(Object.class, named("H"));
     final Key<String> i = Key.get(String.class, named("I"));
 
-    Module singletonBindings = new AbstractModule() {
-      @Override protected void configure() {
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(Scopes.SINGLETON);
-        bind(d).toInstance("d");
-        bind(e).toProvider(Providers.of("e")).asEagerSingleton();
-        bind(f).toProvider(Providers.of("f")).in(Singleton.class);
-        bind(h).to(AnnotatedSingleton.class);
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(i).toProvider(Providers.of("i")).in(Singleton.class);
-            expose(i);
+    Module singletonBindings =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(Scopes.SINGLETON);
+            bind(d).toInstance("d");
+            bind(e).toProvider(Providers.of("e")).asEagerSingleton();
+            bind(f).toProvider(Providers.of("f")).in(Singleton.class);
+            bind(h).to(AnnotatedSingleton.class);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(i).toProvider(Providers.of("i")).in(Singleton.class);
+                    expose(i);
+                  }
+                });
           }
-        });
-      }
 
-      @Provides @Named("G") @Singleton String provideG() {
-        return "g";
-      }
-    };
+          @Provides
+          @Named("G")
+          @Singleton
+          String provideG() {
+            return "g";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(singletonBindings);
@@ -607,25 +684,32 @@
     final Key<String> e = Key.get(String.class, named("E"));
     final Key<String> f = Key.get(String.class, named("F"));
 
-    Module singletonBindings = new AbstractModule() {
-      @Override protected void configure() {
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
-        bind(d).toProvider(Providers.of("d")).in(CustomScoped.class);
-        bindScope(CustomScoped.class, Scopes.NO_SCOPE);
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(f).toProvider(Providers.of("f")).in(CustomScoped.class);
-            expose(f);
+    Module singletonBindings =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
+            bind(d).toProvider(Providers.of("d")).in(CustomScoped.class);
+            bindScope(CustomScoped.class, Scopes.NO_SCOPE);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(f).toProvider(Providers.of("f")).in(CustomScoped.class);
+                    expose(f);
+                  }
+                });
           }
-        });
-      }
 
-      @Provides @Named("E") @CustomScoped String provideE() {
-        return "e";
-      }
-    };
+          @Provides
+          @Named("E")
+          @CustomScoped
+          String provideE() {
+            return "e";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(singletonBindings);
@@ -655,26 +739,33 @@
     final Key<Object> f = Key.get(Object.class, named("F"));
     final Key<String> g = Key.get(String.class, named("G"));
 
-    Module customBindings = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(CustomScoped.class, CUSTOM_SCOPE);
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(CUSTOM_SCOPE);
-        bind(d).toProvider(Providers.of("d")).in(CustomScoped.class);
-        bind(f).to(AnnotatedCustomScoped.class);
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(g).toProvider(Providers.of("g")).in(CustomScoped.class);
-            expose(g);
+    Module customBindings =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(CustomScoped.class, CUSTOM_SCOPE);
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(CUSTOM_SCOPE);
+            bind(d).toProvider(Providers.of("d")).in(CustomScoped.class);
+            bind(f).to(AnnotatedCustomScoped.class);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(g).toProvider(Providers.of("g")).in(CustomScoped.class);
+                    expose(g);
+                  }
+                });
           }
-        });
-      }
 
-      @Provides @Named("E") @CustomScoped String provideE() {
-        return "e";
-      }
-    };
+          @Provides
+          @Named("E")
+          @CustomScoped
+          String provideE() {
+            return "e";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(customBindings);
@@ -707,27 +798,33 @@
     final Key<String> g = Key.get(String.class, named("G"));
     final Key<String> h = Key.get(String.class, named("H"));
 
-    Module customBindings = new AbstractModule() {
-      @Override protected void configure() {
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
-        bind(d).toProvider(Providers.of("d")).in(Singleton.class);
-        install(new PrivateModule() {
+    Module customBindings =
+        new AbstractModule() {
           @Override
           protected void configure() {
-            bind(f).toProvider(Providers.of("f")).in(Singleton.class);
-            expose(f);
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
+            bind(d).toProvider(Providers.of("d")).in(Singleton.class);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(f).toProvider(Providers.of("f")).in(Singleton.class);
+                    expose(f);
+                  }
+                });
+            bind(g).toInstance("g");
+            bind(h).toProvider(Providers.of("h")).asEagerSingleton();
           }
-        });
-        bind(g).toInstance("g");
-        bind(h).toProvider(Providers.of("h")).asEagerSingleton();
-      }
 
-      @Provides @Named("E") @Singleton String provideE() {
-        return "e";
-      }
-    };
+          @Provides
+          @Named("E")
+          @Singleton
+          String provideE() {
+            return "e";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(customBindings);
@@ -763,9 +860,9 @@
         Binding<?> binding = (Binding<?>) element;
         builder.put(binding.getKey(), binding);
       } else if (element instanceof PrivateElements) {
-        PrivateElements privateElements = (PrivateElements)element;
+        PrivateElements privateElements = (PrivateElements) element;
         Map<Key<?>, Binding<?>> privateBindings = indexBindings(privateElements.getElements());
-        for(Key<?> exposed : privateElements.getExposedKeys()) {
+        for (Key<?> exposed : privateElements.getExposedKeys()) {
           builder.put(exposed, privateBindings.get(exposed));
         }
       }
@@ -809,8 +906,7 @@
    */
   static class S {
 
-    private S(int preventInjectionWithoutProvider) {
-    }
+    private S(int preventInjectionWithoutProvider) {}
   }
 
   /**
@@ -823,14 +919,19 @@
     volatile boolean barrierPassed = false;
 
     SBarrierProvider(int nThreads) {
-      barrier = new CyclicBarrier(nThreads, new Runnable() {
-        public void run() {
-          // would finish before returning from await() for any thread
-          barrierPassed = true;
-        }
-      });
+      barrier =
+          new CyclicBarrier(
+              nThreads,
+              new Runnable() {
+                @Override
+                public void run() {
+                  // would finish before returning from await() for any thread
+                  barrierPassed = true;
+                }
+              });
     }
 
+    @Override
     public S get() {
       try {
         if (!barrierPassed) {
@@ -847,33 +948,41 @@
   /**
    * Tests that different injectors should not affect each other.
    *
-   * <p>This creates a second thread to work in parallel, to create two instances of
-   * {@link S} as the same time. If the lock if not granular enough (i.e. JVM-wide)
-   * then they would block each other creating a deadlock and await timeout.
+   * <p>This creates a second thread to work in parallel, to create two instances of {@link S} as
+   * the same time. If the lock if not granular enough (i.e. JVM-wide) then they would block each
+   * other creating a deadlock and await timeout.
    */
 
   public void testInjectorsDontDeadlockOnSingletons() throws Exception {
     final Provider<S> provider = new SBarrierProvider(2);
-    final Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        Thread.currentThread().setName("S.class[1]");
-        bind(S.class).toProvider(provider).in(Scopes.SINGLETON);
-      }
-    });
-    final Injector secondInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        Thread.currentThread().setName("S.class[2]");
-        bind(S.class).toProvider(provider).in(Scopes.SINGLETON);
-      }
-    });
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Thread.currentThread().setName("S.class[1]");
+                bind(S.class).toProvider(provider).in(Scopes.SINGLETON);
+              }
+            });
+    final Injector secondInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Thread.currentThread().setName("S.class[2]");
+                bind(S.class).toProvider(provider).in(Scopes.SINGLETON);
+              }
+            });
 
-    Future<S> secondThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<S>() {
-      public S call() {
-        return secondInjector.getInstance(S.class);
-      }
-    });
+    Future<S> secondThreadResult =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<S>() {
+                  @Override
+                  public S call() {
+                    return secondInjector.getInstance(S.class);
+                  }
+                });
 
     S firstS = injector.getInstance(S.class);
     S secondS = secondThreadResult.get();
@@ -882,18 +991,14 @@
   }
 
   @ImplementedBy(GImpl.class)
-  interface G {
-
-  }
+  interface G {}
 
   @Singleton
   static class GImpl implements G {
 
     final H h;
 
-    /**
-     * Relies on Guice implementation to inject S first and H later, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first and H later, which provides a barrier . */
     @Inject
     GImpl(S synchronizationBarrier, H h) {
       this.h = h;
@@ -901,18 +1006,14 @@
   }
 
   @ImplementedBy(HImpl.class)
-  interface H {
-
-  }
+  interface H {}
 
   @Singleton
   static class HImpl implements H {
 
     final G g;
 
-    /**
-     * Relies on Guice implementation to inject S first and G later, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first and G later, which provides a barrier . */
     @Inject
     HImpl(S synchronizationBarrier, G g) throws Exception {
       this.g = g;
@@ -922,35 +1023,45 @@
   /**
    * Tests that injector can create two singletons with circular dependency in parallel.
    *
-   * <p>This creates two threads to work in parallel, to create instances of
-   * {@link G} and {@link H}. Creation is synchronized by injection of {@link S},
-   * first thread would block until second would be inside a singleton creation as well.
+   * <p>This creates two threads to work in parallel, to create instances of {@link G} and {@link
+   * H}. Creation is synchronized by injection of {@link S}, first thread would block until second
+   * would be inside a singleton creation as well.
    *
-   * <p>Both instances are created by sibling injectors, that share singleton scope.
-   * Verifies that exactly one circular proxy object is created.
+   * <p>Both instances are created by sibling injectors, that share singleton scope. Verifies that
+   * exactly one circular proxy object is created.
    */
 
   public void testSiblingInjectorGettingCircularSingletonsOneCircularProxy() throws Exception {
     final Provider<S> provider = new SBarrierProvider(2);
-    final Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(S.class).toProvider(provider);
-      }
-    });
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(S.class).toProvider(provider);
+              }
+            });
 
-    Future<G> firstThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<G>() {
-      public G call() {
-        Thread.currentThread().setName("G.class");
-        return injector.createChildInjector().getInstance(G.class);
-      }
-    });
-    Future<H> secondThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<H>() {
-      public H call() {
-        Thread.currentThread().setName("H.class");
-        return injector.createChildInjector().getInstance(H.class);
-      }
-    });
+    Future<G> firstThreadResult =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<G>() {
+                  @Override
+                  public G call() {
+                    Thread.currentThread().setName("G.class");
+                    return injector.createChildInjector().getInstance(G.class);
+                  }
+                });
+    Future<H> secondThreadResult =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<H>() {
+                  @Override
+                  public H call() {
+                    Thread.currentThread().setName("H.class");
+                    return injector.createChildInjector().getInstance(H.class);
+                  }
+                });
 
     // using separate threads to avoid potential deadlock on the main thread
     // waiting twice as much to be sure that both would time out in their respective barriers
@@ -974,143 +1085,115 @@
   @Singleton
   static class I0 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    I0(I1 i) {
-    }
+    I0(I1 i) {}
   }
 
   @Singleton
   static class I1 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    I1(S synchronizationBarrier, I2 i) {
-    }
+    I1(S synchronizationBarrier, I2 i) {}
   }
 
   @Singleton
   static class I2 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    I2(J1 j) {
-    }
+    I2(J1 j) {}
   }
 
   @Singleton
   static class J0 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    J0(J1 j) {
-    }
+    J0(J1 j) {}
   }
 
   @Singleton
   static class J1 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    J1(S synchronizationBarrier, J2 j) {
-    }
+    J1(S synchronizationBarrier, J2 j) {}
   }
 
   @Singleton
   static class J2 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    J2(K1 k) {
-    }
+    J2(K1 k) {}
   }
 
   @Singleton
   static class K0 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    K0(K1 k) {
-    }
+    K0(K1 k) {}
   }
 
   @Singleton
   static class K1 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    K1(S synchronizationBarrier, K2 k) {
-    }
+    K1(S synchronizationBarrier, K2 k) {}
   }
 
   @Singleton
   static class K2 {
 
-    /**
-     * Relies on Guice implementation to inject S first, which provides a barrier .
-     */
+    /** Relies on Guice implementation to inject S first, which provides a barrier . */
     @Inject
-    K2(I1 i) {
-    }
+    K2(I1 i) {}
   }
 
   /**
    * Check that circular dependencies on non-interfaces are correctly resolved in multi-threaded
    * case. And that an error message constructed is a good one.
    *
-   * <p>I0 -> I1 -> I2 -> J1 and J0 -> J1 -> J2 -> K1 and K0 -> K1 -> K2,
-   * where I1, J1 and K1 are created in parallel.
+   * <p>I0 -> I1 -> I2 -> J1 and J0 -> J1 -> J2 -> K1 and K0 -> K1 -> K2, where I1, J1 and K1 are
+   * created in parallel.
    *
    * <p>Creation is synchronized by injection of {@link S}, first thread would block until second
    * would be inside a singleton creation as well.
    *
-   * <p>Verifies that provision results in an error, that spans two threads and
-   * has a dependency cycle.
+   * <p>Verifies that provision results in an error, that spans two threads and has a dependency
+   * cycle.
    */
 
   public void testUnresolvableSingletonCircularDependencyErrorMessage() throws Exception {
     final Provider<S> provider = new SBarrierProvider(3);
-    final Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(S.class).toProvider(provider);
-      }
-    });
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(S.class).toProvider(provider);
+              }
+            });
 
-    Future<I0> firstThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<I0>() {
-      public I0 call() {
-        Thread.currentThread().setName("I0.class");
-        return injector.getInstance(I0.class);
-      }
-    });
-    Future<J0> secondThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<J0>() {
-      public J0 call() {
-        Thread.currentThread().setName("J0.class");
-        return injector.getInstance(J0.class);
-      }
-    });
-    Future<K0> thirdThreadResult = Executors.newSingleThreadExecutor().submit(new Callable<K0>() {
-      public K0 call() {
-        Thread.currentThread().setName("K0.class");
-        return injector.getInstance(K0.class);
-      }
-    });
+    FutureTask<I0> firstThreadResult = new FutureTask<>(fetchClass(injector, I0.class));
+    Thread i0Thread = new Thread(firstThreadResult, "I0.class");
+    // we need to call toString() now, because the toString() changes after the thread exits.
+    String i0ThreadString = i0Thread.toString();
+    i0Thread.start();
+
+    FutureTask<J0> secondThreadResult = new FutureTask<>(fetchClass(injector, J0.class));
+    Thread j0Thread = new Thread(secondThreadResult, "J0.class");
+    String j0ThreadString = j0Thread.toString();
+    j0Thread.start();
+
+    FutureTask<K0> thirdThreadResult = new FutureTask<>(fetchClass(injector, K0.class));
+    Thread k0Thread = new Thread(thirdThreadResult, "K0.class");
+    String k0ThreadString = k0Thread.toString();
+    k0Thread.start();
 
     // using separate threads to avoid potential deadlock on the main thread
     // waiting twice as much to be sure that both would time out in their respective barriers
@@ -1137,56 +1220,160 @@
     }
 
     // verification of error messages generated
-    assertEquals(firstException.getClass(), ProvisionException.class);
-    assertEquals(secondException.getClass(), ProvisionException.class);
-    assertEquals(thirdException.getClass(), ProvisionException.class);
-    List<String> errorMessages = Lists.newArrayList(
-        String.format("%s\n%s\n%s",
-            firstException.getMessage(), secondException.getMessage(), thirdException.getMessage())
-            .split("\\n\\n"));
-    Collections.sort(errorMessages, new Comparator<String>() {
-      @Override
-      public int compare(String s1, String s2) {
-        return s2.length() - s1.length();
-      }
-    });
-    // this is brittle, but turns out that second to longest message spans all threads
-    String errorMessage = errorMessages.get(1);
-    assertContains(errorMessage,
-        "Encountered circular dependency spanning several threads. Tried proxying "
-            + this.getClass().getName());
-    assertFalse("Both I0 and J0 can not be a part of a dependency cycle",
-        errorMessage.contains(I0.class.getName()) && errorMessage.contains(J0.class.getName()));
-    assertFalse("Both J0 and K0 can not be a part of a dependency cycle",
-        errorMessage.contains(J0.class.getName()) && errorMessage.contains(K0.class.getName()));
-    assertFalse("Both K0 and I0 can not be a part of a dependency cycle",
-        errorMessage.contains(K0.class.getName()) && errorMessage.contains(I0.class.getName()));
-
-    List<String> firstErrorLineForThread = new ArrayList<String>();
-    boolean addNextLine = false;
-    for (String errorLine : errorMessage.split("\\n")) {
-      if (errorLine.contains("in thread")) {
-        addNextLine = true;
-        firstErrorLineForThread.add(errorLine);
-      } else if (addNextLine) {
-        addNextLine = false;
-        firstErrorLineForThread.add(errorLine);
+    List<Message> errors = new ArrayList<>();
+    errors.addAll(((ProvisionException) firstException).getErrorMessages());
+    errors.addAll(((ProvisionException) secondException).getErrorMessages());
+    errors.addAll(((ProvisionException) thirdException).getErrorMessages());
+    // We want to find the longest error reported for a cycle spanning multiple threads
+    Message spanningError = null;
+    for (Message error : errors) {
+      if (error.getMessage().contains("Encountered circular dependency spanning several threads")) {
+        if (spanningError == null
+            || spanningError.getMessage().length() < error.getMessage().length()) {
+          spanningError = error;
+        }
       }
     }
-    assertEquals("we expect to see [T1, $A, T2, $B, T3, $C, T1, $A]",
-        8, firstErrorLineForThread.size());
-    assertEquals("first four elements should be different",
-        6, new HashSet<String>(firstErrorLineForThread.subList(0, 6)).size());
-    assertEquals(firstErrorLineForThread.get(6), firstErrorLineForThread.get(0));
-    assertEquals(firstErrorLineForThread.get(7), firstErrorLineForThread.get(1));
-    assertFalse("K0 thread could not be blocked by J0",
-        firstErrorLineForThread.get(0).contains("J0")
-            && firstErrorLineForThread.get(2).contains("K0"));
-    assertFalse("J0 thread could not be blocked by I0",
-        firstErrorLineForThread.get(0).contains("I0")
-            && firstErrorLineForThread.get(2).contains("J0"));
-    assertFalse("I0 thread could not be blocked by K0",
-        firstErrorLineForThread.get(0).contains("K0")
-            && firstErrorLineForThread.get(2).contains("I0"));
+    if (spanningError == null) {
+      fail(
+          "Couldn't find multi thread circular dependency error: "
+              + Joiner.on("\n\n").join(errors));
+    }
+
+    String errorMessage = spanningError.getMessage();
+    assertContains(
+        errorMessage,
+        "Encountered circular dependency spanning several threads. Tried proxying "
+            + this.getClass().getName());
+    assertFalse(
+        "Both I0 and J0 can not be a part of a dependency cycle",
+        errorMessage.contains(I0.class.getName()) && errorMessage.contains(J0.class.getName()));
+    assertFalse(
+        "Both J0 and K0 can not be a part of a dependency cycle",
+        errorMessage.contains(J0.class.getName()) && errorMessage.contains(K0.class.getName()));
+    assertFalse(
+        "Both K0 and I0 can not be a part of a dependency cycle",
+        errorMessage.contains(K0.class.getName()) && errorMessage.contains(I0.class.getName()));
+
+    ListMultimap<String, String> threadToSingletons = ArrayListMultimap.create();
+    boolean inSingletonsList = false;
+    String currentThread = null;
+    for (String errorLine : errorMessage.split("\\n")) {
+      if (errorLine.startsWith("Thread[")) {
+        inSingletonsList = true;
+        currentThread =
+            errorLine.substring(
+                0, errorLine.indexOf(" is holding locks the following singletons in the cycle:"));
+      } else if (inSingletonsList) {
+        if (errorLine.startsWith("\tat ")) {
+          inSingletonsList = false;
+        } else {
+          threadToSingletons.put(currentThread, errorLine);
+        }
+      }
+    }
+
+    assertEquals("All threads should be in the cycle", 3, threadToSingletons.keySet().size());
+
+    // NOTE:  J0,K0,I0 are not reported because their locks are not part of the cycle.
+    assertEquals(
+        threadToSingletons.get(j0ThreadString),
+        ImmutableList.of(J1.class.getName(), J2.class.getName(), K1.class.getName()));
+    assertEquals(
+        threadToSingletons.get(k0ThreadString),
+        ImmutableList.of(K1.class.getName(), K2.class.getName(), I1.class.getName()));
+    assertEquals(
+        threadToSingletons.get(i0ThreadString),
+        ImmutableList.of(I1.class.getName(), I2.class.getName(), J1.class.getName()));
+  }
+
+  private static <T> Callable<T> fetchClass(final Injector injector, final Class<T> clazz) {
+    return new Callable<T>() {
+      @Override
+      public T call() {
+        return injector.getInstance(clazz);
+      }
+    };
+  }
+
+  // Test for https://github.com/google/guice/issues/1032
+
+  public void testScopeAppliedByUserInsteadOfScoping() throws Exception {
+    Injector injector =
+        java.util.concurrent.Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Injector>() {
+                  @Override
+                  public Injector call() {
+                    return Guice.createInjector(
+                        new AbstractModule() {
+                          @Override
+                          protected void configure() {
+                            bindListener(Matchers.any(), new ScopeMutatingProvisionListener());
+                            bind(SingletonClass.class);
+                          }
+                        });
+                  }
+                })
+            .get();
+    injector.getInstance(SingletonClass.class); // will fail here with NPE
+  }
+
+  @Singleton
+  static class SingletonClass {}
+
+  /** Uses Scope's public API to add a 'marker' into the provisioned instance's scope. */
+  private static final class ScopeMutatingProvisionListener implements ProvisionListener {
+    private static class ScopeMarker {
+      static final Provider<ScopeMarker> PROVIDER =
+          new Provider<ScopeMarker>() {
+            @Override
+            public ScopeMarker get() {
+              return new ScopeMarker();
+            }
+          };
+    }
+
+    @Override
+    public <T> void onProvision(final ProvisionInvocation<T> provisionInvocation) {
+      provisionInvocation.provision();
+      provisionInvocation
+          .getBinding()
+          .acceptScopingVisitor(
+              new DefaultBindingScopingVisitor<Void>() {
+                @Override
+                public Void visitScope(Scope scope) {
+                  scope.scope(Key.get(ScopeMarker.class), ScopeMarker.PROVIDER);
+                  return null;
+                }
+              });
+    }
+  }
+
+  public void testForInstanceOfNoScopingReturnsUnscoped() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(AImpl.class).in(Scopes.NO_SCOPE);
+              }
+            });
+
+    assertTrue(
+        injector
+            .getBinding(Key.get(AImpl.class))
+            .acceptScopingVisitor(
+                new DefaultBindingScopingVisitor<Boolean>() {
+                  @Override
+                  protected Boolean visitOther() {
+                    return false;
+                  }
+
+                  @Override
+                  public Boolean visitNoScoping() {
+                    return true;
+                  }
+                }));
   }
 }
diff --git a/core/test/com/google/inject/SerializationTest.java b/core/test/com/google/inject/SerializationTest.java
index df353f6..6e2c0b7 100644
--- a/core/test/com/google/inject/SerializationTest.java
+++ b/core/test/com/google/inject/SerializationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,28 +14,24 @@
  * limitations under the License.
  */
 
-
 package com.google.inject;
 
 import static com.google.inject.Asserts.assertSimilarWhenReserialized;
 
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.List;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class SerializationTest extends TestCase {
 
   public void testAbstractModuleIsSerializable() throws IOException {
     Asserts.reserialize(new MyAbstractModule());
   }
+
   static class MyAbstractModule extends AbstractModule implements Serializable {
-    protected void configure() {}
   }
 
   public void testCreationExceptionIsSerializable() throws IOException {
@@ -44,11 +40,13 @@
 
   private CreationException createCreationException() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(List.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(List.class);
+            }
+          });
       throw new AssertionFailedError();
     } catch (CreationException e) {
       return e;
diff --git a/core/test/com/google/inject/SuiteUtils.java b/core/test/com/google/inject/SuiteUtils.java
index cd9eb10..7af0059 100644
--- a/core/test/com/google/inject/SuiteUtils.java
+++ b/core/test/com/google/inject/SuiteUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,32 +16,30 @@
 
 package com.google.inject;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import java.util.Enumeration;
 import java.util.Set;
+import junit.framework.Test;
+import junit.framework.TestSuite;
 
 public class SuiteUtils {
 
   public static TestSuite removeSuppressedTests(TestSuite suite, Set<String> suppressedTestNames) {
     TestSuite result = new TestSuite(suite.getName());
-  
-    for(Enumeration e = suite.tests(); e.hasMoreElements(); ) {
+
+    for (Enumeration e = suite.tests(); e.hasMoreElements(); ) {
       Test test = (Test) e.nextElement();
-  
+
       if (suppressedTestNames.contains(test.toString())) {
         continue;
       }
-  
+
       if (test instanceof TestSuite) {
         result.addTest(removeSuppressedTests((TestSuite) test, suppressedTestNames));
       } else {
         result.addTest(test);
       }
     }
-  
+
     return result;
   }
-
 }
diff --git a/core/test/com/google/inject/SuperclassTest.java b/core/test/com/google/inject/SuperclassTest.java
index 3dda585..c3ee055 100644
--- a/core/test/com/google/inject/SuperclassTest.java
+++ b/core/test/com/google/inject/SuperclassTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,17 +18,18 @@
 
 import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class SuperclassTest extends TestCase {
 
   public void testSuperclassInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Foo.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class);
+              }
+            });
 
     Provider<Sub> creator = injector.getProvider(Sub.class);
     Sub sub = creator.get();
@@ -40,17 +41,18 @@
     assertNotNull(sub.fromMethod);
   }
 
-  static abstract class Super {
+  abstract static class Super {
     @Inject Foo field;
 
     Foo fromMethod;
-    @Inject void setC(Foo foo) {
+
+    @Inject
+    void setC(Foo foo) {
       fromMethod = foo;
     }
   }
 
-  static class Sub extends Super {
-  }
+  static class Sub extends Super {}
 
   static class Foo {}
 }
diff --git a/core/test/com/google/inject/TypeConversionTest.java b/core/test/com/google/inject/TypeConversionTest.java
index e318477..546b4d8 100644
--- a/core/test/com/google/inject/TypeConversionTest.java
+++ b/core/test/com/google/inject/TypeConversionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,29 +26,29 @@
 import com.google.inject.spi.ConvertedConstantBinding;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.TypeConverterBinding;
-
+import java.lang.annotation.Retention;
+import java.util.Date;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import java.lang.annotation.Retention;
-import java.util.Date;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class TypeConversionTest extends TestCase {
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface NumericValue {}
+  @BindingAnnotation
+  @interface NumericValue {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface BooleanValue {}
+  @BindingAnnotation
+  @interface BooleanValue {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface EnumValue {}
+  @BindingAnnotation
+  @interface EnumValue {}
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface ClassName {}
+  @BindingAnnotation
+  @interface ClassName {}
 
   public static class Foo {
     @Inject @BooleanValue Boolean booleanField;
@@ -70,16 +70,21 @@
   }
 
   public enum Bar {
-    TEE, BAZ, BOB
+    TEE,
+    BAZ,
+    BOB
   }
 
   public void testOneConstantInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(NumericValue.class).to("5");
-        bind(Simple.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(NumericValue.class).to("5");
+                bind(Simple.class);
+              }
+            });
 
     Simple simple = injector.getInstance(Simple.class);
     assertEquals(5, simple.i);
@@ -90,64 +95,68 @@
   }
 
   public void testConstantInjection() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(NumericValue.class).to("5");
-        bindConstant().annotatedWith(BooleanValue.class).to("true");
-        bindConstant().annotatedWith(EnumValue.class).to("TEE");
-        bindConstant().annotatedWith(ClassName.class).to(Foo.class.getName());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(NumericValue.class).to("5");
+                bindConstant().annotatedWith(BooleanValue.class).to("true");
+                bindConstant().annotatedWith(EnumValue.class).to("TEE");
+                bindConstant().annotatedWith(ClassName.class).to(Foo.class.getName());
+              }
+            });
 
     Foo foo = injector.getInstance(Foo.class);
 
     checkNumbers(
-      foo.integerField,
-      foo.primitiveIntField,
-      foo.longField,
-      foo.primitiveLongField,
-      foo.byteField,
-      foo.primitiveByteField,
-      foo.shortField,
-      foo.primitiveShortField,
-      foo.floatField,
-      foo.primitiveFloatField,
-      foo.doubleField,
-      foo.primitiveDoubleField
-    );
+        foo.integerField,
+        foo.primitiveIntField,
+        foo.longField,
+        foo.primitiveLongField,
+        foo.byteField,
+        foo.primitiveByteField,
+        foo.shortField,
+        foo.primitiveShortField,
+        foo.floatField,
+        foo.primitiveFloatField,
+        foo.doubleField,
+        foo.primitiveDoubleField);
 
     assertEquals(Bar.TEE, foo.enumField);
     assertEquals(Foo.class, foo.classField);
   }
 
   public void testConstantInjectionWithExplicitBindingsRequired() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        binder().requireExplicitBindings();
-        bind(Foo.class);
-        bindConstant().annotatedWith(NumericValue.class).to("5");
-        bindConstant().annotatedWith(BooleanValue.class).to("true");
-        bindConstant().annotatedWith(EnumValue.class).to("TEE");
-        bindConstant().annotatedWith(ClassName.class).to(Foo.class.getName());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+                bind(Foo.class);
+                bindConstant().annotatedWith(NumericValue.class).to("5");
+                bindConstant().annotatedWith(BooleanValue.class).to("true");
+                bindConstant().annotatedWith(EnumValue.class).to("TEE");
+                bindConstant().annotatedWith(ClassName.class).to(Foo.class.getName());
+              }
+            });
 
     Foo foo = injector.getInstance(Foo.class);
 
     checkNumbers(
-      foo.integerField,
-      foo.primitiveIntField,
-      foo.longField,
-      foo.primitiveLongField,
-      foo.byteField,
-      foo.primitiveByteField,
-      foo.shortField,
-      foo.primitiveShortField,
-      foo.floatField,
-      foo.primitiveFloatField,
-      foo.doubleField,
-      foo.primitiveDoubleField
-    );
+        foo.integerField,
+        foo.primitiveIntField,
+        foo.longField,
+        foo.primitiveLongField,
+        foo.byteField,
+        foo.primitiveByteField,
+        foo.shortField,
+        foo.primitiveShortField,
+        foo.floatField,
+        foo.primitiveFloatField,
+        foo.doubleField,
+        foo.primitiveDoubleField);
 
     assertEquals(Bar.TEE, foo.enumField);
     assertEquals(Foo.class, foo.classField);
@@ -160,13 +169,15 @@
   }
 
   static class OuterErrorModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerErrorModule());
     }
   }
 
   static class InnerErrorModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindConstant().annotatedWith(NumericValue.class).to("invalid");
     }
   }
@@ -177,8 +188,10 @@
       injector.getInstance(InvalidInteger.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
-          "Error converting 'invalid' (bound at " + InnerErrorModule.class.getName()
+      assertContains(
+          expected.getMessage(),
+          "Error converting 'invalid' (bound at "
+              + InnerErrorModule.class.getName()
               + getDeclaringSourcePart(getClass()),
           asModuleChain(OuterErrorModule.class, InnerErrorModule.class),
           "using TypeConverter<Integer> which matches identicalTo(class java.lang.Integer)"
@@ -192,11 +205,14 @@
   }
 
   public void testInvalidCharacter() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(NumericValue.class).to("invalid");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(NumericValue.class).to("invalid");
+              }
+            });
 
     try {
       injector.getInstance(InvalidCharacter.class);
@@ -213,11 +229,14 @@
   }
 
   public void testInvalidEnum() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(NumericValue.class).to("invalid");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(NumericValue.class).to("invalid");
+              }
+            });
 
     try {
       injector.getInstance(InvalidEnum.class);
@@ -234,12 +253,15 @@
   }
 
   public void testToInstanceIsTreatedLikeConstant() throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("5");
-        bind(LongHolder.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("5");
+                bind(LongHolder.class);
+              }
+            });
 
     assertEquals(5L, (long) injector.getInstance(LongHolder.class).foo);
   }
@@ -251,27 +273,33 @@
   public void testCustomTypeConversion() throws CreationException {
     final Date result = new Date();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        convertToTypes(Matchers.only(TypeLiteral.get(Date.class)) , mockTypeConverter(result));
-        bindConstant().annotatedWith(NumericValue.class).to("Today");
-        bind(DateHolder.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                convertToTypes(
+                    Matchers.only(TypeLiteral.get(Date.class)), mockTypeConverter(result));
+                bindConstant().annotatedWith(NumericValue.class).to("Today");
+                bind(DateHolder.class);
+              }
+            });
 
     assertSame(result, injector.getInstance(DateHolder.class).date);
 
     Binding<Date> binding = injector.getBinding(Key.get(Date.class, NumericValue.class));
     assertTrue(binding instanceof ConvertedConstantBinding<?>);
 
-    TypeConverterBinding converterBinding = ((ConvertedConstantBinding<?>)binding).getTypeConverterBinding();
+    TypeConverterBinding converterBinding =
+        ((ConvertedConstantBinding<?>) binding).getTypeConverterBinding();
     assertEquals("CustomConverter", converterBinding.getTypeConverter().toString());
 
     assertTrue(injector.getTypeConverterBindings().contains(converterBinding));
   }
 
   static class InvalidCustomValueModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), failingTypeConverter());
       bindConstant().annotatedWith(NumericValue.class).to("invalid");
       bind(DateHolder.class);
@@ -286,11 +314,15 @@
     } catch (CreationException expected) {
       Throwable cause = Iterables.getOnlyElement(expected.getErrorMessages()).getCause();
       assertTrue(cause instanceof UnsupportedOperationException);
-      assertContains(expected.getMessage(),
-          "1) Error converting 'invalid' (bound at ", getClass().getName(),
-          getDeclaringSourcePart(getClass()), "to java.util.Date",
+      assertContains(
+          expected.getMessage(),
+          "1) Error converting 'invalid' (bound at ",
+          getClass().getName(),
+          getDeclaringSourcePart(getClass()),
+          "to java.util.Date",
           "using BrokenConverter which matches only(java.util.Date) ",
-          "(bound at " + getClass().getName(), getDeclaringSourcePart(getClass()),
+          "(bound at " + getClass().getName(),
+          getDeclaringSourcePart(getClass()),
           "Reason: java.lang.UnsupportedOperationException: Cannot convert",
           "at " + DateHolder.class.getName() + ".date(TypeConversionTest.java:");
     }
@@ -298,22 +330,26 @@
 
   static class OuterModule extends AbstractModule {
     private final Module converterModule;
+
     OuterModule(Module converterModule) {
       this.converterModule = converterModule;
     }
 
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerModule(converterModule));
     }
   }
 
   static class InnerModule extends AbstractModule {
     private final Module converterModule;
+
     InnerModule(Module converterModule) {
       this.converterModule = converterModule;
     }
 
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(converterModule);
       bindConstant().annotatedWith(NumericValue.class).to("foo");
       bind(DateHolder.class);
@@ -321,7 +357,8 @@
   }
 
   class ConverterNullModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), mockTypeConverter(null));
     }
   }
@@ -331,7 +368,8 @@
       Guice.createInjector(new OuterModule(new ConverterNullModule()));
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Received null converting 'foo' (bound at ",
           getClass().getName(),
           getDeclaringSourcePart(getClass()),
@@ -347,7 +385,8 @@
   }
 
   class ConverterCustomModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), mockTypeConverter(-1));
     }
   }
@@ -357,7 +396,8 @@
       Guice.createInjector(new OuterModule(new ConverterCustomModule()));
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Type mismatch converting 'foo' (bound at ",
           getClass().getName(),
           getDeclaringSourcePart(getClass()),
@@ -374,23 +414,29 @@
   }
 
   public void testStringIsConvertedOnlyOnce() {
-    final TypeConverter converter = new TypeConverter() {
-      boolean converted = false;
-      public Object convert(String value, TypeLiteral<?> toType) {
-        if (converted) {
-          throw new AssertionFailedError("converted multiple times!");
-        }
-        converted = true;
-        return new Date();
-      }
-    };
+    final TypeConverter converter =
+        new TypeConverter() {
+          boolean converted = false;
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), converter);
-        bindConstant().annotatedWith(NumericValue.class).to("unused");
-      }
-    });
+          @Override
+          public Object convert(String value, TypeLiteral<?> toType) {
+            if (converted) {
+              throw new AssertionFailedError("converted multiple times!");
+            }
+            converted = true;
+            return new Date();
+          }
+        };
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), converter);
+                bindConstant().annotatedWith(NumericValue.class).to("unused");
+              }
+            });
 
     Date first = injector.getInstance(Key.get(Date.class, NumericValue.class));
     Date second = injector.getInstance(Key.get(Date.class, NumericValue.class));
@@ -398,13 +444,15 @@
   }
 
   class OuterAmbiguousModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerAmbiguousModule());
     }
   }
 
   class InnerAmbiguousModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new Ambiguous1Module());
       install(new Ambiguous2Module());
       bindConstant().annotatedWith(NumericValue.class).to("foo");
@@ -413,13 +461,15 @@
   }
 
   class Ambiguous1Module extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), mockTypeConverter(new Date()));
     }
   }
 
   class Ambiguous2Module extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), mockTypeConverter(new Date()));
     }
   }
@@ -429,8 +479,10 @@
       Guice.createInjector(new OuterAmbiguousModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "1) Multiple converters can convert 'foo' (bound at ", getClass().getName(),
+      assertContains(
+          expected.getMessage(),
+          "1) Multiple converters can convert 'foo' (bound at ",
+          getClass().getName(),
           getDeclaringSourcePart(getClass()),
           asModuleChain(OuterAmbiguousModule.class, InnerAmbiguousModule.class),
           "to java.util.Date:",
@@ -452,11 +504,13 @@
 
   TypeConverter mockTypeConverter(final Object result) {
     return new TypeConverter() {
+      @Override
       public Object convert(String value, TypeLiteral<?> toType) {
         return result;
       }
 
-      @Override public String toString() {
+      @Override
+      public String toString() {
         return "CustomConverter";
       }
     };
@@ -464,10 +518,13 @@
 
   private static TypeConverter failingTypeConverter() {
     return new TypeConverter() {
+      @Override
       public Object convert(String value, TypeLiteral<?> toType) {
         throw new UnsupportedOperationException("Cannot convert");
       }
-      @Override public String toString() {
+
+      @Override
+      public String toString() {
         return "BrokenConverter";
       }
     };
@@ -478,18 +535,21 @@
   }
 
   public void testCannotConvertUnannotatedBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("55");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("55");
+              }
+            });
 
     try {
       injector.getInstance(Integer.class);
       fail("Converted an unannotated String to an Integer");
     } catch (ConfigurationException expected) {
-      Asserts.assertContains(expected.getMessage(),
-          "Could not find a suitable constructor in java.lang.Integer.");
+      Asserts.assertContains(
+          expected.getMessage(), "Could not find a suitable constructor in java.lang.Integer.");
     }
   }
 }
diff --git a/core/test/com/google/inject/TypeListenerTest.java b/core/test/com/google/inject/TypeListenerTest.java
index ba7520d..9131f56 100644
--- a/core/test/com/google/inject/TypeListenerTest.java
+++ b/core/test/com/google/inject/TypeListenerTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,97 +31,115 @@
 import com.google.inject.spi.Message;
 import com.google.inject.spi.TypeEncounter;
 import com.google.inject.spi.TypeListener;
-
-import junit.framework.TestCase;
-
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class TypeListenerTest extends TestCase {
 
-  private final Matcher<Object> onlyAbcd = Matchers.only(new TypeLiteral<A>() {})
-      .or(only(new TypeLiteral<B>() {}))
-      .or(only(new TypeLiteral<C>() {}))
-      .or(only(new TypeLiteral<D>() {}));
+  private final Matcher<Object> onlyAbcd =
+      Matchers.only(new TypeLiteral<A>() {})
+          .or(only(new TypeLiteral<B>() {}))
+          .or(only(new TypeLiteral<C>() {}))
+          .or(only(new TypeLiteral<D>() {}));
 
-  final TypeListener failingTypeListener = new TypeListener() {
-    int failures = 0;
+  final TypeListener failingTypeListener =
+      new TypeListener() {
+        int failures = 0;
 
-    public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-      throw new ClassCastException("whoops, failure #" + (++failures));
-    }
+        @Override
+        public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+          throw new ClassCastException("whoops, failure #" + (++failures));
+        }
 
-    @Override public String toString() {
-      return "clumsy";
-    }
-  };
+        @Override
+        public String toString() {
+          return "clumsy";
+        }
+      };
 
-  final InjectionListener<Object> failingInjectionListener = new InjectionListener<Object>() {
-    int failures = 0;
+  final InjectionListener<Object> failingInjectionListener =
+      new InjectionListener<Object>() {
+        int failures = 0;
 
-    public void afterInjection(Object injectee) {
-      throw new ClassCastException("whoops, failure #" + (++failures));
-    }
+        @Override
+        public void afterInjection(Object injectee) {
+          throw new ClassCastException("whoops, failure #" + (++failures));
+        }
 
-    @Override public String toString() {
-      return "goofy";
-    }
-  };
+        @Override
+        public String toString() {
+          return "goofy";
+        }
+      };
 
-  final MembersInjector<Object> failingMembersInjector = new MembersInjector<Object>() {
-    int failures = 0;
+  final MembersInjector<Object> failingMembersInjector =
+      new MembersInjector<Object>() {
+        int failures = 0;
 
-    public void injectMembers(Object instance) {
-      throw new ClassCastException("whoops, failure #" + (++failures));
-    }
+        @Override
+        public void injectMembers(Object instance) {
+          throw new ClassCastException("whoops, failure #" + (++failures));
+        }
 
-    @Override public String toString() {
-      return "awkward";
-    }
-  };
+        @Override
+        public String toString() {
+          return "awkward";
+        }
+      };
 
   public void testTypeListenersAreFired() {
     final AtomicInteger firedCount = new AtomicInteger();
 
-    final TypeListener typeListener = new TypeListener() {
-      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-        assertEquals(new TypeLiteral<A>() {}, type);
-        firedCount.incrementAndGet();
-      }
-    };
+    final TypeListener typeListener =
+        new TypeListener() {
+          @Override
+          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+            assertEquals(new TypeLiteral<A>() {}, type);
+            firedCount.incrementAndGet();
+          }
+        };
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, typeListener);
-        bind(A.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindListener(onlyAbcd, typeListener);
+            bind(A.class);
+          }
+        });
 
     assertEquals(1, firedCount.get());
   }
 
   public void testInstallingInjectionListener() {
     final List<Object> injectees = Lists.newArrayList();
-    final InjectionListener<Object> injectionListener = new InjectionListener<Object>() {
-      public void afterInjection(Object injectee) {
-        injectees.add(injectee);
-      }
-    };
-
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounter.register(injectionListener);
+    final InjectionListener<Object> injectionListener =
+        new InjectionListener<Object>() {
+          @Override
+          public void afterInjection(Object injectee) {
+            injectees.add(injectee);
           }
-        });
-        bind(A.class);
-      }
-    });
+        };
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        encounter.register(injectionListener);
+                      }
+                    });
+                bind(A.class);
+              }
+            });
 
     assertEquals(ImmutableList.of(), injectees);
 
@@ -140,11 +158,12 @@
     A a4 = aProvider.get();
     assertEquals(ImmutableList.of(a1, a2, b1, a3, a4), injectees);
   }
-  
+
   /*if[AOP]*/
   private static org.aopalliance.intercept.MethodInterceptor prefixInterceptor(
       final String prefix) {
     return new org.aopalliance.intercept.MethodInterceptor() {
+      @Override
       public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation)
           throws Throwable {
         return prefix + methodInvocation.proceed();
@@ -155,19 +174,25 @@
   public void testAddingInterceptors() throws NoSuchMethodException {
     final Matcher<Object> buzz = only(C.class.getMethod("buzz"));
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindInterceptor(any(), buzz, prefixInterceptor("ka"));
-        bindInterceptor(any(), any(), prefixInterceptor("fe"));
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(any(), buzz, prefixInterceptor("ka"));
+                bindInterceptor(any(), any(), prefixInterceptor("fe"));
 
-        bindListener(onlyAbcd, new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounter.bindInterceptor(any(), prefixInterceptor("li"));
-            encounter.bindInterceptor(buzz, prefixInterceptor("no"));
-          }
-        });
-      }
-    });
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        encounter.bindInterceptor(any(), prefixInterceptor("li"));
+                        encounter.bindInterceptor(buzz, prefixInterceptor("no"));
+                      }
+                    });
+              }
+            });
 
     // interceptors must be invoked in the order they're bound.
     C c = injector.getInstance(C.class);
@@ -177,27 +202,32 @@
   /*end[AOP]*/
 
   class OuterThrowsModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerThrowsModule());
     }
   }
+
   class InnerThrowsModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bindListener(onlyAbcd, failingTypeListener);
       bind(B.class);
       bind(C.class);
     }
   }
+
   public void testTypeListenerThrows() {
     try {
       Guice.createInjector(new OuterThrowsModule());
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
           getDeclaringSourcePart(getClass()),
           asModuleChain(OuterThrowsModule.class, InnerThrowsModule.class),
-          "of " + B.class.getName(), 
+          "of " + B.class.getName(),
           "Reason: java.lang.ClassCastException: whoops, failure #1",
           "2) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
           getDeclaringSourcePart(getClass()),
@@ -205,17 +235,21 @@
           "of " + C.class.getName(),
           "Reason: java.lang.ClassCastException: whoops, failure #2");
     }
-    
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, failingTypeListener);
-      }
-    });
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(onlyAbcd, failingTypeListener);
+              }
+            });
     try {
       injector.getProvider(B.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
           getDeclaringSourcePart(getClass()),
           "of " + B.class.getName(),
@@ -227,7 +261,8 @@
       injector.getInstance(B.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
           getDeclaringSourcePart(getClass()),
           "of " + B.class.getName(),
@@ -239,22 +274,29 @@
   }
 
   public void testInjectionListenerThrows() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounter.register(failingInjectionListener);
-          }
-        });
-        bind(B.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        encounter.register(failingInjectionListener);
+                      }
+                    });
+                bind(B.class);
+              }
+            });
 
     try {
       injector.getInstance(A.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error notifying InjectionListener goofy of " + A.class.getName(),
           " Reason: java.lang.ClassCastException: whoops, failure #1");
     }
@@ -264,7 +306,8 @@
       injector.getInstance(A.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error notifying InjectionListener goofy of " + A.class.getName(),
           " Reason: java.lang.ClassCastException: whoops, failure #2");
     }
@@ -275,7 +318,8 @@
       bProvider.get();
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error notifying InjectionListener goofy of " + B.class.getName(),
           " Reason: java.lang.ClassCastException: whoops, failure #3");
     }
@@ -286,17 +330,21 @@
 
   public void testInjectMembersTypeListenerFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          getMembersInjector(A.class);
-          bindListener(onlyAbcd, failingTypeListener);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              getMembersInjector(A.class);
+              bindListener(onlyAbcd, failingTypeListener);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Error notifying TypeListener clumsy (bound at ",
-          TypeListenerTest.class.getName(), getDeclaringSourcePart(getClass()),
+          TypeListenerTest.class.getName(),
+          getDeclaringSourcePart(getClass()),
           "of " + A.class.getName(),
           " Reason: java.lang.ClassCastException: whoops, failure #1");
     }
@@ -306,27 +354,35 @@
     final AtomicInteger typeEncounters = new AtomicInteger();
     final AtomicInteger injections = new AtomicInteger();
 
-    final InjectionListener<A> listener = new InjectionListener<A>() {
-      public void afterInjection(A injectee) {
-        injections.incrementAndGet();
-        assertNotNull(injectee.injector);
-      }
-    };
-
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          @SuppressWarnings("unchecked")
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            typeEncounters.incrementAndGet();
-            encounter.register((InjectionListener) listener);
+    final InjectionListener<A> listener =
+        new InjectionListener<A>() {
+          @Override
+          public void afterInjection(A injectee) {
+            injections.incrementAndGet();
+            assertNotNull(injectee.injector);
           }
-        });
+        };
 
-        bind(A.class);
-        getMembersInjector(A.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      @SuppressWarnings("unchecked")
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        typeEncounters.incrementAndGet();
+                        encounter.register((InjectionListener) listener);
+                      }
+                    });
+
+                bind(A.class);
+                getMembersInjector(A.class);
+              }
+            });
 
     // creating the injector shouldn't trigger injections
     assertEquals(0, injections.getAndSet(0));
@@ -359,107 +415,130 @@
   }
 
   public void testLookupsAtInjectorCreateTime() {
-    final AtomicReference<Provider<B>> bProviderReference = new AtomicReference<Provider<B>>();
-    final AtomicReference<MembersInjector<A>> aMembersInjectorReference
-        = new AtomicReference<MembersInjector<A>>();
+    final AtomicReference<Provider<B>> bProviderReference = new AtomicReference<>();
+    final AtomicReference<MembersInjector<A>> aMembersInjectorReference = new AtomicReference<>();
 
-    final InjectionListener<Object> lookupsTester = new InjectionListener<Object>() {
-      public void afterInjection(Object injectee) {
-        assertNotNull(bProviderReference.get().get());
+    final InjectionListener<Object> lookupsTester =
+        new InjectionListener<Object>() {
+          @Override
+          public void afterInjection(Object injectee) {
+            assertNotNull(bProviderReference.get().get());
 
-        A a = new A();
-        aMembersInjectorReference.get().injectMembers(a);
-        assertNotNull(a.injector);
-      }
-    };
+            A a = new A();
+            aMembersInjectorReference.get().injectMembers(a);
+            assertNotNull(a.injector);
+          }
+        };
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(only(TypeLiteral.get(C.class)), new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            Provider<B> bProvider = encounter.getProvider(B.class);
-            try {
-              bProvider.get();
-              fail();
-            } catch (IllegalStateException expected) {
-              assertEquals("This Provider cannot be used until the Injector has been created.",
-                  expected.getMessage());
-            }
-            bProviderReference.set(bProvider);
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindListener(
+                only(TypeLiteral.get(C.class)),
+                new TypeListener() {
+                  @Override
+                  public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                    Provider<B> bProvider = encounter.getProvider(B.class);
+                    try {
+                      bProvider.get();
+                      fail();
+                    } catch (IllegalStateException expected) {
+                      assertEquals(
+                          "This Provider cannot be used until the Injector has been created.",
+                          expected.getMessage());
+                    }
+                    bProviderReference.set(bProvider);
 
-            MembersInjector<A> aMembersInjector = encounter.getMembersInjector(A.class);
-            try {
-              aMembersInjector.injectMembers(new A());
-              fail();
-            } catch (IllegalStateException expected) {
-              assertEquals(
-                  "This MembersInjector cannot be used until the Injector has been created.",
-                  expected.getMessage());
-            }
-            aMembersInjectorReference.set(aMembersInjector);
+                    MembersInjector<A> aMembersInjector = encounter.getMembersInjector(A.class);
+                    try {
+                      aMembersInjector.injectMembers(new A());
+                      fail();
+                    } catch (IllegalStateException expected) {
+                      assertEquals(
+                          "This MembersInjector cannot be used until the Injector has been created.",
+                          expected.getMessage());
+                    }
+                    aMembersInjectorReference.set(aMembersInjector);
 
-            encounter.register(lookupsTester);
+                    encounter.register(lookupsTester);
+                  }
+                });
+
+            // this ensures the type listener fires, and also the afterInjection() listener
+            bind(C.class).asEagerSingleton();
           }
         });
 
-        // this ensures the type listener fires, and also the afterInjection() listener
-        bind(C.class).asEagerSingleton();
-      }
-    });
-
     lookupsTester.afterInjection(null);
   }
 
   public void testLookupsPostCreate() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(only(TypeLiteral.get(C.class)), new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            assertNotNull(encounter.getProvider(B.class).get());
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    only(TypeLiteral.get(C.class)),
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        assertNotNull(encounter.getProvider(B.class).get());
 
-            A a = new A();
-            encounter.getMembersInjector(A.class).injectMembers(a);
-            assertNotNull(a.injector);
-          }
-        });
-      }
-    });
-    
+                        A a = new A();
+                        encounter.getMembersInjector(A.class).injectMembers(a);
+                        assertNotNull(a.injector);
+                      }
+                    });
+              }
+            });
+
     injector.getInstance(C.class);
   }
 
   public void testMembersInjector() {
-    final MembersInjector<D> membersInjector = new MembersInjector<D>() {
-      public void injectMembers(D instance) {
-        instance.userInjected++;
-        assertEquals(instance.guiceInjected, instance.userInjected);
-      }
-    };
-
-    final InjectionListener<D> injectionListener = new InjectionListener<D>() {
-      public void afterInjection(D injectee) {
-        assertTrue(injectee.userInjected > 0);
-        injectee.listenersNotified++;
-        assertEquals(injectee.guiceInjected, injectee.listenersNotified);
-      }
-    };
-
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          @SuppressWarnings("unchecked")
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounter.register((MembersInjector) membersInjector);
-            encounter.register((InjectionListener) injectionListener);
+    final MembersInjector<D> membersInjector =
+        new MembersInjector<D>() {
+          @Override
+          public void injectMembers(D instance) {
+            instance.userInjected++;
+            assertEquals(instance.guiceInjected, instance.userInjected);
           }
-        });
+        };
 
-        D boundThreeTimes = new D();
-        bind(D.class).annotatedWith(named("i")).toInstance(boundThreeTimes);
-        bind(D.class).annotatedWith(named("ii")).toInstance(boundThreeTimes);
-        bind(D.class).annotatedWith(named("iii")).toInstance(boundThreeTimes);
-      }
-    });
+    final InjectionListener<D> injectionListener =
+        new InjectionListener<D>() {
+          @Override
+          public void afterInjection(D injectee) {
+            assertTrue(injectee.userInjected > 0);
+            injectee.listenersNotified++;
+            assertEquals(injectee.guiceInjected, injectee.listenersNotified);
+          }
+        };
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      @SuppressWarnings("unchecked")
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        encounter.register((MembersInjector) membersInjector);
+                        encounter.register((InjectionListener) injectionListener);
+                      }
+                    });
+
+                D boundThreeTimes = new D();
+                bind(D.class).annotatedWith(named("i")).toInstance(boundThreeTimes);
+                bind(D.class).annotatedWith(named("ii")).toInstance(boundThreeTimes);
+                bind(D.class).annotatedWith(named("iii")).toInstance(boundThreeTimes);
+              }
+            });
 
     D boundThreeTimes = injector.getInstance(Key.get(D.class, named("iii")));
     boundThreeTimes.assertAllCounts(1);
@@ -480,22 +559,29 @@
   }
 
   public void testMembersInjectorThrows() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounter.register(failingMembersInjector);
-          }
-        });
-        bind(B.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(
+                    onlyAbcd,
+                    new TypeListener() {
+                      @Override
+                      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                        encounter.register(failingMembersInjector);
+                      }
+                    });
+                bind(B.class);
+              }
+            });
 
     try {
       injector.getInstance(A.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error injecting " + A.class.getName() + " using awkward.",
           "Reason: java.lang.ClassCastException: whoops, failure #1");
     }
@@ -505,7 +591,8 @@
       injector.getInstance(A.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error injecting " + A.class.getName() + " using awkward.",
           "Reason: java.lang.ClassCastException: whoops, failure #2");
     }
@@ -516,7 +603,8 @@
       bProvider.get();
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) Error injecting " + B.class.getName() + " using awkward.",
           "Reason: java.lang.ClassCastException: whoops, failure #3");
     }
@@ -533,53 +621,69 @@
   public void testTypesWithNoInjectableMembersAreNotified() {
     final AtomicInteger notificationCount = new AtomicInteger();
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(onlyAbcd, new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            notificationCount.incrementAndGet();
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindListener(
+                onlyAbcd,
+                new TypeListener() {
+                  @Override
+                  public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                    notificationCount.incrementAndGet();
+                  }
+                });
+
+            bind(C.class).toInstance(new C());
           }
         });
 
-        bind(C.class).toInstance(new C());
-      }
-    });
-
     assertEquals(1, notificationCount.get());
   }
 
   public void testEncounterCannotBeUsedAfterHearReturns() {
-    final AtomicReference<TypeEncounter<?>> encounterReference = new AtomicReference<TypeEncounter<?>>();
+    final AtomicReference<TypeEncounter<?>> encounterReference =
+        new AtomicReference<TypeEncounter<?>>();
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindListener(any(), new TypeListener() {
-          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-            encounterReference.set(encounter);
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindListener(
+                any(),
+                new TypeListener() {
+                  @Override
+                  public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                    encounterReference.set(encounter);
+                  }
+                });
+
+            bind(C.class);
           }
         });
-
-        bind(C.class);
-      }
-    });
     TypeEncounter<?> encounter = encounterReference.get();
 
     try {
-      encounter.register(new InjectionListener<Object>() {
-        public void afterInjection(Object injectee) {}
-      });
+      encounter.register(
+          new InjectionListener<Object>() {
+            @Override
+            public void afterInjection(Object injectee) {}
+          });
       fail();
     } catch (IllegalStateException expected) {
     }
 
     /*if[AOP]*/
     try {
-      encounter.bindInterceptor(any(), new org.aopalliance.intercept.MethodInterceptor() {
-        public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation)
-            throws Throwable {
-          return methodInvocation.proceed();
-        }
-      });
+      encounter.bindInterceptor(
+          any(),
+          new org.aopalliance.intercept.MethodInterceptor() {
+            @Override
+            public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation)
+                throws Throwable {
+              return methodInvocation.proceed();
+            }
+          });
       fail();
     } catch (IllegalStateException expected) {
     }
@@ -606,22 +710,28 @@
 
   public void testAddErrors() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          requestInjection(new Object());
-          bindListener(Matchers.any(), new TypeListener() {
-            public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-              encounter.addError("There was an error on %s", type);
-              encounter.addError(new IllegalArgumentException("whoops!"));
-              encounter.addError(new Message("And another problem"));
-              encounter.addError(new IllegalStateException());
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestInjection(new Object());
+              bindListener(
+                  Matchers.any(),
+                  new TypeListener() {
+                    @Override
+                    public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+                      encounter.addError("There was an error on %s", type);
+                      encounter.addError(new IllegalArgumentException("whoops!"));
+                      encounter.addError(new Message("And another problem"));
+                      encounter.addError(new IllegalStateException());
+                    }
+                  });
             }
           });
-        }
-      });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) There was an error on java.lang.Object",
           "2) An exception was caught and reported. Message: whoops!",
           "3) And another problem",
@@ -631,12 +741,14 @@
   }
 
   private static class CountingMembersInjector implements MembersInjector<D> {
+    @Override
     public void injectMembers(D instance) {
       ++instance.userInjected;
     }
   }
 
   private static class CountingInjectionListener implements InjectionListener<D> {
+    @Override
     public void afterInjection(D injectee) {
       ++injectee.listenersNotified;
     }
@@ -645,6 +757,7 @@
   private static class DuplicatingTypeListener implements TypeListener {
     int count = 0;
 
+    @Override
     @SuppressWarnings({"rawtypes", "unchecked"})
     public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
       ++count;
@@ -661,13 +774,15 @@
 
   public void testDeDuplicateTypeListeners() {
     final DuplicatingTypeListener typeListener = new DuplicatingTypeListener();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindListener(any(), typeListener);
-        bindListener(only(new TypeLiteral<D>() {}), typeListener);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindListener(any(), typeListener);
+                bindListener(only(new TypeLiteral<D>() {}), typeListener);
+              }
+            });
     D d = injector.getInstance(D.class);
     d.assertAllCounts(1);
     assertEquals(1, typeListener.count);
@@ -697,7 +812,8 @@
     int userInjected = 0;
     int listenersNotified = 0;
 
-    @Inject void guiceInjected() {
+    @Inject
+    void guiceInjected() {
       guiceInjected++;
     }
 
diff --git a/core/test/com/google/inject/TypeLiteralInjectionTest.java b/core/test/com/google/inject/TypeLiteralInjectionTest.java
index 1231a81..125bd6b 100644
--- a/core/test/com/google/inject/TypeLiteralInjectionTest.java
+++ b/core/test/com/google/inject/TypeLiteralInjectionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,43 +20,47 @@
 import static com.google.inject.util.Types.listOf;
 
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.util.List;
+import junit.framework.TestCase;
 
 /**
  * Demonstrates type reification.
- * 
+ *
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public class TypeLiteralInjectionTest extends TestCase {
 
   public void testBindingToRawTypeLiteralIsNotAllowed() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(TypeLiteral.class).toInstance(TypeLiteral.get(String.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(TypeLiteral.class).toInstance(TypeLiteral.get(String.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Binding to core guice framework type is not allowed: TypeLiteral");
     }
   }
 
   public void testBindingToParameterizedTypeLiteralIsNotAllowed() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(new TypeLiteral<TypeLiteral<String>>() {})
-              .toInstance(TypeLiteral.get(String.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(new TypeLiteral<TypeLiteral<String>>() {})
+                  .toInstance(TypeLiteral.get(String.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Binding to core guice framework type is not allowed: TypeLiteral");
     }
   }
@@ -70,8 +74,11 @@
       Guice.createInjector().getInstance(B.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), TypeLiteral.class.getName() + "<java.util.List<T>> "
-          + "cannot be used as a key; It is not fully specified.");
+      assertContains(
+          expected.getMessage(),
+          TypeLiteral.class.getName()
+              + "<java.util.List<T>> "
+              + "cannot be used as a key; It is not fully specified.");
     }
   }
 
@@ -88,8 +95,8 @@
       Guice.createInjector().getInstance(TypeLiteral.class);
       fail();
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(),
-          "Cannot inject a TypeLiteral that has no type parameter");
+      assertContains(
+          expected.getMessage(), "Cannot inject a TypeLiteral that has no type parameter");
     }
   }
 
diff --git a/core/test/com/google/inject/TypeLiteralTest.java b/core/test/com/google/inject/TypeLiteralTest.java
index de8b5da..1216788 100644
--- a/core/test/com/google/inject/TypeLiteralTest.java
+++ b/core/test/com/google/inject/TypeLiteralTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,23 +21,18 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.util.List;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class TypeLiteralTest extends TestCase {
 
   public void testWithParameterizedType() {
     TypeLiteral<List<String>> a = new TypeLiteral<List<String>>() {};
-    TypeLiteral<List<String>> b = new TypeLiteral<List<String>>(
-        Types.listOf(String.class)) {};
+    TypeLiteral<List<String>> b = new TypeLiteral<List<String>>(Types.listOf(String.class)) {};
     assertEqualsBothWays(a, b);
   }
 
@@ -79,15 +74,16 @@
     try {
       new TypeLiteral() {};
       fail();
-    } catch (RuntimeException e) { /* expected */ }
+    } catch (RuntimeException e) {
+      /* expected */
+    }
   }
 
   public void testTypesInvolvingArraysForEquality() {
     TypeLiteral<String[]> stringArray = new TypeLiteral<String[]>() {};
     assertEquals(stringArray, new TypeLiteral<String[]>() {});
 
-    TypeLiteral<List<String[]>> listOfStringArray
-        = new TypeLiteral<List<String[]>>() {};
+    TypeLiteral<List<String[]>> listOfStringArray = new TypeLiteral<List<String[]>>() {};
     assertEquals(listOfStringArray, new TypeLiteral<List<String[]>>() {});
   }
 
@@ -104,29 +100,39 @@
   }
 
   public void testTypeLiteralsMustHaveRawTypes() {
-    try {
-      TypeLiteral.get(Types.subtypeOf(Runnable.class));
-      fail();
-    } catch (IllegalArgumentException expected) {
-      Asserts.assertContains(expected.getMessage(), "Expected a Class, ParameterizedType, or "
-          + "GenericArrayType, but <? extends java.lang.Runnable> is of type "
-          + "com.google.inject.internal.MoreTypes$WildcardTypeImpl");
-    }
+    // kind of weird, but wildcards and type variables always go to Object
+    assertEquals(Object.class, TypeLiteral.get(Types.subtypeOf(Runnable.class)).getRawType());
   }
 
   /**
-   * Unlike Key, TypeLiteral retains full type information and differentiates
-   * between {@code int.class} and {@code Integer.class}.
+   * Unlike Key, TypeLiteral retains full type information and differentiates between {@code
+   * int.class} and {@code Integer.class}.
    */
   public void testDifferentiationBetweenWrappersAndPrimitives() {
-    Class[] primitives = new Class[] {
-        boolean.class, byte.class, short.class, int.class, long.class,
-        float.class, double.class, char.class, void.class
-    };
-    Class[] wrappers = new Class[] {
-        Boolean.class, Byte.class, Short.class, Integer.class, Long.class,
-        Float.class, Double.class, Character.class, Void.class
-    };
+    Class[] primitives =
+        new Class[] {
+          boolean.class,
+          byte.class,
+          short.class,
+          int.class,
+          long.class,
+          float.class,
+          double.class,
+          char.class,
+          void.class
+        };
+    Class[] wrappers =
+        new Class[] {
+          Boolean.class,
+          Byte.class,
+          Short.class,
+          Integer.class,
+          Long.class,
+          Float.class,
+          Double.class,
+          Character.class,
+          Void.class
+        };
 
     for (int t = 0; t < primitives.length; t++) {
       @SuppressWarnings("unchecked")
@@ -147,8 +153,8 @@
   }
 
   public void testTypeVariableWithNoBound() {
-    TypeVariable<Class<HasTypeParameters>>[] typeVariables
-        = HasTypeParameters.class.getTypeParameters();
+    TypeVariable<Class<HasTypeParameters>>[] typeVariables =
+        HasTypeParameters.class.getTypeParameters();
 
     TypeLiteral<?> aTl = TypeLiteral.get(typeVariables[0]);
     assertEquals(Object.class, aTl.getRawType());
@@ -162,8 +168,8 @@
   }
 
   public void testTypeVariablesWithSingleBound() {
-    TypeVariable<Class<HasTypeParameters>>[] typeVariables
-        = HasTypeParameters.class.getTypeParameters();
+    TypeVariable<Class<HasTypeParameters>>[] typeVariables =
+        HasTypeParameters.class.getTypeParameters();
 
     TypeLiteral<?> cTl = TypeLiteral.get(typeVariables[2]);
     assertEquals(Object.class, cTl.getRawType());
@@ -177,8 +183,8 @@
   }
 
   public void testTypeVariableWithMultipleBounds() {
-    TypeVariable<Class<HasTypeParameters>>[] typeVariables
-        = HasTypeParameters.class.getTypeParameters();
+    TypeVariable<Class<HasTypeParameters>>[] typeVariables =
+        HasTypeParameters.class.getTypeParameters();
 
     TypeLiteral<?> bTl = TypeLiteral.get(typeVariables[1]);
     assertEquals(Object.class, bTl.getRawType());
@@ -186,13 +192,16 @@
     TypeVariable<?> bTv = (TypeVariable) bTl.getType();
     assertEquals(HasTypeParameters.class, bTv.getGenericDeclaration());
     assertEquals("B", bTv.getName());
-    assertEquals(ImmutableList.<Type>of(Types.listOf(typeVariables[0]), Runnable.class),
+    assertEquals(
+        ImmutableList.<Type>of(Types.listOf(typeVariables[0]), Runnable.class),
         ImmutableList.copyOf(bTv.getBounds()));
     assertEquals("B", bTv.toString());
     assertEqualsBothWays(bTl, TypeLiteral.get(HasTypeParameters.class.getTypeParameters()[1]));
   }
 
-  class HasTypeParameters<A, B extends List<A> & Runnable, C extends Runnable> {
-    A a; B b; C c;
+  static class HasTypeParameters<A, B extends List<A> & Runnable, C extends Runnable> {
+    A a;
+    B b;
+    C c;
   }
 }
diff --git a/core/test/com/google/inject/TypeLiteralTypeResolutionTest.java b/core/test/com/google/inject/TypeLiteralTypeResolutionTest.java
index 64bc4c7..d2dc724 100644
--- a/core/test/com/google/inject/TypeLiteralTypeResolutionTest.java
+++ b/core/test/com/google/inject/TypeLiteralTypeResolutionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,9 +26,6 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -43,6 +40,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * This test checks that TypeLiteral can perform type resolution on its members.
@@ -51,20 +49,20 @@
  */
 public class TypeLiteralTypeResolutionTest extends TestCase {
   Type arrayListOfString = newParameterizedType(ArrayList.class, String.class);
-  Type hasGenericFieldsOfShort = newParameterizedTypeWithOwner(
-      getClass(), HasGenericFields.class, Short.class);
-  Type hasGenericConstructorOfShort = newParameterizedTypeWithOwner(
-      getClass(), GenericConstructor.class, Short.class);
-  Type throwerOfNpe = newParameterizedTypeWithOwner(
-      getClass(), Thrower.class, NullPointerException.class);
+  Type hasGenericFieldsOfShort =
+      newParameterizedTypeWithOwner(getClass(), HasGenericFields.class, Short.class);
+  Type hasGenericConstructorOfShort =
+      newParameterizedTypeWithOwner(getClass(), GenericConstructor.class, Short.class);
+  Type throwerOfNpe =
+      newParameterizedTypeWithOwner(getClass(), Thrower.class, NullPointerException.class);
   Type hasArrayOfShort = newParameterizedTypeWithOwner(getClass(), HasArray.class, Short.class);
-  Type hasRelatedOfString = newParameterizedTypeWithOwner(
-      getClass(), HasRelated.class, String.class, String.class);
+  Type hasRelatedOfString =
+      newParameterizedTypeWithOwner(getClass(), HasRelated.class, String.class, String.class);
   Type mapK = Map.class.getTypeParameters()[0];
   Type hashMapK = HashMap.class.getTypeParameters()[0];
   Type setEntryKV;
-  Type entryStringInteger = setOf(newParameterizedTypeWithOwner(
-      Map.class, Map.Entry.class, String.class, Integer.class));
+  Type entryStringInteger =
+      setOf(newParameterizedTypeWithOwner(Map.class, Map.Entry.class, String.class, Integer.class));
   Field list;
   Field instance;
   Constructor<GenericConstructor> newHasGenericConstructor;
@@ -77,7 +75,8 @@
   Method echo;
   Method throwS;
 
-  @Override protected void setUp() throws Exception {
+  @Override
+  protected void setUp() throws Exception {
     super.setUp();
 
     list = HasGenericFields.class.getField("list");
@@ -96,19 +95,24 @@
 
   public void testDirectInheritance() throws NoSuchMethodException {
     TypeLiteral<?> resolver = TypeLiteral.get(arrayListOfString);
-    assertEquals(listOf(String.class),
+    assertEquals(
+        listOf(String.class),
         resolver.getReturnType(List.class.getMethod("subList", int.class, int.class)).getType());
-    assertEquals(ImmutableList.<TypeLiteral<?>>of(TypeLiteral.get(String.class)),
+    assertEquals(
+        ImmutableList.<TypeLiteral<?>>of(TypeLiteral.get(String.class)),
         resolver.getParameterTypes(Collection.class.getMethod("add", Object.class)));
   }
-  
+
   public void testGenericSupertype() {
     TypeLiteral<?> resolver = TypeLiteral.get(arrayListOfString);
-    assertEquals(newParameterizedType(Collection.class, String.class),
+    assertEquals(
+        newParameterizedType(Collection.class, String.class),
         resolver.getSupertype(Collection.class).getType());
-    assertEquals(newParameterizedType(Iterable.class, String.class),
+    assertEquals(
+        newParameterizedType(Iterable.class, String.class),
         resolver.getSupertype(Iterable.class).getType());
-    assertEquals(newParameterizedType(AbstractList.class, String.class),
+    assertEquals(
+        newParameterizedType(AbstractList.class, String.class),
         resolver.getSupertype(AbstractList.class).getType());
     assertEquals(Object.class, resolver.getSupertype(Object.class).getType());
   }
@@ -122,11 +126,13 @@
 
   static class MyInteger implements MyComparable<MyInteger> {
     int value;
+
+    @Override
     public int compareTo(MyInteger o) {
       return value - o.value;
     }
   }
-  
+
   public void testFields() {
     TypeLiteral<?> resolver = TypeLiteral.get(hasGenericFieldsOfShort);
     assertEquals(listOf(Short.class), resolver.getFieldType(list).getType());
@@ -140,8 +146,8 @@
 
   public void testGenericConstructor() throws NoSuchMethodException {
     TypeLiteral<?> resolver = TypeLiteral.get(hasGenericConstructorOfShort);
-    assertEquals(Short.class,
-        resolver.getParameterTypes(newHasGenericConstructor).get(0).getType());
+    assertEquals(
+        Short.class, resolver.getParameterTypes(newHasGenericConstructor).get(0).getType());
   }
 
   static class GenericConstructor<S> {
@@ -157,6 +163,7 @@
 
   static class Thrower<S extends Exception> {
     public Thrower() throws S {}
+
     public void throwS() throws S {}
   }
 
@@ -168,6 +175,7 @@
 
   static interface HasArray<T extends Number> {
     T[] getArray();
+
     Set<T[]> getSetOfArray();
   }
 
@@ -183,17 +191,20 @@
 
   /** Ensure the cache doesn't cache too much */
   public void testCachingAndReindexing() throws NoSuchMethodException {
-    TypeLiteral<?> resolver = TypeLiteral.get(
-        newParameterizedTypeWithOwner(getClass(), HasLists.class, String.class, Short.class));
-    assertEquals(listOf(String.class),
-        resolver.getReturnType(HasLists.class.getMethod("listS")).getType());
-    assertEquals(listOf(Short.class),
-        resolver.getReturnType(HasLists.class.getMethod("listT")).getType());
+    TypeLiteral<?> resolver =
+        TypeLiteral.get(
+            newParameterizedTypeWithOwner(getClass(), HasLists.class, String.class, Short.class));
+    assertEquals(
+        listOf(String.class), resolver.getReturnType(HasLists.class.getMethod("listS")).getType());
+    assertEquals(
+        listOf(Short.class), resolver.getReturnType(HasLists.class.getMethod("listT")).getType());
   }
 
   interface HasLists<S, T> {
     List<S> listS();
+
     List<T> listT();
+
     List<Map.Entry<S, T>> listEntries();
   }
 
@@ -204,43 +215,54 @@
       resolver.getExceptionTypes(stringIndexOf);
       fail();
     } catch (IllegalArgumentException e) {
-      assertEquals("public int java.lang.String.indexOf(java.lang.String) is not defined by a "
-          + "supertype of java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "public int java.lang.String.indexOf(java.lang.String) is not defined by a "
+              + "supertype of java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
     try {
       resolver.getParameterTypes(stringIndexOf);
       fail();
     } catch (Exception e) {
-      assertEquals("public int java.lang.String.indexOf(java.lang.String) is not defined by a "
-          + "supertype of java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "public int java.lang.String.indexOf(java.lang.String) is not defined by a "
+              + "supertype of java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
     try {
       resolver.getReturnType(stringIndexOf);
       fail();
     } catch (Exception e) {
-      assertEquals("public int java.lang.String.indexOf(java.lang.String) is not defined by a "
-          + "supertype of java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "public int java.lang.String.indexOf(java.lang.String) is not defined by a "
+              + "supertype of java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
     try {
       resolver.getSupertype(String.class);
       fail();
     } catch (Exception e) {
-      assertEquals("class java.lang.String is not a supertype of "
-          + "java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "class java.lang.String is not a supertype of " + "java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
     try {
       resolver.getExceptionTypes(newString);
       fail();
     } catch (Exception e) {
-      assertEquals("public java.lang.String(java.lang.String) does not construct "
-          + "a supertype of java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "public java.lang.String(java.lang.String) does not construct "
+              + "a supertype of java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
     try {
       resolver.getParameterTypes(newString);
       fail();
     } catch (Exception e) {
-      assertEquals("public java.lang.String(java.lang.String) does not construct "
-          + "a supertype of java.util.ArrayList<java.lang.String>", e.getMessage());
+      assertEquals(
+          "public java.lang.String(java.lang.String) does not construct "
+              + "a supertype of java.util.ArrayList<java.lang.String>",
+          e.getMessage());
     }
   }
 
@@ -250,8 +272,8 @@
 
     typeResolver = new TypeLiteral<Map<String, Integer>>() {};
     assertEquals(String.class, typeResolver.resolveType(mapK));
-    assertEquals(Types.mapOf(String.class, Integer.class),
-        typeResolver.getSupertype(Map.class).getType());
+    assertEquals(
+        Types.mapOf(String.class, Integer.class), typeResolver.getSupertype(Map.class).getType());
 
     typeResolver = new TypeLiteral<BetterMap<String, Integer>>() {};
     assertEquals(String.class, typeResolver.resolveType(mapK));
@@ -277,17 +299,21 @@
   }
 
   interface StringIntegerMap extends Map<String, Integer> {}
+
   interface BetterMap<K1, V1> extends Map<K1, V1> {}
+
   interface BestMap<K2, V2> extends BetterMap<K2, V2> {}
+
   static class StringIntegerHashMap extends HashMap<String, Integer> {}
 
   public void testGetSupertype() {
     TypeLiteral<AbstractList<String>> listOfString = new TypeLiteral<AbstractList<String>>() {};
-    assertEquals(Types.newParameterizedType(AbstractCollection.class, String.class),
+    assertEquals(
+        Types.newParameterizedType(AbstractCollection.class, String.class),
         listOfString.getSupertype(AbstractCollection.class).getType());
 
-    TypeLiteral arrayListOfE = TypeLiteral.get(newParameterizedType(
-        ArrayList.class, ArrayList.class.getTypeParameters()));
+    TypeLiteral arrayListOfE =
+        TypeLiteral.get(newParameterizedType(ArrayList.class, ArrayList.class.getTypeParameters()));
     assertEquals(
         newParameterizedType(AbstractCollection.class, ArrayList.class.getTypeParameters()),
         arrayListOfE.getSupertype(AbstractCollection.class).getType());
@@ -297,18 +323,22 @@
     Class<? extends List> arraysAsListClass = Arrays.asList().getClass();
     Type anotherE = arraysAsListClass.getTypeParameters()[0];
     TypeLiteral type = TypeLiteral.get(newParameterizedType(AbstractList.class, anotherE));
-    assertEquals(newParameterizedType(AbstractCollection.class, anotherE),
+    assertEquals(
+        newParameterizedType(AbstractCollection.class, anotherE),
         type.getSupertype(AbstractCollection.class).getType());
   }
 
   public void testWildcards() throws NoSuchFieldException {
     TypeLiteral<Parameterized<String>> ofString = new TypeLiteral<Parameterized<String>>() {};
 
-    assertEquals(new TypeLiteral<List<String>>() {}.getType(),
+    assertEquals(
+        new TypeLiteral<List<String>>() {}.getType(),
         ofString.getFieldType(Parameterized.class.getField("t")).getType());
-    assertEquals(new TypeLiteral<List<? extends String>>() {}.getType(),
+    assertEquals(
+        new TypeLiteral<List<? extends String>>() {}.getType(),
         ofString.getFieldType(Parameterized.class.getField("extendsT")).getType());
-    assertEquals(new TypeLiteral<List<? super String>>() {}.getType(),
+    assertEquals(
+        new TypeLiteral<List<? super String>>() {}.getType(),
         ofString.getFieldType(Parameterized.class.getField("superT")).getType());
   }
 
diff --git a/core/test/com/google/inject/example/ClientServiceWithDependencyInjection.java b/core/test/com/google/inject/example/ClientServiceWithDependencyInjection.java
index 838a60b..eb2fa5b 100644
--- a/core/test/com/google/inject/example/ClientServiceWithDependencyInjection.java
+++ b/core/test/com/google/inject/example/ClientServiceWithDependencyInjection.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,76 +18,76 @@
 
 import static junit.framework.Assert.assertTrue;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ClientServiceWithDependencyInjection {
 
-// 62 lines
+  // 62 lines
 
-public interface Service {
-  void go();
-}
-
-public static class ServiceImpl implements ClientServiceWithDependencyInjection.Service {
-  public void go() {
-    // ...
-  }
-}
-
-public static class ServiceFactory {
-
-  private ServiceFactory() {}
-
-  private static final Service service = new ServiceImpl();
-
-  public static Service getInstance() {
-    return service;
-  }
-}
-
-public static class Client {
-
-  private final Service service;
-
-  public Client(Service service) {
-    this.service = service;
+  public interface Service {
+    void go();
   }
 
-  public void go() {
-    service.go();
-  }
-}
-
-public static class ClientFactory {
-
-  private ClientFactory() {}
-
-  public static Client getInstance() {
-    Service service = ServiceFactory.getInstance();
-    return new Client(service);
-  }
-}
-
-public void testClient() {
-  MockService mock = new MockService();
-  Client client = new Client(mock);
-  client.go();
-  assertTrue(mock.isGone());
-}
-
-public static class MockService implements Service {
-
-  private boolean gone = false;
-
-  public void go() {
-    gone = true;
+  public static class ServiceImpl implements ClientServiceWithDependencyInjection.Service {
+    @Override
+    public void go() {
+      // ...
+    }
   }
 
-  public boolean isGone() {
-    return gone;
+  public static class ServiceFactory {
+
+    private ServiceFactory() {}
+
+    private static final Service service = new ServiceImpl();
+
+    public static Service getInstance() {
+      return service;
+    }
   }
-}
+
+  public static class Client {
+
+    private final Service service;
+
+    public Client(Service service) {
+      this.service = service;
+    }
+
+    public void go() {
+      service.go();
+    }
+  }
+
+  public static class ClientFactory {
+
+    private ClientFactory() {}
+
+    public static Client getInstance() {
+      Service service = ServiceFactory.getInstance();
+      return new Client(service);
+    }
+  }
+
+  public void testClient() {
+    MockService mock = new MockService();
+    Client client = new Client(mock);
+    client.go();
+    assertTrue(mock.isGone());
+  }
+
+  public static class MockService implements Service {
+
+    private boolean gone = false;
+
+    @Override
+    public void go() {
+      gone = true;
+    }
+
+    public boolean isGone() {
+      return gone;
+    }
+  }
 
   public static void main(String[] args) {
     new ClientServiceWithDependencyInjection().testClient();
diff --git a/core/test/com/google/inject/example/ClientServiceWithFactories.java b/core/test/com/google/inject/example/ClientServiceWithFactories.java
index b3829a1..83a8ae6 100644
--- a/core/test/com/google/inject/example/ClientServiceWithFactories.java
+++ b/core/test/com/google/inject/example/ClientServiceWithFactories.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,72 +18,71 @@
 
 import static junit.framework.Assert.assertTrue;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ClientServiceWithFactories {
 
-// 58 lines
+  // 58 lines
 
-public interface Service {
-  void go();
-}
-
-public static class ServiceImpl implements Service {
-  public void go() {
-    // ...
-  }
-}
-
-public static class ServiceFactory {
-
-  private ServiceFactory() {}
-
-  private static Service instance = new ServiceImpl();
-
-  public static Service getInstance() {
-    return instance;
+  public interface Service {
+    void go();
   }
 
-  public static void setInstance(Service service) {
-    instance = service;
-  }
-}
-
-public static class Client {
-
-  public void go() {
-    Service service = ServiceFactory.getInstance();
-    service.go();
-  }
-}
-
-public void testClient() {
-  Service previous = ServiceFactory.getInstance();
-  try {
-    final MockService mock = new MockService();
-    ServiceFactory.setInstance(mock);
-    Client client = new Client();
-    client.go();
-    assertTrue(mock.isGone());
-  }
-  finally {
-    ServiceFactory.setInstance(previous);
-  }
-}
-
-public static class MockService implements Service {
-
-  private boolean gone = false;
-
-  public void go() {
-    gone = true;
+  public static class ServiceImpl implements Service {
+    @Override
+    public void go() {
+      // ...
+    }
   }
 
-  public boolean isGone() {
-    return gone;
+  public static class ServiceFactory {
+
+    private ServiceFactory() {}
+
+    private static Service instance = new ServiceImpl();
+
+    public static Service getInstance() {
+      return instance;
+    }
+
+    public static void setInstance(Service service) {
+      instance = service;
+    }
   }
-}
+
+  public static class Client {
+
+    public void go() {
+      Service service = ServiceFactory.getInstance();
+      service.go();
+    }
+  }
+
+  public void testClient() {
+    Service previous = ServiceFactory.getInstance();
+    try {
+      final MockService mock = new MockService();
+      ServiceFactory.setInstance(mock);
+      Client client = new Client();
+      client.go();
+      assertTrue(mock.isGone());
+    } finally {
+      ServiceFactory.setInstance(previous);
+    }
+  }
+
+  public static class MockService implements Service {
+
+    private boolean gone = false;
+
+    @Override
+    public void go() {
+      gone = true;
+    }
+
+    public boolean isGone() {
+      return gone;
+    }
+  }
 
   public static void main(String[] args) {
     new ClientServiceWithFactories().testClient();
diff --git a/core/test/com/google/inject/example/ClientServiceWithGuice.java b/core/test/com/google/inject/example/ClientServiceWithGuice.java
index c027377..2c7567d 100644
--- a/core/test/com/google/inject/example/ClientServiceWithGuice.java
+++ b/core/test/com/google/inject/example/ClientServiceWithGuice.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,66 +25,67 @@
 import com.google.inject.Injector;
 import com.google.inject.Scopes;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ClientServiceWithGuice {
 
-// 48 lines
+  // 48 lines
 
-public interface Service {
-  void go();
-}
-
-public static class ServiceImpl implements Service {
-  public void go() {
-    // ...
-  }
-}
-
-public static class MyModule extends AbstractModule {
-  protected void configure() {
-    bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);
-  }
-}
-
-public static class Client {
-
-  private final Service service;
-
-  @Inject
-  public Client(Service service) {
-    this.service = service;
+  public interface Service {
+    void go();
   }
 
-  public void go() {
-    service.go();
-  }
-}
-
-public void testClient() {
-  MockService mock = new MockService();
-  Client client = new Client(mock);
-  client.go();
-  assertTrue(mock.isGone());
-}
-
-public static class MockService implements Service {
-
-  private boolean gone = false;
-
-  public void go() {
-    gone = true;
+  public static class ServiceImpl implements Service {
+    @Override
+    public void go() {
+      // ...
+    }
   }
 
-  public boolean isGone() {
-    return gone;
+  public static class MyModule extends AbstractModule {
+    @Override
+    protected void configure() {
+      bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);
+    }
   }
-}
 
-public static void main(String[] args) throws CreationException {
-  new ClientServiceWithGuice().testClient();
-  Injector injector = Guice.createInjector(new MyModule());
-  Client client = injector.getInstance(Client.class);
-}
+  public static class Client {
+
+    private final Service service;
+
+    @Inject
+    public Client(Service service) {
+      this.service = service;
+    }
+
+    public void go() {
+      service.go();
+    }
+  }
+
+  public void testClient() {
+    MockService mock = new MockService();
+    Client client = new Client(mock);
+    client.go();
+    assertTrue(mock.isGone());
+  }
+
+  public static class MockService implements Service {
+
+    private boolean gone = false;
+
+    @Override
+    public void go() {
+      gone = true;
+    }
+
+    public boolean isGone() {
+      return gone;
+    }
+  }
+
+  public static void main(String[] args) throws CreationException {
+    new ClientServiceWithGuice().testClient();
+    Injector injector = Guice.createInjector(new MyModule());
+    Client client = injector.getInstance(Client.class);
+  }
 }
diff --git a/core/test/com/google/inject/example/ClientServiceWithGuiceDefaults.java b/core/test/com/google/inject/example/ClientServiceWithGuiceDefaults.java
index 5a3d9a7..ce90db7 100644
--- a/core/test/com/google/inject/example/ClientServiceWithGuiceDefaults.java
+++ b/core/test/com/google/inject/example/ClientServiceWithGuiceDefaults.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,65 +22,64 @@
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
-
 import junit.framework.Assert;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ClientServiceWithGuiceDefaults {
 
-// 44 lines
+  // 44 lines
 
-@ImplementedBy(ServiceImpl.class)
-public interface Service {
-  void go();
-}
-
-@Singleton
-public static class ServiceImpl implements ClientServiceWithGuiceDefaults.Service {
-  public void go() {
-    // ...
-  }
-}
-
-public static class Client {
-
-  private final Service service;
-
-  @Inject
-  public Client(Service service) {
-    this.service = service;
+  @ImplementedBy(ServiceImpl.class)
+  public interface Service {
+    void go();
   }
 
-  public void go() {
-    service.go();
-  }
-}
-
-public void testClient() {
-  MockService mock = new MockService();
-  Client client = new Client(mock);
-  client.go();
-  Assert.assertTrue(mock.isGone());
-}
-
-public static class MockService implements Service {
-
-  private boolean gone = false;
-
-  public void go() {
-    gone = true;
+  @Singleton
+  public static class ServiceImpl implements ClientServiceWithGuiceDefaults.Service {
+    @Override
+    public void go() {
+      // ...
+    }
   }
 
-  public boolean isGone() {
-    return gone;
-  }
-}
+  public static class Client {
 
-public static void main(String[] args) throws CreationException {
-  new ClientServiceWithGuiceDefaults().testClient();
-  Injector injector = Guice.createInjector();
-  Client client = injector.getProvider(Client.class).get();
-}
+    private final Service service;
+
+    @Inject
+    public Client(Service service) {
+      this.service = service;
+    }
+
+    public void go() {
+      service.go();
+    }
+  }
+
+  public void testClient() {
+    MockService mock = new MockService();
+    Client client = new Client(mock);
+    client.go();
+    Assert.assertTrue(mock.isGone());
+  }
+
+  public static class MockService implements Service {
+
+    private boolean gone = false;
+
+    @Override
+    public void go() {
+      gone = true;
+    }
+
+    public boolean isGone() {
+      return gone;
+    }
+  }
+
+  public static void main(String[] args) throws CreationException {
+    new ClientServiceWithGuiceDefaults().testClient();
+    Injector injector = Guice.createInjector();
+    Client client = injector.getProvider(Client.class).get();
+  }
 }
diff --git a/core/test/com/google/inject/example/JndiProvider.java b/core/test/com/google/inject/example/JndiProvider.java
index fd90dc0..fbb1069 100644
--- a/core/test/com/google/inject/example/JndiProvider.java
+++ b/core/test/com/google/inject/example/JndiProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
 import javax.naming.Context;
 import javax.naming.NamingException;
 
@@ -33,21 +32,17 @@
     this.type = type;
   }
 
+  @Override
   public T get() {
     try {
       return type.cast(context.lookup(name));
-    }
-    catch (NamingException e) {
+    } catch (NamingException e) {
       throw new RuntimeException(e);
     }
   }
 
-  /**
-   * Creates a JNDI provider for the given
-   * type and name.
-   */
-  static <T> Provider<T> fromJndi(
-      Class<T> type, String name) {
+  /** Creates a JNDI provider for the given type and name. */
+  static <T> Provider<T> fromJndi(Class<T> type, String name) {
     return new JndiProvider<T>(type, name);
   }
 }
diff --git a/core/test/com/google/inject/example/JndiProviderClient.java b/core/test/com/google/inject/example/JndiProviderClient.java
index 897b249..d56c4bb 100644
--- a/core/test/com/google/inject/example/JndiProviderClient.java
+++ b/core/test/com/google/inject/example/JndiProviderClient.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
 import com.google.inject.CreationException;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.sql.DataSource;
@@ -30,15 +29,17 @@
 class JndiProviderClient {
 
   public static void main(String[] args) throws CreationException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-// Bind Context to the default InitialContext.
-bind(Context.class).to(InitialContext.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                // Bind Context to the default InitialContext.
+                bind(Context.class).to(InitialContext.class);
 
-// Bind to DataSource from JNDI.
-bind(DataSource.class)
-    .toProvider(fromJndi(DataSource.class, "..."));
-      }
-    });
+                // Bind to DataSource from JNDI.
+                bind(DataSource.class).toProvider(fromJndi(DataSource.class, "..."));
+              }
+            });
   }
 }
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/Collector.java b/core/test/com/google/inject/internal/Collector.java
similarity index 75%
rename from extensions/multibindings/test/com/google/inject/multibindings/Collector.java
rename to core/test/com/google/inject/internal/Collector.java
index 18f2527..937ac9c 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/Collector.java
+++ b/core/test/com/google/inject/internal/Collector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
-package com.google.inject.multibindings;
+package com.google.inject.internal;
 
+import com.google.inject.multibindings.MapBinderBinding;
+import com.google.inject.multibindings.MultibinderBinding;
+import com.google.inject.multibindings.MultibindingsTargetVisitor;
+import com.google.inject.multibindings.OptionalBinderBinding;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
 
-class Collector extends DefaultBindingTargetVisitor<Object, Object> implements
-    MultibindingsTargetVisitor<Object, Object> {
+class Collector extends DefaultBindingTargetVisitor<Object, Object>
+    implements MultibindingsTargetVisitor<Object, Object> {
   MapBinderBinding<? extends Object> mapbinding;
   MultibinderBinding<? extends Object> setbinding;
   OptionalBinderBinding<? extends Object> optionalbinding;
@@ -32,10 +36,10 @@
 
   @Override
   public Object visit(MultibinderBinding<? extends Object> multibinding) {
-   this.setbinding = multibinding;
-   return null;
+    this.setbinding = multibinding;
+    return null;
   }
-  
+
   @Override
   public Object visit(OptionalBinderBinding<? extends Object> optionalbinding) {
     this.optionalbinding = optionalbinding;
diff --git a/core/test/com/google/inject/internal/CycleDetectingLockTest.java b/core/test/com/google/inject/internal/CycleDetectingLockTest.java
index 0d10824..7454685 100644
--- a/core/test/com/google/inject/internal/CycleDetectingLockTest.java
+++ b/core/test/com/google/inject/internal/CycleDetectingLockTest.java
@@ -1,15 +1,20 @@
 package com.google.inject.internal;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Multimaps;
 import com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory;
-
-import junit.framework.TestCase;
-
+import com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock;
+import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
+import junit.framework.TestCase;
 
 public class CycleDetectingLockTest extends TestCase {
 
@@ -27,75 +32,218 @@
    *   T1: Finishes locking B, unlocks B, unlocks A
    * </pre>
    *
-   * <p>This should succeed, even though T1 was locked on T2 and T2 is locked on T1 when T2 locks
-   * A. Incorrect implementation detects a cycle waiting on S3.
+   * <p>This should succeed, even though T1 was locked on T2 and T2 is locked on T1 when T2 locks A.
+   * Incorrect implementation detects a cycle waiting on S3.
    */
 
   public void testSingletonThreadsRuntimeCircularDependency() throws Exception {
     final CyclicBarrier signal1 = new CyclicBarrier(2);
     final CyclicBarrier signal2 = new CyclicBarrier(2);
     final CyclicBarrier signal3 = new CyclicBarrier(2);
-    CycleDetectingLockFactory<String> lockFactory = new CycleDetectingLockFactory<String>();
+    final CycleDetectingLockFactory<String> lockFactory = new CycleDetectingLockFactory<>();
     final CycleDetectingLock<String> lockA =
-        lockFactory.new ReentrantCycleDetectingLock("A", new ReentrantLock() {
-          @Override
-          public void lock() {
-            if (Thread.currentThread().getName().equals("T2")) {
-              try {
-                signal3.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-              } catch (Exception e) {
-                throw new RuntimeException(e);
+        new ReentrantCycleDetectingLock<String>(
+            lockFactory,
+            "A",
+            new ReentrantLock() {
+              @Override
+              public void lock() {
+                if (Thread.currentThread().getName().equals("T2")) {
+                  try {
+                    signal3.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                  } catch (Exception e) {
+                    throw new RuntimeException(e);
+                  }
+                } else {
+                  assertEquals("T1", Thread.currentThread().getName());
+                }
+                super.lock();
               }
-            } else {
-              assertEquals("T1", Thread.currentThread().getName());
-            }
-            super.lock();
-          }
-        });
+            });
     final CycleDetectingLock<String> lockB =
-        lockFactory.new ReentrantCycleDetectingLock("B", new ReentrantLock() {
-          @Override
-          public void lock() {
-            if (Thread.currentThread().getName().equals("T1")) {
-              try {
-                signal2.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-                signal3.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-              } catch (Exception e) {
-                throw new RuntimeException(e);
+        new ReentrantCycleDetectingLock<String>(
+            lockFactory,
+            "B",
+            new ReentrantLock() {
+              @Override
+              public void lock() {
+                if (Thread.currentThread().getName().equals("T1")) {
+                  try {
+                    signal2.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    signal3.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                  } catch (Exception e) {
+                    throw new RuntimeException(e);
+                  }
+                } else {
+                  assertEquals("T2", Thread.currentThread().getName());
+                }
+                super.lock();
               }
-            } else {
-              assertEquals("T2", Thread.currentThread().getName());
-            }
-            super.lock();
-          }
-        });
-    Future<Void> firstThreadResult = Executors.newSingleThreadExecutor().submit(
-        new Callable<Void>() {
-          public Void call() throws Exception {
-            Thread.currentThread().setName("T1");
-            signal1.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-            assertTrue(lockA.lockOrDetectPotentialLocksCycle().isEmpty());
-            assertTrue(lockB.lockOrDetectPotentialLocksCycle().isEmpty());
-            lockB.unlock();
-            lockA.unlock();
-            return null;
-          }
-        });
-    Future<Void> secondThreadResult = Executors.newSingleThreadExecutor().submit(
-        new Callable<Void>() {
-          public Void call() throws Exception {
-            Thread.currentThread().setName("T2");
-            assertTrue(lockB.lockOrDetectPotentialLocksCycle().isEmpty());
-            signal1.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-            signal2.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-            lockB.unlock();
-            assertTrue(lockA.lockOrDetectPotentialLocksCycle().isEmpty());
-            lockA.unlock();
-            return null;
-          }
-        });
+            });
+    Future<Void> firstThreadResult =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Void>() {
+                  @Override
+                  public Void call() throws Exception {
+                    Thread.currentThread().setName("T1");
+                    signal1.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    assertTrue(lockA.lockOrDetectPotentialLocksCycle().isEmpty());
+                    assertTrue(lockB.lockOrDetectPotentialLocksCycle().isEmpty());
+                    lockB.unlock();
+                    lockA.unlock();
+                    return null;
+                  }
+                });
+    Future<Void> secondThreadResult =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Void>() {
+                  @Override
+                  public Void call() throws Exception {
+                    Thread.currentThread().setName("T2");
+                    assertTrue(lockB.lockOrDetectPotentialLocksCycle().isEmpty());
+                    signal1.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    signal2.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    lockB.unlock();
+                    assertTrue(lockA.lockOrDetectPotentialLocksCycle().isEmpty());
+                    lockA.unlock();
+                    return null;
+                  }
+                });
 
-    firstThreadResult.get();
-    secondThreadResult.get();
+    firstThreadResult.get(DEADLOCK_TIMEOUT_SECONDS * 3, TimeUnit.SECONDS);
+    secondThreadResult.get(DEADLOCK_TIMEOUT_SECONDS * 3, TimeUnit.SECONDS);
+  }
+
+  /**
+   * Verifies that factories do not deadlock each other.
+   *
+   * <pre>
+   *   Thread A: lock a lock A (factory A)
+   *   Thread B: lock a lock B (factory B)
+   *   Thread A: lock a lock B (factory B)
+   *   Thread B: lock a lock A (factory A)
+   * </pre>
+   *
+   * <p>This should succeed even though from the point of view of each individual factory there are
+   * no deadlocks to detect.
+   */
+
+  public void testCycleDetectingLockFactoriesDoNotDeadlock() throws Exception {
+    final CycleDetectingLockFactory<String> factoryA = new CycleDetectingLockFactory<>();
+    final CycleDetectingLock<String> lockA = factoryA.create("A");
+    final CycleDetectingLockFactory<String> factoryB = new CycleDetectingLockFactory<>();
+    final CycleDetectingLock<String> lockB = factoryB.create("B");
+    final CyclicBarrier eachThreadAcquiredFirstLock = new CyclicBarrier(2);
+    Future<Boolean> threadA =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Boolean>() {
+                  @Override
+                  public Boolean call() throws Exception {
+                    Thread.currentThread().setName("A");
+                    assertTrue(lockA.lockOrDetectPotentialLocksCycle().isEmpty());
+                    eachThreadAcquiredFirstLock.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    boolean isEmpty = lockB.lockOrDetectPotentialLocksCycle().isEmpty();
+                    if (isEmpty) {
+                      lockB.unlock();
+                    }
+                    lockA.unlock();
+                    return isEmpty;
+                  }
+                });
+    Future<Boolean> threadB =
+        Executors.newSingleThreadExecutor()
+            .submit(
+                new Callable<Boolean>() {
+                  @Override
+                  public Boolean call() throws Exception {
+                    Thread.currentThread().setName("B");
+                    assertTrue(lockB.lockOrDetectPotentialLocksCycle().isEmpty());
+                    eachThreadAcquiredFirstLock.await(DEADLOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                    boolean isEmpty = lockA.lockOrDetectPotentialLocksCycle().isEmpty();
+                    if (isEmpty) {
+                      lockA.unlock();
+                    }
+                    lockB.unlock();
+                    return isEmpty;
+                  }
+                });
+
+    boolean deadlockADetected = threadA.get(DEADLOCK_TIMEOUT_SECONDS * 2, TimeUnit.SECONDS);
+    boolean deadlockBDetected = threadB.get(DEADLOCK_TIMEOUT_SECONDS * 2, TimeUnit.SECONDS);
+
+    assertTrue("Deadlock should get detected", deadlockADetected || deadlockBDetected);
+    assertTrue("One deadlock should get detected", deadlockADetected != deadlockBDetected);
+  }
+
+  /**
+   * Verifies that factories deadlocks report the correct cycles.
+   *
+   * <pre>
+   *   Thread 1: takes locks a, b
+   *   Thread 2: takes locks b, c
+   *   Thread 3: takes locks c, a
+   * </pre>
+   *
+   * <p>In order to ensure a deadlock, each thread will wait on a barrier right after grabbing the
+   * first lock.
+   */
+
+  public void testCycleReporting() throws Exception {
+    final CycleDetectingLockFactory<String> factory = new CycleDetectingLockFactory<>();
+    final CycleDetectingLock<String> lockA = factory.create("a");
+    final CycleDetectingLock<String> lockB = factory.create("b");
+    final CycleDetectingLock<String> lockC = factory.create("c");
+    final CyclicBarrier barrier = new CyclicBarrier(3);
+    ImmutableList<Future<ListMultimap<Thread, String>>> futures =
+        ImmutableList.of(
+            grabLocksInThread(lockA, lockB, barrier),
+            grabLocksInThread(lockB, lockC, barrier),
+            grabLocksInThread(lockC, lockA, barrier));
+
+    // At least one of the threads will report a lock cycle, it is possible that they all will, but
+    // there is no guarantee, so we just scan for the first thread that reported a cycle
+    ListMultimap<Thread, String> cycle = null;
+    for (Future<ListMultimap<Thread, String>> future : futures) {
+      ListMultimap<Thread, String> value =
+          future.get(DEADLOCK_TIMEOUT_SECONDS * 3, TimeUnit.SECONDS);
+      if (!value.isEmpty()) {
+        cycle = value;
+        break;
+      }
+    }
+    // We don't really care about the keys in the multimap, but we want to make sure that all locks
+    // were reported in the right order.
+    assertEquals(6, cycle.size());
+    Collection<List<String>> edges = Multimaps.asMap(cycle).values();
+    assertTrue(edges.contains(ImmutableList.of("a", "b")));
+    assertTrue(edges.contains(ImmutableList.of("b", "c")));
+    assertTrue(edges.contains(ImmutableList.of("c", "a")));
+  }
+
+  private static <T> Future<ListMultimap<Thread, T>> grabLocksInThread(
+      final CycleDetectingLock<T> lock1,
+      final CycleDetectingLock<T> lock2,
+      final CyclicBarrier barrier) {
+    FutureTask<ListMultimap<Thread, T>> future =
+        new FutureTask<ListMultimap<Thread, T>>(
+            new Callable<ListMultimap<Thread, T>>() {
+              @Override
+              public ListMultimap<Thread, T> call() throws Exception {
+                assertTrue(lock1.lockOrDetectPotentialLocksCycle().isEmpty());
+                barrier.await();
+                ListMultimap<Thread, T> cycle = lock2.lockOrDetectPotentialLocksCycle();
+                if (cycle == null) {
+                  lock2.unlock();
+                }
+                lock1.unlock();
+                return cycle;
+              }
+            });
+    Thread thread = new Thread(future);
+    thread.start();
+    return future;
   }
 }
diff --git a/core/test/com/google/inject/internal/InternalProvisionExceptionTest.java b/core/test/com/google/inject/internal/InternalProvisionExceptionTest.java
new file mode 100644
index 0000000..9e4ec44
--- /dev/null
+++ b/core/test/com/google/inject/internal/InternalProvisionExceptionTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.inject.internal.util.SourceProvider;
+import junit.framework.TestCase;
+
+public final class InternalProvisionExceptionTest extends TestCase {
+
+  public void testSourceFormatting() {
+    // Note that the duplicate source gets dropped as well as the unknown source
+    assertThat(
+            InternalProvisionException.create("An error")
+                .addSource("Source1")
+                .addSource(SourceProvider.UNKNOWN_SOURCE)
+                .addSource("Source2")
+                .addSource("Source2")
+                .toProvisionException()
+                .getMessage())
+        .isEqualTo(
+            ""
+                + "Unable to provision, see the following errors:\n"
+                + "\n"
+                + "1) An error\n"
+                + "  at Source1\n"
+                + "  at Source2\n"
+                + "\n"
+                + "1 error");
+  }
+}
diff --git a/core/test/com/google/inject/internal/MapBinderTest.java b/core/test/com/google/inject/internal/MapBinderTest.java
new file mode 100644
index 0000000..5933dde
--- /dev/null
+++ b/core/test/com/google/inject/internal/MapBinderTest.java
@@ -0,0 +1,1590 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.inject.Asserts.asModuleChain;
+import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.internal.SpiUtils.VisitType.BOTH;
+import static com.google.inject.internal.SpiUtils.VisitType.MODULE;
+import static com.google.inject.internal.SpiUtils.assertMapVisitor;
+import static com.google.inject.internal.SpiUtils.instance;
+import static com.google.inject.internal.SpiUtils.providerInstance;
+import static com.google.inject.name.Names.named;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.base.Function;
+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.inject.AbstractModule;
+import com.google.inject.Asserts;
+import com.google.inject.Binding;
+import com.google.inject.BindingAnnotation;
+import com.google.inject.ConfigurationException;
+import com.google.inject.CreationException;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.ProvisionException;
+import com.google.inject.Stage;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.RealMapBinder.ProviderMapEntry;
+import com.google.inject.multibindings.MapBinder;
+import com.google.inject.multibindings.MapBinderBinding;
+import com.google.inject.name.Names;
+import com.google.inject.spi.DefaultElementVisitor;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Elements;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.InstanceBinding;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.util.Modules;
+import com.google.inject.util.Providers;
+import com.google.inject.util.Types;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+
+/** @author dpb@google.com (David P. Baker) */
+public class MapBinderTest extends TestCase {
+
+  private static final ImmutableSet<Key<?>> FRAMEWORK_KEYS =
+      ImmutableSet.of(
+          Key.get(java.util.logging.Logger.class), Key.get(Stage.class), Key.get(Injector.class));
+
+  final TypeLiteral<Map<String, javax.inject.Provider<String>>> mapOfStringJavaxProvider =
+      new TypeLiteral<Map<String, javax.inject.Provider<String>>>() {};
+  final TypeLiteral<Map<String, Provider<String>>> mapOfStringProvider =
+      new TypeLiteral<Map<String, Provider<String>>>() {};
+  final TypeLiteral<Map<String, String>> mapOfString = new TypeLiteral<Map<String, String>>() {};
+  final TypeLiteral<Map<Integer, String>> mapOfIntString =
+      new TypeLiteral<Map<Integer, String>>() {};
+  final TypeLiteral<Map<String, Integer>> mapOfInteger = new TypeLiteral<Map<String, Integer>>() {};
+  final TypeLiteral<Map<String, Set<String>>> mapOfSetOfString =
+      new TypeLiteral<Map<String, Set<String>>>() {};
+
+  private final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
+  private final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
+
+  private Type javaxProviderOf(Type type) {
+    return Types.javaxProviderOf(type);
+  }
+
+  private Type mapEntryOf(Type keyType, Type valueType) {
+    return Types.newParameterizedTypeWithOwner(Map.class, Map.Entry.class, keyType, valueType);
+  }
+
+  private Type collectionOf(Type type) {
+    return Types.newParameterizedType(Collection.class, type);
+  }
+
+  public void testAllBindings() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder.newMapBinder(binder(), String.class, String.class).permitDuplicates();
+          }
+        };
+
+    Injector injector = Guice.createInjector(module);
+
+    Map<Key<?>, Binding<?>> bindings = injector.getBindings();
+
+    ImmutableSet<Key<?>> expectedBindings =
+        ImmutableSet.<Key<?>>builder()
+            .add(
+                // Map<K, V>
+                Key.get(Types.mapOf(String.class, String.class)),
+                // Map<K, Provider<V>>
+                Key.get(Types.mapOf(String.class, Types.providerOf(String.class))),
+                // Map<K, javax.inject.Provider<V>>
+                Key.get(Types.mapOf(String.class, javaxProviderOf(String.class))),
+                // Map<K, Set<V>>
+                Key.get(Types.mapOf(String.class, Types.setOf(String.class))),
+                // Map<K, Set<Provider<V>>
+                Key.get(Types.mapOf(String.class, Types.setOf(Types.providerOf(String.class)))),
+                // Map<K, Set<javax.inject.Provider<V>>
+                Key.get(
+                    Types.mapOf(String.class, Types.setOf(Types.javaxProviderOf(String.class)))),
+                // Map<K, Collection<Provider<V>>
+                Key.get(
+                    Types.mapOf(String.class, Types.collectionOf(Types.providerOf(String.class)))),
+                // Map<K, Collection<javax.inject.Provider<V>>
+                Key.get(
+                    Types.mapOf(
+                        String.class, Types.collectionOf(Types.javaxProviderOf(String.class)))),
+                // Set<Map.Entry<K, Provider<V>>>
+                Key.get(Types.setOf(mapEntryOf(String.class, Types.providerOf(String.class)))),
+                // Set<Map.Entry<K, javax.inject.Provider<V>>>
+                Key.get(Types.setOf(mapEntryOf(String.class, Types.javaxProviderOf(String.class)))),
+                // Collection<Provider<Map.Entry<K, Provider<V>>>>
+                Key.get(
+                    collectionOf(
+                        Types.providerOf(
+                            mapEntryOf(String.class, Types.providerOf(String.class))))),
+                // Collection<javax.inject.Provider<Map.Entry<K, Provider<V>>>>
+                Key.get(
+                    collectionOf(
+                        Types.javaxProviderOf(
+                            mapEntryOf(String.class, Types.providerOf(String.class))))),
+                // @Named(...) Boolean
+                Key.get(
+                    Boolean.class,
+                    named(
+                        "Multibinder<java.util.Map$Entry<java.lang.String, "
+                            + "com.google.inject.Provider<java.lang.String>>> permits duplicates")))
+            .addAll(FRAMEWORK_KEYS)
+            .build();
+
+    Set<Key<?>> missingBindings = Sets.difference(expectedBindings, bindings.keySet());
+    Set<Key<?>> extraBindings = Sets.difference(bindings.keySet(), expectedBindings);
+
+    assertTrue(
+        "There should be no missing bindings. Missing: " + missingBindings,
+        missingBindings.isEmpty());
+    assertTrue(
+        "There should be no extra bindings. Extra: " + extraBindings, extraBindings.isEmpty());
+  }
+
+  public void testMapBinderAggregatesMultipleModules() {
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    Module de =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("d").toInstance("D");
+            multibinder.addBinding("e").toInstance("E");
+          }
+        };
+
+    Injector injector = Guice.createInjector(abc, de);
+    Map<String, String> abcde = injector.getInstance(Key.get(mapOfString));
+
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E"), abcde);
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(abc, de),
+        BOTH,
+        false,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"),
+        instance("d", "D"),
+        instance("e", "E"));
+
+    // just make sure these succeed
+    injector.getInstance(Key.get(mapOfStringProvider));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider));
+  }
+
+  public void testMapBinderAggregationForAnnotationInstance() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Names.named("abc"));
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+
+            multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Names.named("abc"));
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Map<String, String>> key = Key.get(mapOfString, Names.named("abc"));
+    Map<String, String> abc = injector.getInstance(key);
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
+    assertMapVisitor(
+        key,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"));
+
+    // just make sure these succeed
+    injector.getInstance(Key.get(mapOfStringProvider, Names.named("abc")));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, Names.named("abc")));
+  }
+
+  public void testMapBinderAggregationForAnnotationType() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Abc.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+
+            multibinder = MapBinder.newMapBinder(binder(), String.class, String.class, Abc.class);
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Map<String, String>> key = Key.get(mapOfString, Abc.class);
+    Map<String, String> abc = injector.getInstance(key);
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
+    assertMapVisitor(
+        key,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"));
+
+    // just make sure these succeed
+    injector.getInstance(Key.get(mapOfStringProvider, Abc.class));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, Abc.class));
+  }
+
+  public void testMapBinderWithMultipleAnnotationValueSets() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> abcMapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, named("abc"));
+            abcMapBinder.addBinding("a").toInstance("A");
+            abcMapBinder.addBinding("b").toInstance("B");
+            abcMapBinder.addBinding("c").toInstance("C");
+
+            MapBinder<String, String> deMapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, named("de"));
+            deMapBinder.addBinding("d").toInstance("D");
+            deMapBinder.addBinding("e").toInstance("E");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Map<String, String>> abcKey = Key.get(mapOfString, named("abc"));
+    Map<String, String> abc = injector.getInstance(abcKey);
+    Key<Map<String, String>> deKey = Key.get(mapOfString, named("de"));
+    Map<String, String> de = injector.getInstance(deKey);
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
+    assertEquals(mapOf("d", "D", "e", "E"), de);
+    assertMapVisitor(
+        abcKey,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"));
+    assertMapVisitor(
+        deKey,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("d", "D"),
+        instance("e", "E"));
+
+    // just make sure these succeed
+    injector.getInstance(Key.get(mapOfStringProvider, named("abc")));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, named("abc")));
+    injector.getInstance(Key.get(mapOfStringProvider, named("de")));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, named("de")));
+  }
+
+  public void testMapBinderWithMultipleAnnotationTypeSets() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> abcMapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Abc.class);
+            abcMapBinder.addBinding("a").toInstance("A");
+            abcMapBinder.addBinding("b").toInstance("B");
+            abcMapBinder.addBinding("c").toInstance("C");
+
+            MapBinder<String, String> deMapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, De.class);
+            deMapBinder.addBinding("d").toInstance("D");
+            deMapBinder.addBinding("e").toInstance("E");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Map<String, String>> abcKey = Key.get(mapOfString, Abc.class);
+    Map<String, String> abc = injector.getInstance(abcKey);
+    Key<Map<String, String>> deKey = Key.get(mapOfString, De.class);
+    Map<String, String> de = injector.getInstance(deKey);
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
+    assertEquals(mapOf("d", "D", "e", "E"), de);
+    assertMapVisitor(
+        abcKey,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"));
+    assertMapVisitor(
+        deKey,
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("d", "D"),
+        instance("e", "E"));
+
+    // just make sure these succeed
+    injector.getInstance(Key.get(mapOfStringProvider, Abc.class));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, Abc.class));
+    injector.getInstance(Key.get(mapOfStringProvider, De.class));
+    injector.getInstance(Key.get(mapOfStringJavaxProvider, De.class));
+  }
+
+  public void testMapBinderWithMultipleTypes() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder.newMapBinder(binder(), String.class, String.class)
+                .addBinding("a")
+                .toInstance("A");
+            MapBinder.newMapBinder(binder(), String.class, Integer.class)
+                .addBinding("1")
+                .toInstance(1);
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    assertEquals(mapOf("a", "A"), injector.getInstance(Key.get(mapOfString)));
+    assertEquals(mapOf("1", 1), injector.getInstance(Key.get(mapOfInteger)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("a", "A"));
+    assertMapVisitor(
+        Key.get(mapOfInteger),
+        stringType,
+        intType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("1", 1));
+  }
+
+  public void testMapBinderWithEmptyMap() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder.newMapBinder(binder(), String.class, String.class);
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Map<String, String> map = injector.getInstance(Key.get(mapOfString));
+    assertEquals(Collections.emptyMap(), map);
+    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(module), BOTH, false, 0);
+  }
+
+  public void testMapBinderMapIsUnmodifiable() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder.newMapBinder(binder(), String.class, String.class)
+                    .addBinding("a")
+                    .toInstance("A");
+              }
+            });
+
+    Map<String, String> map = injector.getInstance(Key.get(mapOfString));
+    try {
+      map.clear();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+
+  public void testMapBinderMapIsLazy() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder.newMapBinder(binder(), String.class, Integer.class)
+                .addBinding("num")
+                .toProvider(
+                    new Provider<Integer>() {
+                      int nextValue = 1;
+
+                      @Override
+                      public Integer get() {
+                        return nextValue++;
+                      }
+                    });
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    assertEquals(mapOf("num", 1), injector.getInstance(Key.get(mapOfInteger)));
+    assertEquals(mapOf("num", 2), injector.getInstance(Key.get(mapOfInteger)));
+    assertEquals(mapOf("num", 3), injector.getInstance(Key.get(mapOfInteger)));
+    assertMapVisitor(
+        Key.get(mapOfInteger),
+        stringType,
+        intType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        providerInstance("num", 1));
+  }
+
+  public void testMapBinderMapForbidsDuplicateKeys() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("a").toInstance("B");
+          }
+        };
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(), "Map injection failed due to duplicated key \"a\"");
+    }
+
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(module),
+        MODULE,
+        false,
+        0,
+        instance("a", "A"),
+        instance("a", "B"));
+  }
+
+  public void testExhaustiveDuplicateErrorMessage() throws Exception {
+    class Module1 extends AbstractModule {
+      @Override
+      protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("a").to(String.class);
+      }
+    }
+    class Module2 extends AbstractModule {
+      @Override
+      protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("a").to(Integer.class);
+        mapbinder.addBinding("b").to(String.class);
+      }
+    }
+    class Module3 extends AbstractModule {
+      @Override
+      protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("b").to(Integer.class);
+      }
+    }
+    class Main extends AbstractModule {
+      @Override
+      protected void configure() {
+        MapBinder.newMapBinder(binder(), String.class, Object.class);
+        install(new Module1());
+        install(new Module2());
+        install(new Module3());
+      }
+
+      @Provides
+      String provideString() {
+        return "foo";
+      }
+
+      @Provides
+      Integer provideInt() {
+        return 42;
+      }
+    }
+    try {
+      Guice.createInjector(new Main());
+      fail();
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "Map injection failed due to duplicated key \"a\", from bindings:",
+          asModuleChain(Main.class, Module1.class),
+          asModuleChain(Main.class, Module2.class),
+          "and key: \"b\", from bindings:",
+          asModuleChain(Main.class, Module2.class),
+          asModuleChain(Main.class, Module3.class),
+          "at " + Main.class.getName() + ".configure(",
+          asModuleChain(Main.class, RealMapBinder.class));
+      assertEquals(1, ce.getErrorMessages().size());
+    }
+  }
+
+  public void testMapBinderMapPermitDuplicateElements() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.permitDuplicates();
+          }
+        };
+    Module bc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.permitDuplicates();
+          }
+        };
+    Injector injector = Guice.createInjector(ab, bc);
+
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), injector.getInstance(Key.get(mapOfString)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(ab, bc),
+        BOTH,
+        true,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"));
+  }
+
+  public void testMapBinderMapDoesNotDedupeDuplicateValues() {
+    class ValueType {
+      int keyPart;
+      int dataPart;
+
+      private ValueType(int keyPart, int dataPart) {
+        this.keyPart = keyPart;
+        this.dataPart = dataPart;
+      }
+
+      @Override
+      public boolean equals(Object obj) {
+        return (obj instanceof ValueType) && (keyPart == ((ValueType) obj).keyPart);
+      }
+
+      @Override
+      public int hashCode() {
+        return keyPart;
+      }
+    }
+    Module m1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, ValueType> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, ValueType.class);
+            multibinder.addBinding("a").toInstance(new ValueType(1, 2));
+          }
+        };
+    Module m2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, ValueType> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, ValueType.class);
+            multibinder.addBinding("b").toInstance(new ValueType(1, 3));
+          }
+        };
+
+    Injector injector = Guice.createInjector(m1, m2);
+    Map<String, ValueType> map = injector.getInstance(new Key<Map<String, ValueType>>() {});
+    assertEquals(2, map.get("a").dataPart);
+    assertEquals(3, map.get("b").dataPart);
+  }
+
+  public void testMapBinderMultimap() {
+    AbstractModule ab1c =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B1");
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    AbstractModule b2c =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("b").toInstance("B2");
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.permitDuplicates();
+          }
+        };
+    Injector injector = Guice.createInjector(ab1c, b2c);
+
+    assertEquals(
+        mapOf("a", setOf("A"), "b", setOf("B1", "B2"), "c", setOf("C")),
+        injector.getInstance(Key.get(mapOfSetOfString)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(ab1c, b2c),
+        BOTH,
+        true,
+        0,
+        instance("a", "A"),
+        instance("b", "B1"),
+        instance("b", "B2"),
+        instance("c", "C"));
+  }
+
+  public void testMapBinderMultimapWithAnotation() {
+    AbstractModule ab1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Abc.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B1");
+          }
+        };
+    AbstractModule b2c =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class, Abc.class);
+            multibinder.addBinding("b").toInstance("B2");
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.permitDuplicates();
+          }
+        };
+    Injector injector = Guice.createInjector(ab1, b2c);
+
+    assertEquals(
+        mapOf("a", setOf("A"), "b", setOf("B1", "B2"), "c", setOf("C")),
+        injector.getInstance(Key.get(mapOfSetOfString, Abc.class)));
+    try {
+      injector.getInstance(Key.get(mapOfSetOfString));
+      fail();
+    } catch (ConfigurationException expected) {
+    }
+
+    assertMapVisitor(
+        Key.get(mapOfString, Abc.class),
+        stringType,
+        stringType,
+        setOf(ab1, b2c),
+        BOTH,
+        true,
+        0,
+        instance("a", "A"),
+        instance("b", "B1"),
+        instance("b", "B2"),
+        instance("c", "C"));
+  }
+
+  public void testMapBinderMultimapIsUnmodifiable() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder<String, String> mapBinder =
+                    MapBinder.newMapBinder(binder(), String.class, String.class);
+                mapBinder.addBinding("a").toInstance("A");
+                mapBinder.permitDuplicates();
+              }
+            });
+
+    Map<String, Set<String>> map = injector.getInstance(Key.get(mapOfSetOfString));
+    try {
+      map.clear();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      map.get("a").clear();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+
+  public void testMapBinderMapForbidsNullKeys() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              MapBinder.newMapBinder(binder(), String.class, String.class).addBinding(null);
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+    }
+  }
+
+  public void testMapBinderMapForbidsNullValues() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder.newMapBinder(binder(), String.class, String.class)
+                .addBinding("null")
+                .toProvider(Providers.<String>of(null));
+          }
+        };
+    Injector injector = Guice.createInjector(m);
+
+    try {
+      injector.getInstance(Key.get(mapOfString));
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) Map injection failed due to null value for key \"null\", bound at: "
+              + m.getClass().getName()
+              + ".configure(");
+    }
+  }
+
+  public void testMapBinderProviderIsScoped() {
+    final Provider<Integer> counter =
+        new Provider<Integer>() {
+          int next = 1;
+
+          @Override
+          public Integer get() {
+            return next++;
+          }
+        };
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder.newMapBinder(binder(), String.class, Integer.class)
+                    .addBinding("one")
+                    .toProvider(counter)
+                    .asEagerSingleton();
+              }
+            });
+
+    assertEquals(1, (int) injector.getInstance(Key.get(mapOfInteger)).get("one"));
+    assertEquals(1, (int) injector.getInstance(Key.get(mapOfInteger)).get("one"));
+  }
+
+  public void testSourceLinesInMapBindings() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              MapBinder.newMapBinder(binder(), String.class, Integer.class).addBinding("one");
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) No implementation for java.lang.Integer",
+          "at " + getClass().getName());
+    }
+  }
+
+  /** Check that the dependencies are correct. */
+  public void testMultibinderDependencies() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder<Integer, String> mapBinder =
+                    MapBinder.newMapBinder(binder(), Integer.class, String.class);
+                mapBinder.addBinding(1).toInstance("A");
+                mapBinder.addBinding(2).to(Key.get(String.class, Names.named("b")));
+
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<Map<Integer, String>> binding = injector.getBinding(new Key<Map<Integer, String>>() {});
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<Dependency<?>> actualDependencies = withDependencies.getDependencies();
+
+    // We expect two dependencies, because the dependencies are annotated with
+    // Element, which has a uniqueId, it's difficult to directly compare them.
+    // Instead we will manually compare all the fields except the uniqueId
+    assertEquals(2, actualDependencies.size());
+    for (Dependency<?> dependency : actualDependencies) {
+      Key<?> key = dependency.getKey();
+      assertEquals(new TypeLiteral<String>() {}, key.getTypeLiteral());
+      Annotation annotation = dependency.getKey().getAnnotation();
+      assertTrue(annotation instanceof Element);
+      Element element = (Element) annotation;
+      assertEquals("", element.setName());
+      assertEquals(Element.Type.MAPBINDER, element.type());
+      assertEquals("java.lang.Integer", element.keyType());
+    }
+
+    Set<String> elements = Sets.newHashSet();
+    elements.addAll(recurseForDependencies(injector, withDependencies));
+    assertEquals(ImmutableSet.of("A", "B"), elements);
+  }
+
+  private Set<String> recurseForDependencies(Injector injector, HasDependencies hasDependencies) {
+    Set<String> elements = Sets.newHashSet();
+    for (Dependency<?> dependency : hasDependencies.getDependencies()) {
+      Binding<?> binding = injector.getBinding(dependency.getKey());
+      HasDependencies deps = (HasDependencies) binding;
+      if (binding instanceof InstanceBinding) {
+        elements.add((String) ((InstanceBinding<?>) binding).getInstance());
+      } else {
+        elements.addAll(recurseForDependencies(injector, deps));
+      }
+    }
+    return elements;
+  }
+
+  /** Check that the dependencies are correct in the Tool Stage. */
+  public void testMultibinderDependenciesInToolStage() {
+    Injector injector =
+        Guice.createInjector(
+            Stage.TOOL,
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder<Integer, String> mapBinder =
+                    MapBinder.newMapBinder(binder(), Integer.class, String.class);
+                mapBinder.addBinding(1).toInstance("A");
+                mapBinder.addBinding(2).to(Key.get(String.class, Names.named("b")));
+
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<Map<Integer, String>> binding = injector.getBinding(new Key<Map<Integer, String>>() {});
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<Dependency<?>> actualDependencies = withDependencies.getDependencies();
+
+    // We expect two dependencies, because the dependencies are annotated with
+    // Element, which has a uniqueId, it's difficult to directly compare them.
+    // Instead we will manually compare all the fields except the uniqueId
+    assertEquals(2, actualDependencies.size());
+    for (Dependency<?> dependency : actualDependencies) {
+      Key<?> key = dependency.getKey();
+      assertEquals(new TypeLiteral<String>() {}, key.getTypeLiteral());
+      Annotation annotation = dependency.getKey().getAnnotation();
+      assertTrue(annotation instanceof Element);
+      Element element = (Element) annotation;
+      assertEquals("", element.setName());
+      assertEquals(Element.Type.MAPBINDER, element.type());
+      assertEquals("java.lang.Integer", element.keyType());
+    }
+  }
+
+  /** Our implementation maintains order, but doesn't guarantee it in the API spec. */
+  // TODO: specify the iteration order
+  public void testBindOrderEqualsIterationOrder() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder<String, String> mapBinder =
+                    MapBinder.newMapBinder(binder(), String.class, String.class);
+                mapBinder.addBinding("leonardo").toInstance("blue");
+                mapBinder.addBinding("donatello").toInstance("purple");
+                install(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        MapBinder.newMapBinder(binder(), String.class, String.class)
+                            .addBinding("michaelangelo")
+                            .toInstance("orange");
+                      }
+                    });
+              }
+            },
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder.newMapBinder(binder(), String.class, String.class)
+                    .addBinding("raphael")
+                    .toInstance("red");
+              }
+            });
+
+    Map<String, String> map = injector.getInstance(new Key<Map<String, String>>() {});
+    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
+    assertEquals(Maps.immutableEntry("leonardo", "blue"), iterator.next());
+    assertEquals(Maps.immutableEntry("donatello", "purple"), iterator.next());
+    assertEquals(Maps.immutableEntry("michaelangelo", "orange"), iterator.next());
+    assertEquals(Maps.immutableEntry("raphael", "red"), iterator.next());
+  }
+
+  /** With overrides, we should get the union of all map bindings. */
+  public void testModuleOverrideAndMapBindings() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+          }
+        };
+    Module cd =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.addBinding("d").toInstance("D");
+          }
+        };
+    Module ef =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("e").toInstance("E");
+            multibinder.addBinding("f").toInstance("F");
+          }
+        };
+
+    Module abcd = Modules.override(ab).with(cd);
+    Injector injector = Guice.createInjector(abcd, ef);
+    assertEquals(
+        mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F"),
+        injector.getInstance(Key.get(mapOfString)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(abcd, ef),
+        BOTH,
+        false,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"),
+        instance("d", "D"),
+        instance("e", "E"),
+        instance("f", "F"));
+  }
+
+  public void testDeduplicateMapBindings() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> mapbinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            mapbinder.addBinding("a").toInstance("A");
+            mapbinder.addBinding("a").toInstance("A");
+            mapbinder.addBinding("b").toInstance("B");
+            mapbinder.addBinding("b").toInstance("B");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals(mapOf("a", "A", "b", "B"), injector.getInstance(Key.get(mapOfString)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        instance("a", "A"),
+        instance("b", "B"));
+  }
+
+  /** With overrides, we should get the union of all map bindings. */
+  public void testModuleOverrideAndMapBindingsWithPermitDuplicates() {
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.permitDuplicates();
+          }
+        };
+    Module cd =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("c").toInstance("C");
+            multibinder.addBinding("d").toInstance("D");
+            multibinder.permitDuplicates();
+          }
+        };
+    Module ef =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("e").toInstance("E");
+            multibinder.addBinding("f").toInstance("F");
+            multibinder.permitDuplicates();
+          }
+        };
+
+    Module abcd = Modules.override(abc).with(cd);
+    Injector injector = Guice.createInjector(abcd, ef);
+    assertEquals(
+        mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F"),
+        injector.getInstance(Key.get(mapOfString)));
+    assertMapVisitor(
+        Key.get(mapOfString),
+        stringType,
+        stringType,
+        setOf(abcd, ef),
+        BOTH,
+        true,
+        0,
+        instance("a", "A"),
+        instance("b", "B"),
+        instance("c", "C"),
+        instance("d", "D"),
+        instance("e", "E"),
+        instance("f", "F"));
+  }
+
+  /** Ensure there are no initialization race conditions in basic map injection. */
+  public void testBasicMapDependencyInjection() {
+    final AtomicReference<Map<String, String>> injectedMap =
+        new AtomicReference<Map<String, String>>();
+    final Object anObject =
+        new Object() {
+          @Inject
+          void initialize(Map<String, String> map) {
+            injectedMap.set(map);
+          }
+        };
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestInjection(anObject);
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    Guice.createInjector(abc);
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), injectedMap.get());
+  }
+
+  /** Ensure there are no initialization race conditions in provider multimap injection. */
+  public void testProviderMultimapDependencyInjection() {
+    final AtomicReference<Map<String, Set<Provider<String>>>> injectedMultimap =
+        new AtomicReference<Map<String, Set<Provider<String>>>>();
+    final Object anObject =
+        new Object() {
+          @Inject
+          void initialize(Map<String, Set<Provider<String>>> multimap) {
+            injectedMultimap.set(multimap);
+          }
+        };
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestInjection(anObject);
+            MapBinder<String, String> multibinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            multibinder.permitDuplicates();
+            multibinder.addBinding("a").toInstance("A");
+            multibinder.addBinding("b").toInstance("B");
+            multibinder.addBinding("c").toInstance("C");
+          }
+        };
+    Guice.createInjector(abc);
+    Map<String, String> map =
+        Maps.transformValues(
+            injectedMultimap.get(),
+            new Function<Set<Provider<String>>, String>() {
+              @Override
+              public String apply(Set<Provider<String>> stringProvidersSet) {
+                return Iterables.getOnlyElement(stringProvidersSet).get();
+              }
+            });
+    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), map);
+  }
+
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface Abc {}
+
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface De {}
+
+  @SuppressWarnings("unchecked")
+  private <K, V> Map<K, V> mapOf(Object... elements) {
+    Map<K, V> result = new HashMap<>();
+    for (int i = 0; i < elements.length; i += 2) {
+      result.put((K) elements[i], (V) elements[i + 1]);
+    }
+    return result;
+  }
+
+  @SuppressWarnings("unchecked")
+  private <V> Set<V> setOf(V... elements) {
+    return new HashSet<V>(Arrays.asList(elements));
+  }
+
+  @BindingAnnotation
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+  private static @interface Marker {}
+
+  @Marker
+  public void testMapBinderMatching() throws Exception {
+    Method m = MapBinderTest.class.getDeclaredMethod("testMapBinderMatching");
+    assertNotNull(m);
+    final Annotation marker = m.getAnnotation(Marker.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              public void configure() {
+                MapBinder<Integer, Integer> mb1 =
+                    MapBinder.newMapBinder(binder(), Integer.class, Integer.class, Marker.class);
+                MapBinder<Integer, Integer> mb2 =
+                    MapBinder.newMapBinder(binder(), Integer.class, Integer.class, marker);
+                mb1.addBinding(1).toInstance(1);
+                mb2.addBinding(2).toInstance(2);
+
+                // This assures us that the two binders are equivalent, so we expect the instance added to
+                // each to have been added to one set.
+                assertEquals(mb1, mb2);
+              }
+            });
+    TypeLiteral<Map<Integer, Integer>> t = new TypeLiteral<Map<Integer, Integer>>() {};
+    Map<Integer, Integer> s1 = injector.getInstance(Key.get(t, Marker.class));
+    Map<Integer, Integer> s2 = injector.getInstance(Key.get(t, marker));
+
+    // This assures us that the two sets are in fact equal.  They may not be same set (as in Java
+    // object identical), but we shouldn't expect that, since probably Guice creates the set each
+    // time in case the elements are dependent on scope.
+    assertEquals(s1, s2);
+
+    // This ensures that MultiBinder is internally using the correct set name --
+    // making sure that instances of marker annotations have the same set name as
+    // MarkerAnnotation.class.
+    Map<Integer, Integer> expected = new HashMap<>();
+    expected.put(1, 1);
+    expected.put(2, 2);
+    assertEquals(expected, s1);
+  }
+
+  public void testTwoMapBindersAreDistinct() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder.newMapBinder(binder(), String.class, String.class)
+                    .addBinding("A")
+                    .toInstance("a");
+
+                MapBinder.newMapBinder(binder(), Integer.class, String.class)
+                    .addBinding(1)
+                    .toInstance("b");
+              }
+            });
+    Collector collector = new Collector();
+    Binding<Map<String, String>> map1 = injector.getBinding(Key.get(mapOfString));
+    map1.acceptTargetVisitor(collector);
+    assertNotNull(collector.mapbinding);
+    MapBinderBinding<?> map1Binding = collector.mapbinding;
+
+    Binding<Map<Integer, String>> map2 = injector.getBinding(Key.get(mapOfIntString));
+    map2.acceptTargetVisitor(collector);
+    assertNotNull(collector.mapbinding);
+    MapBinderBinding<?> map2Binding = collector.mapbinding;
+
+    List<Binding<String>> bindings = injector.findBindingsByType(stringType);
+    assertEquals("should have two elements: " + bindings, 2, bindings.size());
+    Binding<String> a = bindings.get(0);
+    Binding<String> b = bindings.get(1);
+    assertEquals("a", ((InstanceBinding<String>) a).getInstance());
+    assertEquals("b", ((InstanceBinding<String>) b).getInstance());
+
+    // Make sure the correct elements belong to their own sets.
+    assertTrue(map1Binding.containsElement(a));
+    assertFalse(map1Binding.containsElement(b));
+
+    assertFalse(map2Binding.containsElement(a));
+    assertTrue(map2Binding.containsElement(b));
+  }
+
+  // Tests for com.google.inject.internal.WeakKeySet not leaking memory.
+  public void testWeakKeySet_integration_mapbinder() {
+    Key<Map<String, String>> mapKey = Key.get(new TypeLiteral<Map<String, String>>() {});
+
+    Injector parentInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("hi");
+              }
+            });
+    WeakKeySetUtils.assertNotBlacklisted(parentInjector, mapKey);
+
+    Injector childInjector =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                MapBinder<String, String> binder =
+                    MapBinder.newMapBinder(binder(), String.class, String.class);
+                binder.addBinding("bar").toInstance("foo");
+              }
+            });
+    WeakReference<Injector> weakRef = new WeakReference<>(childInjector);
+    WeakKeySetUtils.assertBlacklisted(parentInjector, mapKey);
+
+    // Clear the ref, GC, and ensure that we are no longer blacklisting.
+    childInjector = null;
+
+    Asserts.awaitClear(weakRef);
+    WeakKeySetUtils.assertNotBlacklisted(parentInjector, mapKey);
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void testGetEntries() {
+    List<com.google.inject.spi.Element> elements =
+        Elements.getElements(new MapBinderWithTwoEntriesModule());
+
+    // Get the MapBinderBinding
+    MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements);
+
+    // Execute the call to getEntries
+    List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements);
+
+    // Assert on the results
+    Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0);
+    assertEquals("keyOne", firstEntry.getKey());
+    Binding<?> firstBinding = firstEntry.getValue();
+    assertEquals("valueOne", ((InstanceBinding) firstBinding).getInstance());
+
+    Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1);
+    assertEquals("keyTwo", secondEntry.getKey());
+    Binding<?> secondBinding = secondEntry.getValue();
+    assertEquals("valueTwo", ((InstanceBinding) secondBinding).getInstance());
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void testGetEntriesWithDuplicateKeys() {
+    // Set up the module
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> mapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            mapBinder.addBinding("A").toInstance("a1");
+            mapBinder.addBinding("A").toInstance("a2");
+            mapBinder.permitDuplicates();
+          }
+        };
+
+    // Get the MapBinderBinding
+    List<com.google.inject.spi.Element> elements = Elements.getElements(module);
+    MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements);
+
+    // Execute the call to getEntries
+    List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements);
+
+    // Assert on the results
+    Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0);
+    assertEquals("A", firstEntry.getKey());
+    Binding<?> firstBinding = firstEntry.getValue();
+    assertEquals("a1", ((InstanceBinding) firstBinding).getInstance());
+
+    Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1);
+    assertEquals("A", secondEntry.getKey());
+    Binding<?> secondBinding = secondEntry.getValue();
+    assertEquals("a2", ((InstanceBinding) secondBinding).getInstance());
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void testGetEntriesWithDuplicateValues() {
+    // Set up the module
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            MapBinder<String, String> mapBinder =
+                MapBinder.newMapBinder(binder(), String.class, String.class);
+            mapBinder.addBinding("A").toInstance("a");
+            mapBinder.addBinding("A").toInstance("a");
+          }
+        };
+
+    // Get the MapBinderBinding
+    List<com.google.inject.spi.Element> elements = Elements.getElements(module);
+    MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements);
+
+    // Execute the call to getEntries
+    List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements);
+
+    // Assert on the results
+    Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0);
+    assertEquals("A", firstEntry.getKey());
+    Binding<?> firstBinding = firstEntry.getValue();
+    assertEquals("a", ((InstanceBinding) firstBinding).getInstance());
+
+    Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1);
+    assertEquals("A", secondEntry.getKey());
+    Binding<?> secondBinding = secondEntry.getValue();
+    assertEquals("a", ((InstanceBinding) secondBinding).getInstance());
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void testGetEntriesMissingProviderMapEntry() {
+    List<com.google.inject.spi.Element> elements =
+        Lists.newArrayList(Elements.getElements(new MapBinderWithTwoEntriesModule()));
+
+    // Get the MapBinderBinding
+    MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements);
+
+    // Remove the ProviderMapEntry for "a" from the elements
+    com.google.inject.spi.Element providerMapEntryForA = getProviderMapEntry("keyOne", elements);
+    boolean removeSuccessful = elements.remove(providerMapEntryForA);
+    assertTrue(removeSuccessful);
+
+    // Execute the call to getEntries, we expect it to fail
+    try {
+      mapBinderBinding.getEntries(elements);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertContains(
+          expected.getMessage(),
+          "Expected a 1:1 mapping from map keys to values.",
+          "Found these Bindings that were missing an associated entry:",
+          "java.lang.String",
+          "bound at:",
+          "MapBinderWithTwoEntriesModule");
+    }
+  }
+
+  /**
+   * Will find and return the {@link com.google.inject.spi.Element} that is a {@link
+   * ProviderMapEntry} with a key that matches the one supplied by the user in {@code k}.
+   *
+   * <p>Will return {@code null} if it cannot be found.
+   */
+  private static com.google.inject.spi.Element getProviderMapEntry(
+      Object kToFind, Iterable<com.google.inject.spi.Element> elements) {
+    for (com.google.inject.spi.Element element : elements) {
+      if (element instanceof ProviderInstanceBinding) {
+        javax.inject.Provider<?> usp =
+            ((ProviderInstanceBinding<?>) element).getUserSuppliedProvider();
+        if (usp instanceof ProviderMapEntry) {
+          ProviderMapEntry<?, ?> pme = (ProviderMapEntry<?, ?>) usp;
+
+          // Check if the key from the ProviderMapEntry matches the one we're looking for
+          if (kToFind.equals(pme.getKey())) {
+            return element;
+          }
+        }
+      }
+    }
+    // No matching ProviderMapEntry found
+    return null;
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void testGetEntriesMissingBindingForValue() {
+    List<com.google.inject.spi.Element> elements =
+        Lists.newArrayList(Elements.getElements(new MapBinderWithTwoEntriesModule()));
+
+    // Get the MapBinderBinding
+    MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements);
+
+    // Remove the ProviderMapEntry for "a" from the elements
+    com.google.inject.spi.Element bindingForA = getInstanceBindingForValue("valueOne", elements);
+    boolean removeSuccessful = elements.remove(bindingForA);
+    assertTrue(removeSuccessful);
+
+    // Execute the call to getEntries, we expect it to fail
+    try {
+      mapBinderBinding.getEntries(elements);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertContains(
+          expected.getMessage(),
+          "Expected a 1:1 mapping from map keys to values.",
+          "Found these map keys without a corresponding value:",
+          "keyOne",
+          "bound at:",
+          "MapBinderWithTwoEntriesModule");
+    }
+  }
+
+  /**
+   * Will find and return the {@link com.google.inject.spi.Element} that is an {@link
+   * InstanceBinding} and binds {@code vToFind}.
+   */
+  private static com.google.inject.spi.Element getInstanceBindingForValue(
+      Object vToFind, Iterable<com.google.inject.spi.Element> elements) {
+    for (com.google.inject.spi.Element element : elements) {
+      if (element instanceof InstanceBinding) {
+        Object instanceFromBinding = ((InstanceBinding<?>) element).getInstance();
+        if (vToFind.equals(instanceFromBinding)) {
+          return element;
+        }
+      }
+    }
+    // No matching binding found
+    return null;
+  }
+
+  /** A simple module with a MapBinder with two entries. */
+  private static final class MapBinderWithTwoEntriesModule extends AbstractModule {
+    @Override
+    protected void configure() {
+      MapBinder<String, String> mapBinder =
+          MapBinder.newMapBinder(binder(), String.class, String.class);
+      mapBinder.addBinding("keyOne").toInstance("valueOne");
+      mapBinder.addBinding("keyTwo").toInstance("valueTwo");
+    }
+  }
+
+  /**
+   * Given an {@link Iterable} of elements, return the one that is a {@link MapBinderBinding}, or
+   * {@code null} if it cannot be found.
+   */
+  private static MapBinderBinding<?> getMapBinderBinding(
+      Iterable<com.google.inject.spi.Element> elements) {
+    final Collector collector = new Collector();
+    for (com.google.inject.spi.Element element : elements) {
+      element.acceptVisitor(
+          new DefaultElementVisitor<Void>() {
+            @Override
+            public <T> Void visit(Binding<T> binding) {
+              binding.acceptTargetVisitor(collector);
+              return null;
+            }
+          });
+    }
+    return collector.mapbinding;
+  }
+}
diff --git a/core/test/com/google/inject/internal/MoreTypesTest.java b/core/test/com/google/inject/internal/MoreTypesTest.java
index 0ce5504..c376eb0 100644
--- a/core/test/com/google/inject/internal/MoreTypesTest.java
+++ b/core/test/com/google/inject/internal/MoreTypesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,30 +17,32 @@
 package com.google.inject.internal;
 
 import com.google.inject.TypeLiteral;
-
-import junit.framework.TestCase;
-
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
-/**
- * @author schmitt@google.com (Peter Schmitt)
- */
+/** @author schmitt@google.com (Peter Schmitt) */
 public class MoreTypesTest extends TestCase {
 
   public void testParameterizedTypeToString() {
-    TypeLiteral<Inner<String>> innerString = new TypeLiteral<Inner<String>>(){};
-    assertEquals("com.google.inject.internal.MoreTypesTest$Inner<java.lang.String>",
+    TypeLiteral<Inner<String>> innerString = new TypeLiteral<Inner<String>>() {};
+    assertEquals(
+        "com.google.inject.internal.MoreTypesTest$Inner<java.lang.String>",
         MoreTypes.typeToString(innerString.getType()));
 
     TypeLiteral<Set<Inner<Integer>>> mapInnerInteger = new TypeLiteral<Set<Inner<Integer>>>() {};
-    assertEquals("java.util.Set<com.google.inject.internal.MoreTypesTest$Inner<java.lang.Integer>>",
+    assertEquals(
+        "java.util.Set<com.google.inject.internal.MoreTypesTest$Inner<java.lang.Integer>>",
         MoreTypes.typeToString(mapInnerInteger.getType()));
 
     TypeLiteral<Map<Inner<Long>, Set<Inner<Long>>>> mapInnerLongToSetInnerLong =
         new TypeLiteral<Map<Inner<Long>, Set<Inner<Long>>>>() {};
-    assertEquals("java.util.Map<com.google.inject.internal.MoreTypesTest$Inner<java.lang.Long>, "
+    assertEquals(
+        "java.util.Map<com.google.inject.internal.MoreTypesTest$Inner<java.lang.Long>, "
             + "java.util.Set<com.google.inject.internal.MoreTypesTest$Inner<java.lang.Long>>>",
         MoreTypes.typeToString(mapInnerLongToSetInnerLong.getType()));
   }
@@ -50,5 +52,13 @@
     assertTrue(MoreTypes.equals(new TypeLiteral<T>() {}.getType(), type));
   }
 
+  public <T> void testGetRawType_wildcard() throws Exception {
+    WildcardType wildcard =
+        (WildcardType)
+            ((ParameterizedType) new TypeLiteral<List<?>>() {}.getType())
+                .getActualTypeArguments()[0];
+    assertEquals(Object.class, MoreTypes.getRawType(wildcard));
+  }
+
   public static class Inner<T> {}
 }
diff --git a/core/test/com/google/inject/internal/MultibinderTest.java b/core/test/com/google/inject/internal/MultibinderTest.java
new file mode 100644
index 0000000..62d816b
--- /dev/null
+++ b/core/test/com/google/inject/internal/MultibinderTest.java
@@ -0,0 +1,1537 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.inject.internal;
+
+import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.internal.RealMultibinder.collectionOfJavaxProvidersOf;
+import static com.google.inject.internal.SpiUtils.VisitType.BOTH;
+import static com.google.inject.internal.SpiUtils.VisitType.MODULE;
+import static com.google.inject.internal.SpiUtils.assertSetVisitor;
+import static com.google.inject.internal.SpiUtils.instance;
+import static com.google.inject.internal.SpiUtils.providerInstance;
+import static com.google.inject.name.Names.named;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+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.Sets;
+import com.google.inject.AbstractModule;
+import com.google.inject.Binding;
+import com.google.inject.BindingAnnotation;
+import com.google.inject.CreationException;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.ProvisionException;
+import com.google.inject.Scopes;
+import com.google.inject.Stage;
+import com.google.inject.TypeLiteral;
+import com.google.inject.multibindings.MapBinder;
+import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.OptionalBinder;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.Elements;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.InstanceBinding;
+import com.google.inject.spi.LinkedKeyBinding;
+import com.google.inject.util.Modules;
+import com.google.inject.util.Providers;
+import com.google.inject.util.Types;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import junit.framework.TestCase;
+
+/** @author jessewilson@google.com (Jesse Wilson) */
+public class MultibinderTest extends TestCase {
+
+  final TypeLiteral<Optional<String>> optionalOfString = new TypeLiteral<Optional<String>>() {};
+  final TypeLiteral<Map<String, String>> mapOfStringString =
+      new TypeLiteral<Map<String, String>>() {};
+  final TypeLiteral<Set<String>> setOfString = new TypeLiteral<Set<String>>() {};
+  final TypeLiteral<Set<Integer>> setOfInteger = new TypeLiteral<Set<Integer>>() {};
+  final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
+  final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
+  final TypeLiteral<List<String>> listOfStrings = new TypeLiteral<List<String>>() {};
+  final TypeLiteral<Set<List<String>>> setOfListOfStrings = new TypeLiteral<Set<List<String>>>() {};
+  final TypeLiteral<Collection<Provider<String>>> collectionOfProvidersOfStrings =
+      new TypeLiteral<Collection<Provider<String>>>() {};
+
+  public void testMultibinderAggregatesMultipleModules() {
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Module de =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("D");
+            multibinder.addBinding().toInstance("E");
+          }
+        };
+
+    Injector injector = Guice.createInjector(abc, de);
+    Key<Set<String>> setKey = Key.get(setOfString);
+    Set<String> abcde = injector.getInstance(setKey);
+    Set<String> results = setOf("A", "B", "C", "D", "E");
+
+    assertEquals(results, abcde);
+    assertSetVisitor(
+        setKey,
+        stringType,
+        setOf(abc, de),
+        BOTH,
+        false,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"),
+        instance("D"),
+        instance("E"));
+  }
+
+  public void testMultibinderAggregationForAnnotationInstance() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+
+            multibinder = Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Set<String>> setKey = Key.get(setOfString, Names.named("abc"));
+    Set<String> abc = injector.getInstance(setKey);
+    Set<String> results = setOf("A", "B", "C");
+    assertEquals(results, abc);
+    assertSetVisitor(
+        setKey,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+  }
+
+  public void testMultibinderAggregationForAnnotationType() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class, Abc.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+
+            multibinder = Multibinder.newSetBinder(binder(), String.class, Abc.class);
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Set<String>> setKey = Key.get(setOfString, Abc.class);
+    Set<String> abcde = injector.getInstance(setKey);
+    Set<String> results = setOf("A", "B", "C");
+    assertEquals(results, abcde);
+    assertSetVisitor(
+        setKey,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+  }
+
+  public void testMultibinderWithMultipleAnnotationValueSets() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> abcMultibinder =
+                Multibinder.newSetBinder(binder(), String.class, named("abc"));
+            abcMultibinder.addBinding().toInstance("A");
+            abcMultibinder.addBinding().toInstance("B");
+            abcMultibinder.addBinding().toInstance("C");
+
+            Multibinder<String> deMultibinder =
+                Multibinder.newSetBinder(binder(), String.class, named("de"));
+            deMultibinder.addBinding().toInstance("D");
+            deMultibinder.addBinding().toInstance("E");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Set<String>> abcSetKey = Key.get(setOfString, named("abc"));
+    Set<String> abc = injector.getInstance(abcSetKey);
+    Key<Set<String>> deSetKey = Key.get(setOfString, named("de"));
+    Set<String> de = injector.getInstance(deSetKey);
+    Set<String> abcResults = setOf("A", "B", "C");
+    assertEquals(abcResults, abc);
+    Set<String> deResults = setOf("D", "E");
+    assertEquals(deResults, de);
+    assertSetVisitor(
+        abcSetKey,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+    assertSetVisitor(
+        deSetKey, stringType, setOf(module), BOTH, false, 1, instance("D"), instance("E"));
+  }
+
+  public void testMultibinderWithMultipleAnnotationTypeSets() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> abcMultibinder =
+                Multibinder.newSetBinder(binder(), String.class, Abc.class);
+            abcMultibinder.addBinding().toInstance("A");
+            abcMultibinder.addBinding().toInstance("B");
+            abcMultibinder.addBinding().toInstance("C");
+
+            Multibinder<String> deMultibinder =
+                Multibinder.newSetBinder(binder(), String.class, De.class);
+            deMultibinder.addBinding().toInstance("D");
+            deMultibinder.addBinding().toInstance("E");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Key<Set<String>> abcSetKey = Key.get(setOfString, Abc.class);
+    Set<String> abc = injector.getInstance(abcSetKey);
+    Key<Set<String>> deSetKey = Key.get(setOfString, De.class);
+    Set<String> de = injector.getInstance(deSetKey);
+    Set<String> abcResults = setOf("A", "B", "C");
+    assertEquals(abcResults, abc);
+    Set<String> deResults = setOf("D", "E");
+    assertEquals(deResults, de);
+    assertSetVisitor(
+        abcSetKey,
+        stringType,
+        setOf(module),
+        BOTH,
+        false,
+        1,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+    assertSetVisitor(
+        deSetKey, stringType, setOf(module), BOTH, false, 1, instance("D"), instance("E"));
+  }
+
+  public void testMultibinderWithMultipleSetTypes() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("A");
+            Multibinder.newSetBinder(binder(), Integer.class).addBinding().toInstance(1);
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    assertEquals(setOf("A"), injector.getInstance(Key.get(setOfString)));
+    assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
+    assertSetVisitor(
+        Key.get(setOfString), stringType, setOf(module), BOTH, false, 1, instance("A"));
+    assertSetVisitor(Key.get(setOfInteger), intType, setOf(module), BOTH, false, 1, instance(1));
+  }
+
+  public void testMultibinderWithEmptySet() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder.newSetBinder(binder(), String.class);
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Set<String> set = injector.getInstance(Key.get(setOfString));
+    assertEquals(Collections.emptySet(), set);
+    assertSetVisitor(Key.get(setOfString), stringType, setOf(module), BOTH, false, 0);
+  }
+
+  public void testMultibinderSetIsUnmodifiable() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("A");
+              }
+            });
+
+    Set<String> set = injector.getInstance(Key.get(setOfString));
+    try {
+      set.clear();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+
+  public void testMultibinderSetIsSerializable() throws IOException, ClassNotFoundException {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("A");
+              }
+            });
+
+    Set<String> set = injector.getInstance(Key.get(setOfString));
+    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+    ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
+    try {
+      objectOutputStream.writeObject(set);
+    } finally {
+      objectOutputStream.close();
+    }
+    ObjectInputStream objectInputStream =
+        new ObjectInputStream(new ByteArrayInputStream(byteStream.toByteArray()));
+    try {
+      Object setCopy = objectInputStream.readObject();
+      assertEquals(set, setCopy);
+    } finally {
+      objectInputStream.close();
+    }
+  }
+
+  public void testMultibinderSetIsLazy() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder.newSetBinder(binder(), Integer.class)
+                .addBinding()
+                .toProvider(
+                    new Provider<Integer>() {
+                      int nextValue = 1;
+
+                      @Override
+                      public Integer get() {
+                        return nextValue++;
+                      }
+                    });
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
+    assertEquals(setOf(2), injector.getInstance(Key.get(setOfInteger)));
+    assertEquals(setOf(3), injector.getInstance(Key.get(setOfInteger)));
+    assertSetVisitor(
+        Key.get(setOfInteger), intType, setOf(module), BOTH, false, 0, providerInstance(1));
+  }
+
+  public void testMultibinderSetForbidsDuplicateElements() {
+    Module module1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toProvider(Providers.of("A"));
+          }
+        };
+    Module module2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+          }
+        };
+    Injector injector = Guice.createInjector(module1, module2);
+
+    try {
+      injector.getInstance(Key.get(setOfString));
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) Set injection failed due to duplicated element \"A\"",
+          "Bound at " + module1.getClass().getName(),
+          "Bound at " + module2.getClass().getName());
+    }
+
+    // But we can still visit the module!
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(module1, module2),
+        MODULE,
+        false,
+        0,
+        instance("A"),
+        instance("A"));
+  }
+
+  public void testMultibinderSetShowsBothElementsIfToStringDifferent() {
+    // A simple example of a type whose toString returns more information than its equals method
+    // considers.
+    class ValueType {
+      int a;
+      int b;
+
+      ValueType(int a, int b) {
+        this.a = a;
+        this.b = b;
+      }
+
+      @Override
+      public boolean equals(Object obj) {
+        return (obj instanceof ValueType) && (((ValueType) obj).a == a);
+      }
+
+      @Override
+      public int hashCode() {
+        return a;
+      }
+
+      @Override
+      public String toString() {
+        return String.format("ValueType(%d,%d)", a, b);
+      }
+    }
+
+    Module module1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<ValueType> multibinder =
+                Multibinder.newSetBinder(binder(), ValueType.class);
+            multibinder.addBinding().toProvider(Providers.of(new ValueType(1, 2)));
+          }
+        };
+    Module module2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<ValueType> multibinder =
+                Multibinder.newSetBinder(binder(), ValueType.class);
+            multibinder.addBinding().toInstance(new ValueType(1, 3));
+          }
+        };
+    Injector injector = Guice.createInjector(module1, module2);
+
+    TypeLiteral<ValueType> valueType = TypeLiteral.get(ValueType.class);
+    TypeLiteral<Set<ValueType>> setOfValueType = new TypeLiteral<Set<ValueType>>() {};
+    try {
+      injector.getInstance(Key.get(setOfValueType));
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) Set injection failed due to multiple elements comparing equal:",
+          "\"ValueType(1,2)\"",
+          "bound at " + module1.getClass().getName(),
+          "\"ValueType(1,3)\"",
+          "bound at " + module2.getClass().getName());
+    }
+
+    // But we can still visit the module!
+    assertSetVisitor(
+        Key.get(setOfValueType),
+        valueType,
+        setOf(module1, module2),
+        MODULE,
+        false,
+        0,
+        instance(new ValueType(1, 2)),
+        instance(new ValueType(1, 3)));
+  }
+
+  public void testMultibinderSetPermitDuplicateElements() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+          }
+        };
+    Module bc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.permitDuplicates();
+            multibinder.addBinding().toInstance("B");
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(ab, bc);
+
+    assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(ab, bc),
+        BOTH,
+        true,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+  }
+
+  public void testMultibinderSetPermitDuplicateElementsFromOtherModule() {
+    // This module duplicates a binding for "B", which would normally be an error.
+    // Because module cd is also installed and the Multibinder<String>
+    // in cd sets permitDuplicates, there should be no error.
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+            multibinder.addBinding().toProvider(Providers.of("B"));
+          }
+        };
+    Module cd =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.permitDuplicates();
+            multibinder.addBinding().toInstance("C");
+            multibinder.addBinding().toInstance("D");
+          }
+        };
+    Injector injector = Guice.createInjector(ab, cd);
+
+    assertEquals(setOf("A", "B", "C", "D"), injector.getInstance(Key.get(setOfString)));
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(ab, cd),
+        BOTH,
+        true,
+        0,
+        instance("A"),
+        instance("B"),
+        providerInstance("B"),
+        instance("C"),
+        instance("D"));
+  }
+
+  public void testMultibinderSetPermitDuplicateCallsToPermitDuplicates() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.permitDuplicates();
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+          }
+        };
+    Module bc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.permitDuplicates();
+            multibinder.addBinding().toInstance("B");
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Injector injector = Guice.createInjector(ab, bc);
+
+    assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(ab, bc),
+        BOTH,
+        true,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"));
+  }
+
+  public void testMultibinderSetForbidsNullElements() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder.newSetBinder(binder(), String.class)
+                .addBinding()
+                .toProvider(Providers.<String>of(null));
+          }
+        };
+    Injector injector = Guice.createInjector(m);
+
+    try {
+      injector.getInstance(Key.get(setOfString));
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(
+          expected.getMessage(),
+          "1) Set injection failed due to null element bound at: "
+              + m.getClass().getName()
+              + ".configure(");
+    }
+  }
+
+  public void testSourceLinesInMultibindings() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              Multibinder.newSetBinder(binder(), Integer.class).addBinding();
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(
+          expected.getMessage(),
+          true,
+          "No implementation for java.lang.Integer",
+          "at " + getClass().getName());
+    }
+  }
+
+  /**
+   * We just want to make sure that multibinder's binding depends on each of its values. We don't
+   * really care about the underlying structure of those bindings, which are implementation details.
+   */
+  public void testMultibinderDependencies() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+                multibinder.addBinding().toInstance("A");
+                multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
+
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<String> elements = Sets.newHashSet();
+    for (Dependency<?> dependency : withDependencies.getDependencies()) {
+      elements.add((String) injector.getInstance(dependency.getKey()));
+    }
+    assertEquals(ImmutableSet.of("A", "B"), elements);
+  }
+
+  /**
+   * We just want to make sure that multibinder's binding depends on each of its values. We don't
+   * really care about the underlying structure of those bindings, which are implementation details.
+   */
+  public void testMultibinderDependenciesInToolStage() {
+    Injector injector =
+        Guice.createInjector(
+            Stage.TOOL,
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+                multibinder.addBinding().toInstance("A");
+                multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
+
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
+    HasDependencies withDependencies = (HasDependencies) binding;
+    InstanceBinding<?> instanceBinding = null;
+    LinkedKeyBinding<?> linkedBinding = null;
+    // The non-tool stage test can test this by calling injector.getInstance to ensure
+    // the right values are returned -- in tool stage we can't do that.  It's also a
+    // little difficult to validate the dependencies & bindings, because they're
+    // bindings created internally within Multibinder.
+    // To workaround this, we just validate that the dependencies lookup to a single
+    // InstanceBinding whose value is "A" and another LinkedBinding whose target is
+    // the Key of @Named("b") String=B
+    for (Dependency<?> dependency : withDependencies.getDependencies()) {
+      Binding<?> b = injector.getBinding(dependency.getKey());
+      if (b instanceof InstanceBinding) {
+        if (instanceBinding != null) {
+          fail(
+              "Already have an instance binding of: "
+                  + instanceBinding
+                  + ", and now want to add: "
+                  + b);
+        } else {
+          instanceBinding = (InstanceBinding) b;
+        }
+      } else if (b instanceof LinkedKeyBinding) {
+        if (linkedBinding != null) {
+          fail(
+              "Already have a linked binding of: " + linkedBinding + ", and now want to add: " + b);
+        } else {
+          linkedBinding = (LinkedKeyBinding) b;
+        }
+      } else {
+        fail("Unexpected dependency of: " + dependency);
+      }
+    }
+
+    assertNotNull(instanceBinding);
+    assertNotNull(linkedBinding);
+
+    assertEquals("A", instanceBinding.getInstance());
+    assertEquals(Key.get(String.class, Names.named("b")), linkedBinding.getLinkedKey());
+  }
+
+  /**
+   * Our implementation maintains order, but doesn't guarantee it in the API spec. TODO: specify the
+   * iteration order?
+   */
+  public void testBindOrderEqualsIterationOrder() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+                multibinder.addBinding().toInstance("leonardo");
+                multibinder.addBinding().toInstance("donatello");
+                install(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        Multibinder.newSetBinder(binder(), String.class)
+                            .addBinding()
+                            .toInstance("michaelangelo");
+                      }
+                    });
+              }
+            },
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("raphael");
+              }
+            });
+
+    List<String> inOrder = ImmutableList.copyOf(injector.getInstance(Key.get(setOfString)));
+    assertEquals(ImmutableList.of("leonardo", "donatello", "michaelangelo", "raphael"), inOrder);
+  }
+
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface Abc {}
+
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface De {}
+
+  private <T> Set<T> setOf(T... elements) {
+    Set<T> result = Sets.newHashSet();
+    Collections.addAll(result, elements);
+    return result;
+  }
+
+  /** With overrides, we should get the union of all multibindings. */
+  public void testModuleOverrideAndMultibindings() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+          }
+        };
+    Module cd =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("C");
+            multibinder.addBinding().toInstance("D");
+          }
+        };
+    Module ef =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("E");
+            multibinder.addBinding().toInstance("F");
+          }
+        };
+
+    Module abcd = Modules.override(ab).with(cd);
+    Injector injector = Guice.createInjector(abcd, ef);
+    assertEquals(
+        ImmutableSet.of("A", "B", "C", "D", "E", "F"), injector.getInstance(Key.get(setOfString)));
+
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(abcd, ef),
+        BOTH,
+        false,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"),
+        instance("D"),
+        instance("E"),
+        instance("F"));
+  }
+
+  /** With overrides, we should get the union of all multibindings. */
+  public void testModuleOverrideAndMultibindingsWithPermitDuplicates() {
+    Module abc =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+            multibinder.addBinding().toInstance("C");
+            multibinder.permitDuplicates();
+          }
+        };
+    Module cd =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("C");
+            multibinder.addBinding().toInstance("D");
+            multibinder.permitDuplicates();
+          }
+        };
+    Module ef =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("E");
+            multibinder.addBinding().toInstance("F");
+            multibinder.permitDuplicates();
+          }
+        };
+
+    Module abcd = Modules.override(abc).with(cd);
+    Injector injector = Guice.createInjector(abcd, ef);
+    assertEquals(
+        ImmutableSet.of("A", "B", "C", "D", "E", "F"), injector.getInstance(Key.get(setOfString)));
+
+    assertSetVisitor(
+        Key.get(setOfString),
+        stringType,
+        setOf(abcd, ef),
+        BOTH,
+        true,
+        0,
+        instance("A"),
+        instance("B"),
+        instance("C"),
+        instance("D"),
+        instance("E"),
+        instance("F"));
+  }
+
+  /** Doubly-installed modules should not conflict, even when one is overridden. */
+  public void testModuleOverrideRepeatedInstallsAndMultibindings_toInstance() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toInstance("A");
+            multibinder.addBinding().toInstance("B");
+          }
+        };
+
+    // Guice guarantees this assertion, as the same module cannot be installed twice.
+    assertEquals(
+        ImmutableSet.of("A", "B"), Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
+
+    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
+    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
+    assertEquals(ImmutableSet.of("A", "B"), injector.getInstance(Key.get(setOfString)));
+  }
+
+  public void testModuleOverrideRepeatedInstallsAndMultibindings_toKey() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Key<String> aKey = Key.get(String.class, Names.named("A_string"));
+            Key<String> bKey = Key.get(String.class, Names.named("B_string"));
+            bind(aKey).toInstance("A");
+            bind(bKey).toInstance("B");
+
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().to(aKey);
+            multibinder.addBinding().to(bKey);
+          }
+        };
+
+    // Guice guarantees this assertion, as the same module cannot be installed twice.
+    assertEquals(
+        ImmutableSet.of("A", "B"), Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
+
+    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
+    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
+    assertEquals(ImmutableSet.of("A", "B"), injector.getInstance(Key.get(setOfString)));
+  }
+
+  public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderInstance() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toProvider(Providers.of("A"));
+            multibinder.addBinding().toProvider(Providers.of("B"));
+          }
+        };
+
+    // Guice guarantees this assertion, as the same module cannot be installed twice.
+    assertEquals(
+        ImmutableSet.of("A", "B"), Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
+
+    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
+    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
+    assertEquals(ImmutableSet.of("A", "B"), injector.getInstance(Key.get(setOfString)));
+  }
+
+  private static class AStringProvider implements Provider<String> {
+    @Override
+    public String get() {
+      return "A";
+    }
+  }
+
+  private static class BStringProvider implements Provider<String> {
+    @Override
+    public String get() {
+      return "B";
+    }
+  }
+
+  public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderKey() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toProvider(Key.get(AStringProvider.class));
+            multibinder.addBinding().toProvider(Key.get(BStringProvider.class));
+          }
+        };
+
+    // Guice guarantees this assertion, as the same module cannot be installed twice.
+    assertEquals(
+        ImmutableSet.of("A", "B"), Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
+
+    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
+    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
+    assertEquals(ImmutableSet.of("A", "B"), injector.getInstance(Key.get(setOfString)));
+  }
+
+  private static class StringGrabber {
+    private final String string;
+
+    @SuppressWarnings("unused") // Found by reflection
+    public StringGrabber(@Named("A_string") String string) {
+      this.string = string;
+    }
+
+    @SuppressWarnings("unused") // Found by reflection
+    public StringGrabber(@Named("B_string") String string, int unused) {
+      this.string = string;
+    }
+
+    @Override
+    public int hashCode() {
+      return string.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return (obj instanceof StringGrabber) && ((StringGrabber) obj).string.equals(string);
+    }
+
+    @Override
+    public String toString() {
+      return "StringGrabber(" + string + ")";
+    }
+
+    static Set<String> values(Iterable<StringGrabber> grabbers) {
+      Set<String> result = new HashSet<>();
+      for (StringGrabber grabber : grabbers) {
+        result.add(grabber.string);
+      }
+      return result;
+    }
+  }
+
+  public void testModuleOverrideRepeatedInstallsAndMultibindings_toConstructor() {
+    TypeLiteral<Set<StringGrabber>> setOfStringGrabber = new TypeLiteral<Set<StringGrabber>>() {};
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Key<String> aKey = Key.get(String.class, Names.named("A_string"));
+            Key<String> bKey = Key.get(String.class, Names.named("B_string"));
+            bind(aKey).toInstance("A");
+            bind(bKey).toInstance("B");
+            bind(Integer.class).toInstance(0); // used to disambiguate constructors
+
+            Multibinder<StringGrabber> multibinder =
+                Multibinder.newSetBinder(binder(), StringGrabber.class);
+            try {
+              multibinder
+                  .addBinding()
+                  .toConstructor(StringGrabber.class.getConstructor(String.class));
+              multibinder
+                  .addBinding()
+                  .toConstructor(StringGrabber.class.getConstructor(String.class, int.class));
+            } catch (NoSuchMethodException e) {
+              fail("No such method: " + e.getMessage());
+            }
+          }
+        };
+
+    // Guice guarantees this assertion, as the same module cannot be installed twice.
+    assertEquals(
+        ImmutableSet.of("A", "B"),
+        StringGrabber.values(
+            Guice.createInjector(ab, ab).getInstance(Key.get(setOfStringGrabber))));
+
+    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
+    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
+    assertEquals(
+        ImmutableSet.of("A", "B"),
+        StringGrabber.values(injector.getInstance(Key.get(setOfStringGrabber))));
+  }
+
+  /**
+   * Unscoped bindings should not conflict, whether they were bound with no explicit scope, or
+   * explicitly bound in {@link Scopes#NO_SCOPE}.
+   */
+  public void testDuplicateUnscopedBindings() {
+    Module singleBinding =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).to(Key.get(Integer.class, named("A")));
+            bind(Integer.class).to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
+          }
+
+          @Provides
+          @Named("A")
+          int provideInteger() {
+            return 5;
+          }
+        };
+    Module multibinding =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<Integer> multibinder = Multibinder.newSetBinder(binder(), Integer.class);
+            multibinder.addBinding().to(Key.get(Integer.class, named("A")));
+            multibinder.addBinding().to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
+          }
+        };
+
+    assertEquals(5, (int) Guice.createInjector(singleBinding).getInstance(Integer.class));
+    assertEquals(
+        ImmutableSet.of(5),
+        Guice.createInjector(singleBinding, multibinding).getInstance(Key.get(setOfInteger)));
+  }
+
+  /** Ensure key hash codes are fixed at injection time, not binding time. */
+  public void testKeyHashCodesFixedAtInjectionTime() {
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<List<String>> multibinder =
+                Multibinder.newSetBinder(binder(), listOfStrings);
+            List<String> list = Lists.newArrayList();
+            multibinder.addBinding().toInstance(list);
+            list.add("A");
+            list.add("B");
+          }
+        };
+
+    Injector injector = Guice.createInjector(ab);
+    for (Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
+      Key<?> bindingKey = entry.getKey();
+      Key<?> clonedKey;
+      if (bindingKey.getAnnotation() != null) {
+        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotation());
+      } else if (bindingKey.getAnnotationType() != null) {
+        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotationType());
+      } else {
+        clonedKey = Key.get(bindingKey.getTypeLiteral());
+      }
+      assertEquals(bindingKey, clonedKey);
+      assertEquals(
+          "Incorrect hashcode for " + bindingKey + " -> " + entry.getValue(),
+          bindingKey.hashCode(),
+          clonedKey.hashCode());
+    }
+  }
+
+  /** Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */
+  public void testBindingKeysFixedOnReturnFromGetElements() {
+    final List<String> list = Lists.newArrayList();
+    Module ab =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<List<String>> multibinder =
+                Multibinder.newSetBinder(binder(), listOfStrings);
+            multibinder.addBinding().toInstance(list);
+            list.add("A");
+            list.add("B");
+          }
+        };
+
+    InstanceBinding<?> binding =
+        Iterables.getOnlyElement(Iterables.filter(Elements.getElements(ab), InstanceBinding.class));
+    Key<?> keyBefore = binding.getKey();
+    assertEquals(listOfStrings, keyBefore.getTypeLiteral());
+
+    list.add("C");
+    Key<?> keyAfter = binding.getKey();
+    assertSame(keyBefore, keyAfter);
+  }
+
+  /*
+   * Verify through gratuitous mutation that key hashCode snapshots and whatnot happens at the right
+   * times, by binding two lists that are different at injector creation, but compare equal when the
+   * module is configured *and* when the set is instantiated.
+   */
+  public void testConcurrentMutation_bindingsDiffentAtInjectorCreation() {
+    // We initially bind two equal lists
+    final List<String> list1 = Lists.newArrayList();
+    final List<String> list2 = Lists.newArrayList();
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<List<String>> multibinder =
+                Multibinder.newSetBinder(binder(), listOfStrings);
+            multibinder.addBinding().toInstance(list1);
+            multibinder.addBinding().toInstance(list2);
+          }
+        };
+    List<Element> elements = Elements.getElements(module);
+
+    // Now we change the lists so they no longer match, and create the injector.
+    list1.add("A");
+    list2.add("B");
+    Injector injector = Guice.createInjector(Elements.getModule(elements));
+
+    // Now we change the lists so they compare equal again, and create the set.
+    list1.add(1, "B");
+    list2.add(0, "A");
+    try {
+      injector.getInstance(Key.get(setOfListOfStrings));
+      fail();
+    } catch (ProvisionException e) {
+      assertEquals(1, e.getErrorMessages().size());
+      assertContains(
+          Iterables.getOnlyElement(e.getErrorMessages()).getMessage().toString(),
+          "Set injection failed due to duplicated element \"[A, B]\"");
+    }
+
+    // Finally, we change the lists again so they are once more different, and ensure the set
+    // contains both.
+    list1.remove("A");
+    list2.remove("B");
+    Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
+    assertEquals(ImmutableSet.of(ImmutableList.of("A"), ImmutableList.of("B")), set);
+  }
+
+  /*
+   * Verify through gratuitous mutation that key hashCode snapshots and whatnot happen at the right
+   * times, by binding two lists that compare equal at injector creation, but are different when the
+   * module is configured *and* when the set is instantiated.
+   */
+  public void testConcurrentMutation_bindingsSameAtInjectorCreation() {
+    // We initially bind two distinct lists
+    final List<String> list1 = Lists.newArrayList("A");
+    final List<String> list2 = Lists.newArrayList("B");
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Multibinder<List<String>> multibinder =
+                Multibinder.newSetBinder(binder(), listOfStrings);
+            multibinder.addBinding().toInstance(list1);
+            multibinder.addBinding().toInstance(list2);
+          }
+        };
+    List<Element> elements = Elements.getElements(module);
+
+    // Now we change the lists so they compare equal, and create the injector.
+    list1.add(1, "B");
+    list2.add(0, "A");
+    Injector injector = Guice.createInjector(Elements.getModule(elements));
+
+    // Now we change the lists again so they are once more different, and create the set.
+    list1.remove("A");
+    list2.remove("B");
+    Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
+
+    // The set will contain just one of the two lists.
+    // (In fact, it will be the first one we bound, but we don't promise that, so we won't test it.)
+    assertTrue(
+        ImmutableSet.of(ImmutableList.of("A")).equals(set)
+            || ImmutableSet.of(ImmutableList.of("B")).equals(set));
+  }
+
+  @BindingAnnotation
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+  private static @interface Marker {}
+
+  @Marker
+  public void testMultibinderMatching() throws Exception {
+    Method m = MultibinderTest.class.getDeclaredMethod("testMultibinderMatching");
+    assertNotNull(m);
+    final Annotation marker = m.getAnnotation(Marker.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              public void configure() {
+                Multibinder<Integer> mb1 =
+                    Multibinder.newSetBinder(binder(), Integer.class, Marker.class);
+                Multibinder<Integer> mb2 =
+                    Multibinder.newSetBinder(binder(), Integer.class, marker);
+                mb1.addBinding().toInstance(1);
+                mb2.addBinding().toInstance(2);
+
+                // This assures us that the two binders are equivalent, so we expect the instance added to
+                // each to have been added to one set.
+                assertEquals(mb1, mb2);
+              }
+            });
+    TypeLiteral<Set<Integer>> t = new TypeLiteral<Set<Integer>>() {};
+    Set<Integer> s1 = injector.getInstance(Key.get(t, Marker.class));
+    Set<Integer> s2 = injector.getInstance(Key.get(t, marker));
+
+    // This assures us that the two sets are in fact equal.  They may not be same set (as in Java
+    // object identical), but we shouldn't expect that, since probably Guice creates the set each
+    // time in case the elements are dependent on scope.
+    assertEquals(s1, s2);
+
+    // This ensures that MultiBinder is internally using the correct set name --
+    // making sure that instances of marker annotations have the same set name as
+    // MarkerAnnotation.class.
+    Set<Integer> expected = new HashSet<>();
+    expected.add(1);
+    expected.add(2);
+    assertEquals(expected, s1);
+  }
+
+  // See issue 670
+  public void testSetAndMapValueAreDistinct() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("A");
+
+                MapBinder.newMapBinder(binder(), String.class, String.class)
+                    .addBinding("B")
+                    .toInstance("b");
+
+                OptionalBinder.newOptionalBinder(binder(), String.class)
+                    .setDefault()
+                    .toInstance("C");
+                OptionalBinder.newOptionalBinder(binder(), String.class)
+                    .setBinding()
+                    .toInstance("D");
+              }
+            });
+
+    assertEquals(ImmutableSet.of("A"), injector.getInstance(Key.get(setOfString)));
+    assertEquals(ImmutableMap.of("B", "b"), injector.getInstance(Key.get(mapOfStringString)));
+    assertEquals(Optional.of("D"), injector.getInstance(Key.get(optionalOfString)));
+  }
+
+  // See issue 670
+  public void testSetAndMapValueAreDistinctInSpi() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("A");
+
+                MapBinder.newMapBinder(binder(), String.class, String.class)
+                    .addBinding("B")
+                    .toInstance("b");
+
+                OptionalBinder.newOptionalBinder(binder(), String.class)
+                    .setDefault()
+                    .toInstance("C");
+              }
+            });
+    Collector collector = new Collector();
+    Binding<Map<String, String>> mapbinding = injector.getBinding(Key.get(mapOfStringString));
+    mapbinding.acceptTargetVisitor(collector);
+    assertNotNull(collector.mapbinding);
+
+    Binding<Set<String>> setbinding = injector.getBinding(Key.get(setOfString));
+    setbinding.acceptTargetVisitor(collector);
+    assertNotNull(collector.setbinding);
+
+    Binding<Optional<String>> optionalbinding = injector.getBinding(Key.get(optionalOfString));
+    optionalbinding.acceptTargetVisitor(collector);
+    assertNotNull(collector.optionalbinding);
+
+    // There should only be three instance bindings for string types
+    // (but because of the OptionalBinder, there's 2 ProviderInstanceBindings also).
+    // We also know the InstanceBindings will be in the order: A, b, C because that's
+    // how we bound them, and binding order is preserved.
+    List<Binding<String>> bindings =
+        FluentIterable.from(injector.findBindingsByType(stringType))
+            .filter(Predicates.instanceOf(InstanceBinding.class))
+            .toList();
+    assertEquals(bindings.toString(), 3, bindings.size());
+    Binding<String> a = bindings.get(0);
+    Binding<String> b = bindings.get(1);
+    Binding<String> c = bindings.get(2);
+    assertEquals("A", ((InstanceBinding<String>) a).getInstance());
+    assertEquals("b", ((InstanceBinding<String>) b).getInstance());
+    assertEquals("C", ((InstanceBinding<String>) c).getInstance());
+
+    // Make sure the correct elements belong to their own sets.
+    assertFalse(collector.mapbinding.containsElement(a));
+    assertTrue(collector.mapbinding.containsElement(b));
+    assertFalse(collector.mapbinding.containsElement(c));
+
+    assertTrue(collector.setbinding.containsElement(a));
+    assertFalse(collector.setbinding.containsElement(b));
+    assertFalse(collector.setbinding.containsElement(c));
+
+    assertFalse(collector.optionalbinding.containsElement(a));
+    assertFalse(collector.optionalbinding.containsElement(b));
+    assertTrue(collector.optionalbinding.containsElement(c));
+  }
+
+  public void testMultibinderCanInjectCollectionOfProviders() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class);
+            multibinder.addBinding().toProvider(Providers.of("A"));
+            multibinder.addBinding().toProvider(Providers.of("B"));
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
+
+    Injector injector = Guice.createInjector(module);
+
+    Collection<Provider<String>> providers =
+        injector.getInstance(Key.get(collectionOfProvidersOfStrings));
+    assertEquals(expectedValues, collectValues(providers));
+
+    Collection<javax.inject.Provider<String>> javaxProviders =
+        injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType)));
+    assertEquals(expectedValues, collectValues(javaxProviders));
+  }
+
+  public void testMultibinderCanInjectCollectionOfProvidersWithAnnotation() {
+    final Annotation ann = Names.named("foo");
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            final Multibinder<String> multibinder =
+                Multibinder.newSetBinder(binder(), String.class, ann);
+            multibinder.addBinding().toProvider(Providers.of("A"));
+            multibinder.addBinding().toProvider(Providers.of("B"));
+            multibinder.addBinding().toInstance("C");
+          }
+        };
+    Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
+
+    Injector injector = Guice.createInjector(module);
+
+    Collection<Provider<String>> providers =
+        injector.getInstance(Key.get(collectionOfProvidersOfStrings, ann));
+    Collection<String> values = collectValues(providers);
+    assertEquals(expectedValues, values);
+
+    Collection<javax.inject.Provider<String>> javaxProviders =
+        injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType), ann));
+    assertEquals(expectedValues, collectValues(javaxProviders));
+  }
+
+  public void testMultibindingProviderDependencies() {
+    final Annotation setAnn = Names.named("foo");
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder<String> multibinder =
+                    Multibinder.newSetBinder(binder(), String.class, setAnn);
+                multibinder.addBinding().toInstance("a");
+                multibinder.addBinding().toInstance("b");
+              }
+            });
+    HasDependencies providerBinding =
+        (HasDependencies) injector.getBinding(new Key<Collection<Provider<String>>>(setAnn) {});
+    HasDependencies setBinding =
+        (HasDependencies) injector.getBinding(new Key<Set<String>>(setAnn) {});
+    // sanity check the size
+    assertEquals(setBinding.getDependencies().toString(), 2, setBinding.getDependencies().size());
+    Set<Dependency<?>> expected = Sets.newHashSet();
+    for (Dependency<?> dep : setBinding.getDependencies()) {
+      Key key = dep.getKey();
+      Dependency<?> providerDependency =
+          Dependency.get(key.ofType(Types.providerOf(key.getTypeLiteral().getType())));
+      expected.add(providerDependency);
+    }
+    assertEquals(expected, providerBinding.getDependencies());
+  }
+
+  public void testEmptyMultibinder() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Multibinder.newSetBinder(binder(), String.class);
+              }
+            });
+    assertEquals(ImmutableSet.of(), injector.getInstance(new Key<Set<String>>() {}));
+    assertEquals(
+        ImmutableList.of(), injector.getInstance(new Key<Collection<Provider<String>>>() {}));
+  }
+
+  private static final class ObjectWithInjectionPoint {
+    boolean setterHasBeenCalled;
+
+    @Inject
+    void setter(String dummy) {
+      setterHasBeenCalled = true;
+    }
+  }
+
+  // This tests for a behavior where InstanceBindingImpl.getProvider() would return uninitialized
+  // instances if called during injector creation (depending on the order of injection requests).
+  public void testMultibinderDependsOnInstanceBindingWithInjectionPoints() {
+    Guice.createInjector(
+        new AbstractModule() {
+          private Provider<Set<ObjectWithInjectionPoint>> provider;
+
+          @Override
+          protected void configure() {
+            bind(Object.class).toInstance(this); // force setter() to be injected first
+            bind(String.class).toInstance("foo");
+            this.provider = getProvider(new Key<Set<ObjectWithInjectionPoint>>() {});
+            Multibinder.newSetBinder(binder(), ObjectWithInjectionPoint.class)
+                .addBinding()
+                .toInstance(new ObjectWithInjectionPoint());
+          }
+
+          @Inject
+          void setter(String s) {
+            for (ObjectWithInjectionPoint item : provider.get()) {
+              assertTrue(item.setterHasBeenCalled);
+            }
+          }
+        });
+  }
+
+  private <T> Collection<T> collectValues(
+      Collection<? extends javax.inject.Provider<T>> providers) {
+    Collection<T> values = Lists.newArrayList();
+    for (javax.inject.Provider<T> provider : providers) {
+      values.add(provider.get());
+    }
+    return values;
+  }
+}
diff --git a/core/test/com/google/inject/internal/OptionalBinderTest.java b/core/test/com/google/inject/internal/OptionalBinderTest.java
new file mode 100644
index 0000000..43ecb76
--- /dev/null
+++ b/core/test/com/google/inject/internal/OptionalBinderTest.java
@@ -0,0 +1,1476 @@
+/*
+ * 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.google.inject.internal;
+
+import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.internal.SpiUtils.assertOptionalVisitor;
+import static com.google.inject.internal.SpiUtils.instance;
+import static com.google.inject.internal.SpiUtils.linked;
+import static com.google.inject.internal.SpiUtils.providerInstance;
+import static com.google.inject.internal.SpiUtils.providerKey;
+import static com.google.inject.name.Names.named;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.inject.AbstractModule;
+import com.google.inject.Asserts;
+import com.google.inject.Binding;
+import com.google.inject.BindingAnnotation;
+import com.google.inject.CreationException;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.SpiUtils.VisitType;
+import com.google.inject.multibindings.OptionalBinder;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Elements;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.InstanceBinding;
+import com.google.inject.util.Modules;
+import com.google.inject.util.Providers;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import junit.framework.TestCase;
+
+/** @author sameb@google.com (Sam Berlin) */
+public class OptionalBinderTest extends TestCase {
+
+  private static final boolean HAS_JAVA_OPTIONAL;
+  private static final Class<?> JAVA_OPTIONAL_CLASS;
+  private static final Method JAVA_OPTIONAL_OR_ELSE;
+
+  static {
+    Class<?> optional = null;
+    Method orElse = null;
+    try {
+      optional = Class.forName("java.util.Optional");
+      orElse = optional.getDeclaredMethod("orElse", Object.class);
+    } catch (ClassNotFoundException ignored) {
+    } catch (NoSuchMethodException ignored) {
+    } catch (SecurityException ignored) {
+    }
+    HAS_JAVA_OPTIONAL = optional != null;
+    JAVA_OPTIONAL_CLASS = optional;
+    JAVA_OPTIONAL_OR_ELSE = orElse;
+  }
+
+  final Key<String> stringKey = Key.get(String.class);
+  final TypeLiteral<Optional<String>> optionalOfString = new TypeLiteral<Optional<String>>() {};
+  final TypeLiteral<?> javaOptionalOfString =
+      HAS_JAVA_OPTIONAL ? RealOptionalBinder.javaOptionalOf(stringKey.getTypeLiteral()) : null;
+  final TypeLiteral<Optional<Provider<String>>> optionalOfProviderString =
+      new TypeLiteral<Optional<Provider<String>>>() {};
+  final TypeLiteral<?> javaOptionalOfProviderString =
+      HAS_JAVA_OPTIONAL
+          ? RealOptionalBinder.javaOptionalOfProvider(stringKey.getTypeLiteral())
+          : null;
+  final TypeLiteral<Optional<javax.inject.Provider<String>>> optionalOfJavaxProviderString =
+      new TypeLiteral<Optional<javax.inject.Provider<String>>>() {};
+  final TypeLiteral<?> javaOptionalOfJavaxProviderString =
+      HAS_JAVA_OPTIONAL
+          ? RealOptionalBinder.javaOptionalOfJavaxProvider(stringKey.getTypeLiteral())
+          : null;
+
+  final Key<Integer> intKey = Key.get(Integer.class);
+  final TypeLiteral<Optional<Integer>> optionalOfInteger = new TypeLiteral<Optional<Integer>>() {};
+  final TypeLiteral<?> javaOptionalOfInteger =
+      HAS_JAVA_OPTIONAL ? RealOptionalBinder.javaOptionalOf(intKey.getTypeLiteral()) : null;
+  final TypeLiteral<Optional<Provider<Integer>>> optionalOfProviderInteger =
+      new TypeLiteral<Optional<Provider<Integer>>>() {};
+  final TypeLiteral<?> javaOptionalOfProviderInteger =
+      HAS_JAVA_OPTIONAL ? RealOptionalBinder.javaOptionalOfProvider(intKey.getTypeLiteral()) : null;
+  final TypeLiteral<Optional<javax.inject.Provider<Integer>>> optionalOfJavaxProviderInteger =
+      new TypeLiteral<Optional<javax.inject.Provider<Integer>>>() {};
+  final TypeLiteral<?> javaOptionalOfJavaxProviderInteger =
+      HAS_JAVA_OPTIONAL
+          ? RealOptionalBinder.javaOptionalOfJavaxProvider(intKey.getTypeLiteral())
+          : null;
+
+  final TypeLiteral<List<String>> listOfStrings = new TypeLiteral<List<String>>() {};
+
+  public void testTypeNotBoundByDefault() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class);
+            requireBinding(new Key<Optional<String>>() {}); // the above specifies this.
+            requireBinding(String.class); // but it doesn't specify this.
+            binder().requireExplicitBindings(); // need to do this, otherwise String will JIT
+
+            if (HAS_JAVA_OPTIONAL) {
+              requireBinding(Key.get(javaOptionalOfString));
+            }
+          }
+        };
+
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException ce) {
+      assertContains(
+          ce.getMessage(),
+          "1) Explicit bindings are required and java.lang.String is not explicitly bound.");
+      assertEquals(1, ce.getErrorMessages().size());
+    }
+  }
+
+  public void testOptionalIsAbsentByDefault() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class);
+          }
+        };
+
+    Injector injector = Guice.createInjector(module);
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertFalse(optional.isPresent());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertFalse(optionalP.isPresent());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertFalse(optionalJxP.isPresent());
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, null, null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertFalse(optional.isPresent());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertFalse(optionalP.isPresent());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertFalse(optionalJxP.isPresent());
+    }
+  }
+
+  public void testUsesUserBoundValue() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class);
+          }
+
+          @Provides
+          String provideString() {
+            return "foo";
+          }
+        };
+
+    Injector injector = Guice.createInjector(module);
+    assertEquals("foo", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertEquals("foo", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertEquals("foo", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertEquals("foo", optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey, setOf(module), VisitType.BOTH, 0, null, null, providerInstance("foo"));
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertEquals("foo", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertEquals("foo", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertEquals("foo", optionalJxP.get().get());
+    }
+  }
+
+  public void testUsesUserBoundValueNullProvidersMakeAbsent() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class);
+          }
+
+          @Provides
+          String provideString() {
+            return null;
+          }
+        };
+
+    Injector injector = Guice.createInjector(module);
+    assertEquals(null, injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertFalse(optional.isPresent());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertEquals(null, optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertEquals(null, optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey, setOf(module), VisitType.BOTH, 0, null, null, providerInstance(null));
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertFalse(optional.isPresent());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertEquals(null, optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertEquals(null, optionalJxP.get().get());
+    }
+  }
+
+  private static class JitBinding {
+    @Inject
+    JitBinding() {}
+  }
+
+  private static class DependsOnJitBinding {
+    @Inject
+    DependsOnJitBinding(JitBinding jitBinding) {}
+  }
+
+  // A previous version of OptionalBinder would fail to find jit dependendencies that were created
+  // by other bindings
+  public void testOptionalBinderDependsOnJitBinding() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), JitBinding.class);
+          }
+        };
+
+    // Everything should be absent since nothing triggered discovery of the jit binding
+    Injector injector = Guice.createInjector(module);
+    assertFalse(injector.getInstance(optionalKey(JitBinding.class)).isPresent());
+    assertNull(injector.getExistingBinding(Key.get(JitBinding.class)));
+
+    // in this case, because jit bindings are allowed in this injector, the DependsOnJitBinding
+    // binding will get initialized and create jit bindings for its dependency. The optionalbinder
+    // should then pick it up
+    module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), JitBinding.class);
+            bind(DependsOnJitBinding.class);
+          }
+        };
+    injector = Guice.createInjector(module);
+    assertTrue(injector.getInstance(optionalKey(JitBinding.class)).isPresent());
+    assertNotNull(injector.getExistingBinding(Key.get(JitBinding.class)));
+
+    // in this case, because the jit binding is discovered dynamically, the optionalbinder won't
+    // find it.  In prior implementations of OptionalBinder this would depend on the exact
+    // sequencing of the installation of OptionalBinder vs. these injection points that trigger
+    // dynamic injection.  In the current implementation it will consistently not find it.
+    module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Object.class)
+                .toProvider(
+                    new Provider<Object>() {
+                      @Inject
+                      void setter(Injector injector) {
+                        injector.getInstance(JitBinding.class);
+                      }
+
+                      @Override
+                      public Object get() {
+                        return null;
+                      }
+                    });
+            OptionalBinder.newOptionalBinder(binder(), JitBinding.class);
+          }
+        };
+    injector = Guice.createInjector(module);
+    assertFalse(injector.getInstance(optionalKey(JitBinding.class)).isPresent());
+    assertNotNull(injector.getExistingBinding(Key.get(JitBinding.class)));
+  }
+
+  public <T> Key<Optional<T>> optionalKey(Class<T> type) {
+    return Key.get(RealOptionalBinder.optionalOf(TypeLiteral.get(type)));
+  }
+
+  public void testSetDefault() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("a", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("a", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("a", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("a", optionalJxP.get().get());
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, instance("a"), null, null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("a", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("a", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("a", optionalJxP.get().get());
+    }
+  }
+
+  public void testSetBinding() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("a");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("a", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("a", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("a", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("a", optionalJxP.get().get());
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, instance("a"), null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("a", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("a", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("a", optionalJxP.get().get());
+    }
+  }
+
+  public void testSetBindingOverridesDefault() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<String> optionalBinder =
+                OptionalBinder.newOptionalBinder(binder(), String.class);
+            optionalBinder.setDefault().toInstance("a");
+            optionalBinder.setBinding().toInstance("b");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("b", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("b", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("b", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("b", optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey, setOf(module), VisitType.BOTH, 0, instance("a"), instance("b"), null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("b", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("b", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("b", optionalJxP.get().get());
+    }
+  }
+
+  public void testSpreadAcrossModules() throws Exception {
+    Module module1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class);
+          }
+        };
+    Module module2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+          }
+        };
+    Module module3 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
+          }
+        };
+
+    Injector injector = Guice.createInjector(module1, module2, module3);
+    assertEquals("b", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("b", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("b", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("b", optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(module1, module2, module3),
+        VisitType.BOTH,
+        0,
+        instance("a"),
+        instance("b"),
+        null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("b", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("b", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("b", optionalJxP.get().get());
+    }
+  }
+
+  public void testExactSameBindingCollapses_defaults() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setDefault()
+                .toInstance(new String("a")); // using new String to ensure .equals is checked.
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setDefault()
+                .toInstance(new String("a"));
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("a", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("a", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("a", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("a", optionalJxP.get().get());
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, instance("a"), null, null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("a", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("a", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("a", optionalJxP.get().get());
+    }
+  }
+
+  public void testExactSameBindingCollapses_actual() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setBinding()
+                .toInstance(new String("a")); // using new String to ensure .equals is checked.
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setBinding()
+                .toInstance(new String("a"));
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("a", injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertTrue(optional.isPresent());
+    assertEquals("a", optional.get());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertEquals("a", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("a", optionalJxP.get().get());
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, instance("a"), null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertTrue(optional.isPresent());
+      assertEquals("a", optional.get());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertEquals("a", optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("a", optionalJxP.get().get());
+    }
+  }
+
+  public void testDifferentBindingsFail_defaults() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("b");
+          }
+        };
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(ce.getMessage(), 1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "1) A binding to java.lang.String annotated with @"
+              + RealOptionalBinder.Default.class.getName()
+              + " was already configured at "
+              + module.getClass().getName()
+              + ".configure(",
+          "at " + module.getClass().getName() + ".configure(");
+    }
+  }
+
+  public void testDifferentBindingsFail_actual() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("a");
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
+          }
+        };
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(ce.getMessage(), 1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "1) A binding to java.lang.String annotated with @"
+              + RealOptionalBinder.Actual.class.getName()
+              + " was already configured at "
+              + module.getClass().getName()
+              + ".configure(",
+          "at " + module.getClass().getName() + ".configure(");
+    }
+  }
+
+  public void testDifferentBindingsFail_both() {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("b");
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
+            OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("c");
+          }
+        };
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(ce.getMessage(), 2, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "1) A binding to java.lang.String annotated with @"
+              + RealOptionalBinder.Default.class.getName()
+              + " was already configured at "
+              + module.getClass().getName()
+              + ".configure(",
+          "at " + module.getClass().getName() + ".configure(",
+          "2) A binding to java.lang.String annotated with @"
+              + RealOptionalBinder.Actual.class.getName()
+              + " was already configured at "
+              + module.getClass().getName()
+              + ".configure(",
+          "at " + module.getClass().getName() + ".configure(");
+    }
+  }
+
+  public void testQualifiedAggregatesTogether() throws Exception {
+    Module module1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")));
+          }
+        };
+    Module module2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")))
+                .setDefault()
+                .toInstance("a");
+          }
+        };
+    Module module3 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")))
+                .setBinding()
+                .toInstance("b");
+          }
+        };
+
+    Injector injector = Guice.createInjector(module1, module2, module3);
+    assertEquals("b", injector.getInstance(Key.get(String.class, Names.named("foo"))));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString, Names.named("foo")));
+    assertTrue(optional.isPresent());
+    assertEquals("b", optional.get());
+
+    Optional<Provider<String>> optionalP =
+        injector.getInstance(Key.get(optionalOfProviderString, Names.named("foo")));
+    assertTrue(optionalP.isPresent());
+    assertEquals("b", optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString, Names.named("foo")));
+    assertTrue(optionalJxP.isPresent());
+    assertEquals("b", optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        Key.get(String.class, Names.named("foo")),
+        setOf(module1, module2, module3),
+        VisitType.BOTH,
+        0,
+        instance("a"),
+        instance("b"),
+        null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional =
+          toOptional(injector.getInstance(Key.get(javaOptionalOfString, Names.named("foo"))));
+      assertTrue(optional.isPresent());
+      assertEquals("b", optional.get());
+
+      optionalP =
+          toOptional(
+              injector.getInstance(Key.get(javaOptionalOfProviderString, Names.named("foo"))));
+      assertTrue(optionalP.isPresent());
+      assertEquals("b", optionalP.get().get());
+
+      optionalJxP =
+          toOptional(
+              injector.getInstance(Key.get(javaOptionalOfJavaxProviderString, Names.named("foo"))));
+      assertTrue(optionalJxP.isPresent());
+      assertEquals("b", optionalJxP.get().get());
+    }
+  }
+
+  public void testMultipleDifferentOptionals() {
+    final Key<String> bKey = Key.get(String.class, named("b"));
+    final Key<String> cKey = Key.get(String.class, named("c"));
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+            OptionalBinder.newOptionalBinder(binder(), Integer.class).setDefault().toInstance(1);
+
+            OptionalBinder.newOptionalBinder(binder(), bKey).setDefault().toInstance("b");
+            OptionalBinder.newOptionalBinder(binder(), cKey).setDefault().toInstance("c");
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertEquals("a", injector.getInstance(String.class));
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    assertEquals("b", injector.getInstance(bKey));
+    assertEquals("c", injector.getInstance(cKey));
+
+    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 3, instance("a"), null, null);
+    assertOptionalVisitor(intKey, setOf(module), VisitType.BOTH, 3, instance(1), null, null);
+    assertOptionalVisitor(bKey, setOf(module), VisitType.BOTH, 3, instance("b"), null, null);
+    assertOptionalVisitor(cKey, setOf(module), VisitType.BOTH, 3, instance("c"), null, null);
+  }
+
+  public void testOptionalIsAppropriatelyLazy() throws Exception {
+    Module module =
+        new AbstractModule() {
+          int nextValue = 1;
+
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), Integer.class)
+                .setDefault()
+                .to(Key.get(Integer.class, Names.named("foo")));
+          }
+
+          @Provides
+          @Named("foo")
+          int provideInt() {
+            return nextValue++;
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+
+    Optional<Provider<Integer>> optionalP =
+        injector.getInstance(Key.get(optionalOfProviderInteger));
+    Optional<javax.inject.Provider<Integer>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderInteger));
+
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    assertEquals(2, injector.getInstance(Integer.class).intValue());
+
+    // Calling .get() on an Optional<Integer> multiple times will keep giving the same thing
+    Optional<Integer> optional = injector.getInstance(Key.get(optionalOfInteger));
+    assertEquals(3, optional.get().intValue());
+    assertEquals(3, optional.get().intValue());
+    // But getting another Optional<Integer> will give a new one.
+    assertEquals(4, injector.getInstance(Key.get(optionalOfInteger)).get().intValue());
+
+    // And the Optional<Provider> will return a provider that gives a new value each time.
+    assertEquals(5, optionalP.get().get().intValue());
+    assertEquals(6, optionalP.get().get().intValue());
+
+    assertEquals(7, optionalJxP.get().get().intValue());
+    assertEquals(8, optionalJxP.get().get().intValue());
+
+    // and same rules with java.util.Optional
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfInteger)));
+      assertEquals(9, optional.get().intValue());
+      assertEquals(9, optional.get().intValue());
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfInteger)));
+      assertEquals(10, optional.get().intValue());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderInteger)));
+      assertEquals(11, optionalP.get().get().intValue());
+      assertEquals(12, optionalP.get().get().intValue());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderInteger)));
+      assertEquals(13, optionalJxP.get().get().intValue());
+      assertEquals(14, optionalJxP.get().get().intValue());
+    }
+  }
+
+  public void testLinkedToNullProvidersMakeAbsentValuesAndPresentProviders_default()
+      throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setDefault()
+                .toProvider(Providers.<String>of(null));
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertNull(injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertFalse(optional.isPresent());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertNull(optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertNull(optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(module),
+        VisitType.BOTH,
+        0,
+        SpiUtils.<String>providerInstance(null),
+        null,
+        null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertFalse(optional.isPresent());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertNull(optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertNull(optionalJxP.get().get());
+    }
+  }
+
+  public void testLinkedToNullProvidersMakeAbsentValuesAndPresentProviders_actual()
+      throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setBinding()
+                .toProvider(Providers.<String>of(null));
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertNull(injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertFalse(optional.isPresent());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertNull(optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertNull(optionalJxP.get().get());
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(module),
+        VisitType.BOTH,
+        0,
+        null,
+        SpiUtils.<String>providerInstance(null),
+        null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertFalse(optional.isPresent());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertNull(optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertNull(optionalJxP.get().get());
+    }
+  }
+
+  // TODO(sameb): Maybe change this?
+  public void testLinkedToNullActualDoesntFallbackToDefault() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
+            OptionalBinder.newOptionalBinder(binder(), String.class)
+                .setBinding()
+                .toProvider(Providers.<String>of(null));
+          }
+        };
+    Injector injector = Guice.createInjector(module);
+    assertNull(injector.getInstance(String.class));
+
+    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
+    assertFalse(optional.isPresent());
+
+    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
+    assertTrue(optionalP.isPresent());
+    assertNull(optionalP.get().get());
+
+    Optional<javax.inject.Provider<String>> optionalJxP =
+        injector.getInstance(Key.get(optionalOfJavaxProviderString));
+    assertTrue(optionalJxP.isPresent());
+    assertNull(optionalP.get().get());
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(module),
+        VisitType.BOTH,
+        0,
+        instance("a"),
+        SpiUtils.<String>providerInstance(null),
+        null);
+
+    if (HAS_JAVA_OPTIONAL) {
+      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
+      assertFalse(optional.isPresent());
+
+      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
+      assertTrue(optionalP.isPresent());
+      assertNull(optionalP.get().get());
+
+      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
+      assertTrue(optionalJxP.isPresent());
+      assertNull(optionalJxP.get().get());
+    }
+  }
+
+  public void testSourceLinesInException() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              OptionalBinder.newOptionalBinder(binder(), Integer.class).setDefault();
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(
+          expected.getMessage(),
+          "No implementation for java.lang.Integer",
+          "at " + getClass().getName());
+    }
+  }
+
+  public void testDependencies_both() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                OptionalBinder<String> optionalbinder =
+                    OptionalBinder.newOptionalBinder(binder(), String.class);
+                optionalbinder.setDefault().toInstance("A");
+                optionalbinder.setBinding().to(Key.get(String.class, Names.named("b")));
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<String> binding = injector.getBinding(Key.get(String.class));
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<String> elements = Sets.newHashSet();
+    elements.addAll(recurseForDependencies(injector, withDependencies));
+    assertEquals(ImmutableSet.of("B"), elements);
+  }
+
+  public void testDependencies_actual() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                OptionalBinder<String> optionalbinder =
+                    OptionalBinder.newOptionalBinder(binder(), String.class);
+                optionalbinder.setBinding().to(Key.get(String.class, Names.named("b")));
+                bindConstant().annotatedWith(Names.named("b")).to("B");
+              }
+            });
+
+    Binding<String> binding = injector.getBinding(Key.get(String.class));
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<String> elements = Sets.newHashSet();
+    elements.addAll(recurseForDependencies(injector, withDependencies));
+    assertEquals(ImmutableSet.of("B"), elements);
+  }
+
+  public void testDependencies_default() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                OptionalBinder<String> optionalbinder =
+                    OptionalBinder.newOptionalBinder(binder(), String.class);
+                optionalbinder.setDefault().toInstance("A");
+              }
+            });
+
+    Binding<String> binding = injector.getBinding(Key.get(String.class));
+    HasDependencies withDependencies = (HasDependencies) binding;
+    Set<String> elements = Sets.newHashSet();
+    elements.addAll(recurseForDependencies(injector, withDependencies));
+    assertEquals(ImmutableSet.of("A"), elements);
+  }
+
+  @SuppressWarnings("rawtypes")
+  private Set<String> recurseForDependencies(Injector injector, HasDependencies hasDependencies) {
+    Set<String> elements = Sets.newHashSet();
+    for (Dependency<?> dependency : hasDependencies.getDependencies()) {
+      Binding<?> binding = injector.getBinding(dependency.getKey());
+      HasDependencies deps = (HasDependencies) binding;
+      if (binding instanceof InstanceBinding) {
+        elements.add((String) ((InstanceBinding) binding).getInstance());
+      } else {
+        elements.addAll(recurseForDependencies(injector, deps));
+      }
+    }
+    return elements;
+  }
+
+  /** Doubly-installed modules should not conflict, even when one is overridden. */
+  public void testModuleOverrideRepeatedInstalls_toInstance() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
+            b.setDefault().toInstance("A");
+            b.setBinding().toInstance("B");
+          }
+        };
+
+    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
+
+    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
+    assertEquals("B", injector.getInstance(Key.get(String.class)));
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(m, Modules.override(m).with(m)),
+        VisitType.BOTH,
+        0,
+        instance("A"),
+        instance("B"),
+        null);
+  }
+
+  public void testModuleOverrideRepeatedInstalls_toKey() {
+    final Key<String> aKey = Key.get(String.class, Names.named("A_string"));
+    final Key<String> bKey = Key.get(String.class, Names.named("B_string"));
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(aKey).toInstance("A");
+            bind(bKey).toInstance("B");
+
+            OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
+            b.setDefault().to(aKey);
+            b.setBinding().to(bKey);
+          }
+        };
+
+    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
+
+    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
+    assertEquals("B", injector.getInstance(Key.get(String.class)));
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(m, Modules.override(m).with(m)),
+        VisitType.BOTH,
+        0,
+        linked(aKey),
+        linked(bKey),
+        null);
+  }
+
+  public void testModuleOverrideRepeatedInstalls_toProviderInstance() {
+    // Providers#of() does not redefine equals/hashCode, so use the same one both times.
+    final Provider<String> aProvider = Providers.of("A");
+    final Provider<String> bProvider = Providers.of("B");
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
+            b.setDefault().toProvider(aProvider);
+            b.setBinding().toProvider(bProvider);
+          }
+        };
+
+    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
+
+    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
+    assertEquals("B", injector.getInstance(Key.get(String.class)));
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(m, Modules.override(m).with(m)),
+        VisitType.BOTH,
+        0,
+        providerInstance("A"),
+        providerInstance("B"),
+        null);
+  }
+
+  private static class AStringProvider implements Provider<String> {
+    @Override
+    public String get() {
+      return "A";
+    }
+  }
+
+  private static class BStringProvider implements Provider<String> {
+    @Override
+    public String get() {
+      return "B";
+    }
+  }
+
+  public void testModuleOverrideRepeatedInstalls_toProviderKey() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
+            b.setDefault().toProvider(Key.get(AStringProvider.class));
+            b.setBinding().toProvider(Key.get(BStringProvider.class));
+          }
+        };
+
+    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
+
+    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
+    assertEquals("B", injector.getInstance(Key.get(String.class)));
+
+    assertOptionalVisitor(
+        stringKey,
+        setOf(m, Modules.override(m).with(m)),
+        VisitType.BOTH,
+        0,
+        providerKey(Key.get(AStringProvider.class)),
+        providerKey(Key.get(BStringProvider.class)),
+        null);
+  }
+
+  private static class StringGrabber {
+    private final String string;
+
+    @SuppressWarnings("unused") // Found by reflection
+    public StringGrabber(@Named("A_string") String string) {
+      this.string = string;
+    }
+
+    @SuppressWarnings("unused") // Found by reflection
+    public StringGrabber(@Named("B_string") String string, int unused) {
+      this.string = string;
+    }
+
+    @Override
+    public int hashCode() {
+      return string.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return (obj instanceof StringGrabber) && ((StringGrabber) obj).string.equals(string);
+    }
+
+    @Override
+    public String toString() {
+      return "StringGrabber(" + string + ")";
+    }
+  }
+
+  public void testModuleOverrideRepeatedInstalls_toConstructor() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Key<String> aKey = Key.get(String.class, Names.named("A_string"));
+            Key<String> bKey = Key.get(String.class, Names.named("B_string"));
+            bind(aKey).toInstance("A");
+            bind(bKey).toInstance("B");
+            bind(Integer.class).toInstance(0); // used to disambiguate constructors
+
+            OptionalBinder<StringGrabber> b =
+                OptionalBinder.newOptionalBinder(binder(), StringGrabber.class);
+            try {
+              b.setDefault().toConstructor(StringGrabber.class.getConstructor(String.class));
+              b.setBinding()
+                  .toConstructor(StringGrabber.class.getConstructor(String.class, int.class));
+            } catch (NoSuchMethodException e) {
+              fail("No such method: " + e.getMessage());
+            }
+          }
+        };
+
+    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(StringGrabber.class)).string);
+
+    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
+    assertEquals("B", injector.getInstance(Key.get(StringGrabber.class)).string);
+  }
+
+  /**
+   * Unscoped bindings should not conflict, whether they were bound with no explicit scope, or
+   * explicitly bound in {@link Scopes#NO_SCOPE}.
+   */
+  public void testDuplicateUnscopedBindings() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<Integer> b = OptionalBinder.newOptionalBinder(binder(), Integer.class);
+            b.setDefault().to(Key.get(Integer.class, named("foo")));
+            b.setDefault().to(Key.get(Integer.class, named("foo"))).in(Scopes.NO_SCOPE);
+            b.setBinding().to(Key.get(Integer.class, named("foo")));
+            b.setBinding().to(Key.get(Integer.class, named("foo"))).in(Scopes.NO_SCOPE);
+          }
+
+          @Provides
+          @Named("foo")
+          int provideInt() {
+            return 5;
+          }
+        };
+    assertEquals(5, Guice.createInjector(m).getInstance(Integer.class).intValue());
+  }
+
+  /** Ensure key hash codes are fixed at injection time, not binding time. */
+  public void testKeyHashCodesFixedAtInjectionTime() {
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<List<String>> b =
+                OptionalBinder.newOptionalBinder(binder(), listOfStrings);
+            List<String> list = Lists.newArrayList();
+            b.setDefault().toInstance(list);
+            b.setBinding().toInstance(list);
+            list.add("A");
+            list.add("B");
+          }
+        };
+
+    Injector injector = Guice.createInjector(m);
+    for (Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
+      Key<?> bindingKey = entry.getKey();
+      Key<?> clonedKey;
+      if (bindingKey.getAnnotation() != null) {
+        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotation());
+      } else if (bindingKey.getAnnotationType() != null) {
+        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotationType());
+      } else {
+        clonedKey = Key.get(bindingKey.getTypeLiteral());
+      }
+      assertEquals(bindingKey, clonedKey);
+      assertEquals(
+          "Incorrect hashcode for " + bindingKey + " -> " + entry.getValue(),
+          bindingKey.hashCode(),
+          clonedKey.hashCode());
+    }
+  }
+
+  /** Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */
+  public void testBindingKeysFixedOnReturnFromGetElements() {
+    final List<String> list = Lists.newArrayList();
+    Module m =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            OptionalBinder<List<String>> b =
+                OptionalBinder.newOptionalBinder(binder(), listOfStrings);
+            b.setDefault().toInstance(list);
+            list.add("A");
+            list.add("B");
+          }
+        };
+
+    InstanceBinding<?> binding =
+        Iterables.getOnlyElement(Iterables.filter(Elements.getElements(m), InstanceBinding.class));
+    Key<?> keyBefore = binding.getKey();
+    assertEquals(listOfStrings, keyBefore.getTypeLiteral());
+
+    list.add("C");
+    Key<?> keyAfter = binding.getKey();
+    assertSame(keyBefore, keyAfter);
+  }
+
+  @BindingAnnotation
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+  private static @interface Marker {}
+
+  @Marker
+  public void testMatchingMarkerAnnotations() throws Exception {
+    Method m = OptionalBinderTest.class.getDeclaredMethod("testMatchingMarkerAnnotations");
+    assertNotNull(m);
+    final Annotation marker = m.getAnnotation(Marker.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              public void configure() {
+                OptionalBinder<Integer> mb1 =
+                    OptionalBinder.newOptionalBinder(
+                        binder(), Key.get(Integer.class, Marker.class));
+                OptionalBinder<Integer> mb2 =
+                    OptionalBinder.newOptionalBinder(binder(), Key.get(Integer.class, marker));
+                mb1.setDefault().toInstance(1);
+                mb2.setBinding().toInstance(2);
+
+                // This assures us that the two binders are equivalent, so we expect the instance added to
+                // each to have been added to one set.
+                assertEquals(mb1, mb2);
+              }
+            });
+    Integer i1 = injector.getInstance(Key.get(Integer.class, Marker.class));
+    Integer i2 = injector.getInstance(Key.get(Integer.class, marker));
+
+    // These must be identical, because the marker annotations collapsed to the same thing.
+    assertSame(i1, i2);
+    assertEquals(2, i2.intValue());
+  }
+
+  // Tests for com.google.inject.internal.WeakKeySet not leaking memory.
+  public void testWeakKeySet_integration() {
+    Injector parentInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("hi");
+              }
+            });
+    WeakKeySetUtils.assertNotBlacklisted(parentInjector, Key.get(Integer.class));
+
+    Injector childInjector =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                OptionalBinder.newOptionalBinder(binder(), Integer.class)
+                    .setDefault()
+                    .toInstance(4);
+              }
+            });
+    WeakReference<Injector> weakRef = new WeakReference<>(childInjector);
+    WeakKeySetUtils.assertBlacklisted(parentInjector, Key.get(Integer.class));
+
+    // Clear the ref, GC, and ensure that we are no longer blacklisting.
+    childInjector = null;
+
+    Asserts.awaitClear(weakRef);
+    WeakKeySetUtils.assertNotBlacklisted(parentInjector, Key.get(Integer.class));
+  }
+
+  public void testCompareEqualsAgainstOtherAnnotation() {
+    RealOptionalBinder.Actual impl1 = new RealOptionalBinder.ActualImpl("foo");
+    RealOptionalBinder.Actual other1 = Dummy.class.getAnnotation(RealOptionalBinder.Actual.class);
+    assertEquals(impl1, other1);
+
+    RealOptionalBinder.Default impl2 = new RealOptionalBinder.DefaultImpl("foo");
+    RealOptionalBinder.Default other2 = Dummy.class.getAnnotation(RealOptionalBinder.Default.class);
+    assertEquals(impl2, other2);
+
+    assertFalse(impl1.equals(impl2));
+    assertFalse(impl1.equals(other2));
+    assertFalse(impl2.equals(other1));
+    assertFalse(other1.equals(other2));
+  }
+
+  @RealOptionalBinder.Actual("foo")
+  @RealOptionalBinder.Default("foo")
+  static class Dummy {}
+
+  @SuppressWarnings("unchecked")
+  private <V> Set<V> setOf(V... elements) {
+    return ImmutableSet.copyOf(elements);
+  }
+
+  @SuppressWarnings("unchecked")
+  private <T> Optional<T> toOptional(Object object) throws Exception {
+    assertTrue(
+        "not a java.util.Optional: " + object.getClass(), JAVA_OPTIONAL_CLASS.isInstance(object));
+    return Optional.fromNullable((T) JAVA_OPTIONAL_OR_ELSE.invoke(object, (Void) null));
+  }
+}
diff --git a/core/test/com/google/inject/internal/ProxyFactoryTest.java b/core/test/com/google/inject/internal/ProxyFactoryTest.java
index ce8caa6..7383151 100644
--- a/core/test/com/google/inject/internal/ProxyFactoryTest.java
+++ b/core/test/com/google/inject/internal/ProxyFactoryTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,20 +24,15 @@
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
 import com.google.inject.spi.InjectionPoint;
-
-import junit.framework.TestCase;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.InvocationTargetException;
 import java.util.List;
+import junit.framework.TestCase;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ProxyFactoryTest extends TestCase {
 
   List<MethodAspect> aspects = Lists.newArrayList();
@@ -48,7 +43,7 @@
     InjectionPoint injectionPoint = InjectionPoint.forConstructorOf(Simple.class);
 
     aspects.add(new MethodAspect(any(), any(), interceptor));
-    ProxyFactory<Simple> factory = new ProxyFactory<Simple>(injectionPoint, aspects);
+    ProxyFactory<Simple> factory = new ProxyFactory<>(injectionPoint, aspects);
 
     ConstructionProxy<Simple> constructionProxy = factory.create();
 
@@ -60,6 +55,7 @@
 
   static class Simple {
     boolean invoked = false;
+
     public void invoke() {
       invoked = true;
     }
@@ -69,6 +65,7 @@
 
     boolean invoked = false;
 
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       invoked = true;
       return methodInvocation.proceed();
@@ -81,10 +78,10 @@
 
     aspects.add(new MethodAspect(only(Bar.class), annotatedWith(Intercept.class), interceptor));
 
-    ConstructionProxy<Foo> fooFactory
-        = new ProxyFactory<Foo>(InjectionPoint.forConstructorOf(Foo.class), aspects).create();
-    ConstructionProxy<Bar> barFactory
-        = new ProxyFactory<Bar>(InjectionPoint.forConstructorOf(Bar.class), aspects).create();
+    ConstructionProxy<Foo> fooFactory =
+        new ProxyFactory<Foo>(InjectionPoint.forConstructorOf(Foo.class), aspects).create();
+    ConstructionProxy<Bar> barFactory =
+        new ProxyFactory<Bar>(InjectionPoint.forConstructorOf(Bar.class), aspects).create();
 
     Foo foo = fooFactory.newInstance();
     Bar bar = barFactory.newInstance();
@@ -104,6 +101,7 @@
 
   static class Foo {
     boolean fooCalled;
+
     @Intercept
     void foo() {
       fooCalled = true;
@@ -113,6 +111,7 @@
   static class Bar {
 
     boolean barCalled;
+
     void bar() {
       barCalled = true;
     }
@@ -133,8 +132,8 @@
     SimpleInterceptor interceptor = new SimpleInterceptor();
 
     aspects.add(new MethodAspect(any(), any(), interceptor));
-    ProxyFactory<A> factory
-        = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
+    ProxyFactory<A> factory =
+        new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
 
     ConstructionProxy<A> constructor = factory.create();
 
@@ -148,8 +147,8 @@
     SimpleInterceptor interceptor = new SimpleInterceptor();
 
     aspects.add(new MethodAspect(not(any()), not(any()), interceptor));
-    ProxyFactory<A> factory
-        = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
+    ProxyFactory<A> factory =
+        new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
 
     ConstructionProxy<A> constructor = factory.create();
 
@@ -159,9 +158,12 @@
 
   static class A {
     final int i;
-    @Inject public A(int i) {
+
+    @Inject
+    public A(int i) {
       this.i = i;
     }
+
     public void a() {}
   }
 
@@ -171,8 +173,8 @@
     CountingInterceptor countingInterceptor = new CountingInterceptor();
 
     aspects.add(new MethodAspect(any(), any(), doubleInterceptor, countingInterceptor));
-    ProxyFactory<Counter> factory
-        = new ProxyFactory<Counter>(InjectionPoint.forConstructorOf(Counter.class), aspects);
+    ProxyFactory<Counter> factory =
+        new ProxyFactory<Counter>(InjectionPoint.forConstructorOf(Counter.class), aspects);
 
     ConstructionProxy<Counter> constructor = factory.create();
 
@@ -186,6 +188,7 @@
 
     int count;
 
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       count++;
       return methodInvocation.proceed();
@@ -194,6 +197,7 @@
 
   static class DoubleInterceptor implements MethodInterceptor {
 
+    @Override
     public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       methodInvocation.proceed();
       return methodInvocation.proceed();
@@ -202,6 +206,7 @@
 
   static class Counter {
     int count;
+
     void inc() {
       count++;
     }
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java b/core/test/com/google/inject/internal/RealElementTest.java
similarity index 86%
rename from extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java
rename to core/test/com/google/inject/internal/RealElementTest.java
index 8dabf83..f137e6a 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java
+++ b/core/test/com/google/inject/internal/RealElementTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,43 +14,39 @@
  * limitations under the License.
  */
 
-package com.google.inject.multibindings;
+package com.google.inject.internal;
 
-import com.google.inject.multibindings.Element.Type;
-
+import com.google.inject.internal.Element.Type;
 import junit.framework.TestCase;
 
-/**
- * Tests for {@link RealElement}.
- */
+/** Tests for {@link com.google.inject.internal.RealElement}. */
 public class RealElementTest extends TestCase {
-  
+
   private Element systemElement;
   private RealElement realElement;
-  
-  @Override protected void setUp() throws Exception {
+
+  @Override
+  protected void setUp() throws Exception {
     this.systemElement = Holder.class.getAnnotation(Element.class);
     this.realElement = new RealElement("b", Type.MULTIBINDER, "a", 1);
   }
-  
+
   public void testEquals() {
     assertEquals(systemElement, realElement);
     assertEquals(realElement, systemElement);
   }
-  
+
   public void testHashCode() {
     assertEquals(systemElement.hashCode(), realElement.hashCode());
   }
-  
+
   public void testProperties() {
     assertEquals("a", realElement.keyType());
     assertEquals("b", realElement.setName());
     assertEquals(Type.MULTIBINDER, realElement.type());
     assertEquals(1, realElement.uniqueId());
   }
-  
-  
+
   @Element(keyType = "a", setName = "b", type = Type.MULTIBINDER, uniqueId = 1)
   static class Holder {}
-
 }
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java b/core/test/com/google/inject/internal/SpiUtils.java
similarity index 62%
rename from extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
rename to core/test/com/google/inject/internal/SpiUtils.java
index fd23f6b..1b2f20e 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
+++ b/core/test/com/google/inject/internal/SpiUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-package com.google.inject.multibindings;
+package com.google.inject.internal;
 
-import static com.google.inject.multibindings.MapBinder.entryOfProviderOf;
-import static com.google.inject.multibindings.MapBinder.mapOf;
-import static com.google.inject.multibindings.MapBinder.mapOfJavaxProviderOf;
-import static com.google.inject.multibindings.MapBinder.mapOfProviderOf;
-import static com.google.inject.multibindings.MapBinder.mapOfSetOfProviderOf;
-import static com.google.inject.multibindings.Multibinder.collectionOfJavaxProvidersOf;
-import static com.google.inject.multibindings.Multibinder.collectionOfProvidersOf;
-import static com.google.inject.multibindings.Multibinder.setOf;
-import static com.google.inject.multibindings.OptionalBinder.javaOptionalOfJavaxProvider;
-import static com.google.inject.multibindings.OptionalBinder.javaOptionalOfProvider;
-import static com.google.inject.multibindings.OptionalBinder.optionalOfJavaxProvider;
-import static com.google.inject.multibindings.OptionalBinder.optionalOfProvider;
-import static com.google.inject.multibindings.SpiUtils.BindType.INSTANCE;
-import static com.google.inject.multibindings.SpiUtils.BindType.LINKED;
-import static com.google.inject.multibindings.SpiUtils.BindType.PROVIDER_INSTANCE;
-import static com.google.inject.multibindings.SpiUtils.BindType.PROVIDER_KEY;
-import static com.google.inject.multibindings.SpiUtils.VisitType.BOTH;
-import static com.google.inject.multibindings.SpiUtils.VisitType.INJECTOR;
-import static com.google.inject.multibindings.SpiUtils.VisitType.MODULE;
+import static com.google.inject.internal.RealMapBinder.entryOfJavaxProviderOf;
+import static com.google.inject.internal.RealMapBinder.entryOfProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOf;
+import static com.google.inject.internal.RealMapBinder.mapOfCollectionOfJavaxProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOfCollectionOfProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOfJavaxProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOfProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOfSetOfJavaxProviderOf;
+import static com.google.inject.internal.RealMapBinder.mapOfSetOfProviderOf;
+import static com.google.inject.internal.RealMultibinder.collectionOfJavaxProvidersOf;
+import static com.google.inject.internal.RealMultibinder.collectionOfProvidersOf;
+import static com.google.inject.internal.RealMultibinder.setOf;
+import static com.google.inject.internal.SpiUtils.BindType.INSTANCE;
+import static com.google.inject.internal.SpiUtils.BindType.LINKED;
+import static com.google.inject.internal.SpiUtils.BindType.PROVIDER_INSTANCE;
+import static com.google.inject.internal.SpiUtils.BindType.PROVIDER_KEY;
+import static com.google.inject.internal.SpiUtils.VisitType.BOTH;
+import static com.google.inject.internal.SpiUtils.VisitType.INJECTOR;
+import static com.google.inject.internal.SpiUtils.VisitType.MODULE;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -42,6 +42,7 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
+import com.google.common.base.Joiner;
 import com.google.common.base.Objects;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
@@ -58,9 +59,12 @@
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
-import com.google.inject.multibindings.Indexer.IndexedBinding;
-import com.google.inject.multibindings.MapBinder.RealMapBinder.ProviderMapEntry;
-import com.google.inject.multibindings.OptionalBinder.Source;
+import com.google.inject.internal.Indexer.IndexedBinding;
+import com.google.inject.internal.RealMapBinder.ProviderMapEntry;
+import com.google.inject.multibindings.MapBinderBinding;
+import com.google.inject.multibindings.MultibinderBinding;
+import com.google.inject.multibindings.MultibindingsTargetVisitor;
+import com.google.inject.multibindings.OptionalBinderBinding;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
@@ -69,7 +73,6 @@
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderKeyBinding;
 import com.google.inject.spi.ProviderLookup;
-
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -77,108 +80,139 @@
 
 /**
  * Utilities for testing the Multibinder & MapBinder extension SPI.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 public class SpiUtils {
 
   private static final boolean HAS_JAVA_OPTIONAL;
+
   static {
     Class<?> optional = null;
     try {
       optional = Class.forName("java.util.Optional");
-    } catch (ClassNotFoundException ignored) {}
+    } catch (ClassNotFoundException ignored) {
+    }
     HAS_JAVA_OPTIONAL = optional != null;
   }
 
-  /** The kind of test we should perform.  A live Injector, a raw Elements (Module) test, or both. */
-  enum VisitType { INJECTOR, MODULE, BOTH }
-  
+  /** The kind of test we should perform. A live Injector, a raw Elements (Module) test, or both. */
+  enum VisitType {
+    INJECTOR,
+    MODULE,
+    BOTH
+  }
+
   /**
    * Asserts that MapBinderBinding visitors for work correctly.
-   * 
+   *
    * @param <T> The type of the binding
    * @param mapKey The key the map belongs to.
    * @param keyType the TypeLiteral of the key of the map
    * @param valueType the TypeLiteral of the value of the map
    * @param modules The modules that define the mapbindings
-   * @param visitType The kind of test we should perform.  A live Injector, a raw Elements (Module) test, or both.
+   * @param visitType The kind of test we should perform. A live Injector, a raw Elements (Module)
+   *     test, or both.
    * @param allowDuplicates If duplicates are allowed.
    * @param expectedMapBindings The number of other mapbinders we expect to see.
    * @param results The kind of bindings contained in the mapbinder.
    */
-  static <T> void assertMapVisitor(Key<T> mapKey, TypeLiteral<?> keyType, TypeLiteral<?> valueType,
-      Iterable<? extends Module> modules, VisitType visitType, boolean allowDuplicates,
-      int expectedMapBindings, MapResult... results) {
-    if(visitType == null) {
+  static <T> void assertMapVisitor(
+      Key<T> mapKey,
+      TypeLiteral<?> keyType,
+      TypeLiteral<?> valueType,
+      Iterable<? extends Module> modules,
+      VisitType visitType,
+      boolean allowDuplicates,
+      int expectedMapBindings,
+      MapResult... results) {
+    if (visitType == null) {
       fail("must test something");
     }
 
     if (visitType == BOTH || visitType == INJECTOR) {
-      mapInjectorTest(mapKey, keyType, valueType, modules, allowDuplicates, expectedMapBindings,
-          results);
+      mapInjectorTest(
+          mapKey, keyType, valueType, modules, allowDuplicates, expectedMapBindings, results);
     }
 
     if (visitType == BOTH || visitType == MODULE) {
-      mapModuleTest(mapKey, keyType, valueType, modules, allowDuplicates, expectedMapBindings,
-          results);
+      mapModuleTest(
+          mapKey, keyType, valueType, modules, allowDuplicates, expectedMapBindings, results);
     }
   }
-  
+
   @SuppressWarnings("unchecked")
-  private static <T> void mapInjectorTest(Key<T> mapKey, TypeLiteral<?> keyType,
-      TypeLiteral<?> valueType, Iterable<? extends Module> modules, boolean allowDuplicates,
-      int expectedMapBindings, MapResult... results) {
+  private static <T> void mapInjectorTest(
+      Key<T> mapKey,
+      TypeLiteral<?> keyType,
+      TypeLiteral<?> valueType,
+      Iterable<? extends Module> modules,
+      boolean allowDuplicates,
+      int expectedMapBindings,
+      MapResult... results) {
     Injector injector = Guice.createInjector(modules);
-    Visitor<T> visitor = new Visitor<T>();
+    Visitor<T> visitor = new Visitor<>();
     Binding<T> mapBinding = injector.getBinding(mapKey);
-    MapBinderBinding<T> mapbinder = (MapBinderBinding<T>)mapBinding.acceptTargetVisitor(visitor);
+    MapBinderBinding<T> mapbinder = (MapBinderBinding<T>) mapBinding.acceptTargetVisitor(visitor);
     assertNotNull(mapbinder);
     assertEquals(keyType, mapbinder.getKeyTypeLiteral());
     assertEquals(valueType, mapbinder.getValueTypeLiteral());
     assertEquals(allowDuplicates, mapbinder.permitsDuplicates());
     List<Map.Entry<?, Binding<?>>> entries = Lists.newArrayList(mapbinder.getEntries());
     List<MapResult> mapResults = Lists.newArrayList(results);
-    assertEquals("wrong entries, expected: " + mapResults + ", but was: " + entries,
-        mapResults.size(), entries.size());
+    assertEquals(
+        "wrong entries, expected: " + mapResults + ", but was: " + entries,
+        mapResults.size(),
+        entries.size());
 
-    for(MapResult result : mapResults) {
+    for (MapResult result : mapResults) {
       Map.Entry<?, Binding<?>> found = null;
-      for(Map.Entry<?, Binding<?>> entry : entries) {
+      for (Map.Entry<?, Binding<?>> entry : entries) {
         Object key = entry.getKey();
         Binding<?> value = entry.getValue();
-        if(key.equals(result.k) && matches(value, result.v)) {
+        if (key.equals(result.k) && matches(value, result.v)) {
           found = entry;
           break;
         }
       }
-      if(found == null) {
+      if (found == null) {
         fail("Could not find entry: " + result + " in remaining entries: " + entries);
       } else {
-        assertTrue("mapBinder doesn't contain: " + found.getValue(), 
+        assertTrue(
+            "mapBinder doesn't contain: " + found.getValue(),
             mapbinder.containsElement(found.getValue()));
         entries.remove(found);
       }
     }
-    
-    if(!entries.isEmpty()) {
+
+    if (!entries.isEmpty()) {
       fail("Found all entries of: " + mapResults + ", but more were left over: " + entries);
     }
-    
+
     Key<?> mapOfJavaxProvider = mapKey.ofType(mapOfJavaxProviderOf(keyType, valueType));
     Key<?> mapOfProvider = mapKey.ofType(mapOfProviderOf(keyType, valueType));
     Key<?> mapOfSetOfProvider = mapKey.ofType(mapOfSetOfProviderOf(keyType, valueType));
+    Key<?> mapOfSetOfJavaxProvider = mapKey.ofType(mapOfSetOfJavaxProviderOf(keyType, valueType));
+    Key<?> mapOfCollectionOfProvider =
+        mapKey.ofType(mapOfCollectionOfProviderOf(keyType, valueType));
+    Key<?> mapOfCollectionOfJavaxProvider =
+        mapKey.ofType(mapOfCollectionOfJavaxProviderOf(keyType, valueType));
     Key<?> mapOfSet = mapKey.ofType(mapOf(keyType, setOf(valueType)));
     Key<?> setOfEntry = mapKey.ofType(setOf(entryOfProviderOf(keyType, valueType)));
+    Key<?> setOfJavaxEntry = mapKey.ofType(setOf(entryOfJavaxProviderOf(keyType, valueType)));
     Key<?> collectionOfProvidersOfEntryOfProvider =
         mapKey.ofType(collectionOfProvidersOf(entryOfProviderOf(keyType, valueType)));
     Key<?> collectionOfJavaxProvidersOfEntryOfProvider =
         mapKey.ofType(collectionOfJavaxProvidersOf(entryOfProviderOf(keyType, valueType)));
     boolean entrySetMatch = false;
+    boolean javaxEntrySetMatch = false;
     boolean mapJavaxProviderMatch = false;
     boolean mapProviderMatch = false;
-    boolean mapSetMatch = false; 
+    boolean mapSetMatch = false;
     boolean mapSetProviderMatch = false;
+    boolean mapSetJavaxProviderMatch = false;
+    boolean mapCollectionProviderMatch = false;
+    boolean mapCollectionJavaxProviderMatch = false;
     boolean collectionOfProvidersOfEntryOfProviderMatch = false;
     boolean collectionOfJavaxProvidersOfEntryOfProviderMatch = false;
     List<Object> otherMapBindings = Lists.newArrayList();
@@ -187,41 +221,53 @@
         MultimapBuilder.hashKeys().hashSetValues().build();
     Indexer indexer = new Indexer(injector);
     int duplicates = 0;
-    for(Binding b : injector.getAllBindings().values()) {
-      boolean contains = mapbinder.containsElement(b);      
+    for (Binding b : injector.getAllBindings().values()) {
+      boolean contains = mapbinder.containsElement(b);
       Object visited = b.acceptTargetVisitor(visitor);
-      if(visited instanceof MapBinderBinding) {
-        if(visited.equals(mapbinder)) {
+      if (visited instanceof MapBinderBinding) {
+        if (visited.equals(mapbinder)) {
           assertTrue(contains);
         } else {
           otherMapBindings.add(visited);
         }
-      } else if(b.getKey().equals(mapOfProvider)) {
+      } else if (b.getKey().equals(mapOfProvider)) {
         assertTrue(contains);
         mapProviderMatch = true;
       } else if (b.getKey().equals(mapOfJavaxProvider)) {
         assertTrue(contains);
         mapJavaxProviderMatch = true;
-      } else if(b.getKey().equals(mapOfSet)) {
+      } else if (b.getKey().equals(mapOfSet)) {
         assertTrue(contains);
         mapSetMatch = true;
-      } else if(b.getKey().equals(mapOfSetOfProvider)) {
+      } else if (b.getKey().equals(mapOfSetOfProvider)) {
         assertTrue(contains);
         mapSetProviderMatch = true;
-      } else if(b.getKey().equals(setOfEntry)) {
+      } else if (b.getKey().equals(mapOfSetOfJavaxProvider)) {
+        assertTrue(contains);
+        mapSetJavaxProviderMatch = true;
+      } else if (b.getKey().equals(mapOfCollectionOfProvider)) {
+        assertTrue(contains);
+        mapCollectionProviderMatch = true;
+      } else if (b.getKey().equals(mapOfCollectionOfJavaxProvider)) {
+        assertTrue(contains);
+        mapCollectionJavaxProviderMatch = true;
+      } else if (b.getKey().equals(setOfEntry)) {
         assertTrue(contains);
         entrySetMatch = true;
         // Validate that this binding is also a MultibinderBinding.
         assertTrue(b.acceptTargetVisitor(visitor) instanceof MultibinderBinding);
-      } else if(b.getKey().equals(collectionOfProvidersOfEntryOfProvider)) {
+      } else if (b.getKey().equals(setOfJavaxEntry)) {
+        assertTrue(contains);
+        javaxEntrySetMatch = true;
+      } else if (b.getKey().equals(collectionOfProvidersOfEntryOfProvider)) {
         assertTrue(contains);
         collectionOfProvidersOfEntryOfProviderMatch = true;
-      } else if(b.getKey().equals(collectionOfJavaxProvidersOfEntryOfProvider)) {
+      } else if (b.getKey().equals(collectionOfJavaxProvidersOfEntryOfProvider)) {
         assertTrue(contains);
         collectionOfJavaxProvidersOfEntryOfProviderMatch = true;
       } else if (contains) {
         if (b instanceof ProviderInstanceBinding) {
-          ProviderInstanceBinding<?> pib = (ProviderInstanceBinding<?>)b;
+          ProviderInstanceBinding<?> pib = (ProviderInstanceBinding<?>) b;
           if (pib.getUserSuppliedProvider() instanceof ProviderMapEntry) {
             // weird casting required to workaround compilation issues with jdk6
             ProviderMapEntry<?, ?> pme =
@@ -236,64 +282,116 @@
         otherMatches.add(b);
       }
     }
-    
+
     int sizeOfOther = otherMatches.size();
-    if(allowDuplicates) {
+    if (allowDuplicates) {
       sizeOfOther--; // account for 1 duplicate binding
     }
     // Multiply by two because each has a value and Map.Entry.
     int expectedSize = 2 * (mapResults.size() + duplicates);
-    assertEquals("Incorrect other matches: " + otherMatches, expectedSize, sizeOfOther);
+    assertEquals(
+        "Incorrect other matches:\n\t" + Joiner.on("\n\t").join(otherMatches),
+        expectedSize,
+        sizeOfOther);
     assertTrue(entrySetMatch);
+    assertTrue(javaxEntrySetMatch);
     assertTrue(mapProviderMatch);
     assertTrue(mapJavaxProviderMatch);
     assertTrue(collectionOfProvidersOfEntryOfProviderMatch);
     assertTrue(collectionOfJavaxProvidersOfEntryOfProviderMatch);
     assertEquals(allowDuplicates, mapSetMatch);
     assertEquals(allowDuplicates, mapSetProviderMatch);
-    assertEquals("other MapBindings found: " + otherMapBindings, expectedMapBindings,
+    assertEquals(allowDuplicates, mapSetJavaxProviderMatch);
+    assertEquals(allowDuplicates, mapCollectionJavaxProviderMatch);
+    assertEquals(allowDuplicates, mapCollectionProviderMatch);
+    assertEquals(
+        "other MapBindings found: " + otherMapBindings,
+        expectedMapBindings,
         otherMapBindings.size());
   }
-  
+
   @SuppressWarnings("unchecked")
-  private static <T> void mapModuleTest(Key<T> mapKey, TypeLiteral<?> keyType,
-      TypeLiteral<?> valueType, Iterable<? extends Module> modules, boolean allowDuplicates,
-      int expectedMapBindings, MapResult... results) {
+  private static <T> void mapModuleTest(
+      Key<T> mapKey,
+      TypeLiteral<?> keyType,
+      TypeLiteral<?> valueType,
+      Iterable<? extends Module> modules,
+      boolean allowDuplicates,
+      int expectedMapBindings,
+      MapResult<?, ?>... results) {
     Set<Element> elements = ImmutableSet.copyOf(Elements.getElements(modules));
-    Visitor<T> visitor = new Visitor<T>();
+    Visitor<T> visitor = new Visitor<>();
     MapBinderBinding<T> mapbinder = null;
     Map<Key<?>, Binding<?>> keyMap = Maps.newHashMap();
-    for(Element element : elements) {
-      if(element instanceof Binding) {
-        Binding<?> binding = (Binding<?>)element;
+    for (Element element : elements) {
+      if (element instanceof Binding) {
+        Binding<?> binding = (Binding<?>) element;
         keyMap.put(binding.getKey(), binding);
         if (binding.getKey().equals(mapKey)) {
-          mapbinder = (MapBinderBinding<T>)((Binding<T>)binding).acceptTargetVisitor(visitor);
+          mapbinder = (MapBinderBinding<T>) ((Binding<T>) binding).acceptTargetVisitor(visitor);
         }
       }
     }
     assertNotNull(mapbinder);
-    
+
+    List<MapResult<?, ?>> mapResults = Lists.newArrayList(results);
+
+    // Make sure the entries returned from getEntries(elements) are correct.
+    // Because getEntries() can return duplicates, make sure to continue searching, even
+    // after we find one match.
+    List<Map.Entry<?, Binding<?>>> entries = Lists.newArrayList(mapbinder.getEntries(elements));
+    for (MapResult<?, ?> result : mapResults) {
+      List<Map.Entry<?, Binding<?>>> foundEntries = Lists.newArrayList();
+      for (Map.Entry<?, Binding<?>> entry : entries) {
+        Object key = entry.getKey();
+        Binding<?> value = entry.getValue();
+        if (key.equals(result.k) && matches(value, result.v)) {
+          assertTrue(
+              "mapBinder doesn't contain: " + entry.getValue(),
+              mapbinder.containsElement(entry.getValue()));
+          foundEntries.add(entry);
+        }
+      }
+      assertTrue(
+          "Could not find entry: " + result + " in remaining entries: " + entries,
+          !foundEntries.isEmpty());
+
+      entries.removeAll(foundEntries);
+    }
+
+    assertTrue(
+        "Found all entries of: " + mapResults + ", but more were left over: " + entries,
+        entries.isEmpty());
+
     assertEquals(keyType, mapbinder.getKeyTypeLiteral());
     assertEquals(valueType, mapbinder.getValueTypeLiteral());
-    List<MapResult> mapResults = Lists.newArrayList(results);
-    
+
     Key<?> mapOfProvider = mapKey.ofType(mapOfProviderOf(keyType, valueType));
     Key<?> mapOfJavaxProvider = mapKey.ofType(mapOfJavaxProviderOf(keyType, valueType));
     Key<?> mapOfSetOfProvider = mapKey.ofType(mapOfSetOfProviderOf(keyType, valueType));
+    Key<?> mapOfSetOfJavaxProvider = mapKey.ofType(mapOfSetOfJavaxProviderOf(keyType, valueType));
+    Key<?> mapOfCollectionOfProvider =
+        mapKey.ofType(mapOfCollectionOfProviderOf(keyType, valueType));
+    Key<?> mapOfCollectionOfJavaxProvider =
+        mapKey.ofType(mapOfCollectionOfJavaxProviderOf(keyType, valueType));
     Key<?> mapOfSet = mapKey.ofType(mapOf(keyType, setOf(valueType)));
-    Key<?> setOfEntry = mapKey.ofType(setOf(entryOfProviderOf(keyType, valueType)));    
-    Key<?> collectionOfProvidersOfEntry =
+    Key<?> setOfEntry = mapKey.ofType(setOf(entryOfProviderOf(keyType, valueType)));
+    Key<?> setOfJavaxEntry = mapKey.ofType(setOf(entryOfJavaxProviderOf(keyType, valueType)));
+    Key<?> collectionOfProvidersOfEntryOfProvider =
         mapKey.ofType(collectionOfProvidersOf(entryOfProviderOf(keyType, valueType)));
-    Key<?> collectionOfJavaxProvidersOfEntry =
+    Key<?> collectionOfJavaxProvidersOfEntryOfProvider =
         mapKey.ofType(collectionOfJavaxProvidersOf(entryOfProviderOf(keyType, valueType)));
     boolean entrySetMatch = false;
+    boolean entrySetJavaxMatch = false;
     boolean mapProviderMatch = false;
     boolean mapJavaxProviderMatch = false;
     boolean mapSetMatch = false;
     boolean mapSetProviderMatch = false;
-    boolean collectionOfProvidersOfEntryMatch = false;
-    boolean collectionOfJavaxProvidersOfEntryMatch = false;
+    boolean mapSetJavaxProviderMatch = false;
+    boolean mapCollectionProviderMatch = false;
+    boolean mapCollectionJavaxProviderMatch = false;
+    boolean collectionOfProvidersOfEntryOfProviderMatch = false;
+    boolean collectionOfJavaxProvidersOfEntryOfProviderMatch = false;
     List<Object> otherMapBindings = Lists.newArrayList();
     List<Element> otherMatches = Lists.newArrayList();
     List<Element> otherElements = Lists.newArrayList();
@@ -301,16 +399,16 @@
     Multimap<Object, IndexedBinding> indexedEntries =
         MultimapBuilder.hashKeys().hashSetValues().build();
     int duplicates = 0;
-    for(Element element : elements) {
+    for (Element element : elements) {
       boolean contains = mapbinder.containsElement(element);
-      if(!contains) {
+      if (!contains) {
         otherElements.add(element);
       }
       boolean matched = false;
       Key key = null;
       Binding b = null;
-      if(element instanceof Binding) {
-        b = (Binding)element;
+      if (element instanceof Binding) {
+        b = (Binding) element;
         if (b instanceof ProviderInstanceBinding) {
           ProviderInstanceBinding<?> pb = (ProviderInstanceBinding<?>) b;
           if (pb.getUserSuppliedProvider() instanceof ProviderMapEntry) {
@@ -327,153 +425,186 @@
 
         key = b.getKey();
         Object visited = b.acceptTargetVisitor(visitor);
-        if(visited instanceof MapBinderBinding) {
+        if (visited instanceof MapBinderBinding) {
           matched = true;
-          if(visited.equals(mapbinder)) {
+          if (visited.equals(mapbinder)) {
             assertTrue(contains);
           } else {
             otherMapBindings.add(visited);
           }
         }
-      } else if(element instanceof ProviderLookup) {
-        key = ((ProviderLookup)element).getKey();
+      } else if (element instanceof ProviderLookup) {
+        key = ((ProviderLookup) element).getKey();
       }
-      
-      if(!matched && key != null) {
-        if(key.equals(mapOfProvider)) {
+
+      if (!matched && key != null) {
+        if (key.equals(mapOfProvider)) {
           matched = true;
           assertTrue(contains);
           mapProviderMatch = true;
-        } else if(key.equals(mapOfJavaxProvider)) {
+        } else if (key.equals(mapOfJavaxProvider)) {
           matched = true;
           assertTrue(contains);
           mapJavaxProviderMatch = true;
-        } else if(key.equals(mapOfSet)) {
+        } else if (key.equals(mapOfSet)) {
           matched = true;
           assertTrue(contains);
           mapSetMatch = true;
-        } else if(key.equals(mapOfSetOfProvider)) {
+        } else if (key.equals(mapOfSetOfProvider)) {
           matched = true;
           assertTrue(contains);
           mapSetProviderMatch = true;
-        } else if(key.equals(setOfEntry)) {
+        } else if (key.equals(mapOfSetOfJavaxProvider)) {
+          matched = true;
+          assertTrue(contains);
+          mapSetJavaxProviderMatch = true;
+        } else if (key.equals(mapOfCollectionOfProvider)) {
+          matched = true;
+          assertTrue(contains);
+          mapCollectionProviderMatch = true;
+        } else if (key.equals(mapOfCollectionOfJavaxProvider)) {
+          matched = true;
+          assertTrue(contains);
+          mapCollectionJavaxProviderMatch = true;
+        } else if (key.equals(setOfEntry)) {
           matched = true;
           assertTrue(contains);
           entrySetMatch = true;
           // Validate that this binding is also a MultibinderBinding.
-          if(b != null) {
+          if (b != null) {
             assertTrue(b.acceptTargetVisitor(visitor) instanceof MultibinderBinding);
           }
-        } else if(key.equals(collectionOfProvidersOfEntry)) {
+        } else if (key.equals(setOfJavaxEntry)) {
           matched = true;
           assertTrue(contains);
-          collectionOfProvidersOfEntryMatch = true;
-        } else if(key.equals(collectionOfJavaxProvidersOfEntry)) {
+          entrySetJavaxMatch = true;
+        } else if (key.equals(collectionOfProvidersOfEntryOfProvider)) {
           matched = true;
           assertTrue(contains);
-          collectionOfJavaxProvidersOfEntryMatch = true;
+          collectionOfProvidersOfEntryOfProviderMatch = true;
+        } else if (key.equals(collectionOfJavaxProvidersOfEntryOfProvider)) {
+          matched = true;
+          assertTrue(contains);
+          collectionOfJavaxProvidersOfEntryOfProviderMatch = true;
         }
       }
-      
+
       if (!matched && contains) {
         otherMatches.add(element);
       }
     }
-    
+
     int otherMatchesSize = otherMatches.size();
     if (allowDuplicates) {
       otherMatchesSize--; // allow for 1 duplicate binding
     }
-    // Multiply by 3 because each has a value, ProviderLookup, and Map.Entry
-    int expectedSize = (mapResults.size() + duplicates) * 3;
-    assertEquals("incorrect number of contains, leftover matches: " + otherMatches,
-        expectedSize, otherMatchesSize);
+    // Multiply by 2 because each has a value, and Map.Entry
+    int expectedSize = (mapResults.size() + duplicates) * 2;
+    assertEquals(
+        "incorrect number of contains, leftover matches:\n" + Joiner.on("\n\t").join(otherMatches),
+        expectedSize,
+        otherMatchesSize);
 
     assertTrue(entrySetMatch);
+    assertTrue(entrySetJavaxMatch);
     assertTrue(mapProviderMatch);
     assertTrue(mapJavaxProviderMatch);
-    assertTrue(collectionOfProvidersOfEntryMatch);
-    assertTrue(collectionOfJavaxProvidersOfEntryMatch);
+    assertTrue(collectionOfProvidersOfEntryOfProviderMatch);
+    assertTrue(collectionOfJavaxProvidersOfEntryOfProviderMatch);
     assertEquals(allowDuplicates, mapSetMatch);
     assertEquals(allowDuplicates, mapSetProviderMatch);
-    assertEquals("other MapBindings found: " + otherMapBindings, expectedMapBindings,
+    assertEquals(allowDuplicates, mapSetJavaxProviderMatch);
+    assertEquals(allowDuplicates, mapCollectionProviderMatch);
+    assertEquals(allowDuplicates, mapCollectionJavaxProviderMatch);
+    assertEquals(
+        "other MapBindings found: " + otherMapBindings,
+        expectedMapBindings,
         otherMapBindings.size());
-    
-     // Validate that we can construct an injector out of the remaining bindings.
+
+    // Validate that we can construct an injector out of the remaining bindings.
     Guice.createInjector(Elements.getModule(otherElements));
   }
-  
+
   /**
    * Asserts that MultibinderBinding visitors work correctly.
-   * 
+   *
    * @param <T> The type of the binding
    * @param setKey The key the set belongs to.
    * @param elementType the TypeLiteral of the element
    * @param modules The modules that define the multibindings
-   * @param visitType The kind of test we should perform.  A live Injector, a raw Elements (Module) test, or both.
+   * @param visitType The kind of test we should perform. A live Injector, a raw Elements (Module)
+   *     test, or both.
    * @param allowDuplicates If duplicates are allowed.
    * @param expectedMultibindings The number of other multibinders we expect to see.
    * @param results The kind of bindings contained in the multibinder.
    */
-  static <T> void assertSetVisitor(Key<Set<T>> setKey, TypeLiteral<?> elementType,
-      Iterable<? extends Module> modules, VisitType visitType, boolean allowDuplicates,
-      int expectedMultibindings, BindResult... results) {
-    if(visitType == null) {
+  static <T> void assertSetVisitor(
+      Key<Set<T>> setKey,
+      TypeLiteral<?> elementType,
+      Iterable<? extends Module> modules,
+      VisitType visitType,
+      boolean allowDuplicates,
+      int expectedMultibindings,
+      BindResult... results) {
+    if (visitType == null) {
       fail("must test something");
     }
-    
-    if(visitType == BOTH || visitType == INJECTOR) {
-      setInjectorTest(setKey, elementType, modules, allowDuplicates,
-          expectedMultibindings, results);
+
+    if (visitType == BOTH || visitType == INJECTOR) {
+      setInjectorTest(
+          setKey, elementType, modules, allowDuplicates, expectedMultibindings, results);
     }
-    
-    if(visitType == BOTH || visitType == MODULE) {
-      setModuleTest(setKey, elementType, modules, allowDuplicates,
-          expectedMultibindings, results);
+
+    if (visitType == BOTH || visitType == MODULE) {
+      setModuleTest(setKey, elementType, modules, allowDuplicates, expectedMultibindings, results);
     }
   }
-  
+
   @SuppressWarnings("unchecked")
-  private static <T> void setInjectorTest(Key<Set<T>> setKey, TypeLiteral<?> elementType,
-      Iterable<? extends Module> modules, boolean allowDuplicates, int otherMultibindings,
+  private static <T> void setInjectorTest(
+      Key<Set<T>> setKey,
+      TypeLiteral<?> elementType,
+      Iterable<? extends Module> modules,
+      boolean allowDuplicates,
+      int otherMultibindings,
       BindResult... results) {
     Key<?> collectionOfProvidersKey = setKey.ofType(collectionOfProvidersOf(elementType));
-    Key<?> collectionOfJavaxProvidersKey =
-        setKey.ofType(collectionOfJavaxProvidersOf(elementType));
+    Key<?> collectionOfJavaxProvidersKey = setKey.ofType(collectionOfJavaxProvidersOf(elementType));
     Injector injector = Guice.createInjector(modules);
-    Visitor<Set<T>> visitor = new Visitor<Set<T>>();
+    Visitor<Set<T>> visitor = new Visitor<>();
     Binding<Set<T>> binding = injector.getBinding(setKey);
     MultibinderBinding<Set<T>> multibinder =
-        (MultibinderBinding<Set<T>>)binding.acceptTargetVisitor(visitor);
+        (MultibinderBinding<Set<T>>) binding.acceptTargetVisitor(visitor);
     assertNotNull(multibinder);
     assertEquals(elementType, multibinder.getElementTypeLiteral());
     assertEquals(allowDuplicates, multibinder.permitsDuplicates());
     List<Binding<?>> elements = Lists.newArrayList(multibinder.getElements());
     List<BindResult> bindResults = Lists.newArrayList(results);
-    assertEquals("wrong bind elements, expected: " + bindResults
-        + ", but was: " + multibinder.getElements(),
-        bindResults.size(), elements.size());
+    assertEquals(
+        "wrong bind elements, expected: " + bindResults + ", but was: " + multibinder.getElements(),
+        bindResults.size(),
+        elements.size());
 
-    for(BindResult result : bindResults) {
+    for (BindResult result : bindResults) {
       Binding found = null;
-      for(Binding item : elements) {
+      for (Binding item : elements) {
         if (matches(item, result)) {
           found = item;
           break;
         }
       }
-      if(found == null) {
+      if (found == null) {
         fail("Could not find element: " + result + " in remaining elements: " + elements);
       } else {
         elements.remove(found);
       }
     }
-    
-    if(!elements.isEmpty()) {
+
+    if (!elements.isEmpty()) {
       fail("Found all elements of: " + bindResults + ", but more were left over: " + elements);
     }
 
-    Set<Binding> setOfElements = new HashSet<Binding>(multibinder.getElements()); 
+    Set<Binding> setOfElements = new HashSet<Binding>(multibinder.getElements());
     Set<IndexedBinding> setOfIndexed = Sets.newHashSet();
     Indexer indexer = new Indexer(injector);
     for (Binding<?> oneBinding : setOfElements) {
@@ -484,17 +615,17 @@
     List<Binding> otherContains = Lists.newArrayList();
     boolean collectionOfProvidersMatch = false;
     boolean collectionOfJavaxProvidersMatch = false;
-    for(Binding b : injector.getAllBindings().values()) {
+    for (Binding b : injector.getAllBindings().values()) {
       boolean contains = multibinder.containsElement(b);
       Key key = b.getKey();
       Object visited = b.acceptTargetVisitor(visitor);
-      if(visited != null) {
-        if(visited.equals(multibinder)) {
+      if (visited != null) {
+        if (visited.equals(multibinder)) {
           assertTrue(contains);
         } else {
           otherMultibinders.add(visited);
         }
-      } else if(setOfElements.contains(b)) {
+      } else if (setOfElements.contains(b)) {
         assertTrue(contains);
       } else if (key.equals(collectionOfProvidersKey)) {
         assertTrue(contains);
@@ -512,30 +643,34 @@
     assertTrue(collectionOfProvidersMatch);
     assertTrue(collectionOfJavaxProvidersMatch);
 
-    if(allowDuplicates) {
+    if (allowDuplicates) {
       assertEquals("contained more than it should: " + otherContains, 1, otherContains.size());
     } else {
       assertTrue("contained more than it should: " + otherContains, otherContains.isEmpty());
     }
-    assertEquals("other multibindings found: " + otherMultibinders, otherMultibindings,
+    assertEquals(
+        "other multibindings found: " + otherMultibinders,
+        otherMultibindings,
         otherMultibinders.size());
-    
   }
-  
+
   @SuppressWarnings("unchecked")
-  private static <T> void setModuleTest(Key<Set<T>> setKey, TypeLiteral<?> elementType,
-      Iterable<? extends Module> modules, boolean allowDuplicates, int otherMultibindings,
+  private static <T> void setModuleTest(
+      Key<Set<T>> setKey,
+      TypeLiteral<?> elementType,
+      Iterable<? extends Module> modules,
+      boolean allowDuplicates,
+      int otherMultibindings,
       BindResult... results) {
     Key<?> collectionOfProvidersKey = setKey.ofType(collectionOfProvidersOf(elementType));
-    Key<?> collectionOfJavaxProvidersKey =
-        setKey.ofType(collectionOfJavaxProvidersOf(elementType));
+    Key<?> collectionOfJavaxProvidersKey = setKey.ofType(collectionOfJavaxProvidersOf(elementType));
     List<BindResult> bindResults = Lists.newArrayList(results);
     List<Element> elements = Elements.getElements(modules);
-    Visitor<T> visitor = new Visitor<T>();
+    Visitor<T> visitor = new Visitor<>();
     MultibinderBinding<Set<T>> multibinder = null;
-    for(Element element : elements) {
-      if(element instanceof Binding && ((Binding)element).getKey().equals(setKey)) {
-        multibinder = (MultibinderBinding<Set<T>>)((Binding)element).acceptTargetVisitor(visitor);
+    for (Element element : elements) {
+      if (element instanceof Binding && ((Binding) element).getKey().equals(setKey)) {
+        multibinder = (MultibinderBinding<Set<T>>) ((Binding) element).acceptTargetVisitor(visitor);
         break;
       }
     }
@@ -543,31 +678,31 @@
 
     assertEquals(elementType, multibinder.getElementTypeLiteral());
     List<Object> otherMultibinders = Lists.newArrayList();
-    Set<Element> otherContains = new HashSet<Element>();
+    Set<Element> otherContains = new HashSet<>();
     List<Element> otherElements = Lists.newArrayList();
     int duplicates = 0;
     Set<IndexedBinding> setOfIndexed = Sets.newHashSet();
     Indexer indexer = new Indexer(null);
     boolean collectionOfProvidersMatch = false;
     boolean collectionOfJavaxProvidersMatch = false;
-    for(Element element : elements) {
+    for (Element element : elements) {
       boolean contains = multibinder.containsElement(element);
-      if(!contains) {
+      if (!contains) {
         otherElements.add(element);
       }
       boolean matched = false;
       Key key = null;
-      if(element instanceof Binding) {
-        Binding binding = (Binding)element;
+      if (element instanceof Binding) {
+        Binding binding = (Binding) element;
         if (indexer.isIndexable(binding)
             && !setOfIndexed.add((IndexedBinding) binding.acceptTargetVisitor(indexer))) {
           duplicates++;
         }
         key = binding.getKey();
         Object visited = binding.acceptTargetVisitor(visitor);
-        if(visited != null) {
+        if (visited != null) {
           matched = true;
-          if(visited.equals(multibinder)) {
+          if (visited.equals(multibinder)) {
             assertTrue(contains);
           } else {
             otherMultibinders.add(visited);
@@ -580,23 +715,29 @@
         assertFalse(matched);
         collectionOfProvidersMatch = true;
       } else if (collectionOfJavaxProvidersKey.equals(key)) {
-          assertTrue(contains);
-          assertFalse(matched);
-          collectionOfJavaxProvidersMatch = true;
+        assertTrue(contains);
+        assertFalse(matched);
+        collectionOfJavaxProvidersMatch = true;
       } else if (!matched && contains) {
         otherContains.add(element);
       }
     }
 
-    if(allowDuplicates) {
-      assertEquals("wrong contained elements: " + otherContains,
-          bindResults.size() + 1 + duplicates, otherContains.size());
+    if (allowDuplicates) {
+      assertEquals(
+          "wrong contained elements: " + otherContains,
+          bindResults.size() + 1 + duplicates,
+          otherContains.size());
     } else {
-      assertEquals("wrong contained elements: " + otherContains,
-          bindResults.size() + duplicates, otherContains.size());
+      assertEquals(
+          "wrong contained elements: " + otherContains,
+          bindResults.size() + duplicates,
+          otherContains.size());
     }
 
-    assertEquals("other multibindings found: " + otherMultibinders, otherMultibindings,
+    assertEquals(
+        "other multibindings found: " + otherMultibinders,
+        otherMultibindings,
         otherMultibinders.size());
     assertTrue(collectionOfProvidersMatch);
     assertTrue(collectionOfJavaxProvidersMatch);
@@ -612,14 +753,15 @@
    * @param keyType The key OptionalBinder is binding
    * @param modules The modules that define the bindings
    * @param visitType The kind of test we should perform. A live Injector, a raw Elements (Module)
-   *        test, or both.
+   *     test, or both.
    * @param expectedOtherOptionalBindings the # of other optional bindings we expect to see.
    * @param expectedDefault the expected default binding, or null if none
    * @param expectedActual the expected actual binding, or null if none
-   * @param expectedUserLinkedActual the user binding that is the actual binding, used if
-   *        neither the default nor actual are set and a user binding existed for the type.
+   * @param expectedUserLinkedActual the user binding that is the actual binding, used if neither
+   *     the default nor actual are set and a user binding existed for the type.
    */
-  static <T> void assertOptionalVisitor(Key<T> keyType,
+  static <T> void assertOptionalVisitor(
+      Key<T> keyType,
       Iterable<? extends Module> modules,
       VisitType visitType,
       int expectedOtherOptionalBindings,
@@ -636,18 +778,29 @@
     }
 
     if (visitType == BOTH || visitType == INJECTOR) {
-      optionalInjectorTest(keyType, modules, expectedOtherOptionalBindings, expectedDefault,
-          expectedActual, expectedUserLinkedActual);
+      optionalInjectorTest(
+          keyType,
+          modules,
+          expectedOtherOptionalBindings,
+          expectedDefault,
+          expectedActual,
+          expectedUserLinkedActual);
     }
 
     if (visitType == BOTH || visitType == MODULE) {
-      optionalModuleTest(keyType, modules, expectedOtherOptionalBindings, expectedDefault,
-          expectedActual, expectedUserLinkedActual);
+      optionalModuleTest(
+          keyType,
+          modules,
+          expectedOtherOptionalBindings,
+          expectedDefault,
+          expectedActual,
+          expectedUserLinkedActual);
     }
   }
 
-  @SuppressWarnings({ "unchecked", "rawtypes" })
-  private static <T> void optionalInjectorTest(Key<T> keyType,
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private static <T> void optionalInjectorTest(
+      Key<T> keyType,
       Iterable<? extends Module> modules,
       int expectedOtherOptionalBindings,
       BindResult<?> expectedDefault,
@@ -659,9 +812,11 @@
     }
 
     Key<Optional<T>> optionalKey =
-        keyType.ofType(OptionalBinder.optionalOf(keyType.getTypeLiteral()));
-    Key<?> javaOptionalKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(OptionalBinder.javaOptionalOf(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOf(keyType.getTypeLiteral()));
+    Key<?> javaOptionalKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(RealOptionalBinder.javaOptionalOf(keyType.getTypeLiteral()))
+            : null;
     Injector injector = Guice.createInjector(modules);
     Binding<Optional<T>> optionalBinding = injector.getBinding(optionalKey);
     Visitor visitor = new Visitor();
@@ -674,7 +829,8 @@
     OptionalBinderBinding<?> javaOptionalBinder = null;
     if (HAS_JAVA_OPTIONAL) {
       javaOptionalBinding = injector.getBinding(javaOptionalKey);
-      javaOptionalBinder = (OptionalBinderBinding<?>) javaOptionalBinding.acceptTargetVisitor(visitor);
+      javaOptionalBinder =
+          (OptionalBinderBinding<?>) javaOptionalBinding.acceptTargetVisitor(visitor);
       assertNotNull(javaOptionalBinder);
       assertEquals(javaOptionalKey, javaOptionalBinder.getKey());
     }
@@ -682,14 +838,20 @@
     if (expectedDefault == null) {
       assertNull("did not expect a default binding", optionalBinder.getDefaultBinding());
       if (HAS_JAVA_OPTIONAL) {
-        assertNull("did not expect a default binding", javaOptionalBinder.getDefaultBinding());  
+        assertNull("did not expect a default binding", javaOptionalBinder.getDefaultBinding());
       }
     } else {
-      assertTrue("expectedDefault: " + expectedDefault + ", actualDefault: "
+      assertTrue(
+          "expectedDefault: "
+              + expectedDefault
+              + ", actualDefault: "
               + optionalBinder.getDefaultBinding(),
           matches(optionalBinder.getDefaultBinding(), expectedDefault));
       if (HAS_JAVA_OPTIONAL) {
-        assertTrue("expectedDefault: " + expectedDefault + ", actualDefault: "
+        assertTrue(
+            "expectedDefault: "
+                + expectedDefault
+                + ", actualDefault: "
                 + javaOptionalBinder.getDefaultBinding(),
             matches(javaOptionalBinder.getDefaultBinding(), expectedDefault));
       }
@@ -698,37 +860,53 @@
     if (expectedActual == null && expectedUserLinkedActual == null) {
       assertNull(optionalBinder.getActualBinding());
       if (HAS_JAVA_OPTIONAL) {
-        assertNull(javaOptionalBinder.getActualBinding());  
+        assertNull(javaOptionalBinder.getActualBinding());
       }
     } else if (expectedActual != null) {
-      assertTrue("expectedActual: " + expectedActual + ", actualActual: "
+      assertTrue(
+          "expectedActual: "
+              + expectedActual
+              + ", actualActual: "
               + optionalBinder.getActualBinding(),
           matches(optionalBinder.getActualBinding(), expectedActual));
       if (HAS_JAVA_OPTIONAL) {
-        assertTrue("expectedActual: " + expectedActual + ", actualActual: "
+        assertTrue(
+            "expectedActual: "
+                + expectedActual
+                + ", actualActual: "
                 + javaOptionalBinder.getActualBinding(),
             matches(javaOptionalBinder.getActualBinding(), expectedActual));
       }
     } else if (expectedUserLinkedActual != null) {
-      assertTrue("expectedUserLinkedActual: " + expectedUserLinkedActual + ", actualActual: "
+      assertTrue(
+          "expectedUserLinkedActual: "
+              + expectedUserLinkedActual
+              + ", actualActual: "
               + optionalBinder.getActualBinding(),
           matches(optionalBinder.getActualBinding(), expectedUserLinkedActual));
       if (HAS_JAVA_OPTIONAL) {
-        assertTrue("expectedUserLinkedActual: " + expectedUserLinkedActual + ", actualActual: "
+        assertTrue(
+            "expectedUserLinkedActual: "
+                + expectedUserLinkedActual
+                + ", actualActual: "
                 + javaOptionalBinder.getActualBinding(),
-            matches(javaOptionalBinder.getActualBinding(), expectedUserLinkedActual));  
+            matches(javaOptionalBinder.getActualBinding(), expectedUserLinkedActual));
       }
     }
 
-
     Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey =
-        keyType.ofType(optionalOfJavaxProvider(keyType.getTypeLiteral()));
-    Key<?> javaOptionalJavaxProviderKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(javaOptionalOfJavaxProvider(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOfJavaxProvider(keyType.getTypeLiteral()));
+    Key<?> javaOptionalJavaxProviderKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(
+                RealOptionalBinder.javaOptionalOfJavaxProvider(keyType.getTypeLiteral()))
+            : null;
     Key<Optional<Provider<T>>> optionalProviderKey =
-        keyType.ofType(optionalOfProvider(keyType.getTypeLiteral()));
-    Key<?> javaOptionalProviderKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(javaOptionalOfProvider(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOfProvider(keyType.getTypeLiteral()));
+    Key<?> javaOptionalProviderKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(RealOptionalBinder.javaOptionalOfProvider(keyType.getTypeLiteral()))
+            : null;
 
     boolean keyMatch = false;
     boolean optionalKeyMatch = false;
@@ -803,12 +981,15 @@
     assertEquals(HAS_JAVA_OPTIONAL, javaOptionalProviderKeyMatch);
     assertEquals(expectedDefault != null, defaultMatch);
     assertEquals(expectedActual != null, actualMatch);
-    assertEquals("other OptionalBindings found: " + otherOptionalBindings,
-        expectedOtherOptionalBindings, otherOptionalBindings.size());
+    assertEquals(
+        "other OptionalBindings found: " + otherOptionalBindings,
+        expectedOtherOptionalBindings,
+        otherOptionalBindings.size());
   }
 
-  @SuppressWarnings({ "unchecked", "rawtypes" })
-  private static <T> void optionalModuleTest(Key<T> keyType,
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private static <T> void optionalModuleTest(
+      Key<T> keyType,
       Iterable<? extends Module> modules,
       int expectedOtherOptionalBindings,
       BindResult<?> expectedDefault,
@@ -821,9 +1002,11 @@
     Set<Element> elements = ImmutableSet.copyOf(Elements.getElements(modules));
     Map<Key<?>, Binding<?>> indexed = index(elements);
     Key<Optional<T>> optionalKey =
-        keyType.ofType(OptionalBinder.optionalOf(keyType.getTypeLiteral()));
-    Key<?> javaOptionalKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(OptionalBinder.javaOptionalOf(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOf(keyType.getTypeLiteral()));
+    Key<?> javaOptionalKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(RealOptionalBinder.javaOptionalOf(keyType.getTypeLiteral()))
+            : null;
     Visitor visitor = new Visitor();
     OptionalBinderBinding<Optional<T>> optionalBinder = null;
     OptionalBinderBinding<?> javaOptionalBinder = null;
@@ -843,9 +1026,9 @@
     for (Element element : elements) {
       if (optionalBinder.containsElement(element) && element instanceof Binding) {
         Binding binding = (Binding) element;
-        if (isSourceEntry(binding, Source.DEFAULT)) {
+        if (isSourceEntry(binding, RealOptionalBinder.Source.DEFAULT)) {
           defaultKey = binding.getKey();
-        } else if (isSourceEntry(binding, Source.ACTUAL)) {
+        } else if (isSourceEntry(binding, RealOptionalBinder.Source.ACTUAL)) {
           actualKey = binding.getKey();
         }
       }
@@ -858,13 +1041,18 @@
     assertEquals(expectedActual == null, actualKey == null);
 
     Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey =
-        keyType.ofType(optionalOfJavaxProvider(keyType.getTypeLiteral()));
-    Key<?> javaOptionalJavaxProviderKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(javaOptionalOfJavaxProvider(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOfJavaxProvider(keyType.getTypeLiteral()));
+    Key<?> javaOptionalJavaxProviderKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(
+                RealOptionalBinder.javaOptionalOfJavaxProvider(keyType.getTypeLiteral()))
+            : null;
     Key<Optional<Provider<T>>> optionalProviderKey =
-        keyType.ofType(optionalOfProvider(keyType.getTypeLiteral()));
-    Key<?> javaOptionalProviderKey = HAS_JAVA_OPTIONAL ?
-        keyType.ofType(javaOptionalOfProvider(keyType.getTypeLiteral())) : null;
+        keyType.ofType(RealOptionalBinder.optionalOfProvider(keyType.getTypeLiteral()));
+    Key<?> javaOptionalProviderKey =
+        HAS_JAVA_OPTIONAL
+            ? keyType.ofType(RealOptionalBinder.javaOptionalOfProvider(keyType.getTypeLiteral()))
+            : null;
     boolean keyMatch = false;
     boolean optionalKeyMatch = false;
     boolean javaOptionalKeyMatch = false;
@@ -932,8 +1120,8 @@
       } else if (key != null && key.equals(defaultKey)) {
         assertTrue(contains);
         if (b != null) { // otherwise it might just be a ProviderLookup into it
-          assertTrue("expected: " + expectedDefault + ", but was: " + b,
-              matches(b, expectedDefault));
+          assertTrue(
+              "expected: " + expectedDefault + ", but was: " + b, matches(b, expectedDefault));
           defaultMatch = true;
         }
       } else if (key != null && key.equals(actualKey)) {
@@ -946,7 +1134,7 @@
         otherContains.add(element);
       }
     }
-    
+
     // only expect a keymatch if either default or actual are set
     assertEquals(expectedDefault != null || expectedActual != null, keyMatch);
     assertTrue(optionalKeyMatch);
@@ -958,19 +1146,21 @@
     assertEquals(expectedDefault != null, defaultMatch);
     assertEquals(expectedActual != null, actualMatch);
     assertEquals(otherContains.toString(), 0, otherContains.size());
-    assertEquals("other OptionalBindings found: " + otherOptionalElements,
-        expectedOtherOptionalBindings, otherOptionalElements.size());
-    
-     // Validate that we can construct an injector out of the remaining bindings.
+    assertEquals(
+        "other OptionalBindings found: " + otherOptionalElements,
+        expectedOtherOptionalBindings,
+        otherOptionalElements.size());
+
+    // Validate that we can construct an injector out of the remaining bindings.
     Guice.createInjector(Elements.getModule(nonContainedElements));
   }
 
-  private static boolean isSourceEntry(Binding b, Source type) {
-    switch(type) {
+  private static boolean isSourceEntry(Binding b, RealOptionalBinder.Source type) {
+    switch (type) {
       case ACTUAL:
-        return b.getKey().getAnnotation() instanceof OptionalBinder.Actual;
+        return b.getKey().getAnnotation() instanceof RealOptionalBinder.Actual;
       case DEFAULT:
-        return b.getKey().getAnnotation() instanceof OptionalBinder.Default;
+        return b.getKey().getAnnotation() instanceof RealOptionalBinder.Default;
       default:
         throw new IllegalStateException("invalid type: " + type);
     }
@@ -986,7 +1176,7 @@
     }
     return builder.build();
   }
-  
+
   static <K, V> MapResult instance(K k, V v) {
     return new MapResult<K, V>(k, new BindResult<V>(INSTANCE, v, null));
   }
@@ -1006,45 +1196,46 @@
   static class MapResult<K, V> {
     private final K k;
     private final BindResult<V> v;
-    
+
     MapResult(K k, BindResult<V> v) {
       this.k = k;
       this.v = v;
     }
-    
+
     @Override
     public String toString() {
       return "entry[key[" + k + "],value[" + v + "]]";
     }
-  }  
-  
+  }
+
   private static boolean matches(Binding<?> item, BindResult<?> result) {
     switch (result.type) {
-    case INSTANCE:
-      if (item instanceof InstanceBinding
-          && ((InstanceBinding) item).getInstance().equals(result.instance)) {
-        return true;
-      }
-      break;
-    case LINKED:
-      if (item instanceof LinkedKeyBinding
-          && ((LinkedKeyBinding) item).getLinkedKey().equals(result.key)) {
-        return true;
-      }
-      break;
-    case PROVIDER_INSTANCE:
-      if (item instanceof ProviderInstanceBinding
-          && Objects.equal(((ProviderInstanceBinding) item).getUserSuppliedProvider().get(),
-                           result.instance)) {
-        return true;
-      }
-      break;
-    case PROVIDER_KEY:
-      if (item instanceof ProviderKeyBinding
-          && ((ProviderKeyBinding) item).getProviderKey().equals(result.key)) {
-        return true;
-      }
-      break;
+      case INSTANCE:
+        if (item instanceof InstanceBinding
+            && ((InstanceBinding) item).getInstance().equals(result.instance)) {
+          return true;
+        }
+        break;
+      case LINKED:
+        if (item instanceof LinkedKeyBinding
+            && ((LinkedKeyBinding) item).getLinkedKey().equals(result.key)) {
+          return true;
+        }
+        break;
+      case PROVIDER_INSTANCE:
+        if (item instanceof ProviderInstanceBinding
+            && Objects.equal(
+                ((ProviderInstanceBinding) item).getUserSuppliedProvider().get(),
+                result.instance)) {
+          return true;
+        }
+        break;
+      case PROVIDER_KEY:
+        if (item instanceof ProviderKeyBinding
+            && ((ProviderKeyBinding) item).getProviderKey().equals(result.key)) {
+          return true;
+        }
+        break;
     }
     return false;
   }
@@ -1068,48 +1259,56 @@
   static <T> BindResult<T> providerKey(Key<T> key) {
     return new BindResult<T>(PROVIDER_KEY, null, key);
   }
-  
+
   /** The kind of binding. */
-  static enum BindType { INSTANCE, LINKED, PROVIDER_INSTANCE, PROVIDER_KEY }
+  static enum BindType {
+    INSTANCE,
+    LINKED,
+    PROVIDER_INSTANCE,
+    PROVIDER_KEY
+  }
   /** The result of the binding. */
   static class BindResult<T> {
     private final BindType type;
     private final Key<?> key;
     private final T instance;
-    
+
     private BindResult(BindType type, T instance, Key<?> key) {
       this.type = type;
       this.instance = instance;
       this.key = key;
     }
-    
+
     @Override
     public String toString() {
-      switch(type) {
-      case INSTANCE:
-        return "instance[" + instance + "]";
-      case LINKED:
-        return "linkedKey[" + key + "]";
-      case PROVIDER_INSTANCE:
-        return "providerInstance[" + instance + "]";
-      case PROVIDER_KEY:
-        return "providerKey[" + key + "]";
+      switch (type) {
+        case INSTANCE:
+          return "instance[" + instance + "]";
+        case LINKED:
+          return "linkedKey[" + key + "]";
+        case PROVIDER_INSTANCE:
+          return "providerInstance[" + instance + "]";
+        case PROVIDER_KEY:
+          return "providerKey[" + key + "]";
       }
       return null;
     }
   }
-  
-  private static class Visitor<T> extends
-      DefaultBindingTargetVisitor<T, Object> implements MultibindingsTargetVisitor<T, Object> {
-  
+
+  private static class Visitor<T> extends DefaultBindingTargetVisitor<T, Object>
+      implements MultibindingsTargetVisitor<T, Object> {
+
+    @Override
     public Object visit(MultibinderBinding<? extends T> multibinding) {
       return multibinding;
     }
-  
+
+    @Override
     public Object visit(MapBinderBinding<? extends T> mapbinding) {
       return mapbinding;
     }
-    
+
+    @Override
     public Object visit(OptionalBinderBinding<? extends T> optionalbinding) {
       return optionalbinding;
     }
diff --git a/core/test/com/google/inject/internal/UniqueAnnotationsTest.java b/core/test/com/google/inject/internal/UniqueAnnotationsTest.java
index 9676eca..6d192f7 100644
--- a/core/test/com/google/inject/internal/UniqueAnnotationsTest.java
+++ b/core/test/com/google/inject/internal/UniqueAnnotationsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,20 +14,17 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.internal;
 
+import java.lang.annotation.Annotation;
 import junit.framework.TestCase;
 
-import java.lang.annotation.Annotation;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class UniqueAnnotationsTest extends TestCase {
 
-  @UniqueAnnotations.Internal(31) public Void unused;
-  
+  @UniqueAnnotations.Internal(31)
+  public Void unused;
+
   public void testEqualsHashCodeToString() {
     Annotation actual = UniqueAnnotations.create(31);
 
diff --git a/core/test/com/google/inject/internal/WeakKeySetTest.java b/core/test/com/google/inject/internal/WeakKeySetTest.java
index 4a81ebb..36fd90a 100644
--- a/core/test/com/google/inject/internal/WeakKeySetTest.java
+++ b/core/test/com/google/inject/internal/WeakKeySetTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,20 +39,18 @@
 import com.google.inject.spi.ScopeBinding;
 import com.google.inject.spi.TypeConverterBinding;
 import com.google.inject.spi.TypeListenerBinding;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link WeakKeySet}.
- * <p>
- * Multibinding specific tests can be found in MultibinderTest and MapBinderTest.
- * 
+ *
+ * <p>Multibinding specific tests can be found in MultibinderTest and MapBinderTest.
+ *
  * @author dweis@google.com (Daniel Weis)
  */
 public class WeakKeySetTest extends TestCase {
@@ -68,8 +66,8 @@
     TestState state = new TestState();
     Key<Integer> key = Key.get(Integer.class);
     Object source = new Object();
-    
-    WeakReference<Key<Integer>> weakKeyRef = new WeakReference<Key<Integer>>(key);
+
+    WeakReference<Key<Integer>> weakKeyRef = new WeakReference<>(key);
 
     set.add(key, state, source);
     assertInSet(set, key, 1, source);
@@ -84,13 +82,13 @@
     key = null;
     awaitClear(weakKeyRef);
   }
-  
+
   public void testEviction_nullSource() {
     TestState state = new TestState();
     Key<Integer> key = Key.get(Integer.class);
     Object source = null;
-    
-    WeakReference<Key<Integer>> weakKeyRef = new WeakReference<Key<Integer>>(key);
+
+    WeakReference<Key<Integer>> weakKeyRef = new WeakReference<>(key);
 
     set.add(key, state, source);
     assertInSet(set, key, 1, source);
@@ -120,10 +118,10 @@
     set.add(key2, state2, source2);
     assertInSet(set, key2, 2, source1, source2);
 
-    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<Key<Integer>>(key1);
-    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<Key<Integer>>(key2);
-    WeakReference<Object> weakSource1Ref = new WeakReference<Object>(source1);
-    WeakReference<Object> weakSource2Ref = new WeakReference<Object>(source2);
+    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<>(key1);
+    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<>(key2);
+    WeakReference<Object> weakSource1Ref = new WeakReference<>(source1);
+    WeakReference<Object> weakSource2Ref = new WeakReference<>(source2);
 
     Key<Integer> key = key1 = key2 = Key.get(Integer.class);
     state1 = null;
@@ -134,11 +132,11 @@
     assertInSet(set, key, 1, source2);
 
     source1 = source2 = null;
-    
+
     awaitClear(weakSource1Ref);
     // Key1 will be referenced as the key in the sources backingSet and won't be
     // GC'd.
-    
+
     // Should not be GC'd until state2 goes away.
     assertNotNull(weakSource2Ref.get());
 
@@ -153,7 +151,7 @@
     // Now that the backing set is emptied, key1 is released.
     awaitClear(weakKey1Ref);
   }
-  
+
   public void testNoEviction_keyOverlap_2x() {
     TestState state1 = new TestState();
     TestState state2 = new TestState();
@@ -168,8 +166,8 @@
     set.add(key2, state2, source2);
     assertInSet(set, key2, 2, source1, source2);
 
-    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<Key<Integer>>(key1);
-    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<Key<Integer>>(key2);
+    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<>(key1);
+    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<>(key2);
 
     Key<Integer> key = key1 = key2 = Key.get(Integer.class);
 
@@ -197,9 +195,9 @@
     assertInSet(set, key2, 1, source);
     assertInSet(set, key1, 1, source);
 
-    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<Key<Integer>>(key1);
-    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<Key<Integer>>(key2);
-    WeakReference<Object> weakSourceRef = new WeakReference<Object>(source);
+    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<>(key1);
+    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<>(key2);
+    WeakReference<Object> weakSourceRef = new WeakReference<>(source);
 
     Key<Integer> key = key1 = key2 = Key.get(Integer.class);
     state1 = null;
@@ -224,7 +222,7 @@
     // Now that the backing set is emptied, key1 is released.
     awaitClear(weakKey1Ref);
   }
-  
+
   public void testEviction_keyAndSourceOverlap_nonNull() {
     TestState state1 = new TestState();
     TestState state2 = new TestState();
@@ -239,19 +237,19 @@
     // Same source so still only one value.
     assertInSet(set, key2, 1, source);
 
-    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<Key<Integer>>(key1);
-    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<Key<Integer>>(key2);
-    WeakReference<Object> weakSourceRef = new WeakReference<Object>(source);
+    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<>(key1);
+    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<>(key2);
+    WeakReference<Object> weakSourceRef = new WeakReference<>(source);
 
     Key<Integer> key = key1 = key2 = Key.get(Integer.class);
     state1 = null;
 
     awaitFullGc();
 
- // Same source so still only one value.
+    // Same source so still only one value.
     assertInSet(set, key, 1, source);
     assertInSet(set, key1, 1, source);
-    
+
     source = null;
 
     awaitFullGc();
@@ -291,12 +289,12 @@
     set.add(key3, state3, source3);
     assertInSet(set, key1, 3, source1, source2, source3);
 
-    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<Key<Integer>>(key1);
-    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<Key<Integer>>(key2);
-    WeakReference<Key<Integer>> weakKey3Ref = new WeakReference<Key<Integer>>(key3);
-    WeakReference<Object> weakSource1Ref = new WeakReference<Object>(source1);
-    WeakReference<Object> weakSource2Ref = new WeakReference<Object>(source2);
-    WeakReference<Object> weakSource3Ref = new WeakReference<Object>(source3);
+    WeakReference<Key<Integer>> weakKey1Ref = new WeakReference<>(key1);
+    WeakReference<Key<Integer>> weakKey2Ref = new WeakReference<>(key2);
+    WeakReference<Key<Integer>> weakKey3Ref = new WeakReference<>(key3);
+    WeakReference<Object> weakSource1Ref = new WeakReference<>(source1);
+    WeakReference<Object> weakSource2Ref = new WeakReference<>(source2);
+    WeakReference<Object> weakSource3Ref = new WeakReference<>(source3);
 
     Key<Integer> key = key1 = key2 = key3 = Key.get(Integer.class);
     state1 = null;
@@ -316,7 +314,7 @@
     assertInSet(set, key, 1, source3);
 
     awaitClear(weakKey2Ref);
-    
+
     source2 = null;
     awaitClear(weakSource2Ref);
     // Key1 will be referenced as the key in the sources backingSet and won't be
@@ -334,54 +332,69 @@
   }
 
   public void testWeakKeySet_integration() {
-    Injector parentInjector = Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(4);
-          }
-        });
+    Injector parentInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Integer.class).toInstance(4);
+              }
+            });
     assertNotBlacklisted(parentInjector, Key.get(String.class));
 
-    Injector childInjector = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("bar");
-      }
-    });
-    WeakReference<Injector> weakRef = new WeakReference<Injector>(childInjector);
+    Injector childInjector =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("bar");
+              }
+            });
+    WeakReference<Injector> weakRef = new WeakReference<>(childInjector);
     assertBlacklisted(parentInjector, Key.get(String.class));
-    
+
     // Clear the ref, GC, and ensure that we are no longer blacklisting.
     childInjector = null;
     awaitClear(weakRef);
     assertNotBlacklisted(parentInjector, Key.get(String.class));
   }
-  
+
   public void testWeakKeySet_integration_multipleChildren() {
-    Injector parentInjector = Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(4);
-          }
-        });
+    Injector parentInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Integer.class).toInstance(4);
+              }
+            });
     assertNotBlacklisted(parentInjector, Key.get(String.class));
     assertNotBlacklisted(parentInjector, Key.get(Long.class));
 
-    Injector childInjector1 = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("foo");
-      }
-    });
-    WeakReference<Injector> weakRef1 = new WeakReference<Injector>(childInjector1);
+    Injector childInjector1 =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("foo");
+              }
+            });
+    WeakReference<Injector> weakRef1 = new WeakReference<>(childInjector1);
     assertBlacklisted(parentInjector, Key.get(String.class));
     assertNotBlacklisted(parentInjector, Key.get(Long.class));
-    
-    Injector childInjector2 = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(Long.class).toInstance(6L);
-      }
-    });
-    WeakReference<Injector> weakRef2 = new WeakReference<Injector>(childInjector2);
+
+    Injector childInjector2 =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Long.class).toInstance(6L);
+              }
+            });
+    WeakReference<Injector> weakRef2 = new WeakReference<>(childInjector2);
     assertBlacklisted(parentInjector, Key.get(String.class));
     assertBlacklisted(parentInjector, Key.get(Long.class));
-    
+
     // Clear ref1, GC, and ensure that we still blacklist.
     childInjector1 = null;
     awaitClear(weakRef1);
@@ -394,31 +407,40 @@
     assertNotBlacklisted(parentInjector, Key.get(String.class));
     assertNotBlacklisted(parentInjector, Key.get(Long.class));
   }
-  
+
   public void testWeakKeySet_integration_multipleChildren_overlappingKeys() {
-    Injector parentInjector = Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(4);
-          }
-        });
+    Injector parentInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Integer.class).toInstance(4);
+              }
+            });
     assertNotBlacklisted(parentInjector, Key.get(String.class));
 
-    Injector childInjector1 = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("foo");
-      }
-    });
-    WeakReference<Injector> weakRef1 = new WeakReference<Injector>(childInjector1);
+    Injector childInjector1 =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("foo");
+              }
+            });
+    WeakReference<Injector> weakRef1 = new WeakReference<>(childInjector1);
     assertBlacklisted(parentInjector, Key.get(String.class));
-    
-    Injector childInjector2 = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("bar");
-      }
-    });
-    WeakReference<Injector> weakRef2 = new WeakReference<Injector>(childInjector2);
+
+    Injector childInjector2 =
+        parentInjector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("bar");
+              }
+            });
+    WeakReference<Injector> weakRef2 = new WeakReference<>(childInjector2);
     assertBlacklisted(parentInjector, Key.get(String.class));
-    
+
     // Clear ref1, GC, and ensure that we still blacklist.
     childInjector1 = null;
     awaitClear(weakRef1);
@@ -431,88 +453,108 @@
   }
 
   private static class TestState implements State {
+    @Override
     public State parent() {
       return new TestState();
     }
 
+    @Override
     public <T> BindingImpl<T> getExplicitBinding(Key<T> key) {
       return null;
     }
 
+    @Override
     public Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel() {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public void putBinding(Key<?> key, BindingImpl<?> binding) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public ScopeBinding getScopeBinding(Class<? extends Annotation> scopingAnnotation) {
       return null;
     }
 
+    @Override
     public void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public void addConverter(TypeConverterBinding typeConverterBinding) {
       throw new UnsupportedOperationException();
     }
 
-    public TypeConverterBinding getConverter(String stringValue, TypeLiteral<?> type, Errors errors,
-        Object source) {
+    @Override
+    public TypeConverterBinding getConverter(
+        String stringValue, TypeLiteral<?> type, Errors errors, Object source) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public Iterable<TypeConverterBinding> getConvertersThisLevel() {
       return ImmutableSet.of();
     }
 
     /*if[AOP]*/
+    @Override
     public void addMethodAspect(MethodAspect methodAspect) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public ImmutableList<MethodAspect> getMethodAspects() {
       return ImmutableList.of();
     }
     /*end[AOP]*/
 
+    @Override
     public void addTypeListener(TypeListenerBinding typeListenerBinding) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public List<TypeListenerBinding> getTypeListenerBindings() {
       return ImmutableList.of();
     }
 
+    @Override
     public void addProvisionListener(ProvisionListenerBinding provisionListenerBinding) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public List<ProvisionListenerBinding> getProvisionListenerBindings() {
       return ImmutableList.of();
     }
 
+    @Override
     public void addScanner(ModuleAnnotatedMethodScannerBinding scanner) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public List<ModuleAnnotatedMethodScannerBinding> getScannerBindings() {
       return ImmutableList.of();
     }
 
-    public void blacklist(Key<?> key, State state, Object source) {
-    }
+    @Override
+    public void blacklist(Key<?> key, State state, Object source) {}
 
+    @Override
     public boolean isBlacklisted(Key<?> key) {
       return true;
     }
 
+    @Override
     public Set<Object> getSourcesForBlacklistedKey(Key<?> key) {
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public Object lock() {
       throw new UnsupportedOperationException();
     }
@@ -521,6 +563,7 @@
       throw new UnsupportedOperationException();
     }
 
+    @Override
     public Map<Class<? extends Annotation>, Scope> getScopes() {
       return ImmutableMap.of();
     }
diff --git a/core/test/com/google/inject/internal/WeakKeySetUtils.java b/core/test/com/google/inject/internal/WeakKeySetUtils.java
index b023aa1..80bc59b 100644
--- a/core/test/com/google/inject/internal/WeakKeySetUtils.java
+++ b/core/test/com/google/inject/internal/WeakKeySetUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
@@ -22,7 +22,6 @@
 
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
 import java.util.Set;
 
 /**
@@ -54,8 +53,8 @@
     assertNull(set.getSources(Key.get(Integer.class)));
   }
 
-  public static void assertInSet(WeakKeySet set, Key<?> key, int expectedSources,
-      Object... sources) {
+  public static void assertInSet(
+      WeakKeySet set, Key<?> key, int expectedSources, Object... sources) {
     assertTrue(set.contains(key));
     assertEquals(expectedSources, set.getSources(key).size());
     for (Object source : sources) {
diff --git a/core/test/com/google/inject/internal/util/LineNumbersTest.java b/core/test/com/google/inject/internal/util/LineNumbersTest.java
index 3b23f15..5dbd7f6 100644
--- a/core/test/com/google/inject/internal/util/LineNumbersTest.java
+++ b/core/test/com/google/inject/internal/util/LineNumbersTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,60 +24,69 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.matcher.Matchers;
-
+import java.lang.reflect.Modifier;
+import javax.inject.Inject;
 import junit.framework.TestCase;
 
-import java.lang.reflect.Modifier;
-
-import javax.inject.Inject;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class LineNumbersTest extends TestCase {
 
   public void testLineNumbers() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(A.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(A.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for " + B.class.getName() + " was bound.",
-          "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
-          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
+          "for the 1st parameter of " + A.class.getName() + ".<init>(LineNumbersTest.java:",
+          "at " + LineNumbersTest.class.getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
   static class A {
-    @Inject A(B b) {}
+    @Inject
+    A(B b) {}
   }
+
   public interface B {}
 
   /*if[AOP]*/
   public void testCanHandleLineNumbersForGuiceGeneratedClasses() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bindInterceptor(Matchers.only(A.class), Matchers.any(),
-              new org.aopalliance.intercept.MethodInterceptor() {
-                public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
-                  return null;
-                }
-              });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bindInterceptor(
+                  Matchers.only(A.class),
+                  Matchers.any(),
+                  new org.aopalliance.intercept.MethodInterceptor() {
+                    @Override
+                    public Object invoke(
+                        org.aopalliance.intercept.MethodInvocation methodInvocation) {
+                      return null;
+                    }
+                  });
 
-          bind(A.class);
-        }
-      });
+              bind(A.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for " + B.class.getName() + " was bound.",
-          "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
-          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
+          "for the 1st parameter of " + A.class.getName() + ".<init>(LineNumbersTest.java:",
+          "at " + LineNumbersTest.class.getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
 
@@ -91,19 +100,27 @@
     Class<?> generate() {
       org.objectweb.asm.ClassWriter cw =
           new org.objectweb.asm.ClassWriter(org.objectweb.asm.ClassWriter.COMPUTE_MAXS);
-      cw.visit(org.objectweb.asm.Opcodes.V1_5,
-          Modifier.PUBLIC, name, null,
-          org.objectweb.asm.Type.getInternalName(Object.class), null);
+      cw.visit(
+          org.objectweb.asm.Opcodes.V1_5,
+          Modifier.PUBLIC,
+          name,
+          null,
+          org.objectweb.asm.Type.getInternalName(Object.class),
+          null);
 
-      String sig = "("+org.objectweb.asm.Type.getDescriptor(B.class)+")V";
+      String sig = "(" + org.objectweb.asm.Type.getDescriptor(B.class) + ")V";
 
-      org.objectweb.asm.MethodVisitor mv = cw.visitMethod(Modifier.PUBLIC, "<init>", sig, null, null);
+      org.objectweb.asm.MethodVisitor mv =
+          cw.visitMethod(Modifier.PUBLIC, "<init>", sig, null, null);
 
       mv.visitAnnotation(org.objectweb.asm.Type.getDescriptor(Inject.class), true);
       mv.visitCode();
       mv.visitVarInsn(org.objectweb.asm.Opcodes.ALOAD, 0);
-      mv.visitMethodInsn(org.objectweb.asm.Opcodes.INVOKESPECIAL,
-          org.objectweb.asm.Type.getInternalName(Object.class), "<init>", "()V" );
+      mv.visitMethodInsn(
+          org.objectweb.asm.Opcodes.INVOKESPECIAL,
+          org.objectweb.asm.Type.getInternalName(Object.class),
+          "<init>",
+          "()V");
       mv.visitInsn(org.objectweb.asm.Opcodes.RETURN);
       mv.visitMaxs(0, 0);
       mv.visitEnd();
@@ -117,28 +134,35 @@
 
   public void testUnavailableByteCodeShowsUnknownSource() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(new GeneratingClassLoader().generate());
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(new GeneratingClassLoader().generate());
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) No implementation for " + B.class.getName() + " was bound.",
-          "for parameter 0 at " + GeneratingClassLoader.name + ".<init>(Unknown Source)",
-          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
+          "for the 1st parameter of " + GeneratingClassLoader.name + ".<init>(Unknown Source)",
+          "at " + LineNumbersTest.class.getName(),
+          getDeclaringSourcePart(getClass()));
     }
   }
-  
+
   public void testGeneratedClassesCanSucceed() {
     final Class<?> generated = new GeneratingClassLoader().generate();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(generated);
-        bind(B.class).toInstance(new B() {});
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(generated);
+                bind(B.class).toInstance(new B() {});
+              }
+            });
     Object instance = injector.getInstance(generated);
     assertEquals(instance.getClass(), generated);
   }
diff --git a/core/test/com/google/inject/matcher/MatcherTest.java b/core/test/com/google/inject/matcher/MatcherTest.java
index 58fbdf2..ea89ebe 100644
--- a/core/test/com/google/inject/matcher/MatcherTest.java
+++ b/core/test/com/google/inject/matcher/MatcherTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,18 +30,14 @@
 
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Method;
 import java.util.AbstractList;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 
 public class MatcherTest extends TestCase {
 
@@ -77,8 +73,7 @@
 
   public void testAnnotatedWith() {
     assertTrue(annotatedWith(Foo.class).matches(Bar.class));
-    assertFalse(annotatedWith(Foo.class).matches(
-        MatcherTest.class.getMethods()[0]));
+    assertFalse(annotatedWith(Foo.class).matches(MatcherTest.class.getMethods()[0]));
     assertEquals("annotatedWith(Foo.class)", annotatedWith(Foo.class).toString());
     assertEqualsBothWays(annotatedWith(Foo.class), annotatedWith(Foo.class));
     assertFalse(annotatedWith(Foo.class).equals(annotatedWith(Named.class)));
@@ -134,15 +129,15 @@
     assertFalse(inSubpackage(stringPackageName).matches(Matchers.class));
     assertFalse(inSubpackage("jav").matches(Object.class));
     assertEqualsBothWays(inSubpackage(stringPackageName), inSubpackage(stringPackageName));
-    assertFalse(inSubpackage(stringPackageName).equals(inSubpackage(Matchers.class.getPackage().getName())));
+    assertFalse(
+        inSubpackage(stringPackageName)
+            .equals(inSubpackage(Matchers.class.getPackage().getName())));
   }
 
   public void testReturns() throws NoSuchMethodException {
     Matcher<Method> predicate = returns(only(String.class));
-    assertTrue(predicate.matches(
-        Object.class.getMethod("toString")));
-    assertFalse(predicate.matches(
-        Object.class.getMethod("hashCode")));
+    assertTrue(predicate.matches(Object.class.getMethod("toString")));
+    assertFalse(predicate.matches(Object.class.getMethod("hashCode")));
     assertEquals("returns(only(class java.lang.String))", returns(only(String.class)).toString());
     assertEqualsBothWays(predicate, returns(only(String.class)));
     assertFalse(predicate.equals(returns(only(Integer.class))));
@@ -163,7 +158,7 @@
     assertEqualWhenReserialized(only("a").and(only("b")));
   }
 
-  static abstract class MyRunnable implements Runnable {}
+  abstract static class MyRunnable implements Runnable {}
 
   @Retention(RetentionPolicy.RUNTIME)
   @interface Foo {}
diff --git a/core/test/com/google/inject/multibindings/ProvidesIntoTest.java b/core/test/com/google/inject/multibindings/ProvidesIntoTest.java
new file mode 100644
index 0000000..f74a6b9
--- /dev/null
+++ b/core/test/com/google/inject/multibindings/ProvidesIntoTest.java
@@ -0,0 +1,456 @@
+/*
+ * 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 com.google.inject.multibindings;
+
+import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.name.Names.named;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.multibindings.ProvidesIntoOptional.Type;
+import com.google.inject.name.Named;
+import java.lang.annotation.Retention;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.Set;
+import junit.framework.TestCase;
+
+/**
+ * Tests the various @ProvidesInto annotations.
+ *
+ * @author sameb@google.com (Sam Berlin)
+ */
+public class ProvidesIntoTest extends TestCase {
+
+  public void testAnnotation() throws Exception {
+    Injector injector =
+        Guice.createInjector(
+            MultibindingsScanner.asModule(),
+            new AbstractModule() {
+
+              @ProvidesIntoSet
+              @Named("foo")
+              String setFoo() {
+                return "foo";
+              }
+
+              @ProvidesIntoSet
+              @Named("foo")
+              String setFoo2() {
+                return "foo2";
+              }
+
+              @ProvidesIntoSet
+              @Named("bar")
+              String setBar() {
+                return "bar";
+              }
+
+              @ProvidesIntoSet
+              @Named("bar")
+              String setBar2() {
+                return "bar2";
+              }
+
+              @ProvidesIntoSet
+              String setNoAnnotation() {
+                return "na";
+              }
+
+              @ProvidesIntoSet
+              String setNoAnnotation2() {
+                return "na2";
+              }
+
+              @ProvidesIntoMap
+              @StringMapKey("fooKey")
+              @Named("foo")
+              String mapFoo() {
+                return "foo";
+              }
+
+              @ProvidesIntoMap
+              @StringMapKey("foo2Key")
+              @Named("foo")
+              String mapFoo2() {
+                return "foo2";
+              }
+
+              @ProvidesIntoMap
+              @ClassMapKey(String.class)
+              @Named("bar")
+              String mapBar() {
+                return "bar";
+              }
+
+              @ProvidesIntoMap
+              @ClassMapKey(Number.class)
+              @Named("bar")
+              String mapBar2() {
+                return "bar2";
+              }
+
+              @ProvidesIntoMap
+              @TestEnumKey(TestEnum.A)
+              String mapNoAnnotation() {
+                return "na";
+              }
+
+              @ProvidesIntoMap
+              @TestEnumKey(TestEnum.B)
+              String mapNoAnnotation2() {
+                return "na2";
+              }
+
+              @ProvidesIntoMap
+              @WrappedKey(number = 1)
+              Number wrapped1() {
+                return 11;
+              }
+
+              @ProvidesIntoMap
+              @WrappedKey(number = 2)
+              Number wrapped2() {
+                return 22;
+              }
+
+              @ProvidesIntoOptional(ProvidesIntoOptional.Type.DEFAULT)
+              @Named("foo")
+              String optionalDefaultFoo() {
+                return "foo";
+              }
+
+              @ProvidesIntoOptional(ProvidesIntoOptional.Type.ACTUAL)
+              @Named("foo")
+              String optionalActualFoo() {
+                return "foo2";
+              }
+
+              @ProvidesIntoOptional(ProvidesIntoOptional.Type.DEFAULT)
+              @Named("bar")
+              String optionalDefaultBar() {
+                return "bar";
+              }
+
+              @ProvidesIntoOptional(ProvidesIntoOptional.Type.ACTUAL)
+              String optionalActualBar() {
+                return "na2";
+              }
+            });
+
+    Set<String> fooSet = injector.getInstance(new Key<Set<String>>(named("foo")) {});
+    assertEquals(ImmutableSet.of("foo", "foo2"), fooSet);
+
+    Set<String> barSet = injector.getInstance(new Key<Set<String>>(named("bar")) {});
+    assertEquals(ImmutableSet.of("bar", "bar2"), barSet);
+
+    Set<String> noAnnotationSet = injector.getInstance(new Key<Set<String>>() {});
+    assertEquals(ImmutableSet.of("na", "na2"), noAnnotationSet);
+
+    Map<String, String> fooMap =
+        injector.getInstance(new Key<Map<String, String>>(named("foo")) {});
+    assertEquals(ImmutableMap.of("fooKey", "foo", "foo2Key", "foo2"), fooMap);
+
+    Map<Class<?>, String> barMap =
+        injector.getInstance(new Key<Map<Class<?>, String>>(named("bar")) {});
+    assertEquals(ImmutableMap.of(String.class, "bar", Number.class, "bar2"), barMap);
+
+    Map<TestEnum, String> noAnnotationMap =
+        injector.getInstance(new Key<Map<TestEnum, String>>() {});
+    assertEquals(ImmutableMap.of(TestEnum.A, "na", TestEnum.B, "na2"), noAnnotationMap);
+
+    Map<WrappedKey, Number> wrappedMap =
+        injector.getInstance(new Key<Map<WrappedKey, Number>>() {});
+    assertEquals(ImmutableMap.of(wrappedKeyFor(1), 11, wrappedKeyFor(2), 22), wrappedMap);
+
+    Optional<String> fooOptional = injector.getInstance(new Key<Optional<String>>(named("foo")) {});
+    assertEquals("foo2", fooOptional.get());
+
+    Optional<String> barOptional = injector.getInstance(new Key<Optional<String>>(named("bar")) {});
+    assertEquals("bar", barOptional.get());
+
+    Optional<String> noAnnotationOptional = injector.getInstance(new Key<Optional<String>>() {});
+    assertEquals("na2", noAnnotationOptional.get());
+  }
+
+  enum TestEnum {
+    A,
+    B
+  }
+
+  @MapKey(unwrapValue = true)
+  @Retention(RUNTIME)
+  @interface TestEnumKey {
+    TestEnum value();
+  }
+
+  @MapKey(unwrapValue = false)
+  @Retention(RUNTIME)
+  @interface WrappedKey {
+    int number();
+  }
+
+  @SuppressWarnings("unused")
+  @WrappedKey(number = 1)
+  private static Object wrappedKey1Holder;
+
+  @SuppressWarnings("unused")
+  @WrappedKey(number = 2)
+  private static Object wrappedKey2Holder;
+
+  WrappedKey wrappedKeyFor(int number) throws Exception {
+    Field field;
+    switch (number) {
+      case 1:
+        field = ProvidesIntoTest.class.getDeclaredField("wrappedKey1Holder");
+        break;
+      case 2:
+        field = ProvidesIntoTest.class.getDeclaredField("wrappedKey2Holder");
+        break;
+      default:
+        throw new IllegalArgumentException("only 1 or 2 supported");
+    }
+    return field.getAnnotation(WrappedKey.class);
+  }
+
+  public void testDoubleScannerIsIgnored() {
+    Injector injector =
+        Guice.createInjector(
+            MultibindingsScanner.asModule(),
+            MultibindingsScanner.asModule(),
+            new AbstractModule() {
+
+              @ProvidesIntoSet
+              String provideFoo() {
+                return "foo";
+              }
+            });
+    assertEquals(ImmutableSet.of("foo"), injector.getInstance(new Key<Set<String>>() {}));
+  }
+
+  @MapKey(unwrapValue = true)
+  @Retention(RUNTIME)
+  @interface ArrayUnwrappedKey {
+    int[] value();
+  }
+
+  public void testArrayKeys_unwrapValuesTrue() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoMap
+          @ArrayUnwrappedKey({1, 2})
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "Array types are not allowed in a MapKey with unwrapValue=true: "
+              + ArrayUnwrappedKey.class.getName(),
+          "at " + m.getClass().getName() + ".provideFoo(");
+    }
+  }
+
+  @MapKey(unwrapValue = false)
+  @Retention(RUNTIME)
+  @interface ArrayWrappedKey {
+    int[] number();
+  }
+
+  @SuppressWarnings("unused")
+  @ArrayWrappedKey(number = {1, 2})
+  private static Object arrayWrappedKeyHolder12;
+
+  @SuppressWarnings("unused")
+  @ArrayWrappedKey(number = {3, 4})
+  private static Object arrayWrappedKeyHolder34;
+
+  ArrayWrappedKey arrayWrappedKeyFor(int number) throws Exception {
+    Field field;
+    switch (number) {
+      case 12:
+        field = ProvidesIntoTest.class.getDeclaredField("arrayWrappedKeyHolder12");
+        break;
+      case 34:
+        field = ProvidesIntoTest.class.getDeclaredField("arrayWrappedKeyHolder34");
+        break;
+      default:
+        throw new IllegalArgumentException("only 1 or 2 supported");
+    }
+    return field.getAnnotation(ArrayWrappedKey.class);
+  }
+
+  public void testArrayKeys_unwrapValuesFalse() throws Exception {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoMap
+          @ArrayWrappedKey(number = {1, 2})
+          String provideFoo() {
+            return "foo";
+          }
+
+          @ProvidesIntoMap
+          @ArrayWrappedKey(number = {3, 4})
+          String provideBar() {
+            return "bar";
+          }
+        };
+    Injector injector = Guice.createInjector(MultibindingsScanner.asModule(), m);
+    Map<ArrayWrappedKey, String> map =
+        injector.getInstance(new Key<Map<ArrayWrappedKey, String>>() {});
+    ArrayWrappedKey key12 = arrayWrappedKeyFor(12);
+    ArrayWrappedKey key34 = arrayWrappedKeyFor(34);
+    assertEquals("foo", map.get(key12));
+    assertEquals("bar", map.get(key34));
+    assertEquals(2, map.size());
+  }
+
+  public void testProvidesIntoSetWithMapKey() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoSet
+          @TestEnumKey(TestEnum.A)
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "Found a MapKey annotation on non map binding at "
+              + m.getClass().getName()
+              + ".provideFoo");
+    }
+  }
+
+  public void testProvidesIntoOptionalWithMapKey() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoOptional(Type.ACTUAL)
+          @TestEnumKey(TestEnum.A)
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "Found a MapKey annotation on non map binding at "
+              + m.getClass().getName()
+              + ".provideFoo");
+    }
+  }
+
+  public void testProvidesIntoMapWithoutMapKey() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoMap
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "No MapKey found for map binding at " + m.getClass().getName() + ".provideFoo");
+    }
+  }
+
+  @MapKey(unwrapValue = true)
+  @Retention(RUNTIME)
+  @interface TestEnumKey2 {
+    TestEnum value();
+  }
+
+  public void testMoreThanOneMapKeyAnnotation() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoMap
+          @TestEnumKey(TestEnum.A)
+          @TestEnumKey2(TestEnum.B)
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "Found more than one MapKey annotations on " + m.getClass().getName() + ".provideFoo");
+    }
+  }
+
+  @MapKey(unwrapValue = true)
+  @Retention(RUNTIME)
+  @interface MissingValueMethod {}
+
+  public void testMapKeyMissingValueMethod() {
+    Module m =
+        new AbstractModule() {
+
+          @ProvidesIntoMap
+          @MissingValueMethod
+          String provideFoo() {
+            return "foo";
+          }
+        };
+    try {
+      Guice.createInjector(MultibindingsScanner.asModule(), m);
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(1, ce.getErrorMessages().size());
+      assertContains(
+          ce.getMessage(),
+          "No 'value' method in MapKey with unwrapValue=true: "
+              + MissingValueMethod.class.getName());
+    }
+  }
+}
diff --git a/core/test/com/google/inject/name/NamedEquivalanceTest.java b/core/test/com/google/inject/name/NamedEquivalanceTest.java
index 36dee0c..b1e00ca 100644
--- a/core/test/com/google/inject/name/NamedEquivalanceTest.java
+++ b/core/test/com/google/inject/name/NamedEquivalanceTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,17 +27,16 @@
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provides;
-
-import junit.framework.TestCase;
-
+import com.google.inject.internal.Annotations;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.util.Properties;
+import junit.framework.TestCase;
 
 /**
  * Tests that {@code javax.inject.Named} and {@code com.google.inject.name.Named} are completely
  * interchangeable: bindings for one can be used to inject the other.
- * 
+ *
  * @author cgdecker@gmail.com (Colin Decker)
  */
 public class NamedEquivalanceTest extends TestCase {
@@ -45,21 +44,23 @@
   private static final Module GUICE_BINDING_MODULE = moduleWithAnnotation(Names.named("foo"));
   private static final Module JSR330_BINDING_MODULE = moduleWithAnnotation(new JsrNamed("foo"));
   private static final Module GUICE_PROVIDER_METHOD_MODULE = getGuiceBindingProviderMethodModule();
-  private static final Module JSR330_PROVIDER_METHOD_MODULE = getJsr330BindingProviderMethodModule();
+  private static final Module JSR330_PROVIDER_METHOD_MODULE =
+      getJsr330BindingProviderMethodModule();
 
   public void testKeysCreatedWithDifferentTypesAreEqual() {
     assertEquals(keyForAnnotation(new GuiceNamed("foo")), keyForAnnotation(new JsrNamed("foo")));
     assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new GuiceNamed("foo")));
     assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new JsrNamed("foo")));
 
-    assertEquals(keyForAnnotationType(com.google.inject.name.Named.class),
+    assertEquals(
+        keyForAnnotationType(com.google.inject.name.Named.class),
         keyForAnnotationType(javax.inject.Named.class));
   }
 
   private static Key<String> keyForAnnotation(Annotation annotation) {
     return Key.get(String.class, annotation);
   }
-  
+
   private static Key<String> keyForAnnotationType(Class<? extends Annotation> annotationType) {
     return Key.get(String.class, annotationType);
   }
@@ -104,13 +105,15 @@
   }
 
   public void testBindPropertiesWorksWithJsr330() {
-    assertInjectionsSucceed(new AbstractModule() {
-      @Override protected void configure() {
-        Properties properties = new Properties();
-        properties.put("foo", "bar");
-        Names.bindProperties(binder(), properties);
-      }
-    });
+    assertInjectionsSucceed(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            Properties properties = new Properties();
+            properties.put("foo", "bar");
+            Names.bindProperties(binder(), properties);
+          }
+        });
   }
 
   private static void assertMissingBindingErrorMessageUsesType(Class<?> clientType) {
@@ -118,21 +121,28 @@
       Guice.createInjector().getInstance(clientType);
       fail("should have thrown ConfigurationException");
     } catch (ConfigurationException e) {
-      assertContains(e.getMessage(),
-          "No implementation for java.lang.String annotated with @com.google.inject.name.Named(value=foo) was bound.");
+      assertContains(
+          e.getMessage(),
+          "No implementation for java.lang.String annotated with "
+              + "@com.google.inject.name.Named(value="
+              + Annotations.memberValueString("foo")
+              + ") was bound.");
     }
   }
 
   private static void assertDuplicateBinding(Module a, Module b, boolean fails) {
     try {
       Guice.createInjector(a, b);
-      if(fails) {
+      if (fails) {
         fail("should have thrown CreationException");
       }
     } catch (CreationException e) {
-      if(fails) {
-        assertContains(e.getMessage(),
-            "A binding to java.lang.String annotated with @com.google.inject.name.Named(value=foo) was already configured");
+      if (fails) {
+        assertContains(
+            e.getMessage(),
+            "A binding to java.lang.String annotated with @com.google.inject.name.Named(value="
+                + Annotations.memberValueString("foo")
+                + ") was already configured");
       } else {
         throw e;
       }
@@ -141,7 +151,8 @@
 
   private static Module moduleWithAnnotation(final Annotation annotation) {
     return new AbstractModule() {
-      @Override protected void configure() {
+      @Override
+      protected void configure() {
         bindConstant().annotatedWith(annotation).to("bar");
       }
     };
@@ -149,8 +160,9 @@
 
   private static void assertInjectionsSucceed(Module module) {
     Injector injector = Guice.createInjector(module);
-    assertInjected(injector.getInstance(GuiceNamedClient.class), injector
-        .getInstance(Jsr330NamedClient.class));
+    assertInjected(
+        injector.getInstance(GuiceNamedClient.class),
+        injector.getInstance(Jsr330NamedClient.class));
   }
 
   private static void assertInjected(GuiceNamedClient guiceClient, Jsr330NamedClient jsr330Client) {
@@ -160,8 +172,11 @@
 
   private static Module getJsr330BindingProviderMethodModule() {
     return new AbstractModule() {
-      @Override protected void configure() {}
-      @SuppressWarnings("unused") @Provides @javax.inject.Named("foo") String provideFoo() {
+
+      @SuppressWarnings("unused")
+      @Provides
+      @javax.inject.Named("foo")
+      String provideFoo() {
         return "bar";
       }
     };
@@ -169,19 +184,26 @@
 
   private static Module getGuiceBindingProviderMethodModule() {
     return new AbstractModule() {
-      @Override protected void configure() {}
-      @SuppressWarnings("unused") @Provides @Named("foo") String provideFoo() {
+
+      @SuppressWarnings("unused")
+      @Provides
+      @Named("foo")
+      String provideFoo() {
         return "bar";
       }
     };
   }
 
   private static class GuiceNamedClient {
-    @Inject @Named("foo") String foo;
+    @Inject
+    @Named("foo")
+    String foo;
   }
 
   private static class Jsr330NamedClient {
-    @Inject @javax.inject.Named("foo") String foo;
+    @Inject
+    @javax.inject.Named("foo")
+    String foo;
   }
 
   private static class JsrNamed implements javax.inject.Named, Serializable {
@@ -191,15 +213,18 @@
       this.value = value;
     }
 
+    @Override
     public String value() {
       return this.value;
     }
 
+    @Override
     public int hashCode() {
       // This is specified in java.lang.Annotation.
       return (127 * "value".hashCode()) ^ value.hashCode();
     }
 
+    @Override
     public boolean equals(Object o) {
       if (!(o instanceof javax.inject.Named)) {
         return false;
@@ -209,10 +234,16 @@
       return value.equals(other.value());
     }
 
+    @Override
     public String toString() {
-      return "@" + javax.inject.Named.class.getName() + "(value=" + value + ")";
+      return "@"
+          + javax.inject.Named.class.getName()
+          + "(value="
+          + Annotations.memberValueString(value)
+          + ")";
     }
 
+    @Override
     public Class<? extends Annotation> annotationType() {
       return javax.inject.Named.class;
     }
@@ -222,20 +253,23 @@
 
   private static class GuiceNamed implements com.google.inject.name.Named, Serializable {
     private final String value;
-    
+
     public GuiceNamed(String value) {
       this.value = value;
     }
-    
+
+    @Override
     public String value() {
       return this.value;
     }
-    
+
+    @Override
     public int hashCode() {
       // This is specified in java.lang.Annotation.
       return (127 * "value".hashCode()) ^ value.hashCode();
     }
 
+    @Override
     public boolean equals(Object o) {
       if (!(o instanceof com.google.inject.name.Named)) {
         return false;
@@ -245,10 +279,16 @@
       return value.equals(other.value());
     }
 
+    @Override
     public String toString() {
-      return "@" + com.google.inject.name.Named.class.getName() + "(value=" + value + ")";
+      return "@"
+          + com.google.inject.name.Named.class.getName()
+          + "(value="
+          + Annotations.memberValueString(value)
+          + ")";
     }
 
+    @Override
     public Class<? extends Annotation> annotationType() {
       return com.google.inject.name.Named.class;
     }
diff --git a/core/test/com/google/inject/name/NamesTest.java b/core/test/com/google/inject/name/NamesTest.java
index 0df3513..c8d2d82 100644
--- a/core/test/com/google/inject/name/NamesTest.java
+++ b/core/test/com/google/inject/name/NamesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.name;
 
 import static com.google.inject.Asserts.assertEqualWhenReserialized;
@@ -25,21 +24,20 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Map;
 import java.util.Properties;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class NamesTest extends TestCase {
 
-  @Named("foo") private String foo;
+  @Named("foo")
+  private String foo;
+
   private Named namedFoo;
-  
+
+  @Override
   protected void setUp() throws Exception {
     super.setUp();
     namedFoo = getClass().getDeclaredField("foo").getAnnotation(Named.class);
@@ -60,25 +58,31 @@
     teams.setProperty("SanJose", "Sharks");
     teams.setProperty("Edmonton", "Oilers");
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        Names.bindProperties(binder(), teams);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Names.bindProperties(binder(), teams);
+              }
+            });
 
     assertEquals("Sharks", injector.getInstance(Key.get(String.class, Names.named("SanJose"))));
     assertEquals("Oilers", injector.getInstance(Key.get(String.class, Names.named("Edmonton"))));
   }
 
   public void testBindPropertiesUsingMap() {
-    final Map<String, String> properties = ImmutableMap.of(
-        "SanJose", "Sharks", "Edmonton", "Oilers");
+    final Map<String, String> properties =
+        ImmutableMap.of("SanJose", "Sharks", "Edmonton", "Oilers");
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        Names.bindProperties(binder(), properties);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Names.bindProperties(binder(), properties);
+              }
+            });
 
     assertEquals("Sharks", injector.getInstance(Key.get(String.class, Names.named("SanJose"))));
     assertEquals("Oilers", injector.getInstance(Key.get(String.class, Names.named("Edmonton"))));
@@ -93,11 +97,14 @@
     teams.setProperty("SanJose", "Sharks");
     teams.setProperty("Edmonton", "Oilers");
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        Names.bindProperties(binder(), teams);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                Names.bindProperties(binder(), teams);
+              }
+            });
 
     assertEquals("Pats", injector.getInstance(Key.get(String.class, Names.named("Regina"))));
     assertEquals("Oilers", injector.getInstance(Key.get(String.class, Names.named("Edmonton"))));
diff --git a/core/test/com/google/inject/spi/BindingTargetVisitorTest.java b/core/test/com/google/inject/spi/BindingTargetVisitorTest.java
index 7740551..b2b8ccb 100644
--- a/core/test/com/google/inject/spi/BindingTargetVisitorTest.java
+++ b/core/test/com/google/inject/spi/BindingTargetVisitorTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,12 +18,10 @@
 import com.google.inject.Binding;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import junit.framework.TestCase;
 
 /**
- * Simple little test that should compile. Ensures that wildcards on the
- * generics are correct.
+ * Simple little test that should compile. Ensures that wildcards on the generics are correct.
  *
  * @author phopkins@gmail.com
  */
diff --git a/core/test/com/google/inject/spi/ElementApplyToTest.java b/core/test/com/google/inject/spi/ElementApplyToTest.java
index d483ba4..cd10533 100644
--- a/core/test/com/google/inject/spi/ElementApplyToTest.java
+++ b/core/test/com/google/inject/spi/ElementApplyToTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,7 @@
 
 import com.google.inject.Module;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class ElementApplyToTest extends ElementsTest {
 
   @Override
@@ -28,4 +26,4 @@
     // convert from module to elements and back
     super.checkModule(Elements.getModule(Elements.getElements(module)), visitors);
   }
-}
\ No newline at end of file
+}
diff --git a/core/test/com/google/inject/spi/ElementSourceTest.java b/core/test/com/google/inject/spi/ElementSourceTest.java
index 93fbeac..b2a5da9 100644
--- a/core/test/com/google/inject/spi/ElementSourceTest.java
+++ b/core/test/com/google/inject/spi/ElementSourceTest.java
@@ -8,37 +8,43 @@
 import com.google.inject.Binding;
 import com.google.inject.BindingAnnotation;
 import com.google.inject.Module;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.List;
+import junit.framework.TestCase;
 
-/**
- * Tests for {@link ElementSource}.
- */
+/** Tests for {@link ElementSource}. */
 public class ElementSourceTest extends TestCase {
 
-  private static final StackTraceElement BINDER_INSTALL = 
-      new StackTraceElement("com.google.inject.spi.Elements$RecordingBinder", "install", 
-          "Unknown Source", 234 /* line number*/);
-  
+  private static final StackTraceElement BINDER_INSTALL =
+      new StackTraceElement(
+          "com.google.inject.spi.Elements$RecordingBinder",
+          "install",
+          "Unknown Source",
+          234 /* line number*/);
+
   public void testCallStackSize() {
     ModuleSource moduleSource = createModuleSource();
     StackTraceElement[] bindingCallStack = new StackTraceElement[3];
-    bindingCallStack[0] = new StackTraceElement(
-        "com.google.inject.spi.Elements$RecordingBinder", "bind", "Unknown Source", 200);
-    bindingCallStack[1] = new StackTraceElement(
-        "com.google.inject.spi.Elements$RecordingBinder", "bind", "Unknown Source", 100);
-    bindingCallStack[2] = new StackTraceElement(
-        "com.google.inject.spi.moduleSourceTest$C", "configure", "Unknown Source", 100);
-    ElementSource elementSource = new ElementSource(
-        null /* No original element source */, "" /* Don't care */, moduleSource, bindingCallStack);
+    bindingCallStack[0] =
+        new StackTraceElement(
+            "com.google.inject.spi.Elements$RecordingBinder", "bind", "Unknown Source", 200);
+    bindingCallStack[1] =
+        new StackTraceElement(
+            "com.google.inject.spi.Elements$RecordingBinder", "bind", "Unknown Source", 100);
+    bindingCallStack[2] =
+        new StackTraceElement(
+            "com.google.inject.spi.moduleSourceTest$C", "configure", "Unknown Source", 100);
+    ElementSource elementSource =
+        new ElementSource(
+            null /* No original element source */,
+            "" /* Don't care */,
+            moduleSource,
+            bindingCallStack);
     assertEquals(10 /* call stack size */, elementSource.getStackTrace().length);
-  }  
+  }
 
   public void testGetCallStack_IntegrationTest() throws Exception {
     List<Element> elements = Elements.getElements(new A());
@@ -57,93 +63,87 @@
           // Module A
           assertEquals("com.google.inject.spi.ElementSourceTest$A", moduleClassNames.get(2));
           StackTraceElement[] callStack = elementSource.getStackTrace();
-          switch(getIncludeStackTraceOption()) {
+          switch (getIncludeStackTraceOption()) {
             case OFF:
               // Check declaring source
-              StackTraceElement stackTraceElement = 
+              StackTraceElement stackTraceElement =
                   (StackTraceElement) elementSource.getDeclaringSource();
-              assertEquals(new StackTraceElement(
-                  "com.google.inject.spi.ElementSourceTest$C", "configure", null, -1), 
+              assertEquals(
+                  new StackTraceElement(
+                      "com.google.inject.spi.ElementSourceTest$C", "configure", null, -1),
                   stackTraceElement);
               // Check call stack
               assertEquals(0, callStack.length);
               return;
             case ONLY_FOR_DECLARING_SOURCE:
-                // Check call stack
-                assertEquals(0, callStack.length);
-                return;
+              // Check call stack
+              assertEquals(0, callStack.length);
+              return;
             case COMPLETE:
               // Check call stack
               int skippedCallStackSize = new Throwable().getStackTrace().length - 1;
               assertEquals(skippedCallStackSize + 15, elementSource.getStackTrace().length);
-              assertEquals("com.google.inject.spi.Elements$RecordingBinder",
-                  callStack[0].getClassName());
-              assertEquals("com.google.inject.spi.Elements$RecordingBinder",
-                  callStack[1].getClassName());
-              assertEquals("com.google.inject.AbstractModule",
-                  callStack[2].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.Elements$RecordingBinder", callStack[0].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.Elements$RecordingBinder", callStack[1].getClassName());
+              assertEquals("com.google.inject.AbstractModule", callStack[2].getClassName());
               // Module C
-              assertEquals("com.google.inject.spi.ElementSourceTest$C",
-                  callStack[3].getClassName());
-              assertEquals("configure",
-                  callStack[3].getMethodName());
-              assertEquals("Unknown Source",
-                  callStack[3].getFileName());
-              assertEquals("com.google.inject.AbstractModule",
-                  callStack[4].getClassName());
-              assertEquals("com.google.inject.spi.Elements$RecordingBinder",
-                  callStack[5].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.ElementSourceTest$C", callStack[3].getClassName());
+              assertEquals("configure", callStack[3].getMethodName());
+              assertEquals("Unknown Source", callStack[3].getFileName());
+              assertEquals("com.google.inject.AbstractModule", callStack[4].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.Elements$RecordingBinder", callStack[5].getClassName());
               // Module B
-              assertEquals("com.google.inject.spi.ElementSourceTest$B",
-                  callStack[6].getClassName());
-              assertEquals("com.google.inject.spi.Elements$RecordingBinder",
-                  callStack[7].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.ElementSourceTest$B", callStack[6].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.Elements$RecordingBinder", callStack[7].getClassName());
               // Module A
-              assertEquals("com.google.inject.AbstractModule",
-                  callStack[8].getClassName());
-              assertEquals("com.google.inject.spi.ElementSourceTest$A",
-                  callStack[9].getClassName());
-              assertEquals("com.google.inject.AbstractModule",
-                  callStack[10].getClassName());
-              assertEquals("com.google.inject.spi.Elements$RecordingBinder",
-                  callStack[11].getClassName());
-              assertEquals("com.google.inject.spi.Elements",
-                  callStack[12].getClassName());
-              assertEquals("com.google.inject.spi.Elements",
-                  callStack[13].getClassName());
-              assertEquals("com.google.inject.spi.ElementSourceTest",
-                  callStack[14].getClassName());
+              assertEquals("com.google.inject.AbstractModule", callStack[8].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.ElementSourceTest$A", callStack[9].getClassName());
+              assertEquals("com.google.inject.AbstractModule", callStack[10].getClassName());
+              assertEquals(
+                  "com.google.inject.spi.Elements$RecordingBinder", callStack[11].getClassName());
+              assertEquals("com.google.inject.spi.Elements", callStack[12].getClassName());
+              assertEquals("com.google.inject.spi.Elements", callStack[13].getClassName());
+              assertEquals("com.google.inject.spi.ElementSourceTest", callStack[14].getClassName());
               // Check modules index
               List<Integer> indexes = elementSource.getModuleConfigurePositionsInStackTrace();
-              assertEquals((int) indexes.get(0), 4);
-              assertEquals((int) indexes.get(1), 6);
-              assertEquals((int) indexes.get(2), 10);
+              assertEquals(4, (int) indexes.get(0));
+              assertEquals(6, (int) indexes.get(1));
+              assertEquals(10, (int) indexes.get(2));
               return;
           }
         }
       }
     }
     fail("The test should not reach this line.");
-  }  
+  }
 
   private ModuleSource createModuleSource() {
     // First module
     StackTraceElement[] partialCallStack = new StackTraceElement[1];
-    partialCallStack[0] = BINDER_INSTALL;    
+    partialCallStack[0] = BINDER_INSTALL;
     ModuleSource moduleSource = new ModuleSource(new A(), partialCallStack);
-    // Second module 
+    // Second module
     partialCallStack = new StackTraceElement[2];
     partialCallStack[0] = BINDER_INSTALL;
-    partialCallStack[1] = new StackTraceElement(
-        "com.google.inject.spi.moduleSourceTest$A", "configure", "Unknown Source", 100);
-    moduleSource = moduleSource.createChild(new B(), partialCallStack);    
+    partialCallStack[1] =
+        new StackTraceElement(
+            "com.google.inject.spi.moduleSourceTest$A", "configure", "Unknown Source", 100);
+    moduleSource = moduleSource.createChild(new B(), partialCallStack);
     // Third module
     partialCallStack = new StackTraceElement[4];
     partialCallStack[0] = BINDER_INSTALL;
     partialCallStack[1] = new StackTraceElement("class1", "method1", "Class1.java", 1);
     partialCallStack[2] = new StackTraceElement("class2", "method2", "Class2.java", 2);
-    partialCallStack[3] = new StackTraceElement(
-        "com.google.inject.spi.moduleSourceTest$B", "configure", "Unknown Source", 200);
+    partialCallStack[3] =
+        new StackTraceElement(
+            "com.google.inject.spi.moduleSourceTest$B", "configure", "Unknown Source", 200);
     return moduleSource.createChild(new C(), partialCallStack);
   }
 
@@ -153,23 +153,23 @@
       install(new B());
     }
   }
-  
+
   private static class B implements Module {
     @Override
     public void configure(Binder binder) {
       binder.install(new C());
     }
   }
-  
+
   @Retention(RUNTIME)
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
   @BindingAnnotation
-  @interface SampleAnnotation { }
+  @interface SampleAnnotation {}
 
   private static class C extends AbstractModule {
     @Override
     public void configure() {
       bind(String.class).annotatedWith(SampleAnnotation.class).toInstance("the value");
     }
-  }  
+  }
 }
diff --git a/core/test/com/google/inject/spi/ElementsTest.java b/core/test/com/google/inject/spi/ElementsTest.java
index 6043fac..c2a94f6 100644
--- a/core/test/com/google/inject/spi/ElementsTest.java
+++ b/core/test/com/google/inject/spi/ElementsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,9 +47,6 @@
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -67,10 +64,9 @@
 import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class ElementsTest extends TestCase {
 
   // Binder fidelity tests
@@ -78,75 +74,78 @@
   public void testAddMessageErrorCommand() {
     checkModule(
         new AbstractModule() {
-          @Override protected void configure() {
+          @Override
+          protected void configure() {
             addError("Message %s %d %s", "A", 5, "C");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
+          @Override
+          public Void visit(Message command) {
             assertEquals("Message A 5 C", command.getMessage());
             assertNull(command.getCause());
-            assertContains(command.getSources().toString(),
+            assertContains(
+                command.getSources().toString(),
                 ElementsTest.class.getName(),
                 getDeclaringSourcePart(ElementsTest.class));
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testAddThrowableErrorCommand() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             addError(new Exception("A"));
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
+          @Override
+          public Void visit(Message command) {
             assertEquals("A", command.getCause().getMessage());
-            assertEquals(command.getMessage(),
-                "An exception was caught and reported. Message: A");
+            assertEquals("An exception was caught and reported. Message: A", command.getMessage());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testErrorsAddedWhenExceptionsAreThrown() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
-            install(new AbstractModule() {
-              protected void configure() {
-                throw new RuntimeException("Throwing RuntimeException in AbstractModule.configure().");
-              }
-            });
+            install(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    throw new RuntimeException(
+                        "Throwing RuntimeException in AbstractModule.configure().");
+                  }
+                });
 
             addError("Code after the exception still gets executed");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
-            assertEquals("Throwing RuntimeException in AbstractModule.configure().",
+          @Override
+          public Void visit(Message command) {
+            assertEquals(
+                "Throwing RuntimeException in AbstractModule.configure().",
                 command.getCause().getMessage());
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
-            assertEquals("Code after the exception still gets executed",
-                command.getMessage());
+          @Override
+          public Void visit(Message command) {
+            assertEquals("Code after the exception still gets executed", command.getMessage());
             return null;
           }
-        }
-    );
+        });
   }
 
   private <T> T getInstance(Binding<T> binding) {
@@ -156,35 +155,36 @@
   public void testBindConstantAnnotations() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindConstant().annotatedWith(SampleAnnotation.class).to("A");
             bindConstant().annotatedWith(Names.named("Bee")).to("B");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
             assertEquals("A", getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(String.class, Names.named("Bee")), command.getKey());
             assertEquals("B", getInstance(command));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindConstantTypes() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindConstant().annotatedWith(Names.named("String")).to("A");
             bindConstant().annotatedWith(Names.named("int")).to(2);
@@ -199,118 +199,120 @@
             bindConstant().annotatedWith(Names.named("Enum")).to(CoinSide.TAILS);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(String.class, Names.named("String")), command.getKey());
             assertEquals("A", getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Integer.class, Names.named("int")), command.getKey());
             assertEquals(2, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Long.class, Names.named("long")), command.getKey());
             assertEquals(3L, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Boolean.class, Names.named("boolean")), command.getKey());
             assertEquals(false, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Double.class, Names.named("double")), command.getKey());
             assertEquals(5.0d, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Float.class, Names.named("float")), command.getKey());
             assertEquals(6.0f, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Short.class, Names.named("short")), command.getKey());
             assertEquals((short) 7, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Character.class, Names.named("char")), command.getKey());
             assertEquals('h', getInstance(command));
             return null;
           }
         },
-        
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Byte.class, Names.named("byte")), command.getKey());
             assertEquals((byte) 8, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(Class.class, Names.named("Class")), command.getKey());
             assertEquals(Iterator.class, getInstance(command));
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(CoinSide.class, Names.named("Enum")), command.getKey());
             assertEquals(CoinSide.TAILS, getInstance(command));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindKeysNoAnnotations() {
-    FailingElementVisitor keyChecker = new FailingElementVisitor() {
-      @Override public <T> Void visit(Binding<T> command) {
-        assertEquals(Key.get(String.class), command.getKey());
-        return null;
-      }
-    };
+    FailingElementVisitor keyChecker =
+        new FailingElementVisitor() {
+          @Override
+          public <T> Void visit(Binding<T> command) {
+            assertEquals(Key.get(String.class), command.getKey());
+            return null;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toInstance("A");
             bind(new TypeLiteral<String>() {}).toInstance("B");
@@ -319,74 +321,85 @@
         },
         keyChecker,
         keyChecker,
-        keyChecker
-    );
+        keyChecker);
   }
 
   public void testBindKeysWithAnnotationType() {
-    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
-      @Override public <T> Void visit(Binding<T> command) {
-        assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
-        return null;
-      }
-    };
+    FailingElementVisitor annotationChecker =
+        new FailingElementVisitor() {
+          @Override
+          public <T> Void visit(Binding<T> command) {
+            assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
+            return null;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).annotatedWith(SampleAnnotation.class).toInstance("A");
-            bind(new TypeLiteral<String>() {}).annotatedWith(SampleAnnotation.class).toInstance("B");
+            bind(new TypeLiteral<String>() {})
+                .annotatedWith(SampleAnnotation.class)
+                .toInstance("B");
           }
         },
         annotationChecker,
-        annotationChecker
-    );
+        annotationChecker);
   }
 
   public void testBindKeysWithAnnotationInstance() {
-    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
-      @Override public <T> Void visit(Binding<T> command) {
-        assertEquals(Key.get(String.class, Names.named("a")), command.getKey());
-        return null;
-      }
-    };
-
+    FailingElementVisitor annotationChecker =
+        new FailingElementVisitor() {
+          @Override
+          public <T> Void visit(Binding<T> command) {
+            assertEquals(Key.get(String.class, Names.named("a")), command.getKey());
+            return null;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).annotatedWith(Names.named("a")).toInstance("B");
             bind(new TypeLiteral<String>() {}).annotatedWith(Names.named("a")).toInstance("C");
           }
         },
         annotationChecker,
-        annotationChecker
-    );
+        annotationChecker);
   }
 
   public void testBindToProvider() {
-    final Provider<String> aProvider = new Provider<String>() {
-      public String get() {
-        return "A";
-      }
-    };
-    
-    final javax.inject.Provider<Integer> intJavaxProvider = new javax.inject.Provider<Integer>() {
-      public Integer get() {
-        return 42;
-      }
-    };
-    
-    final javax.inject.Provider<Double> doubleJavaxProvider = new javax.inject.Provider<Double>() {
-      @javax.inject.Inject String string;
-      
-      public Double get() {
-        return 42.42;
-      }
-    };
+    final Provider<String> aProvider =
+        new Provider<String>() {
+          @Override
+          public String get() {
+            return "A";
+          }
+        };
+
+    final javax.inject.Provider<Integer> intJavaxProvider =
+        new javax.inject.Provider<Integer>() {
+          @Override
+          public Integer get() {
+            return 42;
+          }
+        };
+
+    final javax.inject.Provider<Double> doubleJavaxProvider =
+        new javax.inject.Provider<Double>() {
+          @javax.inject.Inject String string;
+
+          @Override
+          public Double get() {
+            return 42.42;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toProvider(aProvider);
             bind(Integer.class).toProvider(intJavaxProvider);
@@ -396,186 +409,203 @@
             bind(Iterable.class).toProvider(new TypeLiteral<TProvider<List>>() {});
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderInstanceBinding);
             assertEquals(Key.get(String.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(
-                  ProviderInstanceBinding<? extends T> binding) {
-                assertSame(aProvider, binding.getUserSuppliedProvider());
-                assertSame(aProvider, binding.getProviderInstance());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderInstanceBinding<? extends T> binding) {
+                    assertSame(aProvider, binding.getUserSuppliedProvider());
+                    assertSame(aProvider, binding.getProviderInstance());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-        
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderInstanceBinding);
             assertEquals(Key.get(Integer.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(
-                  ProviderInstanceBinding<? extends T> binding) {
-                assertSame(intJavaxProvider, binding.getUserSuppliedProvider());
-                assertEquals(42, binding.getProviderInstance().get());
-                // we don't wrap this w/ dependencies if there were none.
-                assertFalse(binding.getProviderInstance() instanceof HasDependencies);
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderInstanceBinding<? extends T> binding) {
+                    assertSame(intJavaxProvider, binding.getUserSuppliedProvider());
+                    assertEquals(42, binding.getProviderInstance().get());
+                    // we don't wrap this w/ dependencies if there were none.
+                    assertFalse(binding.getProviderInstance() instanceof HasDependencies);
+                    return null;
+                  }
+                });
             return null;
           }
-        },        
-        
+        },
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderInstanceBinding);
             assertEquals(Key.get(Double.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(
-                  ProviderInstanceBinding<? extends T> binding) {
-                assertSame(doubleJavaxProvider, binding.getUserSuppliedProvider());
-                assertEquals(42.42, binding.getProviderInstance().get());
-                // we do wrap it with dependencies if there were some.
-                assertTrue(binding.getProviderInstance() instanceof HasDependencies);
-                Set<Dependency<?>> deps =
-                    ((HasDependencies) binding.getProviderInstance()).getDependencies();
-                assertEquals(1, deps.size());
-                assertEquals(String.class,
-                    deps.iterator().next().getKey().getTypeLiteral().getRawType());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderInstanceBinding<? extends T> binding) {
+                    assertSame(doubleJavaxProvider, binding.getUserSuppliedProvider());
+                    assertEquals(42.42, binding.getProviderInstance().get());
+                    // we do wrap it with dependencies if there were some.
+                    assertTrue(binding.getProviderInstance() instanceof HasDependencies);
+                    Set<Dependency<?>> deps =
+                        ((HasDependencies) binding.getProviderInstance()).getDependencies();
+                    assertEquals(1, deps.size());
+                    assertEquals(
+                        String.class,
+                        deps.iterator().next().getKey().getTypeLiteral().getRawType());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderKeyBinding);
             assertEquals(Key.get(List.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderKeyBinding<? extends T> binding) {
+                    assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderKeyBinding);
             assertEquals(Key.get(Collection.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderKeyBinding<? extends T> binding) {
+                    assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof ProviderKeyBinding);
             assertEquals(Key.get(Iterable.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
-                assertEquals(new Key<TProvider<List>>() {}, binding.getProviderKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderKeyBinding<? extends T> binding) {
+                    assertEquals(new Key<TProvider<List>>() {}, binding.getProviderKey());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindToLinkedBinding() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(List.class).to(ArrayList.class);
             bind(Map.class).to(new TypeLiteral<HashMap<Integer, String>>() {});
             bind(Set.class).to(Key.get(TreeSet.class, SampleAnnotation.class));
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof LinkedKeyBinding);
             assertEquals(Key.get(List.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(ArrayList.class), binding.getLinkedKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(LinkedKeyBinding<? extends T> binding) {
+                    assertEquals(Key.get(ArrayList.class), binding.getLinkedKey());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof LinkedKeyBinding);
             assertEquals(Key.get(Map.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(new TypeLiteral<HashMap<Integer, String>>() {}),
-                    binding.getLinkedKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(LinkedKeyBinding<? extends T> binding) {
+                    assertEquals(
+                        Key.get(new TypeLiteral<HashMap<Integer, String>>() {}),
+                        binding.getLinkedKey());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof LinkedKeyBinding);
             assertEquals(Key.get(Set.class), command.getKey());
-            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(TreeSet.class, SampleAnnotation.class),
-                    binding.getLinkedKey());
-                return null;
-              }
-            });
+            command.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(LinkedKeyBinding<? extends T> binding) {
+                    assertEquals(
+                        Key.get(TreeSet.class, SampleAnnotation.class), binding.getLinkedKey());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindToInstance() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toInstance("A");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertTrue(command instanceof InstanceBinding);
             assertEquals(Key.get(String.class), command.getKey());
             assertEquals("A", getInstance(command));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindInScopes() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class);
             bind(List.class).to(ArrayList.class).in(Scopes.SINGLETON);
@@ -583,269 +613,291 @@
             bind(Set.class).to(TreeSet.class).asEagerSingleton();
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(String.class), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitNoScoping() {
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitNoScoping() {
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(List.class), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitScope(Scope scope) {
-                assertEquals(Scopes.SINGLETON, scope);
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitScope(Scope scope) {
+                    assertEquals(Scopes.SINGLETON, scope);
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(Map.class), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
-                assertEquals(Singleton.class, annotation);
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
+                    assertEquals(Singleton.class, annotation);
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(Set.class), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              public Void visitEagerSingleton() {
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitEagerSingleton() {
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindToInstanceInScope() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             AnnotatedBindingBuilder<String> b = bind(String.class);
             b.toInstance("A");
             b.in(Singleton.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
-            assertEquals("Setting the scope is not permitted when binding to a single instance.",
+          @Override
+          public Void visit(Message command) {
+            assertEquals(
+                "Setting the scope is not permitted when binding to a single instance.",
                 command.getMessage());
             assertNull(command.getCause());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-      );
+        });
   }
 
   public void testBindToInstanceScope() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toInstance("A");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertEquals(Key.get(String.class), binding.getKey());
-            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              public Void visitEagerSingleton() {
-                return null;
-              }
-            });
+            binding.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitEagerSingleton() {
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-      );
+        });
   }
 
   /*if[AOP]*/
   public void testBindIntercepor() {
     final Matcher<Class> classMatcher = Matchers.subclassesOf(List.class);
     final Matcher<Object> methodMatcher = Matchers.any();
-    final org.aopalliance.intercept.MethodInterceptor methodInterceptor
-        = new org.aopalliance.intercept.MethodInterceptor() {
-      public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
-        return null;
-      }
-    };
+    final org.aopalliance.intercept.MethodInterceptor methodInterceptor =
+        new org.aopalliance.intercept.MethodInterceptor() {
+          @Override
+          public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
+            return null;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindInterceptor(classMatcher, methodMatcher, methodInterceptor);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(InterceptorBinding command) {
+          @Override
+          public Void visit(InterceptorBinding command) {
             assertSame(classMatcher, command.getClassMatcher());
             assertSame(methodMatcher, command.getMethodMatcher());
             assertEquals(Arrays.asList(methodInterceptor), command.getInterceptors());
             return null;
           }
-        }
-    );
+        });
   }
   /*end[AOP]*/
 
   public void testBindScope() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindScope(SampleAnnotation.class, Scopes.NO_SCOPE);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(ScopeBinding command) {
+          @Override
+          public Void visit(ScopeBinding command) {
             assertSame(SampleAnnotation.class, command.getAnnotationType());
             assertSame(Scopes.NO_SCOPE, command.getScope());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindListener() {
     final Matcher<Object> typeMatcher = Matchers.only(TypeLiteral.get(String.class));
-    final TypeListener listener = new TypeListener() {
-      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
-        throw new UnsupportedOperationException();
-      }
-    };
-    
+    final TypeListener listener =
+        new TypeListener() {
+          @Override
+          public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+            throw new UnsupportedOperationException();
+          }
+        };
+
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindListener(typeMatcher, listener);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(TypeListenerBinding binding) {
+          @Override
+          public Void visit(TypeListenerBinding binding) {
             assertSame(typeMatcher, binding.getTypeMatcher());
             assertSame(listener, binding.getListener());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testConvertToTypes() {
-    final TypeConverter typeConverter = new TypeConverter() {
-      public Object convert(String value, TypeLiteral<?> toType) {
-        return value;
-      }
-    };
+    final TypeConverter typeConverter =
+        new TypeConverter() {
+          @Override
+          public Object convert(String value, TypeLiteral<?> toType) {
+            return value;
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             convertToTypes(Matchers.any(), typeConverter);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(TypeConverterBinding command) {
+          @Override
+          public Void visit(TypeConverterBinding command) {
             assertSame(typeConverter, command.getTypeConverter());
             assertSame(Matchers.any(), command.getTypeMatcher());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testGetProvider() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
-            Provider<String> keyGetProvider
-                = getProvider(Key.get(String.class, SampleAnnotation.class));
+            Provider<String> keyGetProvider =
+                getProvider(Key.get(String.class, SampleAnnotation.class));
             try {
               keyGetProvider.get();
+              fail("Expected IllegalStateException");
             } catch (IllegalStateException e) {
-              assertEquals("This Provider cannot be used until the Injector has been created.",
+              assertEquals(
+                  "This Provider cannot be used until the Injector has been created.",
                   e.getMessage());
             }
 
             Provider<String> typeGetProvider = getProvider(String.class);
             try {
               typeGetProvider.get();
+              fail("Expected IllegalStateException");
             } catch (IllegalStateException e) {
-              assertEquals("This Provider cannot be used until the Injector has been created.",
+              assertEquals(
+                  "This Provider cannot be used until the Injector has been created.",
                   e.getMessage());
             }
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(ProviderLookup<T> command) {
+          @Override
+          public <T> Void visit(ProviderLookup<T> command) {
             assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
             assertNull(command.getDelegate());
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(ProviderLookup<T> command) {
+          @Override
+          public <T> Void visit(ProviderLookup<T> command) {
             assertEquals(Key.get(String.class), command.getKey());
             assertNull(command.getDelegate());
             return null;
           }
-        }
-    );
+        });
   }
-  
-  public void testElementInitialization() {
-    final AtomicReference<Provider<String>> providerFromBinder
-        = new AtomicReference<Provider<String>>();
-    final AtomicReference<MembersInjector<String>> membersInjectorFromBinder
-        = new AtomicReference<MembersInjector<String>>();
 
-    final AtomicReference<String> lastInjected = new AtomicReference<String>();
-    final MembersInjector<String> stringInjector = new MembersInjector<String>() {
-      public void injectMembers(String instance) {
-        lastInjected.set(instance);
-      }
-    };
+  public void testElementInitialization() {
+    final AtomicReference<Provider<String>> providerFromBinder =
+        new AtomicReference<Provider<String>>();
+    final AtomicReference<MembersInjector<String>> membersInjectorFromBinder =
+        new AtomicReference<MembersInjector<String>>();
+
+    final AtomicReference<String> lastInjected = new AtomicReference<>();
+    final MembersInjector<String> stringInjector =
+        new MembersInjector<String>() {
+          @Override
+          public void injectMembers(String instance) {
+            lastInjected.set(instance);
+          }
+        };
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             providerFromBinder.set(getProvider(String.class));
             membersInjectorFromBinder.set(getMembersInjector(String.class));
           }
         },
-
         new FailingElementVisitor() {
+          @Override
           public <T> Void visit(ProviderLookup<T> providerLookup) {
             @SuppressWarnings("unchecked") // we know that T is a String here
             ProviderLookup<String> stringLookup = (ProviderLookup<String>) providerLookup;
@@ -855,9 +907,9 @@
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(MembersInjectorLookup<T> lookup) {
+          @Override
+          public <T> Void visit(MembersInjectorLookup<T> lookup) {
             @SuppressWarnings("unchecked") // we know that T is a String here
             MembersInjectorLookup<String> stringLookup = (MembersInjectorLookup<String>) lookup;
             stringLookup.initializeDelegate(stringInjector);
@@ -872,11 +924,13 @@
   public void testGetMembersInjector() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
-            MembersInjector<A<String>> typeMembersInjector
-                = getMembersInjector(new TypeLiteral<A<String>>() {});
+            MembersInjector<A<String>> typeMembersInjector =
+                getMembersInjector(new TypeLiteral<A<String>>() {});
             try {
               typeMembersInjector.injectMembers(new A<String>());
+              fail("Expected IllegalStateException");
             } catch (IllegalStateException e) {
               assertEquals(
                   "This MembersInjector cannot be used until the Injector has been created.",
@@ -886,6 +940,7 @@
             MembersInjector<String> classMembersInjector = getMembersInjector(String.class);
             try {
               classMembersInjector.injectMembers("hello");
+              fail("Expected IllegalStateException");
             } catch (IllegalStateException e) {
               assertEquals(
                   "This MembersInjector cannot be used until the Injector has been created.",
@@ -893,23 +948,22 @@
             }
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(MembersInjectorLookup<T> command) {
+          @Override
+          public <T> Void visit(MembersInjectorLookup<T> command) {
             assertEquals(new TypeLiteral<A<String>>() {}, command.getType());
             assertNull(command.getDelegate());
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(MembersInjectorLookup<T> command) {
+          @Override
+          public <T> Void visit(MembersInjectorLookup<T> command) {
             assertEquals(TypeLiteral.get(String.class), command.getType());
             assertNull(command.getDelegate());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testRequestInjection() {
@@ -918,43 +972,43 @@
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             requestInjection(firstObject);
             requestInjection(secondObject);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(InjectionRequest<?> command) {
+          @Override
+          public Void visit(InjectionRequest<?> command) {
             assertEquals(firstObject, command.getInstance());
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(InjectionRequest<?> command) {
+          @Override
+          public Void visit(InjectionRequest<?> command) {
             assertEquals(secondObject, command.getInstance());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testRequestStaticInjection() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             requestStaticInjection(ArrayList.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(StaticInjectionRequest command) {
+          @Override
+          public Void visit(StaticInjectionRequest command) {
             assertEquals(ArrayList.class, command.getType());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testNewPrivateBinder() {
@@ -968,189 +1022,191 @@
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             PrivateBinder one = binder().newPrivateBinder();
             one.expose(ArrayList.class);
             one.expose(Collection.class).annotatedWith(SampleAnnotation.class);
             one.bind(List.class).to(ArrayList.class);
 
-            PrivateBinder two = binder().withSource("1 FooBar")
-                .newPrivateBinder().withSource("2 FooBar");
+            PrivateBinder two =
+                binder().withSource("1 FooBar").newPrivateBinder().withSource("2 FooBar");
             two.expose(String.class).annotatedWith(Names.named("a"));
             two.expose(b);
             two.bind(List.class).to(ArrayList.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(PrivateElements one) {
+          @Override
+          public Void visit(PrivateElements one) {
             assertEquals(collections, one.getExposedKeys());
-            checkElements(one.getElements(),
+            checkElements(
+                one.getElements(),
                 new FailingElementVisitor() {
-                  @Override public <T> Void visit(Binding<T> binding) {
+                  @Override
+                  public <T> Void visit(Binding<T> binding) {
                     assertEquals(Key.get(List.class), binding.getKey());
                     return null;
                   }
-                }
-            );
+                });
             return null;
           }
         },
-
         new ExternalFailureVisitor() {
-          @Override public Void visit(PrivateElements two) {
+          @Override
+          public Void visit(PrivateElements two) {
             assertEquals(ab, two.getExposedKeys());
             assertEquals("1 FooBar", two.getSource().toString());
-            checkElements(two.getElements(),
+            checkElements(
+                two.getElements(),
                 new ExternalFailureVisitor() {
-                  @Override public <T> Void visit(Binding<T> binding) {
+                  @Override
+                  public <T> Void visit(Binding<T> binding) {
                     assertEquals("2 FooBar", binding.getSource().toString());
                     assertEquals(Key.get(List.class), binding.getKey());
                     return null;
                   }
-                }
-            );
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindWithMultipleAnnotationsAddsError() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             AnnotatedBindingBuilder<String> abb = bind(String.class);
             abb.annotatedWith(SampleAnnotation.class);
             abb.annotatedWith(Names.named("A"));
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
-            assertEquals("More than one annotation is specified for this binding.",
-                command.getMessage());
+          @Override
+          public Void visit(Message command) {
+            assertEquals(
+                "More than one annotation is specified for this binding.", command.getMessage());
             assertNull(command.getCause());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindWithMultipleTargetsAddsError() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             AnnotatedBindingBuilder<String> abb = bind(String.class);
             abb.toInstance("A");
             abb.toInstance("B");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
+          @Override
+          public Void visit(Message command) {
             assertEquals("Implementation is set more than once.", command.getMessage());
             assertNull(command.getCause());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindWithMultipleScopesAddsError() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             ScopedBindingBuilder sbb = bind(List.class).to(ArrayList.class);
             sbb.in(Scopes.NO_SCOPE);
             sbb.asEagerSingleton();
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
+          @Override
+          public Void visit(Message command) {
             assertEquals("Scope is set more than once.", command.getMessage());
             assertNull(command.getCause());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindConstantWithMultipleAnnotationsAddsError() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             AnnotatedConstantBindingBuilder cbb = bindConstant();
             cbb.annotatedWith(SampleAnnotation.class).to("A");
             cbb.annotatedWith(Names.named("A"));
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message command) {
-            assertEquals("More than one annotation is specified for this binding.",
-                command.getMessage());
+          @Override
+          public Void visit(Message command) {
+            assertEquals(
+                "More than one annotation is specified for this binding.", command.getMessage());
             assertNull(command.getCause());
             assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindConstantWithMultipleTargetsAddsError() {
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             ConstantBindingBuilder cbb = bindConstant().annotatedWith(SampleAnnotation.class);
             cbb.to("A");
             cbb.to("B");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public Void visit(Message message) {
+          @Override
+          public Void visit(Message message) {
             assertEquals("Constant value is set more than once.", message.getMessage());
             assertNull(message.getCause());
             assertContains(message.getSource(), getDeclaringSourcePart(ElementsTest.class));
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindToConstructor() throws NoSuchMethodException, NoSuchFieldException {
@@ -1160,56 +1216,66 @@
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(A.class).toConstructor(aConstructor);
-            bind(B.class).toConstructor(bConstructor, new TypeLiteral<B<Integer>>() {})
+            bind(B.class)
+                .toConstructor(bConstructor, new TypeLiteral<B<Integer>>() {})
                 .in(Singleton.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertEquals(new Key<A>() {}, binding.getKey());
 
-            return binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
-                InjectionPoint injectionPoint = constructorBinding.getConstructor();
-                assertEquals(aConstructor, injectionPoint.getMember());
-                assertEquals(new TypeLiteral<A>() {}, injectionPoint.getDeclaringType());
-                return null;
-              }
-            });
+            return binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ConstructorBinding<? extends T> constructorBinding) {
+                    InjectionPoint injectionPoint = constructorBinding.getConstructor();
+                    assertEquals(aConstructor, injectionPoint.getMember());
+                    assertEquals(new TypeLiteral<A>() {}, injectionPoint.getDeclaringType());
+                    return null;
+                  }
+                });
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertEquals(new Key<B>() {}, binding.getKey());
-            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
-                assertEquals(Singleton.class, annotation);
-                return null;
-              }
-            });
+            binding.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
+                    assertEquals(Singleton.class, annotation);
+                    return null;
+                  }
+                });
 
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
-                assertEquals(bConstructor, constructorBinding.getConstructor().getMember());
-                assertEquals(Key.get(Integer.class),
-                    getOnlyElement(constructorBinding.getConstructor().getDependencies()).getKey());
-                assertEquals(field,
-                    getOnlyElement(constructorBinding.getInjectableMembers()).getMember());
-                assertEquals(2, constructorBinding.getDependencies().size());
-/*if[AOP]*/
-                assertEquals(ImmutableMap.of(), constructorBinding.getMethodInterceptors());
-/*end[AOP]*/
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ConstructorBinding<? extends T> constructorBinding) {
+                    assertEquals(bConstructor, constructorBinding.getConstructor().getMember());
+                    assertEquals(
+                        Key.get(Integer.class),
+                        getOnlyElement(constructorBinding.getConstructor().getDependencies())
+                            .getKey());
+                    assertEquals(
+                        field,
+                        getOnlyElement(constructorBinding.getInjectableMembers()).getMember());
+                    assertEquals(2, constructorBinding.getDependencies().size());
+                    /*if[AOP]*/
+                    assertEquals(ImmutableMap.of(), constructorBinding.getMethodInterceptors());
+                    /*end[AOP]*/
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testBindToMalformedConstructor() throws NoSuchMethodException, NoSuchFieldException {
@@ -1217,67 +1283,73 @@
 
     checkModule(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(C.class).toConstructor(constructor);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertEquals(Key.get(C.class), binding.getKey());
             assertTrue(binding instanceof UntargettedBinding);
             return null;
           }
         },
-
         new ExternalFailureVisitor() {
-          @Override public Void visit(Message message) {
-            assertContains(message.getMessage(),
+          @Override
+          public Void visit(Message message) {
+            assertContains(
+                message.getMessage(),
                 C.class.getName() + ".a has more than one annotation ",
-                Named.class.getName(), SampleAnnotation.class.getName());
+                Named.class.getName(),
+                SampleAnnotation.class.getName());
             return null;
           }
         },
-
         new ExternalFailureVisitor() {
-          @Override public Void visit(Message message) {
-            assertContains(message.getMessage(),
+          @Override
+          public Void visit(Message message) {
+            assertContains(
+                message.getMessage(),
                 C.class.getName() + ".<init>() has more than one annotation ",
-                Named.class.getName(), SampleAnnotation.class.getName());
+                Named.class.getName(),
+                SampleAnnotation.class.getName());
             return null;
           }
-        }
-    );
+        });
   }
 
   // Business logic tests
 
   public void testModulesAreInstalledAtMostOnce() {
     final AtomicInteger aConfigureCount = new AtomicInteger(0);
-    final Module a = new AbstractModule() {
-      public void configure() {
-        aConfigureCount.incrementAndGet();
-      }
-    };
+    final Module a =
+        new AbstractModule() {
+          @Override
+          public void configure() {
+            aConfigureCount.incrementAndGet();
+          }
+        };
 
     Elements.getElements(a, a);
     assertEquals(1, aConfigureCount.get());
 
     aConfigureCount.set(0);
-    Module b = new AbstractModule() {
-      protected void configure() {
-        install(a);
-        install(a);
-      }
-    };
+    Module b =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(a);
+            install(a);
+          }
+        };
 
     Elements.getElements(b);
     assertEquals(1, aConfigureCount.get());
   }
 
-  /**
-   * Ensures the module performs the commands consistent with {@code visitors}.
-   */
+  /** Ensures the module performs the commands consistent with {@code visitors}. */
   protected void checkModule(Module module, ElementVisitor<?>... visitors) {
     List<Element> elements = Elements.getElements(module);
     assertEquals(elements.size(), visitors.length);
@@ -1289,13 +1361,13 @@
       ElementVisitor<?> visitor = visitors[i];
       Element element = elements.get(i);
       if (!(element instanceof Message)) {
-          ElementSource source = (ElementSource) element.getSource();
-          assertFalse(source.getModuleClassNames().isEmpty());
-          if (isIncludeStackTraceComplete()) {
-            assertTrue(source.getStackTrace().length > 0);
-          } else {
-            assertEquals(0, source.getStackTrace().length);
-          }
+        ElementSource source = (ElementSource) element.getSource();
+        assertFalse(source.getModuleClassNames().isEmpty());
+        if (isIncludeStackTraceComplete()) {
+          assertTrue(source.getStackTrace().length > 0);
+        } else {
+          assertEquals(0, source.getStackTrace().length);
+        }
       }
       if (!(visitor instanceof ExternalFailureVisitor)) {
         assertContains(element.getSource().toString(), getDeclaringSourcePart(ElementsTest.class));
@@ -1305,12 +1377,14 @@
   }
 
   private static class ListProvider implements Provider<List> {
+    @Override
     public List get() {
       return new ArrayList();
     }
   }
 
   private static class TProvider<T> implements Provider<T> {
+    @Override
     public T get() {
       return null;
     }
@@ -1320,14 +1394,17 @@
    * By extending this interface rather than FailingElementVisitor, the source of the error doesn't
    * need to contain the string {@code ElementsTest.java}.
    */
-  abstract class ExternalFailureVisitor extends FailingElementVisitor {}
+  abstract static class ExternalFailureVisitor extends FailingElementVisitor {}
 
   @Retention(RUNTIME)
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
   @BindingAnnotation
-  public @interface SampleAnnotation { }
+  public @interface SampleAnnotation {}
 
-  public enum CoinSide { HEADS, TAILS }
+  public enum CoinSide {
+    HEADS,
+    TAILS
+  }
 
   static class A<T> {
     @Inject Stage stage;
@@ -1335,11 +1412,16 @@
 
   static class B<T> {
     @Inject Stage stage;
+
     B(T t) {}
   }
 
   static class C {
-    @Inject @Named("foo") @SampleAnnotation String a;
+    @Inject
+    @Named("foo")
+    @SampleAnnotation
+    String a;
+
     C(@Named("bar") @SampleAnnotation Integer b) {}
   }
 }
diff --git a/core/test/com/google/inject/spi/FailingBindingScopingVisitor.java b/core/test/com/google/inject/spi/FailingBindingScopingVisitor.java
index bd08c4b..615d25a 100644
--- a/core/test/com/google/inject/spi/FailingBindingScopingVisitor.java
+++ b/core/test/com/google/inject/spi/FailingBindingScopingVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,26 +17,28 @@
 package com.google.inject.spi;
 
 import com.google.inject.Scope;
-
-import junit.framework.AssertionFailedError;
-
 import java.lang.annotation.Annotation;
+import junit.framework.AssertionFailedError;
 
 public class FailingBindingScopingVisitor implements BindingScopingVisitor<Void> {
 
+  @Override
   public Void visitEagerSingleton() {
     throw new AssertionFailedError();
   }
 
+  @Override
   public Void visitScope(Scope scope) {
     throw new AssertionFailedError();
   }
 
+  @Override
   public Void visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
     throw new AssertionFailedError();
   }
 
+  @Override
   public Void visitNoScoping() {
     throw new AssertionFailedError();
   }
-}
\ No newline at end of file
+}
diff --git a/core/test/com/google/inject/spi/FailingElementVisitor.java b/core/test/com/google/inject/spi/FailingElementVisitor.java
index d40d084..20b5504 100644
--- a/core/test/com/google/inject/spi/FailingElementVisitor.java
+++ b/core/test/com/google/inject/spi/FailingElementVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,8 @@
 import junit.framework.AssertionFailedError;
 
 class FailingElementVisitor extends DefaultElementVisitor<Void> {
-  @Override protected Void visitOther(Element element) {
+  @Override
+  protected Void visitOther(Element element) {
     throw new AssertionFailedError();
   }
 }
diff --git a/core/test/com/google/inject/spi/FailingTargetVisitor.java b/core/test/com/google/inject/spi/FailingTargetVisitor.java
index 68d5f7e..c2b4418 100644
--- a/core/test/com/google/inject/spi/FailingTargetVisitor.java
+++ b/core/test/com/google/inject/spi/FailingTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +17,11 @@
 package com.google.inject.spi;
 
 import com.google.inject.Binding;
-
 import junit.framework.AssertionFailedError;
 
 public class FailingTargetVisitor<T> extends DefaultBindingTargetVisitor<T, Void> {
-  @Override protected Void visitOther(Binding<? extends T> binding) {
+  @Override
+  protected Void visitOther(Binding<? extends T> binding) {
     throw new AssertionFailedError();
   }
 }
diff --git a/core/test/com/google/inject/spi/HasDependenciesTest.java b/core/test/com/google/inject/spi/HasDependenciesTest.java
index 670f2f4..d5966a5 100644
--- a/core/test/com/google/inject/spi/HasDependenciesTest.java
+++ b/core/test/com/google/inject/spi/HasDependenciesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,37 +24,38 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Provider;
-
+import java.util.Set;
 import junit.framework.TestCase;
 
-import java.util.Set;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class HasDependenciesTest extends TestCase {
 
-  /**
-   * When an instance implements HasDependencies, the injected dependencies aren't used.
-   */
+  /** When an instance implements HasDependencies, the injected dependencies aren't used. */
   public void testInstanceWithDependencies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).toInstance(new AWithDependencies());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).toInstance(new AWithDependencies());
+              }
+            });
 
     InstanceBinding<?> binding = (InstanceBinding<?>) injector.getBinding(A.class);
-    assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Integer.class))),
+    assertEquals(
+        ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Integer.class))),
         binding.getDependencies());
   }
 
   public void testInstanceWithoutDependencies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).toInstance(new A());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).toInstance(new A());
+              }
+            });
 
     InstanceBinding<?> binding = (InstanceBinding<?>) injector.getBinding(A.class);
     Dependency<?> onlyDependency = Iterables.getOnlyElement(binding.getDependencies());
@@ -62,11 +63,14 @@
   }
 
   public void testProvider() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(A.class).toProvider(new ProviderOfA());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(A.class).toProvider(new ProviderOfA());
+              }
+            });
 
     ProviderInstanceBinding<?> binding = (ProviderInstanceBinding<?>) injector.getBinding(A.class);
     Dependency<?> onlyDependency = Iterables.getOnlyElement(binding.getDependencies());
@@ -74,25 +78,30 @@
   }
 
   static class A {
-    @Inject void injectUnusedDependencies(String unused) {}
+    @Inject
+    void injectUnusedDependencies(String unused) {}
   }
 
   static class ProviderOfA implements Provider<A> {
-    @Inject void injectUnusedDependencies(String unused) {}
+    @Inject
+    void injectUnusedDependencies(String unused) {}
 
+    @Override
     public A get() {
       throw new UnsupportedOperationException();
     }
   }
 
   static class AWithDependencies extends A implements HasDependencies {
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Integer.class)));
     }
   }
 
-  static class ProviderOfAWithDependencies
-      extends ProviderOfA implements ProviderWithDependencies<A> {
+  static class ProviderOfAWithDependencies extends ProviderOfA
+      implements ProviderWithDependencies<A> {
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Integer.class)));
     }
diff --git a/core/test/com/google/inject/spi/InjectionPointTest.java b/core/test/com/google/inject/spi/InjectionPointTest.java
index 2ba4f5b..26b1d2e 100644
--- a/core/test/com/google/inject/spi/InjectionPointTest.java
+++ b/core/test/com/google/inject/spi/InjectionPointTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +17,7 @@
 package com.google.inject.spi;
 
 import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.Asserts.assertEqualsBothWays;
 import static com.google.inject.Asserts.assertNotSerializable;
@@ -29,12 +30,10 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Annotations;
 import com.google.inject.internal.ErrorsException;
 import com.google.inject.name.Named;
 import com.google.inject.spi.InjectionPoint.Signature;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -43,17 +42,18 @@
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class InjectionPointTest extends TestCase {
 
   public @Inject @Named("a") String foo;
+
   public @Inject void bar(@Named("b") String param) {}
 
   public static class Constructable {
-    @Inject public Constructable(@Named("c") String param) {}
+    @Inject
+    public Constructable(@Named("c") String param) {}
   }
 
   public void testFieldInjectionPoint() throws NoSuchFieldException, IOException, ErrorsException {
@@ -68,14 +68,20 @@
     assertNotSerializable(injectionPoint);
 
     Dependency<?> dependency = getOnlyElement(injectionPoint.getDependencies());
-    assertEquals("Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value=a)]@"
-        + getClass().getName() + ".foo", dependency.toString());
+    assertEquals(
+        "Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value="
+            + Annotations.memberValueString("a")
+            + ")]@"
+            + getClass().getName()
+            + ".foo",
+        dependency.toString());
     assertEquals(fooField, dependency.getInjectionPoint().getMember());
     assertEquals(-1, dependency.getParameterIndex());
     assertEquals(Key.get(String.class, named("a")), dependency.getKey());
     assertFalse(dependency.isNullable());
     assertNotSerializable(dependency);
-    assertEqualsBothWays(dependency,
+    assertEqualsBothWays(
+        dependency,
         getOnlyElement(new InjectionPoint(typeLiteral, fooField, false).getDependencies()));
   }
 
@@ -91,19 +97,25 @@
     assertNotSerializable(injectionPoint);
 
     Dependency<?> dependency = getOnlyElement(injectionPoint.getDependencies());
-    assertEquals("Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value=b)]@"
-        + getClass().getName() + ".bar()[0]", dependency.toString());
+    assertEquals(
+        "Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value="
+            + Annotations.memberValueString("b")
+            + ")]@"
+            + getClass().getName()
+            + ".bar()[0]",
+        dependency.toString());
     assertEquals(barMethod, dependency.getInjectionPoint().getMember());
     assertEquals(0, dependency.getParameterIndex());
     assertEquals(Key.get(String.class, named("b")), dependency.getKey());
     assertFalse(dependency.isNullable());
     assertNotSerializable(dependency);
-    assertEqualsBothWays(dependency,
+    assertEqualsBothWays(
+        dependency,
         getOnlyElement(new InjectionPoint(typeLiteral, barMethod, false).getDependencies()));
   }
 
-  public void testConstructorInjectionPoint() throws NoSuchMethodException, IOException,
-      ErrorsException {
+  public void testConstructorInjectionPoint()
+      throws NoSuchMethodException, IOException, ErrorsException {
     TypeLiteral<?> typeLiteral = TypeLiteral.get(Constructable.class);
 
     Constructor<?> constructor = Constructable.class.getConstructor(String.class);
@@ -115,20 +127,28 @@
     assertNotSerializable(injectionPoint);
 
     Dependency<?> dependency = getOnlyElement(injectionPoint.getDependencies());
-    assertEquals("Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value=c)]@"
-        + Constructable.class.getName() + ".<init>()[0]", dependency.toString());
+    assertEquals(
+        "Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value="
+            + Annotations.memberValueString("c")
+            + ")]@"
+            + Constructable.class.getName()
+            + ".<init>()[0]",
+        dependency.toString());
     assertEquals(constructor, dependency.getInjectionPoint().getMember());
     assertEquals(0, dependency.getParameterIndex());
     assertEquals(Key.get(String.class, named("c")), dependency.getKey());
     assertFalse(dependency.isNullable());
     assertNotSerializable(dependency);
-    assertEqualsBothWays(dependency,
-        getOnlyElement(new InjectionPoint(typeLiteral, constructor).getDependencies()));
+    assertEqualsBothWays(
+        dependency, getOnlyElement(new InjectionPoint(typeLiteral, constructor).getDependencies()));
   }
 
   public void testUnattachedDependency() throws IOException {
     Dependency<String> dependency = Dependency.get(Key.get(String.class, named("d")));
-    assertEquals("Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value=d)]",
+    assertEquals(
+        "Key[type=java.lang.String, annotation=@com.google.inject.name.Named(value="
+            + Annotations.memberValueString("d")
+            + ")]",
         dependency.toString());
     assertNull(dependency.getInjectionPoint());
     assertEquals(-1, dependency.getParameterIndex());
@@ -149,16 +169,22 @@
 
     try {
       InjectionPoint.forConstructor(constructor, new TypeLiteral<LinkedHashSet<String>>() {});
+      fail("Expected ConfigurationException");
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), "java.util.LinkedHashSet<java.lang.String>",
+      assertContains(
+          expected.getMessage(),
+          "java.util.LinkedHashSet<java.lang.String>",
           " does not define java.util.HashSet.<init>()",
           "  while locating java.util.LinkedHashSet<java.lang.String>");
     }
 
     try {
       InjectionPoint.forConstructor((Constructor) constructor, new TypeLiteral<Set<String>>() {});
+      fail("Expected ConfigurationException");
     } catch (ConfigurationException expected) {
-      assertContains(expected.getMessage(), "java.util.Set<java.lang.String>",
+      assertContains(
+          expected.getMessage(),
+          "java.util.Set<java.lang.String>",
           " does not define java.util.HashSet.<init>()",
           "  while locating java.util.Set<java.lang.String>");
     }
@@ -172,39 +198,66 @@
   public void testAddForInstanceMethodsAndFields() throws Exception {
     Method instanceMethod = HasInjections.class.getMethod("instanceMethod", String.class);
     Field instanceField = HasInjections.class.getField("instanceField");
+    Field instanceField2 = HasInjections.class.getField("instanceField2");
 
     TypeLiteral<HasInjections> type = TypeLiteral.get(HasInjections.class);
-    assertEquals(ImmutableSet.of(
-        new InjectionPoint(type, instanceMethod, false),
-        new InjectionPoint(type, instanceField, false)),
-        InjectionPoint.forInstanceMethodsAndFields(HasInjections.class));
+    Set<InjectionPoint> injectionPoints =
+        InjectionPoint.forInstanceMethodsAndFields(HasInjections.class);
+    // there is a defined order. assert on it
+    assertThat(injectionPoints)
+        .containsExactly(
+            new InjectionPoint(type, instanceField, false),
+            new InjectionPoint(type, instanceField2, false),
+            new InjectionPoint(type, instanceMethod, false))
+        .inOrder();
   }
 
   public void testAddForStaticMethodsAndFields() throws Exception {
     Method staticMethod = HasInjections.class.getMethod("staticMethod", String.class);
     Field staticField = HasInjections.class.getField("staticField");
+    Field staticField2 = HasInjections.class.getField("staticField2");
 
-    Set<InjectionPoint> injectionPoints = InjectionPoint.forStaticMethodsAndFields(
-        HasInjections.class);
-    assertEquals(ImmutableSet.of(
-        new InjectionPoint(TypeLiteral.get(HasInjections.class), staticMethod, false),
-        new InjectionPoint(TypeLiteral.get(HasInjections.class), staticField, false)),
-        injectionPoints);
+    Set<InjectionPoint> injectionPoints =
+        InjectionPoint.forStaticMethodsAndFields(HasInjections.class);
+    TypeLiteral<HasInjections> type = TypeLiteral.get(HasInjections.class);
+    assertThat(injectionPoints)
+        .containsExactly(
+            new InjectionPoint(type, staticField, false),
+            new InjectionPoint(type, staticField2, false),
+            new InjectionPoint(type, staticMethod, false))
+        .inOrder();
   }
 
   static class HasInjections {
-    @Inject public static void staticMethod(@Named("a") String a) {}
-    @Inject @Named("c") public static String staticField;
-    @Inject public void instanceMethod(@Named("d") String d) {}
-    @Inject @Named("f") public String instanceField;
+    @Inject
+    public static void staticMethod(@Named("a") String a) {}
+
+    @Inject
+    @Named("c")
+    public static String staticField;
+
+    @Inject
+    @Named("c")
+    public static String staticField2;
+
+    @Inject
+    public void instanceMethod(@Named("d") String d) {}
+
+    @Inject
+    @Named("f")
+    public String instanceField;
+
+    @Inject
+    @Named("f")
+    public String instanceField2;
   }
 
   public void testAddForParameterizedInjections() {
     TypeLiteral<?> type = new TypeLiteral<ParameterizedInjections<String>>() {};
 
     InjectionPoint constructor = InjectionPoint.forConstructorOf(type);
-    assertEquals(new Key<Map<String, String>>() {},
-        getOnlyElement(constructor.getDependencies()).getKey());
+    assertEquals(
+        new Key<Map<String, String>>() {}, getOnlyElement(constructor.getDependencies()).getKey());
 
     InjectionPoint field = getOnlyElement(InjectionPoint.forInstanceMethodsAndFields(type));
     assertEquals(new Key<Set<String>>() {}, getOnlyElement(field.getDependencies()).getKey());
@@ -212,15 +265,15 @@
 
   static class ParameterizedInjections<T> {
     @Inject Set<T> setOfTees;
-    @Inject public ParameterizedInjections(Map<T, T> map) {}
+
+    @Inject
+    public ParameterizedInjections(Map<T, T> map) {}
   }
 
   public void testSignature() throws Exception {
-    Signature fooA = new Signature(Foo.class.getDeclaredMethod(
-        "a", String.class, int.class));
+    Signature fooA = new Signature(Foo.class.getDeclaredMethod("a", String.class, int.class));
     Signature fooB = new Signature(Foo.class.getDeclaredMethod("b"));
-    Signature barA = new Signature(Bar.class.getDeclaredMethod(
-        "a", String.class, int.class));
+    Signature barA = new Signature(Bar.class.getDeclaredMethod("a", String.class, int.class));
     Signature barB = new Signature(Bar.class.getDeclaredMethod("b"));
 
     assertEquals(fooA.hashCode(), barA.hashCode());
@@ -231,22 +284,32 @@
 
   static class Foo {
     void a(String s, int i) {}
+
     int b() {
       return 0;
     }
   }
+
   static class Bar {
     public void a(String s, int i) {}
+
     void b() {}
   }
-  
+
   public void testOverrideBehavior() {
     Set<InjectionPoint> points;
 
     points = InjectionPoint.forInstanceMethodsAndFields(Super.class);
     assertEquals(points.toString(), 6, points.size());
-    assertPoints(points, Super.class, "atInject", "gInject", "privateAtAndPublicG",
-        "privateGAndPublicAt", "atFirstThenG", "gFirstThenAt");
+    assertPoints(
+        points,
+        Super.class,
+        "atInject",
+        "gInject",
+        "privateAtAndPublicG",
+        "privateGAndPublicAt",
+        "atFirstThenG",
+        "gFirstThenAt");
 
     points = InjectionPoint.forInstanceMethodsAndFields(Sub.class);
     assertEquals(points.toString(), 7, points.size());
@@ -255,9 +318,14 @@
     assertPoints(points, Super.class, "privateAtAndPublicG", "privateGAndPublicAt", "gInject");
     // Subclass also has the "private" methods, but they do not override
     // the superclass' methods, and it now owns the inject2 methods.
-    assertPoints(points, Sub.class, "privateAtAndPublicG", "privateGAndPublicAt",
-        "atFirstThenG", "gFirstThenAt");
-    
+    assertPoints(
+        points,
+        Sub.class,
+        "privateAtAndPublicG",
+        "privateGAndPublicAt",
+        "atFirstThenG",
+        "gFirstThenAt");
+
     points = InjectionPoint.forInstanceMethodsAndFields(SubSub.class);
     assertEquals(points.toString(), 6, points.size());
     // Superclass still has all the injection points it did before..
@@ -266,39 +334,36 @@
     // javax.inject.Inject and was overrode without an annotation, which means it
     // disappears.  (It was guice @Inject in Super, but it was private there, so it doesn't
     // effect the annotations of the subclasses.)
-    assertPoints(points, Sub.class, "privateAtAndPublicG", "atFirstThenG", "gFirstThenAt");    
+    assertPoints(points, Sub.class, "privateAtAndPublicG", "atFirstThenG", "gFirstThenAt");
   }
-  
+
   /**
-   * This test serves two purposes:
-   *   1) It makes sure that the bridge methods javax generates don't stop
-   *   us from injecting superclass methods in the case of javax.inject.Inject.
-   *   This would happen prior to java8 (where javac didn't copy annotations
-   *   from the superclass into the subclass method when it generated the
-   *   bridge methods).
-   *   
-   *   2) It makes sure that the methods we're going to inject have the correct
-   *   generic types.  Java8 copies the annotations from super to subclasses,
-   *   but it doesn't copy the generic type information.  Guice would naively
-   *   consider the subclass an injectable method and eject the superclass
-   *   from the 'overrideIndex', leaving only a class with improper generic types.
+   * This test serves two purposes: 1) It makes sure that the bridge methods javax generates don't
+   * stop us from injecting superclass methods in the case of javax.inject.Inject. This would happen
+   * prior to java8 (where javac didn't copy annotations from the superclass into the subclass
+   * method when it generated the bridge methods).
+   *
+   * <p>2) It makes sure that the methods we're going to inject have the correct generic types.
+   * Java8 copies the annotations from super to subclasses, but it doesn't copy the generic type
+   * information. Guice would naively consider the subclass an injectable method and eject the
+   * superclass from the 'overrideIndex', leaving only a class with improper generic types.
    */
   public void testSyntheticBridgeMethodsInSubclasses() {
     Set<InjectionPoint> points;
-    
+
     points = InjectionPoint.forInstanceMethodsAndFields(RestrictedSuper.class);
     assertPointDependencies(points, new TypeLiteral<Provider<String>>() {});
     assertEquals(points.toString(), 2, points.size());
     assertPoints(points, RestrictedSuper.class, "jInject", "gInject");
-    
+
     points = InjectionPoint.forInstanceMethodsAndFields(ExposedSub.class);
     assertPointDependencies(points, new TypeLiteral<Provider<String>>() {});
     assertEquals(points.toString(), 2, points.size());
     assertPoints(points, RestrictedSuper.class, "jInject", "gInject");
   }
-  
-  private void assertPoints(Iterable<InjectionPoint> points, Class<?> clazz,
-      String... methodNames) {
+
+  private void assertPoints(
+      Iterable<InjectionPoint> points, Class<?> clazz, String... methodNames) {
     Set<String> methods = new HashSet<String>();
     for (InjectionPoint point : points) {
       if (point.getDeclaringType().getRawType() == clazz) {
@@ -307,10 +372,10 @@
     }
     assertEquals(points.toString(), ImmutableSet.copyOf(methodNames), methods);
   }
-  
+
   /** Asserts that each injection point has the specified dependencies, in the given order. */
-  private void assertPointDependencies(Iterable<InjectionPoint> points,
-      TypeLiteral<?>... literals) {
+  private void assertPointDependencies(
+      Iterable<InjectionPoint> points, TypeLiteral<?>... literals) {
     for (InjectionPoint point : points) {
       assertEquals(literals.length, point.getDependencies().size());
       for (Dependency<?> dep : point.getDependencies()) {
@@ -318,47 +383,77 @@
       }
     }
   }
-  
+
   static class Super {
-    @javax.inject.Inject public void atInject() {}
-    @com.google.inject.Inject public void gInject() {}
-
-    @javax.inject.Inject private void privateAtAndPublicG() {}
-    @com.google.inject.Inject private void privateGAndPublicAt() {}
-
-    @javax.inject.Inject public void atFirstThenG() {}
-    @com.google.inject.Inject public void gFirstThenAt() {}
-  }
-  
-  static class Sub extends Super {
-    public void atInject() {}
-    public void gInject() {}
-    
-    @com.google.inject.Inject public void privateAtAndPublicG() {}
-    @javax.inject.Inject public void privateGAndPublicAt() {}
-    
-    @com.google.inject.Inject
-    @Override 
-    public void atFirstThenG() {}
-    
     @javax.inject.Inject
-    @Override 
+    public void atInject() {}
+
+    @com.google.inject.Inject
+    public void gInject() {}
+
+    @javax.inject.Inject
+    private void privateAtAndPublicG() {}
+
+    @com.google.inject.Inject
+    private void privateGAndPublicAt() {}
+
+    @javax.inject.Inject
+    public void atFirstThenG() {}
+
+    @com.google.inject.Inject
     public void gFirstThenAt() {}
   }
-  
+
+  static class Sub extends Super {
+    @Override
+    @SuppressWarnings("OverridesJavaxInjectableMethod")
+    public void atInject() {}
+
+    @Override
+    @SuppressWarnings("OverridesGuiceInjectableMethod")
+    public void gInject() {}
+
+    @com.google.inject.Inject
+    public void privateAtAndPublicG() {}
+
+    @javax.inject.Inject
+    public void privateGAndPublicAt() {}
+
+    @com.google.inject.Inject
+    @Override
+    public void atFirstThenG() {}
+
+    @javax.inject.Inject
+    @Override
+    public void gFirstThenAt() {}
+  }
+
   static class SubSub extends Sub {
-    @Override public void privateAtAndPublicG() {}
-    @Override public void privateGAndPublicAt() {}
-    
-    @Override public void atFirstThenG() {}
-    @Override public void gFirstThenAt() {}
+    @SuppressWarnings("OverridesGuiceInjectableMethod")
+    @Override
+    public void privateAtAndPublicG() {}
+
+    @SuppressWarnings("OverridesJavaxInjectableMethod")
+    @Override
+    public void privateGAndPublicAt() {}
+
+    @SuppressWarnings("OverridesGuiceInjectableMethod")
+    @Override
+    public void atFirstThenG() {}
+
+    @SuppressWarnings("OverridesGuiceInjectableMethod")
+    @Override
+    public void gFirstThenAt() {}
   }
-  
+
   static class RestrictedSuper {
-    @com.google.inject.Inject public void gInject(Provider<String> p) {}
-    @javax.inject.Inject public void jInject(Provider<String> p) {}
+    @com.google.inject.Inject
+    public void gInject(Provider<String> p) {}
+
+    @javax.inject.Inject
+    public void jInject(Provider<String> p) {}
   }
-  
+
   public static class ExposedSub extends RestrictedSuper {
     // The subclass may generate bridge/synthetic methods to increase the visibility
     // of the superclass methods, since the superclass was package-private but this is public.
diff --git a/core/test/com/google/inject/spi/InjectorSpiTest.java b/core/test/com/google/inject/spi/InjectorSpiTest.java
index a973fe9..2346422 100644
--- a/core/test/com/google/inject/spi/InjectorSpiTest.java
+++ b/core/test/com/google/inject/spi/InjectorSpiTest.java
@@ -8,67 +8,71 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
-
+import java.util.Map;
 import junit.framework.TestCase;
 
-import java.util.Map;
-
-/**
- * @author sberlin@gmail.com (Sam Berlin)
- */
+/** @author sberlin@gmail.com (Sam Berlin) */
 public class InjectorSpiTest extends TestCase {
 
   public void testExistingBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Foo.class);
-        bind(Baz.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Foo.class);
+                bind(Baz.class);
+              }
+            });
     // Sanity check -- ensure we return the proper binding for all existing bindings.
-    for(Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
+    for (Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
       assertSame(entry.getValue(), injector.getExistingBinding(entry.getKey()));
     }
-    
+
     // Now run through specifics...
     Binding<?> binding;
-    
+
     // 1) non-Provider Foo.class
     binding = injector.getExistingBinding(Key.get(Foo.class));
     assertNotNull(binding);
     assertEquals(Foo.class, binding.getKey().getTypeLiteral().getRawType());
-    
+
     // 2) Provider<Foo> class (should already exist, because Baz @Injects it).
     // the assertTrue is a bit stricter than necessary, but makes sure this works for pre-existing Provider bindings
     assertTrue(injector.getAllBindings().containsKey(Key.get(new TypeLiteral<Provider<Foo>>() {})));
     binding = injector.getExistingBinding(Key.get(new TypeLiteral<Provider<Foo>>() {}));
     assertNotNull(binding);
     assertEquals(Provider.class, binding.getKey().getTypeLiteral().getRawType());
-    assertEquals(Foo.class, ((Provider)binding.getProvider().get()).get().getClass());
-    
+    assertEquals(Foo.class, ((Provider) binding.getProvider().get()).get().getClass());
+
     // 3) non-Provider Baz.class
     binding = injector.getExistingBinding(Key.get(Baz.class));
     assertNotNull(binding);
     assertEquals(Baz.class, binding.getKey().getTypeLiteral().getRawType());
-    
+
     // 4) Provider<Baz> class (should not already exist, because nothing used it yet).
     // the assertFalse is a bit stricter than necessary, but makes sure this works for non-pre-existing Provider bindings
-    assertFalse(injector.getAllBindings().containsKey(Key.get(new TypeLiteral<Provider<Baz>>() {})));    
+    assertFalse(
+        injector.getAllBindings().containsKey(Key.get(new TypeLiteral<Provider<Baz>>() {})));
     binding = injector.getExistingBinding(Key.get(new TypeLiteral<Provider<Baz>>() {}));
     assertNotNull(binding);
     assertEquals(Provider.class, binding.getKey().getTypeLiteral().getRawType());
-    assertEquals(Baz.class, ((Provider)binding.getProvider().get()).get().getClass());
-    
+    assertEquals(Baz.class, ((Provider) binding.getProvider().get()).get().getClass());
+
     // 5) non-Provider Bar, doesn't exist.
     assertNull(injector.getExistingBinding(Key.get(Bar.class)));
-    
+
     // 6) Provider Bar, doesn't exist.
     assertNull(injector.getExistingBinding(Key.get(new TypeLiteral<Provider<Bar>>() {})));
   }
-  
+
   private static class Foo {}
+
   private static class Bar {}
-  private static class Baz { @SuppressWarnings("unused") @Inject Provider<Foo> fooP; }
-  
+
+  private static class Baz {
+    @SuppressWarnings("unused")
+    @Inject
+    Provider<Foo> fooP;
+  }
 }
diff --git a/core/test/com/google/inject/spi/MessageTest.java b/core/test/com/google/inject/spi/MessageTest.java
new file mode 100644
index 0000000..b582548
--- /dev/null
+++ b/core/test/com/google/inject/spi/MessageTest.java
@@ -0,0 +1,25 @@
+package com.google.inject.spi;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+import junit.framework.TestCase;
+
+/** Tests for {@link Message}. */
+public class MessageTest extends TestCase {
+
+  public void testMessageHashCodeVariesWithSource() {
+    String innerMessage = "This is the message.";
+    Message firstMessage = new Message(1, innerMessage);
+    Message secondMessage = new Message(2, innerMessage);
+    assertFalse(firstMessage.hashCode() == secondMessage.hashCode());
+  }
+
+  public void testMessageHashCodeVariesWithCause() {
+    String innerMessage = "This is the message.";
+    List<Object> sourceList = Lists.newArrayList(new Object());
+    // the throwable argument of each Message below do not have value equality
+    Message firstMessage = new Message(sourceList, innerMessage, new Exception(innerMessage));
+    Message secondMessage = new Message(sourceList, innerMessage, new Exception(innerMessage));
+    assertFalse(firstMessage.hashCode() == secondMessage.hashCode());
+  }
+}
diff --git a/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java b/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
index 6c797b1..38ae60c 100644
--- a/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
+++ b/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,30 +36,32 @@
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /** Tests for {@link ModuleAnnotatedMethodScanner} usage. */
 public class ModuleAnnotatedMethodScannerTest extends TestCase {
 
   public void testScanning() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {}
+    Module module =
+        new AbstractModule() {
 
-      @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
+          @TestProvides
+          @Named("foo")
+          String foo() {
+            return "foo";
+          }
 
-      @TestProvides @Named("foo2") String foo2() {
-        return "foo2";
-      }
-    };
+          @TestProvides
+          @Named("foo2")
+          String foo2() {
+            return "foo2";
+          }
+        };
     Injector injector = Guice.createInjector(module, NamedMunger.module());
 
     // assert no bindings named "foo" or "foo2" exist -- they were munged.
@@ -69,76 +71,103 @@
     Binding<String> fooBinding = injector.getBinding(Key.get(String.class, named("foo-munged")));
     Binding<String> foo2Binding = injector.getBinding(Key.get(String.class, named("foo2-munged")));
     // Validate the provider has a sane toString
-    assertEquals(methodName(TestProvides.class, "foo", module),
-        fooBinding.getProvider().toString());
-    assertEquals(methodName(TestProvides.class, "foo2", module),
-        foo2Binding.getProvider().toString());
+    assertEquals(
+        methodName(TestProvides.class, "foo", module), fooBinding.getProvider().toString());
+    assertEquals(
+        methodName(TestProvides.class, "foo2", module), foo2Binding.getProvider().toString());
   }
 
   public void testSkipSources() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        binder().skipSources(getClass()).install(new AbstractModule() {
-          @Override protected void configure() {}
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            binder()
+                .skipSources(getClass())
+                .install(
+                    new AbstractModule() {
 
-          @TestProvides @Named("foo") String foo() { return "foo"; }
-        });
-      }
-    };
+                      @TestProvides
+                      @Named("foo")
+                      String foo() {
+                        return "foo";
+                      }
+                    });
+          }
+        };
     Injector injector = Guice.createInjector(module, NamedMunger.module());
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
-  
-  public void testWithSource() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        binder().withSource("source").install(new AbstractModule() {
-          @Override protected void configure() {}
 
-          @TestProvides @Named("foo") String foo() { return "foo"; }
-        });
-      }
-    };
+  public void testWithSource() throws Exception {
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            binder()
+                .withSource("source")
+                .install(
+                    new AbstractModule() {
+
+                      @TestProvides
+                      @Named("foo")
+                      String foo() {
+                        return "foo";
+                      }
+                    });
+          }
+        };
     Injector injector = Guice.createInjector(module, NamedMunger.module());
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testMoreThanOneClaimedAnnotationFails() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {}
+    Module module =
+        new AbstractModule() {
 
-      @TestProvides @TestProvides2 String foo() {
-        return "foo";
-      }
-    };
+          @TestProvides
+          @TestProvides2
+          String foo() {
+            return "foo";
+          }
+        };
     try {
       Guice.createInjector(module, NamedMunger.module());
       fail();
-    } catch(CreationException expected) {
+    } catch (CreationException expected) {
       assertEquals(1, expected.getErrorMessages().size());
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "More than one annotation claimed by NamedMunger on method "
-              + module.getClass().getName() + ".foo(). Methods can only have "
+              + module.getClass().getName()
+              + ".foo(). Methods can only have "
               + "one annotation claimed per scanner.");
     }
   }
 
   private String methodName(Class<? extends Annotation> annotation, String method, Object container)
       throws Exception {
-    return "@" + annotation.getName() + " "
+    return "@"
+        + annotation.getName()
+        + " "
         + StackTraceElements.forMember(container.getClass().getDeclaredMethod(method));
   }
 
-  @Documented @Target(METHOD) @Retention(RUNTIME)
+  @Documented
+  @Target(METHOD)
+  @Retention(RUNTIME)
   private @interface TestProvides {}
 
-  @Documented @Target(METHOD) @Retention(RUNTIME)
+  @Documented
+  @Target(METHOD)
+  @Retention(RUNTIME)
   private @interface TestProvides2 {}
 
   private static class NamedMunger extends ModuleAnnotatedMethodScanner {
     static Module module() {
       return new AbstractModule() {
-        @Override protected void configure() {
+        @Override
+        protected void configure() {
           binder().scanModulesForAnnotatedMethods(new NamedMunger());
         }
       };
@@ -155,15 +184,15 @@
     }
 
     @Override
-    public <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key,
-        InjectionPoint injectionPoint) {
-      return Key.get(key.getTypeLiteral(),
-          Names.named(((Named) key.getAnnotation()).value() + "-munged"));
+    public <T> Key<T> prepareMethod(
+        Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
+      return Key.get(
+          key.getTypeLiteral(), Names.named(((Named) key.getAnnotation()).value() + "-munged"));
     }
   }
 
-  private void assertMungedBinding(Injector injector, Class<?> clazz, String originalName,
-      Object expectedValue) {
+  private void assertMungedBinding(
+      Injector injector, Class<?> clazz, String originalName, Object expectedValue) {
     assertNull(injector.getExistingBinding(Key.get(clazz, named(originalName))));
     Binding<?> fooBinding = injector.getBinding(Key.get(clazz, named(originalName + "-munged")));
     assertEquals(expectedValue, fooBinding.getProvider().get());
@@ -176,13 +205,13 @@
     } catch (CreationException expected) {
       Message m = Iterables.getOnlyElement(expected.getErrorMessages());
       assertEquals(
-          "An exception was caught and reported. Message: Failing in the scanner.",
-          m.getMessage());
+          "An exception was caught and reported. Message: Failing in the scanner.", m.getMessage());
       assertEquals(IllegalStateException.class, m.getCause().getClass());
       ElementSource source = (ElementSource) Iterables.getOnlyElement(m.getSources());
-      assertEquals(SomeModule.class.getName(),
-          Iterables.getOnlyElement(source.getModuleClassNames()));
-      assertEquals(String.class.getName() + " " + SomeModule.class.getName() + ".aString()",
+      assertEquals(
+          SomeModule.class.getName(), Iterables.getOnlyElement(source.getModuleClassNames()));
+      assertEquals(
+          String.class.getName() + " " + SomeModule.class.getName() + ".aString()",
           source.toString());
     }
   }
@@ -190,51 +219,58 @@
   public static class FailingScanner extends ModuleAnnotatedMethodScanner {
     static Module module() {
       return new AbstractModule() {
-        @Override protected void configure() {
+        @Override
+        protected void configure() {
           binder().scanModulesForAnnotatedMethods(new FailingScanner());
         }
       };
     }
 
-    @Override public Set<? extends Class<? extends Annotation>> annotationClasses() {
+    @Override
+    public Set<? extends Class<? extends Annotation>> annotationClasses() {
       return ImmutableSet.of(TestProvides.class);
     }
 
-    @Override public <T> Key<T> prepareMethod(
+    @Override
+    public <T> Key<T> prepareMethod(
         Binder binder, Annotation rawAnnotation, Key<T> key, InjectionPoint injectionPoint) {
       throw new IllegalStateException("Failing in the scanner.");
     }
   }
 
   static class SomeModule extends AbstractModule {
-    @TestProvides String aString() {
+    @TestProvides
+    String aString() {
       return "Foo";
     }
 
-    @Override protected void configure() {}
   }
 
   public void testChildInjectorInheritsScanner() {
     Injector parent = Guice.createInjector(NamedMunger.module());
-    Injector child = parent.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {}
+    Injector child =
+        parent.createChildInjector(
+            new AbstractModule() {
 
-      @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
-    });
+              @TestProvides
+              @Named("foo")
+              String foo() {
+                return "foo";
+              }
+            });
     assertMungedBinding(child, String.class, "foo", "foo");
   }
 
   public void testChildInjectorScannersDontImpactSiblings() {
-    Module module = new AbstractModule() {
-      @Override
-      protected void configure() {}
+    Module module =
+        new AbstractModule() {
 
-      @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
-    };
+          @TestProvides
+          @Named("foo")
+          String foo() {
+            return "foo";
+          }
+        };
     Injector parent = Guice.createInjector();
     Injector child = parent.createChildInjector(NamedMunger.module(), module);
     assertMungedBinding(child, String.class, "foo", "foo");
@@ -246,149 +282,245 @@
   }
 
   public void testPrivateModuleInheritScanner_usingPrivateModule() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
-      @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new PrivateModule() {
+              @Override
+              protected void configure() {}
 
-      @Exposed @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
-    });
+              @Exposed
+              @TestProvides
+              @Named("foo")
+              String foo() {
+                return "foo";
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModule_skipSourcesWithinPrivateModule() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
-      @Override protected void configure() {
-        binder().skipSources(getClass()).install(new AbstractModule() {
-          @Override protected void configure() {}
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new PrivateModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .skipSources(getClass())
+                    .install(
+                        new AbstractModule() {
+
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModule_skipSourcesForPrivateModule() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
-      @Override protected void configure() {
-        binder().skipSources(getClass()).install(new PrivateModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .skipSources(getClass())
+                    .install(
+                        new PrivateModule() {
+                          @Override
+                          protected void configure() {}
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }});
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleInheritScanner_usingPrivateBinder() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
-      @Override protected void configure() {
-        binder().newPrivateBinder().install(new AbstractModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .newPrivateBinder()
+                    .install(
+                        new AbstractModule() {
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    });
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleInheritScanner_skipSourcesFromPrivateBinder() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
-      @Override protected void configure() {
-        binder().newPrivateBinder().skipSources(getClass()).install(new AbstractModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .newPrivateBinder()
+                    .skipSources(getClass())
+                    .install(
+                        new AbstractModule() {
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    });
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleInheritScanner_skipSourcesFromPrivateBinder2() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
-      @Override protected void configure() {
-        binder().skipSources(getClass()).newPrivateBinder().install(new AbstractModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .skipSources(getClass())
+                    .newPrivateBinder()
+                    .install(
+                        new AbstractModule() {
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    });
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleScannersDontImpactSiblings_usingPrivateModule() {
-    Injector injector = Guice.createInjector(new PrivateModule() {
-      @Override protected void configure() {
-        install(NamedMunger.module());
-      }
+    Injector injector =
+        Guice.createInjector(
+            new PrivateModule() {
+              @Override
+              protected void configure() {
+                install(NamedMunger.module());
+              }
 
-      @Exposed @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
-    }, new PrivateModule() {
-      @Override protected void configure() {}
+              @Exposed
+              @TestProvides
+              @Named("foo")
+              String foo() {
+                return "foo";
+              }
+            },
+            new PrivateModule() {
+              @Override
+              protected void configure() {}
 
-      // ignored! (because the scanner doesn't run over this module)
-      @Exposed @TestProvides @Named("foo") String foo() {
-        return "foo";
-      }
-    });
+              // ignored! (because the scanner doesn't run over this module)
+              @Exposed
+              @TestProvides
+              @Named("foo")
+              String foo() {
+                return "foo";
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleScannersDontImpactSiblings_usingPrivateBinder() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        binder().newPrivateBinder().install(new AbstractModule() {
-          @Override protected void configure() {
-            install(NamedMunger.module());
-          }
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .newPrivateBinder()
+                    .install(
+                        new AbstractModule() {
+                          @Override
+                          protected void configure() {
+                            install(NamedMunger.module());
+                          }
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    }, new AbstractModule() {
-      @Override protected void configure() {
-        binder().newPrivateBinder().install(new AbstractModule() {
-          @Override protected void configure() {}
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            },
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder()
+                    .newPrivateBinder()
+                    .install(
+                        new AbstractModule() {
 
-          // ignored! (because the scanner doesn't run over this module)
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }});
+                          // ignored! (because the scanner doesn't run over this module)
+                          @Exposed
+                          @TestProvides
+                          @Named("foo")
+                          String foo() {
+                            return "foo";
+                          }
+                        });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 
   public void testPrivateModuleWithinPrivateModule() {
-    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
-      @Override protected void configure() {
-        expose(Key.get(String.class, named("foo-munged")));
-        install(new PrivateModule() {
-          @Override protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            NamedMunger.module(),
+            new PrivateModule() {
+              @Override
+              protected void configure() {
+                expose(Key.get(String.class, named("foo-munged")));
+                install(
+                    new PrivateModule() {
+                      @Override
+                      protected void configure() {}
 
-          @Exposed @TestProvides @Named("foo") String foo() {
-            return "foo";
-          }
-        });
-      }
-    });
+                      @Exposed
+                      @TestProvides
+                      @Named("foo")
+                      String foo() {
+                        return "foo";
+                      }
+                    });
+              }
+            });
     assertMungedBinding(injector, String.class, "foo", "foo");
   }
 }
diff --git a/core/test/com/google/inject/spi/ModuleRewriterTest.java b/core/test/com/google/inject/spi/ModuleRewriterTest.java
index 06581da..e3a4a00 100644
--- a/core/test/com/google/inject/spi/ModuleRewriterTest.java
+++ b/core/test/com/google/inject/spi/ModuleRewriterTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,24 +27,22 @@
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.name.Names;
-
+import java.util.List;
 import junit.framework.TestCase;
 
-import java.util.List;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class ModuleRewriterTest extends TestCase {
 
   public void testRewriteBindings() {
     // create a module the binds String.class and CharSequence.class
-    Module module = new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("Pizza");
-        bind(CharSequence.class).toInstance("Wine");
-      }
-    };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("Pizza");
+            bind(CharSequence.class).toInstance("Wine");
+          }
+        };
 
     // record the elements from that module
     List<Element> elements = Elements.getElements(module);
@@ -52,17 +50,19 @@
     // create a rewriter that rewrites the binding to 'Wine' with a binding to 'Beer'
     List<Element> rewritten = Lists.newArrayList();
     for (Element element : elements) {
-      element = element.acceptVisitor(new DefaultElementVisitor<Element>() {
-        @Override public <T> Element visit(Binding<T> binding) {
-          T target = binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
-          if ("Wine".equals(target)) {
-            return null;
-          }
-          else {
-            return binding;
-          }
-        }
-      });
+      element =
+          element.acceptVisitor(
+              new DefaultElementVisitor<Element>() {
+                @Override
+                public <T> Element visit(Binding<T> binding) {
+                  T target = binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
+                  if ("Wine".equals(target)) {
+                    return null;
+                  } else {
+                    return binding;
+                  }
+                }
+              });
       if (element != null) {
         rewritten.add(element);
       }
@@ -81,25 +81,32 @@
   }
 
   public void testGetProviderAvailableAtInjectMembersTime() {
-    Module module = new AbstractModule() {
-      public void configure() {
-        final Provider<String> stringProvider = getProvider(String.class);
+    Module module =
+        new AbstractModule() {
+          @Override
+          public void configure() {
+            final Provider<String> stringProvider = getProvider(String.class);
 
-        bind(String.class).annotatedWith(Names.named("2")).toProvider(new Provider<String>() {
-          private String value;
+            bind(String.class)
+                .annotatedWith(Names.named("2"))
+                .toProvider(
+                    new Provider<String>() {
+                      private String value;
 
-          @Inject void initialize() {
-            value = stringProvider.get();
+                      @Inject
+                      void initialize() {
+                        value = stringProvider.get();
+                      }
+
+                      @Override
+                      public String get() {
+                        return value;
+                      }
+                    });
+
+            bind(String.class).toInstance("A");
           }
-
-          public String get() {
-            return value;
-          }
-        });
-
-        bind(String.class).toInstance("A");
-      }
-    };
+        };
 
     // the module works fine normally
     Injector injector = Guice.createInjector(module);
diff --git a/core/test/com/google/inject/spi/ModuleSourceTest.java b/core/test/com/google/inject/spi/ModuleSourceTest.java
index b72d976..61f106e 100644
--- a/core/test/com/google/inject/spi/ModuleSourceTest.java
+++ b/core/test/com/google/inject/spi/ModuleSourceTest.java
@@ -3,30 +3,30 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Module;
-
 import junit.framework.TestCase;
 
-/**
- * Tests for {@link ModuleSource}.
- */
+/** Tests for {@link ModuleSource}. */
 public class ModuleSourceTest extends TestCase {
 
-  private static final StackTraceElement BINDER_INSTALL = 
-      new StackTraceElement("com.google.inject.spi.Elements$RecordingBinder", "install", 
-          "Unknown Source", 235 /* line number*/);
-  
+  private static final StackTraceElement BINDER_INSTALL =
+      new StackTraceElement(
+          "com.google.inject.spi.Elements$RecordingBinder",
+          "install",
+          "Unknown Source",
+          235 /* line number*/);
+
   public void testOneModule() {
     ModuleSource moduleSource = createWithSizeOne();
-    checkSizeOne(moduleSource);    
+    checkSizeOne(moduleSource);
   }
-  
+
   public void testTwoModules() {
     ModuleSource moduleSource = createWithSizeTwo();
     checkSizeTwo(moduleSource);
     moduleSource = moduleSource.getParent();
     checkSizeOne(moduleSource);
   }
-  
+
   public void testThreeModules() {
     ModuleSource moduleSource = createWithSizeThree();
     checkSizeThree(moduleSource);
@@ -41,66 +41,68 @@
     assertEquals(1, moduleSource.getStackTraceSize());
     // Check call stack
     StackTraceElement[] callStack = moduleSource.getStackTrace();
-    assertEquals(BINDER_INSTALL, callStack[0]);    
+    assertEquals(BINDER_INSTALL, callStack[0]);
   }
-  
+
   private void checkSizeTwo(ModuleSource moduleSource) {
     assertEquals(2, moduleSource.size());
     assertEquals(3, moduleSource.getStackTraceSize());
     // Check call stack
     StackTraceElement[] callStack = moduleSource.getStackTrace();
-    assertEquals(BINDER_INSTALL, callStack[0]);    
+    assertEquals(BINDER_INSTALL, callStack[0]);
     assertEquals(
         new StackTraceElement(
             "com.google.inject.spi.moduleSourceTest$A", "configure", "Unknown Source", 100),
         callStack[1]);
-    assertEquals(BINDER_INSTALL, callStack[2]);    
+    assertEquals(BINDER_INSTALL, callStack[2]);
   }
-  
+
   private void checkSizeThree(ModuleSource moduleSource) {
     assertEquals(3, moduleSource.size());
     assertEquals(7, moduleSource.getStackTraceSize());
     // Check call stack
     StackTraceElement[] callStack = moduleSource.getStackTrace();
-    assertEquals(BINDER_INSTALL, callStack[0]);    
+    assertEquals(BINDER_INSTALL, callStack[0]);
     assertEquals(new StackTraceElement("class1", "method1", "Unknown Source", 1), callStack[1]);
-    assertEquals(new StackTraceElement("class2", "method2", "Unknown Source", 2), callStack[2]);   
+    assertEquals(new StackTraceElement("class2", "method2", "Unknown Source", 2), callStack[2]);
     assertEquals(
         new StackTraceElement(
             "com.google.inject.spi.moduleSourceTest$B", "configure", "Unknown Source", 200),
-            callStack[3]); 
-    assertEquals(BINDER_INSTALL, callStack[4]);    
+        callStack[3]);
+    assertEquals(BINDER_INSTALL, callStack[4]);
 
     assertEquals(
         new StackTraceElement(
             "com.google.inject.spi.moduleSourceTest$A", "configure", "Unknown Source", 100),
         callStack[5]);
-    assertEquals(BINDER_INSTALL, callStack[6]);    
+    assertEquals(BINDER_INSTALL, callStack[6]);
   }
-  
+
   private ModuleSource createWithSizeOne() {
     StackTraceElement[] partialCallStack = new StackTraceElement[1];
-    partialCallStack[0] = BINDER_INSTALL;    
+    partialCallStack[0] = BINDER_INSTALL;
     return new ModuleSource(new A(), partialCallStack);
   }
-  
+
   private ModuleSource createWithSizeTwo() {
     ModuleSource moduleSource = createWithSizeOne();
     StackTraceElement[] partialCallStack = new StackTraceElement[2];
     partialCallStack[0] = BINDER_INSTALL;
-    partialCallStack[1] = new StackTraceElement(
-        "com.google.inject.spi.moduleSourceTest$A", "configure", "moduleSourceTest.java", 100);
+    partialCallStack[1] =
+        new StackTraceElement(
+            "com.google.inject.spi.moduleSourceTest$A", "configure", "moduleSourceTest.java", 100);
     return moduleSource.createChild(new B(), partialCallStack);
   }
-    
+
   private ModuleSource createWithSizeThree() {
     ModuleSource moduleSource = createWithSizeTwo();
     StackTraceElement[] partialCallStack = new StackTraceElement[4];
     partialCallStack[0] = BINDER_INSTALL;
     partialCallStack[1] = new StackTraceElement("class1", "method1", "Class1.java", 1);
     partialCallStack[2] = new StackTraceElement("class2", "method2", "Class2.java", 2);
-    partialCallStack[3] = new StackTraceElement(
-        "com.google.inject.spi.moduleSourceTest$B", "configure", "moduleSourceTest.java", 200);
+    partialCallStack[3] =
+        new StackTraceElement(
+            "com.google.inject.spi.moduleSourceTest$B", "configure", "moduleSourceTest.java", 200);
     return moduleSource.createChild(new C(), partialCallStack);
   }
 
@@ -110,16 +112,14 @@
       install(new B());
     }
   }
-  
+
   private static class B implements Module {
     @Override
     public void configure(Binder binder) {
       binder.install(new C());
     }
   }
-  
+
   private static class C extends AbstractModule {
-    @Override
-    public void configure() {}
   }
 }
diff --git a/core/test/com/google/inject/spi/ProviderMethodsTest.java b/core/test/com/google/inject/spi/ProviderMethodsTest.java
index 5814967..cfc9490 100644
--- a/core/test/com/google/inject/spi/ProviderMethodsTest.java
+++ b/core/test/com/google/inject/spi/ProviderMethodsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,6 +33,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
+import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.ProvisionException;
 import com.google.inject.Singleton;
@@ -46,9 +47,6 @@
 import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
 import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -62,10 +60,10 @@
 import java.util.logging.Handler;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
+@SuppressWarnings("ProvidesMethodOutsideOfModule")
 public class ProviderMethodsTest extends TestCase implements Module {
 
   @SuppressWarnings("unchecked")
@@ -82,16 +80,15 @@
     assertSame(bob.getDaughter(), clone.getDaughter());
 
     Key soleBobKey = Key.get(Bob.class, Sole.class);
-    assertSame(
-        injector.getInstance(soleBobKey),
-        injector.getInstance(soleBobKey)
-    );
+    assertSame(injector.getInstance(soleBobKey), injector.getInstance(soleBobKey));
   }
 
+  @Override
   public void configure(Binder binder) {}
 
   interface Bob {
     String getName();
+
     Dagny getDaughter();
   }
 
@@ -102,10 +99,12 @@
   @Provides
   Bob provideBob(final Dagny dagny) {
     return new Bob() {
+      @Override
       public String getName() {
         return "A Bob";
       }
 
+      @Override
       public Dagny getDaughter() {
         return dagny;
       }
@@ -117,10 +116,12 @@
   @Sole
   Bob provideSoleBob(final Dagny dagny) {
     return new Bob() {
+      @Override
       public String getName() {
         return "Only Bob";
       }
 
+      @Override
       public Dagny getDaughter() {
         return dagny;
       }
@@ -131,6 +132,7 @@
   @Singleton
   Dagny provideDagny() {
     return new Dagny() {
+      @Override
       public int getAge() {
         return 1;
       }
@@ -138,100 +140,106 @@
   }
 
   @Retention(RUNTIME)
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
   @BindingAnnotation
   @interface Sole {}
 
+  public void testCircularDependency() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
 
+              @Provides
+              Foo newFoo(final Bar bar) {
+                return new Foo() {
 
-// We'll have to make getProvider() support circular dependencies before this
-// will work.
-//
-//  public void testCircularDependency() {
-//    Injector injector = Guice.createInjector(new Module() {
-//      public void configure(Binder binder) {
-//        binder.install(ProviderMethods.from(ProviderMethodsTest.this));
-//      }
-//    });
-//
-//    Foo foo = injector.getInstance(Foo.class);
-//    assertEquals(5, foo.getI());
-//    assertEquals(10, foo.getBar().getI());
-//    assertEquals(5, foo.getBar().getFoo().getI());
-//  }
-//
-//  interface Foo {
-//    Bar getBar();
-//    int getI();
-//  }
-//
-//  interface Bar {
-//    Foo getFoo();
-//    int getI();
-//  }
-//
-//  @Provides Foo newFoo(final Bar bar) {
-//    return new Foo() {
-//
-//      public Bar getBar() {
-//        return bar;
-//      }
-//
-//      public int getI() {
-//        return 5;
-//      }
-//    };
-//  }
-//
-//  @Provides Bar newBar(final Foo foo) {
-//    return new Bar() {
-//
-//      public Foo getFoo() {
-//        return foo;
-//      }
-//
-//      public int getI() {
-//        return 10;
-//      }
-//    };
-//  }
+                  @Override
+                  public Bar getBar() {
+                    return bar;
+                  }
 
+                  @Override
+                  public int getI() {
+                    return 5;
+                  }
+                };
+              }
+
+              @Provides
+              Bar newBar(final Foo foo) {
+                return new Bar() {
+
+                  @Override
+                  public Foo getFoo() {
+                    return foo;
+                  }
+
+                  @Override
+                  public int getI() {
+                    return 10;
+                  }
+                };
+              }
+            });
+
+    Foo foo = injector.getInstance(Foo.class);
+    assertEquals(5, foo.getI());
+    assertEquals(10, foo.getBar().getI());
+    assertEquals(5, foo.getBar().getFoo().getI());
+  }
+
+  public interface Foo {
+    Bar getBar();
+
+    int getI();
+  }
+
+  public interface Bar {
+    Foo getFoo();
+
+    int getI();
+  }
 
   public void testMultipleBindingAnnotations() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {}
+      Guice.createInjector(
+          new AbstractModule() {
 
-        @Provides @Named("A") @Blue
-        public String provideString() {
-          return "a";
-        }
-      });
+            @Provides
+            @Named("A")
+            @Blue
+            public String provideString() {
+              return "a";
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "more than one annotation annotated with @BindingAnnotation:", "Named", "Blue",
-          "at " + getClass().getName(), ".provideString(ProviderMethodsTest.java:");
+      assertContains(
+          expected.getMessage(),
+          "more than one annotation annotated with @BindingAnnotation:",
+          "Named",
+          "Blue",
+          "at " + getClass().getName(),
+          ".provideString(ProviderMethodsTest.java:");
     }
-
   }
 
   @Retention(RUNTIME)
-  @BindingAnnotation @interface Blue {}
+  @BindingAnnotation
+  @interface Blue {}
 
   public void testGenericProviderMethods() {
-    Injector injector = Guice.createInjector(
-        new ProvideTs<String>("A", "B") {}, new ProvideTs<Integer>(1, 2) {});
+    Injector injector =
+        Guice.createInjector(new ProvideTs<String>("A", "B") {}, new ProvideTs<Integer>(1, 2) {});
 
     assertEquals("A", injector.getInstance(Key.get(String.class, Names.named("First"))));
     assertEquals("B", injector.getInstance(Key.get(String.class, Names.named("Second"))));
-    assertEquals(ImmutableSet.of("A", "B"),
-        injector.getInstance(Key.get(Types.setOf(String.class))));
+    assertEquals(
+        ImmutableSet.of("A", "B"), injector.getInstance(Key.get(Types.setOf(String.class))));
 
     assertEquals(1, injector.getInstance(Key.get(Integer.class, Names.named("First"))).intValue());
     assertEquals(2, injector.getInstance(Key.get(Integer.class, Names.named("Second"))).intValue());
-    assertEquals(ImmutableSet.of(1, 2),
-        injector.getInstance(Key.get(Types.setOf(Integer.class))));
+    assertEquals(ImmutableSet.of(1, 2), injector.getInstance(Key.get(Types.setOf(Integer.class))));
   }
 
   abstract class ProvideTs<T> extends AbstractModule {
@@ -243,31 +251,38 @@
       this.second = second;
     }
 
-    @Override protected void configure() {}
-
-    @Named("First") @Provides T provideFirst() {
+    @Named("First")
+    @Provides
+    T provideFirst() {
       return first;
     }
 
-    @Named("Second") @Provides T provideSecond() {
+    @Named("Second")
+    @Provides
+    T provideSecond() {
       return second;
     }
 
-    @Provides Set<T> provideBoth(@Named("First") T first, @Named("Second") T second) {
+    @Provides
+    Set<T> provideBoth(@Named("First") T first, @Named("Second") T second) {
       return ImmutableSet.of(first, second);
     }
   }
 
   public void testAutomaticProviderMethods() {
-    Injector injector = Guice.createInjector((Module) new AbstractModule() {
-      @Override protected void configure() { }
-      private int next = 1;
+    Injector injector =
+        Guice.createInjector(
+            (Module)
+                new AbstractModule() {
 
-      @Provides @Named("count")
-      public Integer provideCount() {
-        return next++;
-      }
-    });
+                  private int next = 1;
+
+                  @Provides
+                  @Named("count")
+                  public Integer provideCount() {
+                    return next++;
+                  }
+                });
 
     assertEquals(1, injector.getInstance(Key.get(Integer.class, Names.named("count"))).intValue());
     assertEquals(2, injector.getInstance(Key.get(Integer.class, Names.named("count"))).intValue());
@@ -279,15 +294,19 @@
    * binding of the provider methods' types.
    */
   public void testAutomaticProviderMethodsDoNotCauseDoubleBinding() {
-    Module installsSelf = new AbstractModule() {
-      @Override protected void configure() {
-        install(this);
-        bind(Integer.class).toInstance(5);
-      }
-      @Provides public String provideString(Integer count) {
-        return "A" + count;
-      }
-    };
+    Module installsSelf =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(this);
+            bind(Integer.class).toInstance(5);
+          }
+
+          @Provides
+          public String provideString(Integer count) {
+            return "A" + count;
+          }
+        };
 
     Injector injector = Guice.createInjector(installsSelf);
     assertEquals("A5", injector.getInstance(String.class));
@@ -297,20 +316,28 @@
     final List<String> strings = ImmutableList.of("A", "B", "C");
     final List<Number> numbers = ImmutableList.<Number>of(1, 2, 3);
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        @SuppressWarnings("unchecked")
-        Key<List<? super Integer>> listOfSupertypesOfInteger = (Key<List<? super Integer>>)
-            Key.get(Types.listOf(Types.supertypeOf(Integer.class)));
-        bind(listOfSupertypesOfInteger).toInstance(numbers);
-      }
-      @Provides public List<? extends CharSequence> provideCharSequences() {
-        return strings;
-      }
-      @Provides public Class<?> provideType() {
-        return Float.class;
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                @SuppressWarnings("unchecked")
+                Key<List<? super Integer>> listOfSupertypesOfInteger =
+                    (Key<List<? super Integer>>)
+                        Key.get(Types.listOf(Types.supertypeOf(Integer.class)));
+                bind(listOfSupertypesOfInteger).toInstance(numbers);
+              }
+
+              @Provides
+              public List<? extends CharSequence> provideCharSequences() {
+                return strings;
+              }
+
+              @Provides
+              public Class<?> provideType() {
+                return Float.class;
+              }
+            });
 
     assertSame(strings, injector.getInstance(HasWildcardInjection.class).charSequences);
     assertSame(numbers, injector.getInstance(HasWildcardInjection.class).numbers);
@@ -324,40 +351,52 @@
   }
 
   public void testProviderMethodDependenciesAreExposed() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Integer.class).toInstance(50);
-        bindConstant().annotatedWith(Names.named("units")).to("Kg");
-      }
-      @Provides @Named("weight") String provideWeight(Integer count, @Named("units") String units) {
-        return count + units;
-      }
-    };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).toInstance(50);
+            bindConstant().annotatedWith(Names.named("units")).to("Kg");
+          }
+
+          @Provides
+          @Named("weight")
+          String provideWeight(Integer count, @Named("units") String units) {
+            return count + units;
+          }
+        };
     Injector injector = Guice.createInjector(module);
 
-    ProviderInstanceBinding<?> binding = (ProviderInstanceBinding<?>) injector.getBinding(
-        Key.get(String.class, Names.named("weight")));
+    ProviderInstanceBinding<?> binding =
+        (ProviderInstanceBinding<?>)
+            injector.getBinding(Key.get(String.class, Names.named("weight")));
     Method method =
-      module.getClass().getDeclaredMethod("provideWeight", Integer.class, String.class);
+        module.getClass().getDeclaredMethod("provideWeight", Integer.class, String.class);
     InjectionPoint point = new InjectionPoint(TypeLiteral.get(module.getClass()), method, false);
-    assertEquals(ImmutableSet.<Dependency<?>>of(
-        new Dependency<Integer>(point, Key.get(Integer.class), false, 0),
-        new Dependency<String>(point, Key.get(String.class, Names.named("units")), false, 1)),
-         binding.getDependencies());
+    assertEquals(
+        ImmutableSet.<Dependency<?>>of(
+            new Dependency<Integer>(point, Key.get(Integer.class), false, 0),
+            new Dependency<String>(point, Key.get(String.class, Names.named("units")), false, 1)),
+        binding.getDependencies());
   }
 
   public void testNonModuleProviderMethods() {
-    final Object methodsObject = new Object() {
-      @Provides @Named("foo") String provideFoo() {
-        return "foo-value";
-      }
-    };
+    final Object methodsObject =
+        new Object() {
+          @Provides
+          @Named("foo")
+          String provideFoo() {
+            return "foo-value";
+          }
+        };
 
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        install(ProviderMethodsModule.forObject(methodsObject));
-      }
-    };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(ProviderMethodsModule.forObject(methodsObject));
+          }
+        };
 
     Injector injector = Guice.createInjector(module);
 
@@ -369,7 +408,8 @@
     assertEquals(1, elements.size());
 
     Element element = elements.get(0);
-    assertTrue(element + " instanceof ProviderInstanceBinding",
+    assertTrue(
+        element + " instanceof ProviderInstanceBinding",
         element instanceof ProviderInstanceBinding);
 
     ProviderInstanceBinding binding = (ProviderInstanceBinding) element;
@@ -381,21 +421,24 @@
 
   public void testVoidProviderMethods() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {}
+      Guice.createInjector(
+          new AbstractModule() {
 
-        @Provides void provideFoo() {}
-      });
+            @Provides
+            void provideFoo() {}
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Provider methods must return a value. Do not return void.",
-          getClass().getName(), ".provideFoo(ProviderMethodsTest.java:");
+          getClass().getName(),
+          ".provideFoo(ProviderMethodsTest.java:");
     }
   }
 
   public void testInjectsJustOneLogger() {
-    AtomicReference<Logger> loggerRef = new AtomicReference<Logger>();
+    AtomicReference<Logger> loggerRef = new AtomicReference<>();
     Injector injector = Guice.createInjector(new FooModule(loggerRef));
 
     assertNull(loggerRef.get());
@@ -415,59 +458,67 @@
       this.loggerRef = loggerRef;
     }
 
-    @Override protected void configure() {}
-
     @SuppressWarnings("unused")
-    @Provides Integer foo(Logger logger) {
+    @Provides
+    Integer foo(Logger logger) {
       loggerRef.set(logger);
       return 42;
     }
   }
 
   public void testSpi() throws Exception {
-    Module m1 = new AbstractModule() {
-      @Override protected void configure() {}
-      @Provides @Named("foo") String provideFoo(Integer dep) { return "foo"; }
-    };
-    Module m2 = new AbstractModule() {
-      @Override protected void configure() {}
-      @Provides Integer provideInt(@Named("foo") String dep) { return 42; }
-    };
+    Module m1 =
+        new AbstractModule() {
+
+          @Provides
+          @Named("foo")
+          String provideFoo(Integer dep) {
+            return "foo";
+          }
+        };
+    Module m2 =
+        new AbstractModule() {
+
+          @Provides
+          Integer provideInt(@Named("foo") String dep) {
+            return 42;
+          }
+        };
     Injector injector = Guice.createInjector(m1, m2);
 
-    Binding<String> stringBinding =
-        injector.getBinding(Key.get(String.class, Names.named("foo")));
+    Binding<String> stringBinding = injector.getBinding(Key.get(String.class, Names.named("foo")));
     ProvidesMethodBinding<String> stringMethod =
         stringBinding.acceptTargetVisitor(new BindingCapturer<String>());
     assertEquals(m1, stringMethod.getEnclosingInstance());
-    assertEquals(m1.getClass().getDeclaredMethod("provideFoo", Integer.class),
-        stringMethod.getMethod());
-    assertEquals(((HasDependencies) stringBinding).getDependencies(),
-        stringMethod.getDependencies());
+    assertEquals(
+        m1.getClass().getDeclaredMethod("provideFoo", Integer.class), stringMethod.getMethod());
+    assertEquals(
+        ((HasDependencies) stringBinding).getDependencies(), stringMethod.getDependencies());
     assertEquals(Key.get(String.class, Names.named("foo")), stringMethod.getKey());
 
     Binding<Integer> intBinding = injector.getBinding(Integer.class);
     ProvidesMethodBinding<Integer> intMethod =
         intBinding.acceptTargetVisitor(new BindingCapturer<Integer>());
     assertEquals(m2, intMethod.getEnclosingInstance());
-    assertEquals(m2.getClass().getDeclaredMethod("provideInt", String.class),
-        intMethod.getMethod());
-    assertEquals(((HasDependencies) intBinding).getDependencies(),
-        intMethod.getDependencies());
+    assertEquals(
+        m2.getClass().getDeclaredMethod("provideInt", String.class), intMethod.getMethod());
+    assertEquals(((HasDependencies) intBinding).getDependencies(), intMethod.getDependencies());
     assertEquals(Key.get(Integer.class), intMethod.getKey());
-
   }
 
-  private static class BindingCapturer<T> extends DefaultBindingTargetVisitor<T, ProvidesMethodBinding<T>>
+  private static class BindingCapturer<T>
+      extends DefaultBindingTargetVisitor<T, ProvidesMethodBinding<T>>
       implements ProvidesMethodTargetVisitor<T, ProvidesMethodBinding<T>> {
 
+    @Override
     @SuppressWarnings("unchecked")
     public ProvidesMethodBinding<T> visit(
         ProvidesMethodBinding<? extends T> providesMethodBinding) {
-      return (ProvidesMethodBinding<T>)providesMethodBinding;
+      return (ProvidesMethodBinding<T>) providesMethodBinding;
     }
 
-    @Override protected ProvidesMethodBinding<T> visitOther(Binding<? extends T> binding) {
+    @Override
+    protected ProvidesMethodBinding<T> visitOther(Binding<? extends T> binding) {
       throw new IllegalStateException("unexpected visit of: " + binding);
     }
   }
@@ -477,30 +528,33 @@
 
     assertEquals(42, injector.getInstance(Integer.class).intValue());
     assertEquals(42L, injector.getInstance(Long.class).longValue());
-    assertEquals(42D, injector.getInstance(Double.class).doubleValue());
-    assertEquals(42F, injector.getInstance(Float.class).floatValue());
+    assertEquals(42D, injector.getInstance(Double.class).doubleValue(), 0.0);
+    assertEquals(42F, injector.getInstance(Float.class).floatValue(), 0.0f);
   }
 
   private static class VisibilityModule extends AbstractModule {
-    @Override protected void configure() {}
 
     @SuppressWarnings("unused")
-    @Provides Integer foo() {
+    @Provides
+    Integer foo() {
       return 42;
     }
 
     @SuppressWarnings("unused")
-    @Provides private Long bar() {
+    @Provides
+    private Long bar() {
       return 42L;
     }
 
     @SuppressWarnings("unused")
-    @Provides protected Double baz() {
+    @Provides
+    protected Double baz() {
       return 42D;
     }
 
     @SuppressWarnings("unused")
-    @Provides public Float quux() {
+    @Provides
+    public Float quux() {
       return 42F;
     }
   }
@@ -511,7 +565,8 @@
       fail("Expected injector creation failure");
     } catch (CreationException expected) {
       // both of our super class bindings cause errors
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "A binding to java.lang.Long was already configured",
           "A binding to java.lang.Integer was already configured");
     }
@@ -521,29 +576,32 @@
     Injector injector = Guice.createInjector(new Sub1Module());
     assertEquals(42, injector.getInstance(Integer.class).intValue());
     assertEquals(42L, injector.getInstance(Long.class).longValue());
-    assertEquals(42D, injector.getInstance(Double.class).doubleValue());
+    assertEquals(42D, injector.getInstance(Double.class).doubleValue(), 0.0);
   }
 
   private static class BaseModule extends AbstractModule {
-    @Override protected void configure() {}
 
-    @Provides Integer foo() {
+    @Provides
+    Integer foo() {
       return 42;
     }
 
-    @Provides Long bar() {
+    @Provides
+    Long bar() {
       return 42L;
     }
   }
 
   private static class Sub1Module extends BaseModule {
-    @Provides Double baz() {
+    @Provides
+    Double baz() {
       return 42D;
     }
   }
 
   private static class Sub2Module extends BaseModule {
-    @Provides Float quux() {
+    @Provides
+    Float quux() {
       return 42F;
     }
   }
@@ -561,14 +619,16 @@
     String barCallerClass = "not_set_bar";
     String fooCallerClass = "not_set_foo";
 
-    @Override protected void configure() {}
-
-    @Provides @Singleton Integer foo() {
+    @Provides
+    @Singleton
+    Integer foo() {
       this.fooCallerClass = new Exception().getStackTrace()[1].getClassName();
       return 42;
     }
 
-    @Provides @Singleton Long bar() {
+    @Provides
+    @Singleton
+    Long bar() {
       this.barCallerClass = new Exception().getStackTrace()[1].getClassName();
       return 42L;
     }
@@ -577,21 +637,25 @@
   public void testShareFastClassWithSuperClass() {
     CallerInspecterSubClassModule module = new CallerInspecterSubClassModule();
     Guice.createInjector(Stage.PRODUCTION, module);
-    assertEquals("Expected provider methods in the same class to share fastclass classes",
-        module.fooCallerClass, module.barCallerClass);
+    assertEquals(
+        "Expected provider methods in the same class to share fastclass classes",
+        module.fooCallerClass,
+        module.barCallerClass);
     assertFalse(
         "Did not expect provider methods in the subclasses to share fastclass classes "
             + "with their parent classes",
         module.bazCallerClass.equals(module.barCallerClass));
   }
 
-
   private static class CallerInspecterSubClassModule extends CallerInspecterModule {
     String bazCallerClass;
 
-    @Override protected void configure() {}
+    @Override
+    protected void configure() {}
 
-    @Provides @Singleton Double baz() {
+    @Provides
+    @Singleton
+    Double baz() {
       this.bazCallerClass = new Exception().getStackTrace()[1].getClassName();
       return 42D;
     }
@@ -599,33 +663,47 @@
   /*end[AOP]*/
 
   static class SuperClassModule extends AbstractModule {
-    @Override protected void configure() {}
-    @Provides Number providerMethod() {
+
+    @Provides
+    Number providerMethod() {
       return 1D;
     }
-    @Provides @Named("rawlist") List rawProvider(@Named("list") List<String> f) {
+
+    @Provides
+    @Named("rawlist")
+    List rawProvider(@Named("list") List<String> f) {
       return f;
     }
 
-    @Provides @Named("unrawlist") List<String> rawParameterProvider(@Named("rawlist") List f) {
+    @Provides
+    @Named("unrawlist")
+    List<String> rawParameterProvider(@Named("rawlist") List f) {
       return f;
     }
 
-    @Provides @Named("list") List<String> annotatedGenericProviderMethod() {
+    @Provides
+    @Named("list")
+    List<String> annotatedGenericProviderMethod() {
       return new ArrayList<String>();
     }
-    @Provides @Named("collection") Collection<String> annotatedGenericParameterProviderMethod(
-        @Named("list") List<String> foo) {
+
+    @Provides
+    @Named("collection")
+    Collection<String> annotatedGenericParameterProviderMethod(@Named("list") List<String> foo) {
       return foo;
     }
-    @Provides private String privateProviderMethod() {
+
+    @Provides
+    private String privateProviderMethod() {
       return "hello";
     }
   }
 
   public void testOverrideProviderMethod_overrideHasProvides() {
     class SubClassModule extends SuperClassModule {
-      @Override @Provides Number providerMethod() {
+      @Override
+      @Provides
+      Number providerMethod() {
         return 2D;
       }
     }
@@ -633,7 +711,8 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
@@ -642,7 +721,10 @@
 
   public void testOverrideProviderMethod_overrideHasProvides_withNewAnnotation() {
     class SubClassModule extends SuperClassModule {
-      @Override @Provides @Named("foo") Number providerMethod() {
+      @Override
+      @Provides
+      @Named("foo")
+      Number providerMethod() {
         return 2D;
       }
     }
@@ -650,7 +732,8 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
@@ -659,7 +742,8 @@
 
   public void testOverrideProviderMethod_overrideDoesntHaveProvides() {
     class SubClassModule extends SuperClassModule {
-      @Override Number providerMethod() {
+      @Override
+      Number providerMethod() {
         return 2D;
       }
     }
@@ -667,33 +751,38 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
-          "Overriding @Provides methods is not allowed.",
-          "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
-          "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
-    }
-  }
-  public void testOverrideProviderMethod_overrideDoesntHaveProvides_withNewAnnotation() {
-    class SubClassModule extends SuperClassModule {
-      @Override @Named("foo") Number providerMethod() {
-        return 2D;
-      }
-    }
-    try {
-      Guice.createInjector(new SubClassModule());
-      fail();
-    } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
     }
   }
 
+  public void testOverrideProviderMethod_overrideDoesntHaveProvides_withNewAnnotation() {
+    class SubClassModule extends SuperClassModule {
+      @Override
+      @Named("foo")
+      Number providerMethod() {
+        return 2D;
+      }
+    }
+    try {
+      Guice.createInjector(new SubClassModule());
+      fail();
+    } catch (CreationException e) {
+      assertContains(
+          e.getMessage(),
+          "Overriding @Provides methods is not allowed.",
+          "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
+          "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
+    }
+  }
 
   public void testOverrideProviderMethod_covariantOverrideDoesntHaveProvides() {
     class SubClassModule extends SuperClassModule {
-      @Override Double providerMethod() {
+      @Override
+      Double providerMethod() {
         return 2D;
       }
     }
@@ -701,7 +790,8 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
@@ -710,7 +800,9 @@
 
   public void testOverrideProviderMethod_covariantOverrideHasProvides() {
     class SubClassModule extends SuperClassModule {
-      @Override @Provides Double providerMethod() {
+      @Override
+      @Provides
+      Double providerMethod() {
         return 2D;
       }
     }
@@ -718,7 +810,8 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".providerMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".providerMethod()");
@@ -737,7 +830,8 @@
 
   public void testOverrideProviderMethod_subclassRawTypes_returnType() {
     class SubClassModule extends SuperClassModule {
-      @Override List annotatedGenericProviderMethod() {
+      @Override
+      List annotatedGenericProviderMethod() {
         return super.annotatedGenericProviderMethod();
       }
     }
@@ -745,9 +839,11 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
-          "@Provides method: " + SuperClassModule.class.getName()
+          "@Provides method: "
+              + SuperClassModule.class.getName()
               + ".annotatedGenericProviderMethod()",
           "overridden by: " + SubClassModule.class.getName() + ".annotatedGenericProviderMethod()");
     }
@@ -755,7 +851,8 @@
 
   public void testOverrideProviderMethod_subclassRawTypes_parameterType() {
     class SubClassModule extends SuperClassModule {
-      @Override Collection<String> annotatedGenericParameterProviderMethod(List foo) {
+      @Override
+      Collection<String> annotatedGenericParameterProviderMethod(List foo) {
         return super.annotatedGenericParameterProviderMethod(foo);
       }
     }
@@ -763,11 +860,14 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
-          "@Provides method: " + SuperClassModule.class.getName()
+          "@Provides method: "
+              + SuperClassModule.class.getName()
               + ".annotatedGenericParameterProviderMethod()",
-          "overridden by: " + SubClassModule.class.getName()
+          "overridden by: "
+              + SubClassModule.class.getName()
               + ".annotatedGenericParameterProviderMethod()");
     }
   }
@@ -775,7 +875,8 @@
   public void testOverrideProviderMethod_superclassRawTypes_returnType() {
     class SubClassModule extends SuperClassModule {
       // remove the rawtype from the override
-      @Override List<String> rawProvider(List<String> f) {
+      @Override
+      List<String> rawProvider(List<String> f) {
         return f;
       }
     }
@@ -783,7 +884,8 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + SuperClassModule.class.getName() + ".rawProvider()",
           "overridden by: " + SubClassModule.class.getName() + ".rawProvider()");
@@ -791,7 +893,8 @@
   }
 
   abstract static class GenericSuperModule<T> extends AbstractModule {
-    @Provides String provide(T thing) {
+    @Provides
+    String provide(T thing) {
       return thing.toString();
     }
   }
@@ -800,11 +903,13 @@
   // bridge method)
   public void testOverrideProviderMethod_erasureBasedOverrides() {
     class SubClassModule extends GenericSuperModule<Integer> {
-      @Override String provide(Integer thing) {
+      @Override
+      String provide(Integer thing) {
         return thing.toString();
       }
 
-      @Override protected void configure() {
+      @Override
+      protected void configure() {
         bind(Integer.class).toInstance(3);
       }
     }
@@ -812,19 +917,23 @@
       Guice.createInjector(new SubClassModule());
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Overriding @Provides methods is not allowed.",
           "@Provides method: " + GenericSuperModule.class.getName() + ".provide()",
           "overridden by: " + SubClassModule.class.getName() + ".provide()");
     }
   }
 
-  class RestrictedSuper extends AbstractModule {
-    @Provides public String provideFoo() { return "foo"; }
-    @Override protected void configure() {}
+  static class RestrictedSuper extends AbstractModule {
+    @Provides
+    public String provideFoo() {
+      return "foo";
+    }
+
   }
 
-  public class ExposedSub extends RestrictedSuper {}
+  public static class ExposedSub extends RestrictedSuper {}
 
   public void testOverrideProviderMethod_increasedVisibility() {
     // ensure we don't detect the synthetic provideFoo method in ExposedSub as an override (it is,
@@ -837,11 +946,15 @@
   }
 
   static class ModuleImpl extends AbstractModule implements ProviderInterface<String> {
-    @Override protected void configure() {}
-    @Provides public String getT() {
+
+    @Override
+    @Provides
+    public String getT() {
       return "string";
     }
-    @Provides public Object getObject() {
+
+    @Provides
+    public Object getObject() {
       return new Object();
     }
     /* javac will synthesize a bridge method for getT with the types erased, equivalent to:
@@ -853,29 +966,53 @@
     Guice.createInjector(new ModuleImpl());
   }
 
+  public void testScopedProviderMethodThrowsException() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+
+              @Provides
+              @Singleton
+              int provideInt() {
+                throw new RuntimeException("boom");
+              }
+            });
+    Provider<Integer> intProvider = injector.getProvider(Integer.class);
+    try {
+      intProvider.get();
+      fail();
+    } catch (ProvisionException pe) {
+      // by default assertContains asserts that the last item doesn't repeat... which is the main
+      // thing we are testing for
+      assertContains(pe.getMessage(), "java.lang.RuntimeException: boom", "provideInt");
+    }
+  }
+
   public void testNullability() throws Exception {
-    Module module = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toProvider(Providers.<String>of(null));
-      }
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toProvider(Providers.<String>of(null));
+          }
 
-      @SuppressWarnings("unused")
-      @Provides
-      Integer fail(String foo) {
-        return 1;
-      }
+          @SuppressWarnings("unused")
+          @Provides
+          Integer fail(String foo) {
+            return 1;
+          }
 
-      @SuppressWarnings("unused")
-      @Provides
-      Long succeed(@Nullable String foo) {
-        return 2L;
-      }
-    };
+          @SuppressWarnings("unused")
+          @Provides
+          Long succeed(@Nullable String foo) {
+            return 2L;
+          }
+        };
     Injector injector = Guice.createInjector(module);
-    InjectionPoint fooPoint = InjectionPoint.forMethod(
-        module.getClass().getDeclaredMethod("fail", String.class),
-        TypeLiteral.get(module.getClass()));
+    InjectionPoint fooPoint =
+        InjectionPoint.forMethod(
+            module.getClass().getDeclaredMethod("fail", String.class),
+            TypeLiteral.get(module.getClass()));
     Dependency<?> fooDependency = Iterables.getOnlyElement(fooPoint.getDependencies());
 
     runNullableTest(injector, fooDependency, module);
@@ -883,6 +1020,33 @@
     injector.getInstance(Long.class);
   }
 
+  public void testModuleBindings() throws Exception {
+    Module module =
+        new AbstractModule() {
+
+          @Provides
+          Integer fail() {
+            return 1;
+          }
+        };
+    // sanity check that the injector works
+    Injector injector = Guice.createInjector(module);
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    ProviderInstanceBinding injectorBinding =
+        (ProviderInstanceBinding) injector.getBinding(Integer.class);
+    assertEquals(1, injectorBinding.getUserSuppliedProvider().get());
+
+    ProviderInstanceBinding moduleBinding =
+        (ProviderInstanceBinding) Iterables.getOnlyElement(Elements.getElements(module));
+    try {
+      moduleBinding.getUserSuppliedProvider().get();
+      fail();
+    } catch (IllegalStateException ise) {
+      assertEquals(
+          "This Provider cannot be used until the Injector has been created.", ise.getMessage());
+    }
+  }
+
   private void runNullableTest(Injector injector, Dependency<?> dependency, Module module) {
     switch (InternalFlags.getNullableProvidesOption()) {
       case ERROR:
@@ -902,11 +1066,13 @@
       injector.getInstance(Integer.class);
       fail();
     } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) null returned by binding at " + module.getClass().getName() + ".configure(",
-          "but parameter 0 of " + module.getClass().getName() + ".fail() is not @Nullable",
+          "but the 1st parameter of " + module.getClass().getName() + ".fail(",
+          "is not @Nullable",
           "while locating java.lang.String",
-          "for parameter 0 at " + module.getClass().getName() + ".fail(",
+          "for the 1st parameter of " + module.getClass().getName() + ".fail(",
           "while locating java.lang.Integer");
 
       assertEquals(1, expected.getErrorMessages().size());
@@ -919,29 +1085,29 @@
 
   private void validateNullableWarns(Injector injector, Dependency<?> dependency) {
     final List<LogRecord> logRecords = Lists.newArrayList();
-    final Handler fakeHandler = new Handler() {
-      @Override
-      public void publish(LogRecord logRecord) {
-        logRecords.add(logRecord);
-      }
-      @Override
-      public void flush() {}
-      @Override
-      public void close() throws SecurityException {}
-    };
+    final Handler fakeHandler =
+        new Handler() {
+          @Override
+          public void publish(LogRecord logRecord) {
+            logRecords.add(logRecord);
+          }
+
+          @Override
+          public void flush() {}
+
+          @Override
+          public void close() throws SecurityException {}
+        };
     Logger.getLogger(Guice.class.getName()).addHandler(fakeHandler);
     try {
       injector.getInstance(Integer.class); // no exception, but assert it does log.
       LogRecord record = Iterables.getOnlyElement(logRecords);
       assertEquals(
-          "Guice injected null into parameter {0} of {1} (a {2}), please mark it @Nullable."
+          "Guice injected null into {0} (a {1}), please mark it @Nullable."
               + " Use -Dguice_check_nullable_provides_params=ERROR to turn this into an"
               + " error.",
           record.getMessage());
-      assertEquals(dependency.getParameterIndex(), record.getParameters()[0]);
-      assertEquals(Errors.convert(dependency.getInjectionPoint().getMember()),
-          record.getParameters()[1]);
-      assertEquals(Errors.convert(dependency.getKey()), record.getParameters()[2]);
+      assertEquals(Errors.convert(dependency.getKey()), record.getParameters()[1]);
     } finally {
       Logger.getLogger(Guice.class.getName()).removeHandler(fakeHandler);
     }
diff --git a/core/test/com/google/inject/spi/SpiBindingsTest.java b/core/test/com/google/inject/spi/SpiBindingsTest.java
index 82e969e..28d044e 100644
--- a/core/test/com/google/inject/spi/SpiBindingsTest.java
+++ b/core/test/com/google/inject/spi/SpiBindingsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,10 +35,6 @@
 import com.google.inject.Singleton;
 import com.google.inject.Stage;
 import com.google.inject.name.Names;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
 import java.lang.reflect.Constructor;
 import java.util.Collections;
 import java.util.Comparator;
@@ -46,58 +42,62 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class SpiBindingsTest extends TestCase {
 
   public void testBindConstant() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindConstant().annotatedWith(Names.named("one")).to(1);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof InstanceBinding);
             assertEquals(Key.get(Integer.class, Names.named("one")), binding.getKey());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testToInstanceBinding() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toInstance("A");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof InstanceBinding);
             checkBindingSource(binding);
             assertEquals(Key.get(String.class), binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(InstanceBinding<? extends T> binding) {
-                assertEquals("A", binding.getInstance());
-                return null;
-              }
-            });
-            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              public Void visitEagerSingleton() {
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(InstanceBinding<? extends T> binding) {
+                    assertEquals("A", binding.getInstance());
+                    return null;
+                  }
+                });
+            binding.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitEagerSingleton() {
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testToProviderBinding() {
@@ -105,52 +105,55 @@
 
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toProvider(stringProvider);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof ProviderInstanceBinding);
             checkBindingSource(binding);
             assertEquals(Key.get(String.class), binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(
-                  ProviderInstanceBinding<? extends T> binding) {
-                assertSame(stringProvider, binding.getUserSuppliedProvider());
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderInstanceBinding<? extends T> binding) {
+                    assertSame(stringProvider, binding.getUserSuppliedProvider());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testToProviderKeyBinding() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(String.class).toProvider(StringProvider.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof ProviderKeyBinding);
             checkBindingSource(binding);
             assertEquals(Key.get(String.class), binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
-                assertEquals(Key.get(StringProvider.class), binding.getProviderKey());
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ProviderKeyBinding<? extends T> binding) {
+                    assertEquals(Key.get(StringProvider.class), binding.getProviderKey());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testToKeyBinding() {
@@ -159,225 +162,262 @@
 
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(aKey).to(bKey);
             bind(bKey).toInstance("B");
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof LinkedKeyBinding);
             checkBindingSource(binding);
             assertEquals(aKey, binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
-                assertEquals(bKey, binding.getLinkedKey());
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(LinkedKeyBinding<? extends T> binding) {
+                    assertEquals(bKey, binding.getLinkedKey());
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertEquals(bKey, binding.getKey());
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testToConstructorBinding() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bind(D.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof ConstructorBinding);
             checkBindingSource(binding);
             assertEquals(Key.get(D.class), binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ConstructorBinding<? extends T> binding) {
-                Constructor<?> expected = D.class.getDeclaredConstructors()[0];
-                assertEquals(expected, binding.getConstructor().getMember());
-                assertEquals(ImmutableSet.<InjectionPoint>of(), binding.getInjectableMembers());
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(ConstructorBinding<? extends T> binding) {
+                    Constructor<?> expected = D.class.getDeclaredConstructors()[0];
+                    assertEquals(expected, binding.getConstructor().getMember());
+                    assertEquals(ImmutableSet.<InjectionPoint>of(), binding.getInjectableMembers());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testConstantBinding() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
             bindConstant().annotatedWith(Names.named("one")).to(1);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
+          @Override
+          public <T> Void visit(Binding<T> binding) {
             assertTrue(binding instanceof InstanceBinding);
             checkBindingSource(binding);
             assertEquals(Key.get(Integer.class, Names.named("one")), binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(InstanceBinding<? extends T> binding) {
-                assertEquals(1, binding.getInstance());
-                return null;
-              }
-            });
+            binding.acceptTargetVisitor(
+                new FailingTargetVisitor<T>() {
+                  @Override
+                  public Void visit(InstanceBinding<? extends T> binding) {
+                    assertEquals(1, binding.getInstance());
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
+        });
   }
 
   public void testConvertedConstantBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bindConstant().annotatedWith(Names.named("one")).to("1");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindConstant().annotatedWith(Names.named("one")).to("1");
+              }
+            });
 
     Binding<Integer> binding = injector.getBinding(Key.get(Integer.class, Names.named("one")));
     assertEquals(Key.get(Integer.class, Names.named("one")), binding.getKey());
     checkBindingSource(binding);
     assertTrue(binding instanceof ConvertedConstantBinding);
-    binding.acceptTargetVisitor(new FailingTargetVisitor<Integer>() {
-      @Override public Void visit(
-          ConvertedConstantBinding<? extends Integer> binding) {
-        assertEquals((Integer) 1, binding.getValue());
-        assertEquals(Key.get(String.class, Names.named("one")), binding.getSourceKey());
-        return null;
-      }
-    });
+    binding.acceptTargetVisitor(
+        new FailingTargetVisitor<Integer>() {
+          @Override
+          public Void visit(ConvertedConstantBinding<? extends Integer> binding) {
+            assertEquals((Integer) 1, binding.getValue());
+            assertEquals(Key.get(String.class, Names.named("one")), binding.getSourceKey());
+            return null;
+          }
+        });
   }
 
   public void testProviderBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("A");
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("A");
+              }
+            });
 
     Key<Provider<String>> providerOfStringKey = new Key<Provider<String>>() {};
     Binding<Provider<String>> binding = injector.getBinding(providerOfStringKey);
     assertEquals(providerOfStringKey, binding.getKey());
     checkBindingSource(binding);
     assertTrue(binding instanceof ProviderBinding);
-    binding.acceptTargetVisitor(new FailingTargetVisitor<Provider<String>>() {
-      @Override public Void visit(
-          ProviderBinding<? extends Provider<String>> binding) {
-        assertEquals(Key.get(String.class), binding.getProvidedKey());
-        return null;
-      }
-    });
+    binding.acceptTargetVisitor(
+        new FailingTargetVisitor<Provider<String>>() {
+          @Override
+          public Void visit(ProviderBinding<? extends Provider<String>> binding) {
+            assertEquals(Key.get(String.class), binding.getProvidedKey());
+            return null;
+          }
+        });
   }
 
   public void testScopes() {
     checkInjector(
         new AbstractModule() {
+          @Override
           protected void configure() {
-            bind(String.class).annotatedWith(Names.named("a"))
-                .toProvider(StringProvider.class).in(Singleton.class);
-            bind(String.class).annotatedWith(Names.named("b"))
-                .toProvider(StringProvider.class).in(Scopes.SINGLETON);
-            bind(String.class).annotatedWith(Names.named("c"))
-                .toProvider(StringProvider.class).asEagerSingleton();
-            bind(String.class).annotatedWith(Names.named("d"))
-                .toProvider(StringProvider.class);
+            bind(String.class)
+                .annotatedWith(Names.named("a"))
+                .toProvider(StringProvider.class)
+                .in(Singleton.class);
+            bind(String.class)
+                .annotatedWith(Names.named("b"))
+                .toProvider(StringProvider.class)
+                .in(Scopes.SINGLETON);
+            bind(String.class)
+                .annotatedWith(Names.named("c"))
+                .toProvider(StringProvider.class)
+                .asEagerSingleton();
+            bind(String.class).annotatedWith(Names.named("d")).toProvider(StringProvider.class);
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(String.class, Names.named("a")), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitScope(Scope scope) {
-                // even though we bound with an annotation, the injector always uses instances
-                assertSame(Scopes.SINGLETON, scope);
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitScope(Scope scope) {
+                    // even though we bound with an annotation, the injector always uses instances
+                    assertSame(Scopes.SINGLETON, scope);
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(String.class, Names.named("b")), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitScope(Scope scope) {
-                assertSame(Scopes.SINGLETON, scope);
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitScope(Scope scope) {
+                    assertSame(Scopes.SINGLETON, scope);
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(String.class, Names.named("c")), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitEagerSingleton() {
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitEagerSingleton() {
+                    return null;
+                  }
+                });
             return null;
           }
         },
-
         new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> command) {
+          @Override
+          public <T> Void visit(Binding<T> command) {
             assertEquals(Key.get(String.class, Names.named("d")), command.getKey());
-            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
-              @Override public Void visitNoScoping() {
-                return null;
-              }
-            });
+            command.acceptScopingVisitor(
+                new FailingBindingScopingVisitor() {
+                  @Override
+                  public Void visitNoScoping() {
+                    return null;
+                  }
+                });
             return null;
           }
-        }
-    );
-  }
-  
-  public void testExtensionSpi() {
-    final AtomicBoolean visiting = new AtomicBoolean(false);
-    
-    final Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toProvider(new ProviderWithExtensionVisitor<String>() {
-          public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
-              ProviderInstanceBinding<? extends B> binding) {
-            assertSame(this, binding.getUserSuppliedProvider());
-            // We can't always check for FailingSpiTargetVisitor,
-            // because constructing the injector visits here, and we need
-            // to process the binding as normal
-            if(visiting.get()) {
-              assertTrue("visitor: " + visitor, visitor instanceof FailingSpiTargetVisitor);
-              return (V)"visited";
-            } else {
-              return visitor.visit(binding);
-            }
-          }
-          
-          public String get() {
-            return "FooBar";
-          }
         });
-      }
-    });
-    
+  }
+
+  public void testExtensionSpi() {
+    final AtomicBoolean visiting = new AtomicBoolean(false);
+
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class)
+                    .toProvider(
+                        new ProviderWithExtensionVisitor<String>() {
+                          @Override
+                          public <B, V> V acceptExtensionVisitor(
+                              BindingTargetVisitor<B, V> visitor,
+                              ProviderInstanceBinding<? extends B> binding) {
+                            assertSame(this, binding.getUserSuppliedProvider());
+                            // We can't always check for FailingSpiTargetVisitor,
+                            // because constructing the injector visits here, and we need
+                            // to process the binding as normal
+                            if (visiting.get()) {
+                              assertTrue(
+                                  "visitor: " + visitor,
+                                  visitor instanceof FailingSpiTargetVisitor);
+                              return (V) "visited";
+                            } else {
+                              return visitor.visit(binding);
+                            }
+                          }
+
+                          @Override
+                          public String get() {
+                            return "FooBar";
+                          }
+                        });
+              }
+            });
+
     visiting.set(true);
 
     // Check for Provider<String> binding -- that is still a ProviderBinding.
@@ -386,13 +426,15 @@
     assertEquals(providerOfStringKey, providerBinding.getKey());
     checkBindingSource(providerBinding);
     assertTrue("binding: " + providerBinding, providerBinding instanceof ProviderBinding);
-    providerBinding.acceptTargetVisitor(new FailingTargetVisitor<Provider<String>>() {
-      @Override public Void visit(ProviderBinding<? extends Provider<String>> binding) {
-        assertEquals(Key.get(String.class), binding.getProvidedKey());
-        return null;
-      }
-    });
-    
+    providerBinding.acceptTargetVisitor(
+        new FailingTargetVisitor<Provider<String>>() {
+          @Override
+          public Void visit(ProviderBinding<? extends Provider<String>> binding) {
+            assertEquals(Key.get(String.class), binding.getProvidedKey());
+            return null;
+          }
+        });
+
     // Check for String binding -- that one is ProviderInstanceBinding, and gets hooked
     Binding<String> binding = injector.getBinding(String.class);
     assertEquals(Key.get(String.class), binding.getKey());
@@ -418,7 +460,7 @@
       assertEquals(0, source.getStackTrace().length);
     }
   }
-  
+
   public void checkInjector(Module module, ElementVisitor<?>... visitors) {
     Injector injector = Guice.createInjector(module);
 
@@ -440,24 +482,28 @@
     }
   }
 
-  private final ImmutableSet<Key<?>> BUILT_IN_BINDINGS = ImmutableSet.of(
-      Key.get(Injector.class), Key.get(Stage.class), Key.get(Logger.class));
+  private final ImmutableSet<Key<?>> BUILT_IN_BINDINGS =
+      ImmutableSet.of(Key.get(Injector.class), Key.get(Stage.class), Key.get(Logger.class));
 
-  private final Comparator<Binding<?>> orderByKey = new Comparator<Binding<?>>() {
-    public int compare(Binding<?> a, Binding<?> b) {
-      return a.getKey().toString().compareTo(b.getKey().toString());
-    }
-  };
+  private final Comparator<Binding<?>> orderByKey =
+      new Comparator<Binding<?>>() {
+        @Override
+        public int compare(Binding<?> a, Binding<?> b) {
+          return a.getKey().toString().compareTo(b.getKey().toString());
+        }
+      };
 
   private static class StringProvider implements Provider<String> {
+    @Override
     public String get() {
       return "A";
     }
   }
 
-  private static class C { }
+  private static class C {}
 
   private static class D extends C {
-    @Inject public D(Injector unused) { }
+    @Inject
+    public D(Injector unused) {}
   }
 }
diff --git a/core/test/com/google/inject/spi/ToolStageInjectorTest.java b/core/test/com/google/inject/spi/ToolStageInjectorTest.java
index 7f63f1c..52922e0 100644
--- a/core/test/com/google/inject/spi/ToolStageInjectorTest.java
+++ b/core/test/com/google/inject/spi/ToolStageInjectorTest.java
@@ -9,14 +9,11 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.Stage;
-import com.google.inject.spi.Toolable;
-
-import junit.framework.TestCase;
-
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.TestCase;
 
 public class ToolStageInjectorTest extends TestCase {
 
@@ -58,108 +55,157 @@
     } catch (UnsupportedOperationException expected) {
     }
   }
-  
+
   public void testToolStageDoesntInjectInstances() {
     final Foo foo = new Foo();
-    Guice.createInjector(Stage.TOOL, new AbstractModule() {
-      @Override
-      protected void configure() {
-        requestStaticInjection(Foo.class);
-        requestInjection(foo);
-      }
-    });
+    Guice.createInjector(
+        Stage.TOOL,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestStaticInjection(Foo.class);
+            requestInjection(foo);
+          }
+        });
     assertNull(Foo.s);
     assertNull(Foo.sm);
     assertNull(foo.f);
     assertNull(foo.m);
   }
-  
+
   public void testToolStageDoesntInjectProviders() {
     final Foo foo = new Foo();
-    Guice.createInjector(Stage.TOOL, new AbstractModule() {
-      @Override
-      protected void configure() {
-        requestStaticInjection(Foo.class);
-        bind(Object.class).toProvider(foo);
-      }
-    });
+    Guice.createInjector(
+        Stage.TOOL,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestStaticInjection(Foo.class);
+            bind(Object.class).toProvider(foo);
+          }
+        });
     assertNull(Foo.s);
     assertNull(Foo.sm);
     assertNull(foo.f);
     assertNull(foo.m);
   }
-  
+
   public void testToolStageWarnsOfMissingObjectGraph() {
     final Bar bar = new Bar();
     try {
-      Guice.createInjector(Stage.TOOL, new AbstractModule() {
-        @Override
-        protected void configure() {
-          requestStaticInjection(Bar.class);
-          requestInjection(bar);
-        }
-      });
+      Guice.createInjector(
+          Stage.TOOL,
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              requestStaticInjection(Bar.class);
+              requestInjection(bar);
+            }
+          });
       fail("expected exception");
-    } catch(CreationException expected) {
-      Asserts.assertContains(expected.toString(), "No implementation for java.util.Collection was bound.",
+    } catch (CreationException expected) {
+      Asserts.assertContains(
+          expected.toString(),
+          "No implementation for java.util.Collection was bound.",
           "No implementation for java.util.Map was bound.",
           "No implementation for java.util.List was bound.",
           "No implementation for java.util.Set was bound.");
     }
   }
-  
+
   public void testToolStageInjectsTooledMethods() {
     final Tooled tooled = new Tooled();
-    Guice.createInjector(Stage.TOOL, new AbstractModule() {
-      @Override
-      protected void configure() {
-        requestStaticInjection(Tooled.class);
-        bind(Object.class).toProvider(tooled);
-      }
-    });
+    Guice.createInjector(
+        Stage.TOOL,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            requestStaticInjection(Tooled.class);
+            bind(Object.class).toProvider(tooled);
+          }
+        });
     assertNull(Tooled.s);
     assertNotNull(Tooled.sm);
     assertNull(tooled.f);
     assertNotNull(tooled.m);
   }
-  
+
   @SuppressWarnings("unchecked")
   private static class Bar {
-    @SuppressWarnings("unused") @Inject private static List list;
-    @SuppressWarnings("unused") @Inject private Set set;
-    @SuppressWarnings("unused") @Inject void method(Collection c) {}
-    @SuppressWarnings("unused") @Inject static void staticMethod(Map map) {}
-  }
-  
-  private static class Foo implements Provider<Object> {
-    @Inject private static S s; 
-    @Inject private F f;
-    private M m;
-    @SuppressWarnings("unused") @Inject void method(M m) { this.m = m; }
-    private static SM sm;
-    @SuppressWarnings("unused") @Inject static void staticMethod(SM sm) { Tooled.sm = sm; }
-    
-    public Object get() {
-      return null;
-    }
-  }
-  
-  private static class Tooled implements Provider<Object> {
-    @Inject private static S s; 
-    @Inject private F f;
-    private M m;
-    @Toolable @SuppressWarnings("unused") @Inject void method(M m) { this.m = m; }
-    private static SM sm;
-    @Toolable @SuppressWarnings("unused") @Inject static void staticMethod(SM sm) { Tooled.sm = sm; }
-    
-    public Object get() {
-      return null;
-    }
-  }
-    
-  private static class S {}
-  private static class F {}
-  private static class M {}
-  private static class SM {}
+    @SuppressWarnings("unused")
+    @Inject
+    private static List list;
 
+    @SuppressWarnings("unused")
+    @Inject
+    private Set set;
+
+    @SuppressWarnings("unused")
+    @Inject
+    void method(Collection c) {}
+
+    @SuppressWarnings("unused")
+    @Inject
+    static void staticMethod(Map map) {}
+  }
+
+  private static class Foo implements Provider<Object> {
+    @Inject private static S s;
+    @Inject private F f;
+    private M m;
+
+    @SuppressWarnings("unused")
+    @Inject
+    void method(M m) {
+      this.m = m;
+    }
+
+    private static SM sm;
+
+    @SuppressWarnings("unused")
+    @Inject
+    static void staticMethod(SM sm) {
+      Tooled.sm = sm;
+    }
+
+    @Override
+    public Object get() {
+      return null;
+    }
+  }
+
+  private static class Tooled implements Provider<Object> {
+    @Inject private static S s;
+    @Inject private F f;
+    private M m;
+
+    @Toolable
+    @SuppressWarnings("unused")
+    @Inject
+    void method(M m) {
+      this.m = m;
+    }
+
+    private static SM sm;
+
+    @Toolable
+    @SuppressWarnings("unused")
+    @Inject
+    static void staticMethod(SM sm) {
+      Tooled.sm = sm;
+    }
+
+    @Override
+    public Object get() {
+      return null;
+    }
+  }
+
+  private static class S {}
+
+  private static class F {}
+
+  private static class M {}
+
+  private static class SM {}
 }
diff --git a/core/test/com/google/inject/util/NoopOverrideTest.java b/core/test/com/google/inject/util/NoopOverrideTest.java
index 9f65bf4..9f2063b 100644
--- a/core/test/com/google/inject/util/NoopOverrideTest.java
+++ b/core/test/com/google/inject/util/NoopOverrideTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +20,12 @@
 import com.google.inject.spi.ElementVisitor;
 import com.google.inject.spi.ElementsTest;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class NoopOverrideTest extends ElementsTest {
 
+  @Override
   protected void checkModule(Module module, ElementVisitor<?>... visitors) {
     Module overridden = Modules.override(module).with(Modules.EMPTY_MODULE);
     super.checkModule(overridden, visitors);
   }
-}
\ No newline at end of file
+}
diff --git a/core/test/com/google/inject/util/OverrideModuleTest.java b/core/test/com/google/inject/util/OverrideModuleTest.java
index 16d7a2c..0792c7f 100644
--- a/core/test/com/google/inject/util/OverrideModuleTest.java
+++ b/core/test/com/google/inject/util/OverrideModuleTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -45,9 +45,6 @@
 import com.google.inject.name.Names;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.ModuleAnnotatedMethodScanner;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -55,18 +52,19 @@
 import java.util.Date;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
 
-/**
- * @author sberlin@gmail.com (Sam Berlin)
- */
+/** @author sberlin@gmail.com (Sam Berlin) */
 public class OverrideModuleTest extends TestCase {
 
   private static final Key<String> key2 = Key.get(String.class, named("2"));
   private static final Key<String> key3 = Key.get(String.class, named("3"));
 
-  private static final Module EMPTY_MODULE = new Module() {
-    public void configure(Binder binder) {}
-  };
+  private static final Module EMPTY_MODULE =
+      new Module() {
+        @Override
+        public void configure(Binder binder) {}
+      };
 
   public void testOverride() {
     Injector injector = createInjector(Modules.override(newModule("A")).with(newModule("B")));
@@ -74,13 +72,14 @@
   }
 
   public void testOverrideMultiple() {
-    Module module = Modules.override(newModule("A"), newModule(1), newModule(0.5f))
-        .with(newModule("B"), newModule(2), newModule(1.5d));
+    Module module =
+        Modules.override(newModule("A"), newModule(1), newModule(0.5f))
+            .with(newModule("B"), newModule(2), newModule(1.5d));
     Injector injector = createInjector(module);
     assertEquals("B", injector.getInstance(String.class));
     assertEquals(2, injector.getInstance(Integer.class).intValue());
-    assertEquals(0.5f, injector.getInstance(Float.class));
-    assertEquals(1.5d, injector.getInstance(Double.class));
+    assertEquals(0.5f, injector.getInstance(Float.class), 0.0f);
+    assertEquals(1.5d, injector.getInstance(Double.class), 0.0);
   }
 
   public void testOverrideUnmatchedTolerated() {
@@ -89,29 +88,35 @@
   }
 
   public void testOverrideConstant() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(named("Test")).to("A");
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(named("Test")).to("A");
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bindConstant().annotatedWith(named("Test")).to("B");
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindConstant().annotatedWith(named("Test")).to("B");
+          }
+        };
 
     Injector injector = createInjector(Modules.override(original).with(replacements));
     assertEquals("B", injector.getInstance(Key.get(String.class, named("Test"))));
   }
 
   public void testGetProviderInModule() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("A");
-        bind(key2).toProvider(getProvider(String.class));
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("A");
+            bind(key2).toProvider(getProvider(String.class));
+          }
+        };
 
     Injector injector = createInjector(Modules.override(original).with(EMPTY_MODULE));
     assertEquals("A", injector.getInstance(String.class));
@@ -119,12 +124,14 @@
   }
 
   public void testOverrideWhatGetProviderProvided() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("A");
-        bind(key2).toProvider(getProvider(String.class));
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("A");
+            bind(key2).toProvider(getProvider(String.class));
+          }
+        };
 
     Module replacements = newModule("B");
 
@@ -134,18 +141,22 @@
   }
 
   public void testOverrideUsingOriginalsGetProvider() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("A");
-        bind(key2).toInstance("B");
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("A");
+            bind(key2).toInstance("B");
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toProvider(getProvider(key2));
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toProvider(getProvider(key2));
+          }
+        };
 
     Injector injector = createInjector(Modules.override(original).with(replacements));
     assertEquals("B", injector.getInstance(String.class));
@@ -153,29 +164,35 @@
   }
 
   public void testOverrideOfOverride() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("A1");
-        bind(key2).toInstance("A2");
-        bind(key3).toInstance("A3");
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("A1");
+            bind(key2).toInstance("A2");
+            bind(key3).toInstance("A3");
+          }
+        };
 
-    Module replacements1 = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("B1");
-        bind(key2).toInstance("B2");
-      }
-    };
+    Module replacements1 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("B1");
+            bind(key2).toInstance("B2");
+          }
+        };
 
     Module overrides = Modules.override(original).with(replacements1);
 
-    Module replacements2 = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("C1");
-        bind(key3).toInstance("C3");
-      }
-    };
+    Module replacements2 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("C1");
+            bind(key3).toInstance("C3");
+          }
+        };
 
     Injector injector = createInjector(Modules.override(overrides).with(replacements2));
     assertEquals("C1", injector.getInstance(String.class));
@@ -184,16 +201,20 @@
   }
 
   static class OuterReplacementsModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       install(new InnerReplacementsModule());
     }
   }
+
   static class InnerReplacementsModule extends AbstractModule {
-    @Override protected void configure() {
+    @Override
+    protected void configure() {
       bind(String.class).toInstance("B");
       bind(String.class).toInstance("C");
     }
   }
+
   public void testOverridesTwiceFails() {
     Module original = newModule("A");
     Module replacements = new OuterReplacementsModule();
@@ -202,30 +223,39 @@
       createInjector(module);
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "A binding to java.lang.String was already configured at "
               + InnerReplacementsModule.class.getName(),
-          asModuleChain(Modules.OverrideModule.class,
-              OuterReplacementsModule.class, InnerReplacementsModule.class),
+          asModuleChain(
+              Modules.OverrideModule.class,
+              OuterReplacementsModule.class,
+              InnerReplacementsModule.class),
           "at " + InnerReplacementsModule.class.getName(),
-          asModuleChain(Modules.OverrideModule.class,
-              OuterReplacementsModule.class, InnerReplacementsModule.class));
+          asModuleChain(
+              Modules.OverrideModule.class,
+              OuterReplacementsModule.class,
+              InnerReplacementsModule.class));
     }
   }
 
   public void testOverridesDoesntFixTwiceBoundInOriginal() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("A");
-        bind(String.class).toInstance("B");
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("A");
+            bind(String.class).toInstance("B");
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).toInstance("C");
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(String.class).toInstance("C");
+          }
+        };
 
     Module module = Modules.override(original).with(replacements);
     try {
@@ -234,7 +264,8 @@
     } catch (CreationException expected) {
       // The replacement comes first because we replace A with C,
       // then we encounter B and freak out.
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) A binding to java.lang.String was already configured at "
               + replacements.getClass().getName(),
           asModuleChain(Modules.OverrideModule.class, replacements.getClass()),
@@ -246,12 +277,14 @@
   public void testStandardScopeAnnotation() {
     final SingleUseScope scope = new SingleUseScope();
 
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(TestScopeAnnotation.class, scope);
-        bind(String.class).in(TestScopeAnnotation.class);
-      }
-    };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(TestScopeAnnotation.class, scope);
+            bind(String.class).in(TestScopeAnnotation.class);
+          }
+        };
     assertFalse(scope.used);
 
     Guice.createInjector(module);
@@ -259,43 +292,53 @@
   }
 
   public void testOverrideUntargettedBinding() {
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Date.class);
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Date.class);
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Date.class).toInstance(new Date(0));
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Date.class).toInstance(new Date(0));
+          }
+        };
 
     Injector injector = createInjector(Modules.override(original).with(replacements));
     assertEquals(0, injector.getInstance(Date.class).getTime());
   }
 
   public void testOverrideScopeAnnotation() {
-    final Scope scope = new Scope() {
-      public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
-        throw new AssertionError("Should not be called");
-      }
-    };
+    final Scope scope =
+        new Scope() {
+          @Override
+          public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
+            throw new AssertionError("Should not be called");
+          }
+        };
 
     final SingleUseScope replacementScope = new SingleUseScope();
 
-    Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(TestScopeAnnotation.class, scope);
-        bind(Date.class).in(TestScopeAnnotation.class);
-      }
-    };
+    Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(TestScopeAnnotation.class, scope);
+            bind(Date.class).in(TestScopeAnnotation.class);
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(TestScopeAnnotation.class, replacementScope);
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(TestScopeAnnotation.class, replacementScope);
+          }
+        };
 
     Injector injector = createInjector(Modules.override(original).with(replacements));
     injector.getInstance(Date.class);
@@ -303,63 +346,80 @@
   }
 
   public void testFailsIfOverridenScopeInstanceHasBeenUsed() {
-    final Scope scope = new Scope() {
-      public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
-        return unscoped;
-      }
+    final Scope scope =
+        new Scope() {
+          @Override
+          public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
+            return unscoped;
+          }
 
-      @Override public String toString() {
-        return "ORIGINAL SCOPE";
-      }
-    };
+          @Override
+          public String toString() {
+            return "ORIGINAL SCOPE";
+          }
+        };
 
-    final Module original = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(TestScopeAnnotation.class, scope);
-        bind(Date.class).in(scope);
-        bind(String.class).in(scope);
-      }
-    };
-    Module originalWrapper = new AbstractModule() {
-      @Override protected void configure() {
-        install(original);
-      }
-    };
+    final Module original =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(TestScopeAnnotation.class, scope);
+            bind(Date.class).in(scope);
+            bind(String.class).in(scope);
+          }
+        };
+    Module originalWrapper =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(original);
+          }
+        };
 
-    Module replacements = new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(TestScopeAnnotation.class, new SingleUseScope());
-      }
-    };
+    Module replacements =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bindScope(TestScopeAnnotation.class, new SingleUseScope());
+          }
+        };
 
     try {
       createInjector(Modules.override(originalWrapper).with(replacements));
       fail("Exception expected");
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "1) The scope for @TestScopeAnnotation is bound directly and cannot be overridden.",
           "original binding at " + original.getClass().getName() + ".configure(",
           asModuleChain(originalWrapper.getClass(), original.getClass()),
           "bound directly at " + original.getClass().getName() + ".configure(",
           asModuleChain(originalWrapper.getClass(), original.getClass()),
           "bound directly at " + original.getClass().getName() + ".configure(",
-          asModuleChain(originalWrapper.getClass(), original.getClass()),          
-          "at ", replacements.getClass().getName() + ".configure(",
+          asModuleChain(originalWrapper.getClass(), original.getClass()),
+          "at ",
+          replacements.getClass().getName() + ".configure(",
           asModuleChain(Modules.OverrideModule.class, replacements.getClass()));
     }
   }
 
   public void testOverrideIsLazy() {
-    final AtomicReference<String> value = new AtomicReference<String>("A");
-    Module overridden = Modules.override(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).annotatedWith(named("original")).toInstance(value.get());
-      }
-    }).with(new AbstractModule() {
-      @Override protected void configure() {
-        bind(String.class).annotatedWith(named("override")).toInstance(value.get());
-      }
-    });
+    final AtomicReference<String> value = new AtomicReference<>("A");
+    Module overridden =
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class).annotatedWith(named("original")).toInstance(value.get());
+                  }
+                })
+            .with(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class).annotatedWith(named("override")).toInstance(value.get());
+                  }
+                });
 
     // the value.get() call should be deferred until Guice.createInjector
     value.set("B");
@@ -369,46 +429,58 @@
   }
 
   public void testOverridePrivateModuleOverPrivateModule() {
-    Module exposes5and6 = new AbstractModule() {
-      @Override protected void configure() {
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(5);
-            expose(Integer.class);
+    Module exposes5and6 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Integer.class).toInstance(5);
+                    expose(Integer.class);
 
-            bind(Character.class).toInstance('E');
+                    bind(Character.class).toInstance('E');
+                  }
+                });
+
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Long.class).toInstance(6L);
+                    expose(Long.class);
+
+                    bind(Character.class).toInstance('F');
+                  }
+                });
           }
-        });
+        };
 
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(Long.class).toInstance(6L);
-            expose(Long.class);
+    AbstractModule exposes15 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Integer.class).toInstance(15);
+                    expose(Integer.class);
 
-            bind(Character.class).toInstance('F');
+                    bind(Character.class).toInstance('G');
+                  }
+                });
+
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Character.class).toInstance('H');
+                  }
+                });
           }
-        });
-      }
-    };
-
-    AbstractModule exposes15 = new AbstractModule() {
-      @Override protected void configure() {
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(15);
-            expose(Integer.class);
-
-            bind(Character.class).toInstance('G');
-          }
-        });
-
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(Character.class).toInstance('H');
-          }
-        });
-      }
-    };
+        };
 
     // override forwards
     Injector injector = Guice.createInjector(Modules.override(exposes5and6).with(exposes15));
@@ -422,18 +494,22 @@
   }
 
   public void testOverrideModuleAndPrivateModule() {
-    Module exposes5 = new PrivateModule() {
-      @Override protected void configure() {
-        bind(Integer.class).toInstance(5);
-        expose(Integer.class);
-      }
-    };
+    Module exposes5 =
+        new PrivateModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).toInstance(5);
+            expose(Integer.class);
+          }
+        };
 
-    Module binds15 = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Integer.class).toInstance(15);
-      }
-    };
+    Module binds15 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).toInstance(15);
+          }
+        };
 
     Injector injector = Guice.createInjector(Modules.override(exposes5).with(binds15));
     assertEquals(15, injector.getInstance(Integer.class).intValue());
@@ -443,22 +519,26 @@
   }
 
   public void testOverrideDeepExpose() {
-    final AtomicReference<Provider<Character>> charAProvider
-        = new AtomicReference<Provider<Character>>();
+    final AtomicReference<Provider<Character>> charAProvider =
+        new AtomicReference<Provider<Character>>();
 
-    Module exposes5 = new PrivateModule() {
-      @Override protected void configure() {
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            bind(Integer.class).toInstance(5);
+    Module exposes5 =
+        new PrivateModule() {
+          @Override
+          protected void configure() {
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Integer.class).toInstance(5);
+                    expose(Integer.class);
+                    charAProvider.set(getProvider(Character.class));
+                    bind(Character.class).toInstance('A');
+                  }
+                });
             expose(Integer.class);
-            charAProvider.set(getProvider(Character.class));
-            bind(Character.class).toInstance('A');
           }
-        });
-        expose(Integer.class);
-      }
-    };
+        };
 
     Injector injector = Guice.createInjector(Modules.override(exposes5).with(EMPTY_MODULE));
     assertEquals(5, injector.getInstance(Integer.class).intValue());
@@ -468,21 +548,25 @@
     assertEquals(5, injector.getInstance(Integer.class).intValue());
     assertEquals('A', charAProvider.getAndSet(null).get().charValue());
 
-    final AtomicReference<Provider<Character>> charBProvider
-        = new AtomicReference<Provider<Character>>();
+    final AtomicReference<Provider<Character>> charBProvider =
+        new AtomicReference<Provider<Character>>();
 
-    Module binds15 = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Integer.class).toInstance(15);
+    Module binds15 =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).toInstance(15);
 
-        install(new PrivateModule() {
-          @Override protected void configure() {
-            charBProvider.set(getProvider(Character.class));
-            bind(Character.class).toInstance('B');
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    charBProvider.set(getProvider(Character.class));
+                    bind(Character.class).toInstance('B');
+                  }
+                });
           }
-        });
-      }
-    };
+        };
 
     injector = Guice.createInjector(Modules.override(binds15).with(exposes5));
     assertEquals(5, injector.getInstance(Integer.class).intValue());
@@ -502,21 +586,26 @@
 
   private static class SingleUseScope implements Scope {
     boolean used = false;
+
+    @Override
     public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
       assertFalse(used);
       used = true;
       return unscoped;
     }
   }
-  
+
   static class NewModule<T> extends AbstractModule {
     private final T bound;
+
     NewModule(T bound) {
       this.bound = bound;
     }
-    @Override protected void configure() {
+
+    @Override
+    protected void configure() {
       @SuppressWarnings("unchecked")
-      Class<T> type = (Class<T>)bound.getClass();
+      Class<T> type = (Class<T>) bound.getClass();
       bind(type).toInstance(bound);
     }
   }
@@ -524,7 +613,7 @@
   private static <T> Module newModule(final T bound) {
     return new NewModule<T>(bound);
   }
-  
+
   private static final String RESULT = "RESULT";
   private static final String PRIVATE_INPUT = "PRIVATE_INPUT";
   private static final String OVERRIDDEN_INPUT = "FOO";
@@ -533,117 +622,138 @@
   private static final Key<String> INPUT_KEY = Key.get(String.class, named(PRIVATE_INPUT));
 
   public void testExposedBindingOverride() throws Exception {
-    Injector inj = Guice.createInjector(
-        Modules.override(new ExampleModule()).with(
-            new AbstractModule() {
-              @Override protected void configure() {
-                bind(RESULT_KEY).toInstance(OVERRIDDEN_RESULT);
-              }
-            }));
-    assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+    Injector inj =
+        Guice.createInjector(
+            Modules.override(new ExampleModule())
+                .with(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        bind(RESULT_KEY).toInstance(OVERRIDDEN_RESULT);
+                      }
+                    }));
+    assertEquals(OVERRIDDEN_RESULT, inj.getInstance(RESULT_KEY));
   }
 
   public void testPrivateBindingOverride() throws Exception {
-    Injector inj = Guice.createInjector(
-        Modules.override(new ExampleModule()).with(
-            new AbstractModule() {
-              @Override protected void configure() {
-                bind(INPUT_KEY).toInstance(OVERRIDDEN_INPUT);
-              }
-            }));
-    assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+    Injector inj =
+        Guice.createInjector(
+            Modules.override(new ExampleModule())
+                .with(
+                    new AbstractModule() {
+                      @Override
+                      protected void configure() {
+                        bind(INPUT_KEY).toInstance(OVERRIDDEN_INPUT);
+                      }
+                    }));
+    assertEquals(OVERRIDDEN_RESULT, inj.getInstance(RESULT_KEY));
   }
 
   public static class ExampleModule extends PrivateModule {
-    @Provides @Exposed @Named(RESULT)
+    @Provides
+    @Exposed
+    @Named(RESULT)
     public String provideResult(@Named(PRIVATE_INPUT) String input) {
       return "Size: " + input.length();
     }
 
-    @Provides @Named(PRIVATE_INPUT)
+    @Provides
+    @Named(PRIVATE_INPUT)
     public String provideInput() {
       return "Hello World";
     }
 
-    @Override protected void configure() {
-    }
-  }  
-  
+    @Override
+    protected void configure() {}
+  }
+
   public void testEqualsNotCalledByDefaultOnInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnEquals = true;
-    Guice.createInjector(Modules.override(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(HashEqualsTester.class).toInstance(a);
-      }
-    }).with());
+    Guice.createInjector(
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class);
+                    bind(HashEqualsTester.class).toInstance(a);
+                  }
+                })
+            .with());
   }
-  
+
   public void testEqualsNotCalledByDefaultOnProvider() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnEquals = true;
-    Guice.createInjector(Modules.override(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(Object.class).toProvider(a);
-      }
-    }).with());
+    Guice.createInjector(
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class);
+                    bind(Object.class).toProvider(a);
+                  }
+                })
+            .with());
   }
-  
+
   public void testHashcodeNeverCalledOnInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnHashcode = true;
     a.equality = "test";
-    
+
     final HashEqualsTester b = new HashEqualsTester();
     b.throwOnHashcode = true;
     b.equality = "test";
-    Guice.createInjector(Modules.override(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(HashEqualsTester.class).toInstance(a);
-       bind(HashEqualsTester.class).toInstance(b);
-      }
-    }).with());
+    Guice.createInjector(
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class);
+                    bind(HashEqualsTester.class).toInstance(a);
+                    bind(HashEqualsTester.class).toInstance(b);
+                  }
+                })
+            .with());
   }
-  
+
   public void testHashcodeNeverCalledOnProviderInstance() {
     final HashEqualsTester a = new HashEqualsTester();
     a.throwOnHashcode = true;
     a.equality = "test";
-    
+
     final HashEqualsTester b = new HashEqualsTester();
     b.throwOnHashcode = true;
     b.equality = "test";
-    Guice.createInjector(Modules.override(new AbstractModule() {
-      @Override
-      protected void configure() {
-       bind(String.class);
-       bind(Object.class).toProvider(a);
-       bind(Object.class).toProvider(b);
-      }
-    }).with());
+    Guice.createInjector(
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(String.class);
+                    bind(Object.class).toProvider(a);
+                    bind(Object.class).toProvider(b);
+                  }
+                })
+            .with());
   }
-  
+
   private static class HashEqualsTester implements Provider<Object> {
     private String equality;
     private boolean throwOnEquals;
     private boolean throwOnHashcode;
-    
+
     @Override
     public boolean equals(Object obj) {
       if (throwOnEquals) {
         throw new RuntimeException();
       } else if (obj instanceof HashEqualsTester) {
-        HashEqualsTester o = (HashEqualsTester)obj;
-        if(o.throwOnEquals) {
+        HashEqualsTester o = (HashEqualsTester) obj;
+        if (o.throwOnEquals) {
           throw new RuntimeException();
         }
-        if(equality == null && o.equality == null) {
+        if (equality == null && o.equality == null) {
           return this == o;
         } else {
           return Objects.equal(equality, o.equality);
@@ -652,16 +762,17 @@
         return false;
       }
     }
-    
+
     @Override
     public int hashCode() {
-      if(throwOnHashcode) {
+      if (throwOnHashcode) {
         throw new RuntimeException();
       } else {
         return super.hashCode();
       }
     }
-    
+
+    @Override
     public Object get() {
       return new Object();
     }
@@ -669,43 +780,57 @@
 
   public void testCorrectStage() {
     final Stage stage = Stage.PRODUCTION;
-    Module module = Modules.override(new AbstractModule() {
-      @Override
-      protected void configure() {
-        if (currentStage() != Stage.PRODUCTION) {
-          addError("Wronge stage in overridden module:" + currentStage());
-        }
-      }
-    }).with(new AbstractModule() {
-      @Override
-      protected void configure() {
-        if (currentStage() != Stage.PRODUCTION) {
-          addError("Wronge stage in overriding module:" + currentStage());
-        }
-      }
-    });
+    Module module =
+        Modules.override(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    if (currentStage() != Stage.PRODUCTION) {
+                      addError("Wronge stage in overridden module:" + currentStage());
+                    }
+                  }
+                })
+            .with(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    if (currentStage() != Stage.PRODUCTION) {
+                      addError("Wronge stage in overriding module:" + currentStage());
+                    }
+                  }
+                });
     Guice.createInjector(stage, module);
   }
 
   public void testOverridesApplyOriginalScanners() {
     Injector injector =
-        Guice.createInjector(Modules.override(NamedMunger.module()).with(new AbstractModule() {
-      @Override protected void configure() {}
-      @TestProvides @Named("test") String provideString() { return "foo"; }
-    }));
+        Guice.createInjector(
+            Modules.override(NamedMunger.module())
+                .with(
+                    new AbstractModule() {
+
+                      @TestProvides
+                      @Named("test")
+                      String provideString() {
+                        return "foo";
+                      }
+                    }));
 
     assertNull(injector.getExistingBinding(Key.get(String.class, named("test"))));
     Binding<String> binding = injector.getBinding(Key.get(String.class, named("test-munged")));
     assertEquals("foo", binding.getProvider().get());
   }
 
-  @Documented @Target(METHOD) @Retention(RUNTIME)
+  @Documented
+  @Target(METHOD)
+  @Retention(RUNTIME)
   private @interface TestProvides {}
 
   private static class NamedMunger extends ModuleAnnotatedMethodScanner {
     static Module module() {
       return new AbstractModule() {
-        @Override protected void configure() {
+        @Override
+        protected void configure() {
           binder().scanModulesForAnnotatedMethods(new NamedMunger());
         }
       };
@@ -722,10 +847,10 @@
     }
 
     @Override
-    public <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key,
-        InjectionPoint injectionPoint) {
-      return Key.get(key.getTypeLiteral(),
-          Names.named(((Named) key.getAnnotation()).value() + "-munged"));
+    public <T> Key<T> prepareMethod(
+        Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
+      return Key.get(
+          key.getTypeLiteral(), Names.named(((Named) key.getAnnotation()).value() + "-munged"));
     }
   }
 }
diff --git a/core/test/com/google/inject/util/ProvidersTest.java b/core/test/com/google/inject/util/ProvidersTest.java
index e442c40..7c3c8b7 100644
--- a/core/test/com/google/inject/util/ProvidersTest.java
+++ b/core/test/com/google/inject/util/ProvidersTest.java
@@ -19,10 +19,8 @@
 import com.google.common.base.Objects;
 import com.google.common.testing.EqualsTester;
 import com.google.inject.Provider;
-
-import junit.framework.TestCase;
-
 import javax.inject.Inject;
+import junit.framework.TestCase;
 
 /**
  * Unit tests for {@link Providers}.
@@ -42,68 +40,69 @@
     Provider<String> p = Providers.of(null);
     assertNull(p.get());
   }
-  
+
   public void testOfEquality() {
     new EqualsTester()
-        .addEqualityGroup(
-            Providers.of(null),
-            Providers.of(null))
-        .addEqualityGroup(
-            Providers.of("Hello"),
-            Providers.of("Hello"))
+        .addEqualityGroup(Providers.of(null), Providers.of(null))
+        .addEqualityGroup(Providers.of("Hello"), Providers.of("Hello"))
         .testEquals();
   }
-  
+
   public void testGuicifyEquality() {
     new EqualsTester()
         .addEqualityGroup(
-            Providers.guicify(new JavaxProvider(10)),
-            Providers.guicify(new JavaxProvider(10)))
+            Providers.guicify(new JavaxProvider(10)), Providers.guicify(new JavaxProvider(10)))
         .addEqualityGroup(
-            Providers.guicify(new JavaxProvider(11)),
-            Providers.guicify(new JavaxProvider(11)))
+            Providers.guicify(new JavaxProvider(11)), Providers.guicify(new JavaxProvider(11)))
         .addEqualityGroup(
             Providers.guicify(new JavaxProviderWithDependencies()),
             Providers.guicify(new JavaxProviderWithDependencies()))
         .testEquals();
   }
-  
+
   private static class JavaxProvider implements javax.inject.Provider<Integer> {
     private final int value;
 
     public JavaxProvider(int value) {
       this.value = value;
     }
-    
+
+    @Override
     public Integer get() {
       return value;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return Objects.hashCode(value);
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
       return (obj instanceof JavaxProvider) && (value == ((JavaxProvider) obj).value);
     }
   }
-  
+
   private static class JavaxProviderWithDependencies implements javax.inject.Provider<Integer> {
     private int value;
-    
-    @Inject void setValue(int value) {
+
+    @Inject
+    void setValue(int value) {
       this.value = value;
     }
-    
+
+    @Override
     public Integer get() {
       return value;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return 42;
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
       return (obj instanceof JavaxProviderWithDependencies);
     }
   }
diff --git a/core/test/com/google/inject/util/TypesTest.java b/core/test/com/google/inject/util/TypesTest.java
index db015de..4cdb78a 100644
--- a/core/test/com/google/inject/util/TypesTest.java
+++ b/core/test/com/google/inject/util/TypesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.util;
 
 import static com.google.inject.Asserts.assertContains;
@@ -25,10 +24,6 @@
 
 import com.google.inject.TypeLiteral;
 import com.google.inject.internal.MoreTypes;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
@@ -37,10 +32,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import junit.framework.Assert;
+import junit.framework.TestCase;
 
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
+/** @author jessewilson@google.com (Jesse Wilson) */
 public class TypesTest extends TestCase {
 
   // generic types for comparison
@@ -78,7 +73,7 @@
   }
 
   public void testDefensiveCopies() {
-    Type[] arguments = new Type[] { String.class, Integer.class };
+    Type[] arguments = new Type[] {String.class, Integer.class};
     ParameterizedType parameterizedType = Types.newParameterizedType(Map.class, arguments);
     arguments[0] = null;
     assertEquals(String.class, parameterizedType.getActualTypeArguments()[0]);
@@ -87,17 +82,20 @@
   }
 
   public void testTypeWithOwnerType() {
-    ParameterizedType actual = Types.newParameterizedTypeWithOwner(
-        TypesTest.class, Inner.class, Float.class, Double.class);
+    ParameterizedType actual =
+        Types.newParameterizedTypeWithOwner(
+            TypesTest.class, Inner.class, Float.class, Double.class);
     assertEquals(TypesTest.class, actual.getOwnerType());
     assertEqualsBothWays(innerFloatDouble, actual);
     // The JDK prints this out as:
     //     com.google.inject.util.TypesTest.com.google.inject.util.TypesTest$Inner<java.lang.Float, java.lang.Double>
     // and we think that's wrong, so the assertEquals comparison is worthless. :-(
-//    assertEquals(innerFloatDouble.toString(), actual.toString());
-    
+    //    assertEquals(innerFloatDouble.toString(), actual.toString());
+
     // We think the correct comparison is:
-    assertEquals("com.google.inject.util.TypesTest$Inner<java.lang.Float, java.lang.Double>", actual.toString());
+    assertEquals(
+        "com.google.inject.util.TypesTest$Inner<java.lang.Float, java.lang.Double>",
+        actual.toString());
   }
 
   public void testTypeParametersMustNotBePrimitives() {
@@ -105,8 +103,8 @@
       Types.newParameterizedType(Map.class, String.class, int.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(),
-          "Primitive types are not allowed in type parameters: int");
+      assertContains(
+          expected.getMessage(), "Primitive types are not allowed in type parameters: int");
     }
   }
 
@@ -126,22 +124,22 @@
     assertEqualWhenReserialized(supertypeOf(CharSequence.class));
     assertEqualWhenReserialized(subtypeOf(CharSequence.class));
   }
-  
+
   public void testWildcardBoundsMustNotBePrimitives() {
     try {
       supertypeOf(int.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(),
-          "Primitive types are not allowed in wildcard bounds: int");
+      assertContains(
+          expected.getMessage(), "Primitive types are not allowed in wildcard bounds: int");
     }
 
     try {
       subtypeOf(int.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(),
-          "Primitive types are not allowed in wildcard bounds: int");
+      assertContains(
+          expected.getMessage(), "Primitive types are not allowed in wildcard bounds: int");
     }
   }
 
@@ -151,13 +149,13 @@
   }
 
   public void testEqualsAndHashcode() {
-    ParameterizedType parameterizedType
-        = Types.newParameterizedType(Map.class, String.class, Integer.class);
+    ParameterizedType parameterizedType =
+        Types.newParameterizedType(Map.class, String.class, Integer.class);
     assertEqualsBothWays(mapStringInteger, parameterizedType);
     assertEquals(mapStringInteger.toString(), parameterizedType.toString());
 
-    GenericArrayType genericArrayType = Types.arrayOf(Types.arrayOf(
-        Types.newParameterizedType(Set.class, String.class)));
+    GenericArrayType genericArrayType =
+        Types.arrayOf(Types.arrayOf(Types.newParameterizedType(Set.class, String.class)));
     assertEqualsBothWays(setStringArray, genericArrayType);
     assertEquals(setStringArray.toString(), genericArrayType.toString());
   }
@@ -165,40 +163,37 @@
   public void testToString() {
     Assert.assertEquals("java.lang.String", MoreTypes.typeToString(String.class));
     assertEquals("java.util.Set<java.lang.String>[][]", MoreTypes.typeToString(setStringArray));
-    assertEquals("java.util.Map<java.lang.String, java.lang.Integer>",
+    assertEquals(
+        "java.util.Map<java.lang.String, java.lang.Integer>",
         MoreTypes.typeToString(mapStringInteger));
-    assertEquals("java.util.List<java.util.Set<java.lang.String>[][]>",
+    assertEquals(
+        "java.util.List<java.util.Set<java.lang.String>[][]>",
         MoreTypes.typeToString(listSetStringArray));
-    assertEquals(innerFloatDouble.toString(),
-        MoreTypes.typeToString(innerFloatDouble));
+    assertEquals(innerFloatDouble.toString(), MoreTypes.typeToString(innerFloatDouble));
   }
 
   static class Owning<A> {}
 
-  /**
-   * Ensure that owning types are required when necessary, and forbidden
-   * otherwise.
-   */
+  /** Ensure that owning types are required when necessary, and forbidden otherwise. */
   public void testCanonicalizeRequiresOwnerTypes() {
     try {
       Types.newParameterizedType(Owning.class, String.class);
       fail();
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(),
-          "No owner type for enclosed " + Owning.class);
+      assertContains(expected.getMessage(), "No owner type for enclosed " + Owning.class);
     }
 
     try {
       Types.newParameterizedTypeWithOwner(Object.class, Set.class, String.class);
+      fail("Expected IllegalArgumentException");
     } catch (IllegalArgumentException expected) {
-      assertContains(expected.getMessage(),
-          "Owner type for unenclosed " + Set.class);
+      assertContains(expected.getMessage(), "Owner type for unenclosed " + Set.class);
     }
   }
 
   @SuppressWarnings("UnusedDeclaration")
   class Inner<T1, T2> {}
-  
+
   public void testInnerParameterizedEvenWithZeroArgs() {
     TypeLiteral<Outer<String>.Inner> type = new TypeLiteral<Outer<String>.Inner>() {};
     assertEqualsBothWays(outerInner, type.getType());
@@ -210,6 +205,7 @@
   }
 
   static class Outer<T> {
+    @SuppressWarnings("ClassCanBeStatic")
     class Inner {}
   }
 }
diff --git a/core/test/com/googlecode/guice/BytecodeGenTest.java b/core/test/com/googlecode/guice/BytecodeGenTest.java
index de4d560..1afdd58 100644
--- a/core/test/com/googlecode/guice/BytecodeGenTest.java
+++ b/core/test/com/googlecode/guice/BytecodeGenTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,33 +16,27 @@
 
 package com.googlecode.guice;
 
+import static com.google.inject.Asserts.getClassPathUrls;
 import static com.google.inject.matcher.Matchers.any;
 
+import com.google.common.testing.GcFinalization;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.googlecode.guice.PackageVisibilityTestModule.PublicUserOfPackagePrivate;
-
-import junit.framework.TestCase;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import java.io.File;
-import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.concurrent.TimeoutException;
+import javax.inject.Inject;
+import junit.framework.TestCase;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
 /**
- * This test is in a separate package so we can test package-level visibility
- * with confidence.
+ * This test is in a separate package so we can test package-level visibility with confidence.
  *
  * @author mcculls@gmail.com (Stuart McCulloch)
  */
@@ -50,27 +44,37 @@
 
   private final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
 
-  private final Module interceptorModule = new AbstractModule() {
-    protected void configure() {
-      bindInterceptor(any(), any(), new MethodInterceptor() {
-        public Object invoke(MethodInvocation chain)
-            throws Throwable {
-          return chain.proceed() + " WORLD";
+  private final Module interceptorModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bindInterceptor(
+              any(),
+              any(),
+              new MethodInterceptor() {
+                @Override
+                public Object invoke(MethodInvocation chain) throws Throwable {
+                  return chain.proceed() + " WORLD";
+                }
+              });
         }
-      });
-    }
-  };
+      };
 
-  private final Module noopInterceptorModule = new AbstractModule() {
-      protected void configure() {
-        bindInterceptor(any(), any(), new MethodInterceptor() {
-          public Object invoke(MethodInvocation chain)
-              throws Throwable {
-            return chain.proceed();
-          }
-        });
-      }
-    };
+  private final Module noopInterceptorModule =
+      new AbstractModule() {
+        @Override
+        protected void configure() {
+          bindInterceptor(
+              any(),
+              any(),
+              new MethodInterceptor() {
+                @Override
+                public Object invoke(MethodInvocation chain) throws Throwable {
+                  return chain.proceed();
+                }
+              });
+        }
+      };
 
   public void testPackageVisibility() {
     Injector injector = Guice.createInjector(new PackageVisibilityTestModule());
@@ -85,45 +89,32 @@
   public void testEnhancerNaming() {
     Injector injector = Guice.createInjector(interceptorModule, new PackageVisibilityTestModule());
     PublicUserOfPackagePrivate pupp = injector.getInstance(PublicUserOfPackagePrivate.class);
-    assertTrue(pupp.getClass().getName().startsWith(
-        PublicUserOfPackagePrivate.class.getName() + "$$EnhancerByGuice$$"));
+    assertTrue(
+        pupp.getClass()
+            .getName()
+            .startsWith(PublicUserOfPackagePrivate.class.getName() + "$$EnhancerByGuice$$"));
   }
 
   // TODO(sameb): Figure out how to test FastClass naming tests.
 
-  /**
-   * Custom URL classloader with basic visibility rules
-   */
-  static class TestVisibilityClassLoader
-      extends URLClassLoader {
+  /** Custom URL classloader with basic visibility rules */
+  static class TestVisibilityClassLoader extends URLClassLoader {
 
-    boolean hideInternals;
+    final boolean hideInternals;
 
-    public TestVisibilityClassLoader(boolean hideInternals) {
-      super(new URL[0]);
+    TestVisibilityClassLoader(boolean hideInternals) {
+      this(TestVisibilityClassLoader.class.getClassLoader(), hideInternals);
+    }
 
+    TestVisibilityClassLoader(ClassLoader classloader, boolean hideInternals) {
+      super(getClassPathUrls(), classloader);
       this.hideInternals = hideInternals;
-
-      final String[] classpath = System.getProperty("java.class.path").split(File.pathSeparator);
-      for (final String element : classpath) {
-        try {
-          // is it a remote/local URL?
-          addURL(new URL(element));
-        } catch (final MalformedURLException e1) {
-          try {
-            // nope - perhaps it's a filename?
-            addURL(new File(element).toURI().toURL());
-          } catch (final MalformedURLException e2) {
-            throw new RuntimeException(e1);
-          }
-        }
-      }
     }
 
     /**
-     * Classic parent-delegating classloaders are meant to override findClass.
-     * However, non-delegating classloaders (as used in OSGi) instead override
-     * loadClass to provide support for "class-space" separation.
+     * Classic parent-delegating classloaders are meant to override findClass. However,
+     * non-delegating classloaders (as used in OSGi) instead override loadClass to provide support
+     * for "class-space" separation.
      */
     @Override
     protected Class<?> loadClass(final String name, final boolean resolve)
@@ -167,9 +158,11 @@
 
   /** as loaded by another class loader */
   private Class<ProxyTest> proxyTestClass;
+
   private Class<ProxyTestImpl> realClass;
   private Module testModule;
 
+  @Override
   @SuppressWarnings("unchecked")
   protected void setUp() throws Exception {
     super.setUp();
@@ -178,11 +171,13 @@
     proxyTestClass = (Class<ProxyTest>) testClassLoader.loadClass(ProxyTest.class.getName());
     realClass = (Class<ProxyTestImpl>) testClassLoader.loadClass(ProxyTestImpl.class.getName());
 
-    testModule = new AbstractModule() {
-      public void configure() {
-        bind(proxyTestClass).to(realClass);
-      }
-    };
+    testModule =
+        new AbstractModule() {
+          @Override
+          public void configure() {
+            bind(proxyTestClass).to(realClass);
+          }
+        };
   }
 
   interface ProxyTest {
@@ -190,10 +185,10 @@
   }
 
   /**
-   * Note: this class must be marked as public or protected so that the Guice
-   * custom classloader will intercept it. Private and implementation classes
-   * are not intercepted by the custom classloader.
-   * 
+   * Note: this class must be marked as public or protected so that the Guice custom classloader
+   * will intercept it. Private and implementation classes are not intercepted by the custom
+   * classloader.
+   *
    * @see com.google.inject.internal.BytecodeGen.Visibility
    */
   public static class ProxyTestImpl implements ProxyTest {
@@ -202,14 +197,15 @@
       //System.out.println(ProxyTestImpl.class.getClassLoader());
     }
 
+    @Override
     public String sayHello() {
       return "HELLO";
     }
   }
 
   public void testProxyClassLoading() throws Exception {
-    Object testObject = Guice.createInjector(interceptorModule, testModule)
-        .getInstance(proxyTestClass);
+    Object testObject =
+        Guice.createInjector(interceptorModule, testModule).getInstance(proxyTestClass);
 
     // verify method interception still works
     Method m = realClass.getMethod("sayHello");
@@ -217,11 +213,16 @@
   }
 
   public void testSystemClassLoaderIsUsedIfProxiedClassUsesIt() {
-    ProxyTest testProxy = Guice.createInjector(interceptorModule, new Module() {
-      public void configure(Binder binder) {
-        binder.bind(ProxyTest.class).to(ProxyTestImpl.class);
-      }
-    }).getInstance(ProxyTest.class);
+    ProxyTest testProxy =
+        Guice.createInjector(
+                interceptorModule,
+                new Module() {
+                  @Override
+                  public void configure(Binder binder) {
+                    binder.bind(ProxyTest.class).to(ProxyTestImpl.class);
+                  }
+                })
+            .getInstance(ProxyTest.class);
 
     if (ProxyTest.class.getClassLoader() == systemClassLoader) {
       assertSame(testProxy.getClass().getClassLoader(), systemClassLoader);
@@ -231,13 +232,13 @@
   }
 
   public void testProxyClassUnloading() {
-    Object testObject = Guice.createInjector(interceptorModule, testModule)
-        .getInstance(proxyTestClass);
+    Object testObject =
+        Guice.createInjector(interceptorModule, testModule).getInstance(proxyTestClass);
     assertNotNull(testObject.getClass().getClassLoader());
     assertNotSame(testObject.getClass().getClassLoader(), systemClassLoader);
 
     // take a weak reference to the generated proxy class
-    Reference<Class<?>> clazzRef = new WeakReference<Class<?>>(testObject.getClass());
+    WeakReference<Class<?>> clazzRef = new WeakReference<Class<?>>(testObject.getClass());
 
     assertNotNull(clazzRef.get());
 
@@ -248,17 +249,7 @@
      * this should be enough to queue the weak reference
      * unless something is holding onto it accidentally.
      */
-    final int MAX_COUNT = 100;
-    String[] buf;
-    System.gc();
-    //TODO(cgruber): Use com.google.common.testing.GcFinalization and a countdown latch to un-flake.
-    for (int count = 0 ; clazzRef.get() != null ; count++) {
-      buf = new String[8 * 1024 * 1024];
-      buf = null;
-      System.gc();
-      assertTrue("Timeout waiting for class to be unloaded.  This may be a flaky result.",
-          count <= MAX_COUNT);
-    }
+    GcFinalization.awaitClear(clazzRef);
 
     // This test could be somewhat flaky when the GC isn't working.
     // If it fails, run the test again to make sure it's failing reliably.
@@ -290,8 +281,7 @@
     }
   }
 
-  static class Hidden {
-  }
+  static class Hidden {}
 
   public static class HiddenMethodReturn {
     public Hidden method() {
@@ -300,15 +290,15 @@
   }
 
   public static class HiddenMethodParameter {
-    public void method(Hidden h) {
-    }
+    public void method(Hidden h) {}
   }
 
   public void testClassLoaderBridging() throws Exception {
     ClassLoader testClassLoader = new TestVisibilityClassLoader(false);
 
     Class hiddenMethodReturnClass = testClassLoader.loadClass(HiddenMethodReturn.class.getName());
-    Class hiddenMethodParameterClass = testClassLoader.loadClass(HiddenMethodParameter.class.getName());
+    Class hiddenMethodParameterClass =
+        testClassLoader.loadClass(HiddenMethodParameter.class.getName());
 
     Injector injector = Guice.createInjector(noopInterceptorModule);
 
@@ -325,4 +315,140 @@
     Object o2 = injector.getInstance(hiddenMethodReturnClass);
     o2.getClass().getDeclaredMethod("method").invoke(o2);
   }
+
+  // This tests for a situation where a osgi bundle contains a version of guice.  When guice
+  // generates a fast class it will use a bridge classloader
+  public void testFastClassUsesBridgeClassloader() throws Throwable {
+    Injector injector = Guice.createInjector();
+    // These classes are all in the same classloader as guice itself, so other than the private one
+    // they can all be fast class invoked
+    injector.getInstance(PublicInject.class).assertIsFastClassInvoked();
+    injector.getInstance(ProtectedInject.class).assertIsFastClassInvoked();
+    injector.getInstance(PackagePrivateInject.class).assertIsFastClassInvoked();
+    injector.getInstance(PrivateInject.class).assertIsReflectionInvoked();
+
+    // This classloader will load the types in an loader with a different version of guice/cglib
+    // this prevents the use of fastclass for all but the public types (where the bridge
+    // classloader can be used).
+    MultipleVersionsOfGuiceClassLoader fakeLoader = new MultipleVersionsOfGuiceClassLoader();
+    injector
+        .getInstance(fakeLoader.loadLogCreatorType(PublicInject.class))
+        .assertIsFastClassInvoked();
+    injector
+        .getInstance(fakeLoader.loadLogCreatorType(ProtectedInject.class))
+        .assertIsReflectionInvoked();
+    injector
+        .getInstance(fakeLoader.loadLogCreatorType(PackagePrivateInject.class))
+        .assertIsReflectionInvoked();
+    injector
+        .getInstance(fakeLoader.loadLogCreatorType(PrivateInject.class))
+        .assertIsReflectionInvoked();
+  }
+
+  // This classloader simulates an OSGI environment where a bundle has a conflicting definition of
+  // cglib (or guice).  This is sort of the opposite of the BridgeClassloader and is meant to test
+  // its use.
+  static class MultipleVersionsOfGuiceClassLoader extends URLClassLoader {
+    MultipleVersionsOfGuiceClassLoader() {
+      this(MultipleVersionsOfGuiceClassLoader.class.getClassLoader());
+    }
+
+    MultipleVersionsOfGuiceClassLoader(ClassLoader classloader) {
+      super(getClassPathUrls(), classloader);
+    }
+
+    public Class<? extends LogCreator> loadLogCreatorType(Class<? extends LogCreator> cls)
+        throws ClassNotFoundException {
+      return loadClass(cls.getName()).asSubclass(LogCreator.class);
+    }
+
+    /**
+     * Classic parent-delegating classloaders are meant to override findClass. However,
+     * non-delegating classloaders (as used in OSGi) instead override loadClass to provide support
+     * for "class-space" separation.
+     */
+    @Override
+    protected Class<?> loadClass(final String name, final boolean resolve)
+        throws ClassNotFoundException {
+
+      synchronized (this) {
+        // check our local cache to avoid duplicates
+        final Class<?> clazz = findLoadedClass(name);
+        if (clazz != null) {
+          return clazz;
+        }
+      }
+
+      if (name.startsWith("java.")
+          || name.startsWith("javax.")
+          || name.equals(LogCreator.class.getName())
+          || (!name.startsWith("com.google.inject.")
+              && !name.contains(".cglib.")
+              && !name.startsWith("com.googlecode.guice"))) {
+
+        // standard parent delegation
+        return super.loadClass(name, resolve);
+
+      } else {
+        // load a new copy of the class
+        final Class<?> clazz = findClass(name);
+        if (resolve) {
+          resolveClass(clazz);
+        }
+        return clazz;
+      }
+    }
+  }
+
+  public static class LogCreator {
+    final Throwable caller;
+
+    public LogCreator() {
+      this.caller = new Throwable();
+    }
+
+    void assertIsFastClassInvoked() throws Throwable {
+      // 2 because the first 2 elements are
+      // LogCreator.<init>()
+      // Subclass.<init>()
+      if (!caller.getStackTrace()[2].getClassName().contains("$$FastClassByGuice$$")) {
+        throw new AssertionError("Caller was not FastClass").initCause(caller);
+      }
+    }
+
+    void assertIsReflectionInvoked() throws Throwable {
+      // Scan for a call to Constructor.newInstance, but stop if we see the test itself.
+      for (StackTraceElement element : caller.getStackTrace()) {
+        if (element.getClassName().equals(BytecodeGenTest.class.getName())) {
+          // break when we hit the test method.
+          break;
+        }
+        if (element.getClassName().equals(Constructor.class.getName())
+            && element.getMethodName().equals("newInstance")) {
+          return;
+        }
+      }
+      throw new AssertionError("Caller was not Constructor.newInstance").initCause(caller);
+    }
+  }
+
+  public static class PublicInject extends LogCreator {
+    @Inject
+    public PublicInject() {}
+  }
+
+  static class PackagePrivateInject extends LogCreator {
+    @Inject
+    PackagePrivateInject() {}
+  }
+
+  protected static class ProtectedInject extends LogCreator {
+    @Inject
+    protected ProtectedInject() {}
+  }
+
+  private static class PrivateInject extends LogCreator {
+    @Inject
+    private PrivateInject() {}
+  }
 }
diff --git a/core/test/com/googlecode/guice/GuiceTck.java b/core/test/com/googlecode/guice/GuiceTck.java
index 5616fd7..fc873d4 100644
--- a/core/test/com/googlecode/guice/GuiceTck.java
+++ b/core/test/com/googlecode/guice/GuiceTck.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,10 +19,9 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Provides;
-
+import javax.inject.Named;
 import junit.framework.Test;
 import junit.framework.TestCase;
-
 import org.atinject.tck.Tck;
 import org.atinject.tck.auto.Car;
 import org.atinject.tck.auto.Convertible;
@@ -36,25 +35,31 @@
 import org.atinject.tck.auto.accessories.Cupholder;
 import org.atinject.tck.auto.accessories.SpareTire;
 
-import javax.inject.Named;
-
 public class GuiceTck extends TestCase {
 
   public static Test suite() {
-    return Tck.testsFor(Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Car.class).to(Convertible.class);
-        bind(Seat.class).annotatedWith(Drivers.class).to(DriversSeat.class);
-        bind(Engine.class).to(V8Engine.class);
-        bind(Cupholder.class);
-        bind(Tire.class);
-        bind(FuelTank.class);
-        requestStaticInjection(Convertible.class, SpareTire.class);
-      }
+    return Tck.testsFor(
+        Guice.createInjector(
+                new AbstractModule() {
+                  @Override
+                  protected void configure() {
+                    bind(Car.class).to(Convertible.class);
+                    bind(Seat.class).annotatedWith(Drivers.class).to(DriversSeat.class);
+                    bind(Engine.class).to(V8Engine.class);
+                    bind(Cupholder.class);
+                    bind(Tire.class);
+                    bind(FuelTank.class);
+                    requestStaticInjection(Convertible.class, SpareTire.class);
+                  }
 
-      @Provides @Named("spare") Tire provideSpareTire(SpareTire spare) {
-        return spare;
-      }
-    }).getInstance(Car.class), true, true);
+                  @Provides
+                  @Named("spare")
+                  Tire provideSpareTire(SpareTire spare) {
+                    return spare;
+                  }
+                })
+            .getInstance(Car.class),
+        true,
+        true);
   }
 }
diff --git a/core/test/com/googlecode/guice/Jsr330Test.java b/core/test/com/googlecode/guice/Jsr330Test.java
index 57cd6e0..1610b05 100644
--- a/core/test/com/googlecode/guice/Jsr330Test.java
+++ b/core/test/com/googlecode/guice/Jsr330Test.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,18 +33,15 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.util.Set;
-
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Qualifier;
 import javax.inject.Singleton;
+import junit.framework.TestCase;
 
 public class Jsr330Test extends TestCase {
 
@@ -53,21 +50,25 @@
   private final D d = new D();
   private final E e = new E();
 
-  @Override protected void setUp() throws Exception {
+  @Override
+  protected void setUp() throws Exception {
     J.nextInstanceId = 0;
     K.nextInstanceId = 0;
   }
 
   public void testInject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).toInstance(b);
-        bind(C.class).toInstance(c);
-        bind(D.class).toInstance(d);
-        bind(E.class).toInstance(e);
-        bind(A.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).toInstance(b);
+                bind(C.class).toInstance(c);
+                bind(D.class).toInstance(d);
+                bind(E.class).toInstance(e);
+                bind(A.class);
+              }
+            });
 
     A a = injector.getInstance(A.class);
     assertSame(b, a.b);
@@ -77,15 +78,18 @@
   }
 
   public void testQualifiedInject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
-        bind(C.class).annotatedWith(Red.class).toInstance(c);
-        bind(D.class).annotatedWith(RED).toInstance(d);
-        bind(E.class).annotatedWith(Names.named("jesse")).toInstance(e);
-        bind(F.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
+                bind(C.class).annotatedWith(Red.class).toInstance(c);
+                bind(D.class).annotatedWith(RED).toInstance(d);
+                bind(E.class).annotatedWith(Names.named("jesse")).toInstance(e);
+                bind(F.class);
+              }
+            });
 
     F f = injector.getInstance(F.class);
     assertSame(b, f.b);
@@ -95,15 +99,18 @@
   }
 
   public void testProviderInject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
-        bind(C.class).toInstance(c);
-        bind(D.class).annotatedWith(RED).toInstance(d);
-        bind(E.class).toInstance(e);
-        bind(G.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
+                bind(C.class).toInstance(c);
+                bind(D.class).annotatedWith(RED).toInstance(d);
+                bind(E.class).toInstance(e);
+                bind(G.class);
+              }
+            });
 
     G g = injector.getInstance(G.class);
     assertSame(b, g.bProvider.get());
@@ -115,13 +122,16 @@
   public void testScopeAnnotation() {
     final TestScope scope = new TestScope();
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).in(scope);
-        bind(C.class).in(TestScoped.class);
-        bindScope(TestScoped.class, scope);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).in(scope);
+                bind(C.class).in(TestScoped.class);
+                bindScope(TestScoped.class, scope);
+              }
+            });
 
     B b = injector.getInstance(B.class);
     assertSame(b, injector.getInstance(B.class));
@@ -141,13 +151,16 @@
     assertNotSame(c, injector.getInstance(C.class));
     assertNotSame(h, injector.getInstance(H.class));
   }
-  
+
   public void testSingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).in(Singleton.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).in(Singleton.class);
+              }
+            });
 
     B b = injector.getInstance(B.class);
     assertSame(b, injector.getInstance(B.class));
@@ -159,24 +172,30 @@
   }
 
   public void testEagerSingleton() {
-    Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
-      protected void configure() {
-        bind(J.class);
-        bind(K.class).in(Singleton.class);
-      }
-    });
+    Guice.createInjector(
+        Stage.PRODUCTION,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(J.class);
+            bind(K.class).in(Singleton.class);
+          }
+        });
 
     assertEquals(1, J.nextInstanceId);
     assertEquals(1, K.nextInstanceId);
   }
-  
+
   public void testScopesIsSingleton() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(J.class);
-        bind(K.class).in(Singleton.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(J.class);
+                bind(K.class).in(Singleton.class);
+              }
+            });
 
     assertTrue(Scopes.isSingleton(injector.getBinding(J.class)));
     assertTrue(Scopes.isSingleton(injector.getBinding(K.class)));
@@ -184,70 +203,86 @@
 
   public void testInjectingFinalFieldsIsForbidden() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(L.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(L.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "1) Injected field " + L.class.getName() + ".b cannot be final.");
+      assertContains(
+          expected.getMessage(), "1) Injected field " + L.class.getName() + ".b cannot be final.");
     }
   }
 
   public void testInjectingAbstractMethodsIsForbidden() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(M.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(M.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Injected method " + AbstractM.class.getName() + ".setB() cannot be abstract.");
     }
   }
 
   public void testInjectingMethodsWithTypeParametersIsForbidden() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          bind(N.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(N.class);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "1) Injected method " + N.class.getName()
-          + ".setB() cannot declare type parameters of its own.");
+      assertContains(
+          expected.getMessage(),
+          "1) Injected method "
+              + N.class.getName()
+              + ".setB() cannot declare type parameters of its own.");
     }
   }
 
   public void testInjectingMethodsWithNonVoidReturnTypes() {
-    Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(P.class);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(P.class);
+          }
+        });
   }
 
   /**
-   * This test verifies that we can compile bindings to provider instances
-   * whose compile-time type implements javax.inject.Provider but not
-   * com.google.inject.Provider. For binary compatibility, we don't (and won't)
-   * support binding to instances of javax.inject.Provider.
+   * This test verifies that we can compile bindings to provider instances whose compile-time type
+   * implements javax.inject.Provider but not com.google.inject.Provider. For binary compatibility,
+   * we don't (and won't) support binding to instances of javax.inject.Provider.
    */
   public void testBindProviderClass() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(B.class).toProvider(BProvider.class);
-        bind(B.class).annotatedWith(Names.named("1")).toProvider(BProvider.class);
-        bind(B.class).annotatedWith(Names.named("2")).toProvider(Key.get(BProvider.class));
-        bind(B.class).annotatedWith(Names.named("3")).toProvider(TypeLiteral.get(BProvider.class));
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(B.class).toProvider(BProvider.class);
+                bind(B.class).annotatedWith(Names.named("1")).toProvider(BProvider.class);
+                bind(B.class).annotatedWith(Names.named("2")).toProvider(Key.get(BProvider.class));
+                bind(B.class)
+                    .annotatedWith(Names.named("3"))
+                    .toProvider(TypeLiteral.get(BProvider.class));
+              }
+            });
+
     injector.getInstance(Key.get(B.class));
     injector.getInstance(Key.get(B.class, Names.named("1")));
     injector.getInstance(Key.get(B.class, Names.named("2")));
@@ -255,15 +290,18 @@
   }
 
   public void testGuicify330Provider() {
-    Provider<String> jsr330Provider = new Provider<String>() {
-      public String get() {
-        return "A";
-      }
+    Provider<String> jsr330Provider =
+        new Provider<String>() {
+          @Override
+          public String get() {
+            return "A";
+          }
 
-      @Override public String toString() {
-        return "jsr330Provider";
-      }
-    };
+          @Override
+          public String toString() {
+            return "jsr330Provider";
+          }
+        };
 
     com.google.inject.Provider<String> guicified = Providers.guicify(jsr330Provider);
     assertEquals("guicified(jsr330Provider)", guicified.toString());
@@ -271,51 +309,56 @@
 
     // when you guicify the Guice-friendly, it's a no-op
     assertSame(guicified, Providers.guicify(guicified));
-    
+
     assertFalse(guicified instanceof HasDependencies);
   }
-  
+
   public void testGuicifyWithDependencies() {
-    Provider<String> jsr330Provider = new Provider<String>() {
-      @Inject double d;
-      int i;
-      @Inject void injectMe(int i) {
-        this.i = i;
-      }
-      
-      public String get() {
-        return  d + "-" + i;
-      }
-    };
-    
-    final com.google.inject.Provider<String> guicified =
-        Providers.guicify(jsr330Provider);
+    Provider<String> jsr330Provider =
+        new Provider<String>() {
+          @Inject double d;
+          int i;
+
+          @Inject
+          void injectMe(int i) {
+            this.i = i;
+          }
+
+          @Override
+          public String get() {
+            return d + "-" + i;
+          }
+        };
+
+    final com.google.inject.Provider<String> guicified = Providers.guicify(jsr330Provider);
     assertTrue(guicified instanceof HasDependencies);
-    Set<Dependency<?>> actual = ((HasDependencies)guicified).getDependencies();
+    Set<Dependency<?>> actual = ((HasDependencies) guicified).getDependencies();
     validateDependencies(actual, jsr330Provider.getClass());
-    
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toProvider(guicified);
-        bind(int.class).toInstance(1);
-        bind(double.class).toInstance(2.0d);
-      }
-    });
-    
+
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toProvider(guicified);
+                bind(int.class).toInstance(1);
+                bind(double.class).toInstance(2.0d);
+              }
+            });
+
     Binding<String> binding = injector.getBinding(String.class);
     assertEquals("2.0-1", binding.getProvider().get());
     validateDependencies(actual, jsr330Provider.getClass());
   }
-  
+
   private void validateDependencies(Set<Dependency<?>> actual, Class<?> owner) {
     assertEquals(actual.toString(), 2, actual.size());
     Dependency<?> dDep = null;
     Dependency<?> iDep = null;
-    for(Dependency<?> dep : actual) {
-      if(dep.getKey().equals(Key.get(Double.class))) {
+    for (Dependency<?> dep : actual) {
+      if (dep.getKey().equals(Key.get(Double.class))) {
         dDep = dep;
-      } else if(dep.getKey().equals(Key.get(Integer.class))) {
+      } else if (dep.getKey().equals(Key.get(Integer.class))) {
         iDep = dep;
       }
     }
@@ -324,7 +367,7 @@
     assertEquals(TypeLiteral.get(owner), dDep.getInjectionPoint().getDeclaringType());
     assertEquals("d", dDep.getInjectionPoint().getMember().getName());
     assertEquals(-1, dDep.getParameterIndex());
-    
+
     assertEquals(TypeLiteral.get(owner), iDep.getInjectionPoint().getDeclaringType());
     assertEquals("injectMe", iDep.getInjectionPoint().getMember().getName());
     assertEquals(0, iDep.getParameterIndex());
@@ -336,19 +379,24 @@
     D d;
     E e;
 
-    @Inject A(B b) {
+    @Inject
+    A(B b) {
       this.b = b;
     }
 
-    @Inject void injectD(D d, E e) {
+    @Inject
+    void injectD(D d, E e) {
       this.d = d;
       this.e = e;
     }
   }
 
   static class B {}
+
   static class C {}
+
   static class D {}
+
   static class E {}
 
   static class F {
@@ -357,32 +405,39 @@
     D d;
     E e;
 
-    @Inject F(@Named("jodie") B b) {
+    @Inject
+    F(@Named("jodie") B b) {
       this.b = b;
     }
 
-    @Inject void injectD(@Red D d, @Named("jesse") E e) {
+    @Inject
+    void injectD(@Red D d, @Named("jesse") E e) {
       this.d = d;
       this.e = e;
     }
   }
 
-  @Qualifier @Retention(RUNTIME)
+  @Qualifier
+  @Retention(RUNTIME)
   @interface Red {}
 
-  public static final Red RED = new Red() {
-    public Class<? extends Annotation> annotationType() {
-      return Red.class;
-    }
+  public static final Red RED =
+      new Red() {
+        @Override
+        public Class<? extends Annotation> annotationType() {
+          return Red.class;
+        }
 
-    @Override public boolean equals(Object obj) {
-      return obj instanceof Red;
-    }
+        @Override
+        public boolean equals(Object obj) {
+          return obj instanceof Red;
+        }
 
-    @Override public int hashCode() {
-      return 0;
-    }
-  };
+        @Override
+        public int hashCode() {
+          return 0;
+        }
+      };
 
   static class G {
     final Provider<B> bProvider;
@@ -390,28 +445,33 @@
     Provider<D> dProvider;
     Provider<E> eProvider;
 
-    @Inject G(@Named("jodie") Provider<B> bProvider) {
+    @Inject
+    G(@Named("jodie") Provider<B> bProvider) {
       this.bProvider = bProvider;
     }
 
-    @Inject void injectD(@Red Provider<D> dProvider, Provider<E> eProvider) {
+    @Inject
+    void injectD(@Red Provider<D> dProvider, Provider<E> eProvider) {
       this.dProvider = dProvider;
       this.eProvider = eProvider;
     }
   }
 
-  @javax.inject.Scope @Retention(RUNTIME)
+  @javax.inject.Scope
+  @Retention(RUNTIME)
   @interface TestScoped {}
 
   static class TestScope implements Scope {
     private int now = 0;
 
-    public <T> com.google.inject.Provider<T> scope(Key<T> key,
-        final com.google.inject.Provider<T> unscoped) {
+    @Override
+    public <T> com.google.inject.Provider<T> scope(
+        Key<T> key, final com.google.inject.Provider<T> unscoped) {
       return new com.google.inject.Provider<T>() {
         private T value;
         private int snapshotTime = -1;
 
+        @Override
         public T get() {
           if (snapshotTime != now) {
             value = unscoped.get();
@@ -447,27 +507,32 @@
     final B b = null;
   }
 
-  static abstract class AbstractM {
-    @SuppressWarnings("InjectJavaxInjectOnAbstractMethod")
+  abstract static class AbstractM {
+    @SuppressWarnings("JavaxInjectOnAbstractMethod")
     @Inject
     abstract void setB(B b);
   }
 
   static class M extends AbstractM {
+    @Override
+    @SuppressWarnings("OverridesJavaxInjectableMethod")
     void setB(B b) {}
   }
 
   static class N {
-    @Inject <T> void setB(B b) {}
+    @Inject
+    <T> void setB(B b) {}
   }
 
   static class P {
-    @Inject B setB(B b) {
+    @Inject
+    B setB(B b) {
       return b;
     }
   }
 
   static class BProvider implements Provider<B> {
+    @Override
     public B get() {
       return new B();
     }
diff --git a/core/test/com/googlecode/guice/OSGiContainerTest.java b/core/test/com/googlecode/guice/OSGiContainerTest.java
index b91975f..5191cdb 100644
--- a/core/test/com/googlecode/guice/OSGiContainerTest.java
+++ b/core/test/com/googlecode/guice/OSGiContainerTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,34 +16,26 @@
 
 package com.googlecode.guice;
 
-
 import aQute.bnd.main.bnd;
-
 import com.googlecode.guice.bundle.OSGiTestActivator;
-
-import junit.framework.TestCase;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.launch.Framework;
-import org.osgi.framework.launch.FrameworkFactory;
-
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Iterator;
 import java.util.Properties;
-
-import javax.imageio.spi.ServiceRegistry;
+import java.util.ServiceLoader;
+import junit.framework.TestCase;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
 
 /**
  * Run various tests inside one or more OSGi containers.
  *
  * @author mcculls@gmail.com (Stuart McCulloch)
  */
-public class OSGiContainerTest
-    extends TestCase {
+public class OSGiContainerTest extends TestCase {
 
   // build properties passed from Ant
   static final String VERSION = System.getProperty("version", "snapshot");
@@ -54,34 +46,36 @@
 
   static final String GUICE_JAR = BUILD_DIST_DIR + "/guice-" + VERSION + ".jar";
 
-/*if[AOP]*/
-  static final String AOPALLIANCE_JAR = System.getProperty("aopalliance.jar", "lib/aopalliance.jar");
-/*end[AOP]*/
-  static final String JAVAX_INJECT_JAR = System.getProperty("javax.inject.jar", "lib/javax.inject.jar");
-  static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-16.0.1.jar");
+  /*if[AOP]*/
+  static final String AOPALLIANCE_JAR =
+      System.getProperty("aopalliance.jar", "lib/aopalliance.jar");
+  /*end[AOP]*/
+  static final String JAVAX_INJECT_JAR =
+      System.getProperty("javax.inject.jar", "lib/javax.inject.jar");
+  static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-19.0.jar");
 
   // dynamically build test bundles
-  @Override protected void setUp()
-      throws Exception {
+  @Override
+  protected void setUp() throws Exception {
 
     // verify properties
     assertTrue(failMsg(), new File(BUILD_DIR).isDirectory());
     assertTrue(failMsg(), new File(GUICE_JAR).isFile());
 
-/*if[AOP]*/
+    /*if[AOP]*/
     assertTrue(failMsg(), new File(AOPALLIANCE_JAR).isFile());
-/*end[AOP]*/
+    /*end[AOP]*/
     assertTrue(failMsg(), new File(JAVAX_INJECT_JAR).isFile());
     assertTrue(failMsg(), new File(GUAVA_JAR).isFile());
 
     Properties instructions = new Properties();
 
-/*if[AOP]*/
+    /*if[AOP]*/
     // aopalliance is an API bundle --> export the full API
     instructions.setProperty("Export-Package", "org.aopalliance.*");
     buildBundle("aopalliance", instructions, AOPALLIANCE_JAR);
     instructions.clear();
-/*end[AOP]*/
+    /*end[AOP]*/
 
     // javax.inject is an API bundle --> export the full API
     instructions.setProperty("Export-Package", "javax.inject.*");
@@ -95,11 +89,13 @@
     instructions.clear();
 
     // strict imports to make sure test bundle only has access to these packages
-    instructions.setProperty("Import-Package", "org.osgi.framework,"
-/*if[AOP]*/
-        + "org.aopalliance.intercept,"
-/*end[AOP]*/
-        + "com.google.inject(|.binder|.matcher|.name)");
+    instructions.setProperty(
+        "Import-Package",
+        "org.osgi.framework,"
+            /*if[AOP]*/
+            + "org.aopalliance.intercept,"
+            /*end[AOP]*/
+            + "com.google.inject(|.binder|.matcher|.name)");
 
     // test bundle should only contain the local test classes, nothing else
     instructions.setProperty("Bundle-Activator", OSGiTestActivator.class.getName());
@@ -119,20 +115,19 @@
     os.close();
 
     // assemble bundle, use -failok switch to avoid early exit
-    bnd.main(new String[]{"-failok", "build", "-classpath", classpath, bndFileName});
+    bnd.main(new String[] {"-failok", "build", "-classpath", classpath, bndFileName});
   }
 
   private String failMsg() {
     return "This test may fail if it is not run from ant, or if it is not run after ant has "
-         + "compiled & built jars. This is because the test is validating that the Guice jar "
-         + "is properly setup to load in an OSGi container";
+        + "compiled & built jars. This is because the test is validating that the Guice jar "
+        + "is properly setup to load in an OSGi container";
   }
 
   //This test may fail if it is not run from ant, or if it is not run after ant has
   //compiled & built jars. This is because the test is validating that the Guice jar
   //is properly setup to load in an OSGi container
-  public void testGuiceWorksInOSGiContainer()
-      throws Throwable {
+  public void testGuiceWorksInOSGiContainer() throws Throwable {
 
     // ask framework to clear cache on startup
     Properties properties = new Properties();
@@ -140,17 +135,16 @@
     properties.setProperty("org.osgi.framework.storage.clean", "onFirstInit");
 
     // test each available OSGi framework in turn
-    Iterator<FrameworkFactory> f = ServiceRegistry.lookupProviders(FrameworkFactory.class);
-    while (f.hasNext()) {
-      Framework framework = f.next().newFramework(properties);
+    for (FrameworkFactory frameworkFactory : ServiceLoader.load(FrameworkFactory.class)) {
+      Framework framework = frameworkFactory.newFramework(properties);
 
       framework.start();
       BundleContext systemContext = framework.getBundleContext();
 
       // load all the necessary bundles and start the OSGi test bundle
-/*if[AOP]*/
+      /*if[AOP]*/
       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/aopalliance.jar");
-/*end[AOP]*/
+      /*end[AOP]*/
       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/javax.inject.jar");
       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/guava.jar");
       systemContext.installBundle("reference:file:" + GUICE_JAR);
diff --git a/core/test/com/googlecode/guice/PackageVisibilityTestModule.java b/core/test/com/googlecode/guice/PackageVisibilityTestModule.java
index f228684..1e55666 100644
--- a/core/test/com/googlecode/guice/PackageVisibilityTestModule.java
+++ b/core/test/com/googlecode/guice/PackageVisibilityTestModule.java
@@ -11,8 +11,11 @@
   }
 
   public static class PublicUserOfPackagePrivate {
-    @Inject public PublicUserOfPackagePrivate(PackagePrivateInterface ppi) {}
-    @Inject public void acceptPackagePrivateParameter(PackagePrivateInterface ppi) {}
+    @Inject
+    public PublicUserOfPackagePrivate(PackagePrivateInterface ppi) {}
+
+    @Inject
+    public void acceptPackagePrivateParameter(PackagePrivateInterface ppi) {}
   }
 
   interface PackagePrivateInterface {}
diff --git a/core/test/com/googlecode/guice/bundle/OSGiTestActivator.java b/core/test/com/googlecode/guice/bundle/OSGiTestActivator.java
index 67caee5..5d6b99e 100644
--- a/core/test/com/googlecode/guice/bundle/OSGiTestActivator.java
+++ b/core/test/com/googlecode/guice/bundle/OSGiTestActivator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,23 +24,21 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.matcher.AbstractMatcher;
-
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Random;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Random;
-
 /**
  * Test Guice from inside an OSGi bundle activator.
- * 
+ *
  * @author mcculls@gmail.com (Stuart McCulloch)
  */
-@SuppressWarnings("unused") public class OSGiTestActivator
-    implements BundleActivator {
+@SuppressWarnings("unused")
+public class OSGiTestActivator implements BundleActivator {
 
   // varying visibilities to test our code-generation support
 
@@ -54,18 +52,21 @@
 
   private interface D {}
 
-  public static class AA
-      implements A {
+  public static class AA implements A {
 
     public AA() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -76,18 +77,21 @@
     @Inject private Undefined d;
   }
 
-  protected static class AB
-      implements A {
+  protected static class AB implements A {
 
     public AB() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -98,18 +102,21 @@
     @Inject private Undefined d;
   }
 
-  static class AC
-      implements A {
+  static class AC implements A {
 
     public AC() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -120,18 +127,21 @@
     @Inject private Undefined d;
   }
 
-  private static class AD
-      implements A {
+  private static class AD implements A {
 
     public AD() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -142,18 +152,21 @@
     @Inject private Undefined d;
   }
 
-  public static class BA
-      implements B {
+  public static class BA implements B {
 
     protected BA() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -164,18 +177,21 @@
     @Inject private Undefined d;
   }
 
-  protected static class BB
-      implements B {
+  protected static class BB implements B {
 
     protected BB() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -186,18 +202,21 @@
     @Inject private Undefined d;
   }
 
-  static class BC
-      implements B {
+  static class BC implements B {
 
     protected BC() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -208,18 +227,21 @@
     @Inject private Undefined d;
   }
 
-  private static class BD
-      implements B {
+  private static class BD implements B {
 
     protected BD() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -230,18 +252,21 @@
     @Inject private Undefined d;
   }
 
-  public static class CA
-      implements C {
+  public static class CA implements C {
 
     CA() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -252,18 +277,21 @@
     @Inject private Undefined d;
   }
 
-  protected static class CB
-      implements C {
+  protected static class CB implements C {
 
     CB() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -274,18 +302,21 @@
     @Inject private Undefined d;
   }
 
-  static class CC
-      implements C {
+  static class CC implements C {
 
     CC() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -296,18 +327,21 @@
     @Inject private Undefined d;
   }
 
-  private static class CD
-      implements C {
+  private static class CD implements C {
 
     CD() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -318,18 +352,22 @@
     @Inject private Undefined d;
   }
 
-  public static class DA
-      implements D {
+  public static class DA implements D {
 
-    @Inject private DA() {}
+    @Inject
+    private DA() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -340,18 +378,22 @@
     @Inject private Undefined d;
   }
 
-  protected static class DB
-      implements D {
+  protected static class DB implements D {
 
-    @Inject private DB() {}
+    @Inject
+    private DB() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -362,18 +404,22 @@
     @Inject private Undefined d;
   }
 
-  static class DC
-      implements D {
+  static class DC implements D {
 
-    @Inject private DC() {}
+    @Inject
+    private DC() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -384,18 +430,21 @@
     @Inject private Undefined d;
   }
 
-  private static class DD
-      implements D {
+  private static class DD implements D {
 
     private DD() {}
 
-    @Inject public void setA(Undefined undefined) {}
+    @Inject
+    public void setA(Undefined undefined) {}
 
-    @Inject protected void setB(Undefined undefined) {}
+    @Inject
+    protected void setB(Undefined undefined) {}
 
-    @Inject void setC(Undefined undefined) {}
+    @Inject
+    void setC(Undefined undefined) {}
 
-    @Inject private void setD(Undefined undefined) {}
+    @Inject
+    private void setD(Undefined undefined) {}
 
     @Inject public Undefined a;
 
@@ -407,14 +456,16 @@
   }
 
   enum Visibility {
-    PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE
+    PUBLIC,
+    PROTECTED,
+    PACKAGE_PRIVATE,
+    PRIVATE
   }
 
   static final Class<?>[] TEST_CLAZZES = {A.class, B.class, C.class, D.class};
 
   // registers all the class combinations
-  static class TestModule
-      extends AbstractModule {
+  static class TestModule extends AbstractModule {
 
     final Bundle bundle;
 
@@ -422,7 +473,9 @@
       this.bundle = bundle;
     }
 
-    @Override @SuppressWarnings("unchecked") protected void configure() {
+    @Override
+    @SuppressWarnings("unchecked")
+    protected void configure() {
       for (Class<?> api : TEST_CLAZZES) {
         for (Visibility visibility : Visibility.values()) {
           try {
@@ -440,72 +493,77 @@
     }
   }
 
-/*if[AOP]*/
+  /*if[AOP]*/
   // applies method-interception to classes with enough visibility
-  static class InterceptorModule
-      extends AbstractModule {
-    @Override protected void configure() {
-      bindInterceptor(new AbstractMatcher<Class<?>>() {
-        public boolean matches(Class<?> clazz) {
-          try {
+  static class InterceptorModule extends AbstractModule {
+    @Override
+    protected void configure() {
+      bindInterceptor(
+          new AbstractMatcher<Class<?>>() {
+            @Override
+            public boolean matches(Class<?> clazz) {
+              try {
 
-            // the class and constructor must be visible
-            int clazzModifiers = clazz.getModifiers();
-            int ctorModifiers = clazz.getConstructor().getModifiers();
-            return (clazzModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0
-                && (ctorModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
+                // the class and constructor must be visible
+                int clazzModifiers = clazz.getModifiers();
+                int ctorModifiers = clazz.getConstructor().getModifiers();
+                return (clazzModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0
+                    && (ctorModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
 
-          } catch (NoSuchMethodException e) {
-            return false;
-          }
-        }
-      }, new AbstractMatcher<Method>() {
-        public boolean matches(Method method) {
+              } catch (NoSuchMethodException e) {
+                return false;
+              }
+            }
+          },
+          new AbstractMatcher<Method>() {
+            @Override
+            public boolean matches(Method method) {
 
-          // the intercepted method must also be visible
-          int methodModifiers = method.getModifiers();
-          return (methodModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
+              // the intercepted method must also be visible
+              int methodModifiers = method.getModifiers();
+              return (methodModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
+            }
+          },
+          new org.aopalliance.intercept.MethodInterceptor() {
+            @Override
+            public Object invoke(org.aopalliance.intercept.MethodInvocation mi) throws Throwable {
 
-        }
-      }, new org.aopalliance.intercept.MethodInterceptor() {
-        public Object invoke(org.aopalliance.intercept.MethodInvocation mi)
-            throws Throwable {
-
-          return mi.proceed();
-        }
-      });
+              return mi.proceed();
+            }
+          });
     }
   }
-/*end[AOP]*/
+  /*end[AOP]*/
 
   // called from OSGi when bundle starts
-  public void start(BundleContext context)
-      throws BundleException {
+  @Override
+  public void start(BundleContext context) throws BundleException {
 
     final Bundle bundle = context.getBundle();
 
     Injector injector = Guice.createInjector(new TestModule(bundle));
-/*if[AOP]*/
+    /*if[AOP]*/
     Injector aopInjector = Guice.createInjector(new TestModule(bundle), new InterceptorModule());
-/*end[AOP]*/
+    /*end[AOP]*/
 
     // test code-generation support
     for (Class<?> api : TEST_CLAZZES) {
       for (Visibility vis : Visibility.values()) {
         injector.getInstance(Key.get(api, named(vis.name())));
-/*if[AOP]*/
+        /*if[AOP]*/
         aopInjector.getInstance(Key.get(api, named(vis.name())));
-/*end[AOP]*/
+        /*end[AOP]*/
       }
     }
 
     // test injection of system class (issue 343)
     injector.getInstance(Random.class);
-/*if[AOP]*/
+    /*if[AOP]*/
     aopInjector.getInstance(Random.class);
-/*end[AOP]*/
+    /*end[AOP]*/
   }
 
   // called from OSGi when bundle stops
+  @Override
   public void stop(BundleContext context) {}
 }
diff --git a/examples/src/example/xml/Contact.java b/examples/src/example/xml/Contact.java
index 160dbdc..a5c1c56 100644
--- a/examples/src/example/xml/Contact.java
+++ b/examples/src/example/xml/Contact.java
@@ -1,5 +1,3 @@
 package example.xml;
 
-public class Contact {
-
-}
+public class Contact {}
diff --git a/examples/src/example/xml/FromFlash.java b/examples/src/example/xml/FromFlash.java
index def2044..ba45f9d 100644
--- a/examples/src/example/xml/FromFlash.java
+++ b/examples/src/example/xml/FromFlash.java
@@ -1,7 +1,8 @@
 package example.xml;
 
-import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.*;
 
+import java.lang.annotation.Retention;
+
 @Retention(RUNTIME)
-public @interface FromFlash {}
\ No newline at end of file
+public @interface FromFlash {}
diff --git a/examples/src/example/xml/FromSim.java b/examples/src/example/xml/FromSim.java
index 47ed416..5a83d95 100644
--- a/examples/src/example/xml/FromSim.java
+++ b/examples/src/example/xml/FromSim.java
@@ -1,7 +1,8 @@
 package example.xml;
 
-import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.*;
 
+import java.lang.annotation.Retention;
+
 @Retention(RUNTIME)
 public @interface FromSim {}
diff --git a/examples/src/example/xml/Main.java b/examples/src/example/xml/Main.java
index 6983dec..0e73cd3 100644
--- a/examples/src/example/xml/Main.java
+++ b/examples/src/example/xml/Main.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,26 +16,25 @@
 
 package example.xml;
 
-import com.google.inject.Guice;
 import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
 import com.google.inject.Injector;
 import java.net.URL;
 
-/**
- *
- *
- */
+/** */
 public class Main {
 
   public static void main(String[] args) {
     final URL xmlUrl = Main.class.getResource("phone.xml");
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Contacts.class).to(SimCard.class);
-        install(new XmlBeanModule(xmlUrl));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              protected void configure() {
+                bind(Contacts.class).to(SimCard.class);
+                install(new XmlBeanModule(xmlUrl));
+              }
+            });
 
     Phone phone = injector.getInstance(Phone.class);
 
diff --git a/examples/src/example/xml/SimCard.java b/examples/src/example/xml/SimCard.java
index 71cf39b..8454cee 100644
--- a/examples/src/example/xml/SimCard.java
+++ b/examples/src/example/xml/SimCard.java
@@ -7,4 +7,4 @@
   public Iterable<Contact> findByName(String name) {
     return Collections.emptyList();
   }
-}
\ No newline at end of file
+}
diff --git a/examples/src/example/xml/XmlBeanModule.java b/examples/src/example/xml/XmlBeanModule.java
index 8701d68..99c0ad6 100644
--- a/examples/src/example/xml/XmlBeanModule.java
+++ b/examples/src/example/xml/XmlBeanModule.java
@@ -1,9 +1,9 @@
 package example.xml;
 
+import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provider;
-import com.google.inject.Binder;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.lang.reflect.InvocationTargetException;
@@ -47,8 +47,7 @@
 
       Reader in = new InputStreamReader(xmlUrl.openStream());
       Parsers.parse(in, beans.getContentHandler());
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
       originalBinder.addError(e);
     }
   }
@@ -71,8 +70,7 @@
       Class<?> type;
       try {
         type = Class.forName(typeString);
-      }
-      catch (ClassNotFoundException e) {
+      } catch (ClassNotFoundException e) {
         sourced.addError(e);
         return;
       }
@@ -80,8 +78,7 @@
       // Look for a no-arg constructor.
       try {
         type.getConstructor();
-      }
-      catch (NoSuchMethodException e) {
+      } catch (NoSuchMethodException e) {
         sourced.addError("%s doesn't have a no-arg constructor.");
         return;
       }
@@ -135,21 +132,18 @@
       // Validate number of parameters.
       Type[] parameterTypes = setter.getGenericParameterTypes();
       if (parameterTypes.length != 1) {
-        sourced.addError("%s.%s() must take one argument.",
-            setterName, type.getName());
+        sourced.addError("%s.%s() must take one argument.", setterName, type.getName());
         return;
       }
 
       // Add property descriptor to builder.
       Provider<?> provider = sourced.getProvider(Key.get(parameterTypes[0]));
-      beanBuilder.properties.add(
-          new Property(setter, provider));
+      beanBuilder.properties.add(new Property(setter, provider));
     }
   }
 
   static String capitalize(String s) {
-    return Character.toUpperCase(s.charAt(0)) +
-        s.substring(1);
+    return Character.toUpperCase(s.charAt(0)) + s.substring(1);
   }
 
   static class Property {
@@ -165,19 +159,17 @@
     void setOn(Object o) {
       try {
         setter.invoke(o, provider.get());
-      }
-      catch (IllegalAccessException e) {
+      } catch (IllegalAccessException e) {
         throw new RuntimeException(e);
-      }
-      catch (InvocationTargetException e) {
+      } catch (InvocationTargetException e) {
         throw new RuntimeException(e);
       }
     }
   }
 
   class BeanBuilder {
-    
-    final List<Property> properties = new ArrayList<Property>();
+
+    final List<Property> properties = new ArrayList<>();
     final Class<?> type;
 
     BeanBuilder(Class<?> type) {
@@ -189,8 +181,10 @@
     }
 
     <T> void addBinding(Class<T> type) {
-      originalBinder.withSource(xmlSource())
-          .bind(type).toProvider(new BeanProvider<T>(type, properties));
+      originalBinder
+          .withSource(xmlSource())
+          .bind(type)
+          .toProvider(new BeanProvider<T>(type, properties));
     }
   }
 
@@ -211,11 +205,9 @@
           property.setOn(t);
         }
         return t;
-      }
-      catch (InstantiationException e) {
+      } catch (InstantiationException e) {
         throw new RuntimeException(e);
-      }
-      catch (IllegalAccessException e) {
+      } catch (IllegalAccessException e) {
         throw new RuntimeException(e);
       }
     }
diff --git a/extensions/assistedinject/pom.xml b/extensions/assistedinject/pom.xml
index 5fdb8b2..5baa9c0 100644
--- a/extensions/assistedinject/pom.xml
+++ b/extensions/assistedinject/pom.xml
@@ -6,11 +6,26 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-assistedinject</artifactId>
 
   <name>Google Guice - Extensions - AssistedInject</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.assistedinject</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
 </project>
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java b/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
index bdd633e..90e95fc 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
@@ -32,12 +31,14 @@
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  */
-@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
+@BindingAnnotation
+@Target({FIELD, PARAMETER, METHOD})
+@Retention(RUNTIME)
 public @interface Assisted {
 
   /**
-   * The unique name for this parameter. This is matched to the {@literal @Assisted} constructor 
+   * The unique name for this parameter. This is matched to the {@literal @Assisted} constructor
    * parameter with the same value. Names are not necessary when the parameter types are distinct.
    */
   String value() default "";
-}
\ No newline at end of file
+}
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
index 7ea0498..6284522 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,6 @@
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
 import com.google.inject.TypeLiteral;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -31,9 +30,8 @@
 import java.util.Set;
 
 /**
- * Internal respresentation of a constructor annotated with
- * {@link AssistedInject}
- * 
+ * Internal respresentation of a constructor annotated with {@link AssistedInject}
+ *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  */
@@ -42,7 +40,7 @@
   private final Constructor<T> constructor;
   private final ParameterListKey assistedParameters;
   private final List<Parameter> allParameters;
-  
+
   public static <T> AssistedConstructor<T> create(
       Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes) {
     return new AssistedConstructor<T>(constructor, parameterTypes);
@@ -54,7 +52,7 @@
     Annotation[][] annotations = constructor.getParameterAnnotations();
 
     List<Type> typeList = Lists.newArrayList();
-    allParameters = new ArrayList<Parameter>();
+    allParameters = new ArrayList<>();
 
     // categorize params as @Assisted or @Injected
     for (int i = 0; i < parameterTypes.size(); i++) {
@@ -66,19 +64,18 @@
     }
     this.assistedParameters = new ParameterListKey(typeList);
   }
-  
+
   /**
-   * Returns the {@link ParameterListKey} for this constructor.  The
-   * {@link ParameterListKey} is created from the ordered list of {@link Assisted}
-   * constructor parameters.
+   * Returns the {@link ParameterListKey} for this constructor. The {@link ParameterListKey} is
+   * created from the ordered list of {@link Assisted} constructor parameters.
    */
   public ParameterListKey getAssistedParameters() {
     return assistedParameters;
   }
-  
+
   /**
-   * Returns an ordered list of all constructor parameters (both
-   * {@link Assisted} and {@link Inject}ed).
+   * Returns an ordered list of all constructor parameters (both {@link Assisted} and {@link
+   * Inject}ed).
    */
   public List<Parameter> getAllParameters() {
     return allParameters;
@@ -87,11 +84,8 @@
   public Set<Class<?>> getDeclaredExceptions() {
     return new HashSet<Class<?>>(Arrays.asList(constructor.getExceptionTypes()));
   }
-  
-  /**
-   * Returns an instance of T, constructed using this constructor, with the
-   * supplied arguments.
-   */
+
+  /** Returns an instance of T, constructed using this constructor, with the supplied arguments. */
   public T newInstance(Object[] args) throws Throwable {
     constructor.setAccessible(true);
     try {
@@ -100,7 +94,7 @@
       throw e.getCause();
     }
   }
-  
+
   @Override
   public String toString() {
     return constructor.toString();
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
index b639229..e477677 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,36 +20,31 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.Inject;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * <p>
- * When used in tandem with {@link FactoryModuleBuilder}, constructors annotated with 
+ * When used in tandem with {@link FactoryModuleBuilder}, constructors annotated with
  * {@code @AssistedInject} indicate that multiple constructors can be injected, each with different
  * parameters. AssistedInject annotations should not be mixed with {@literal @}{@link Inject}
  * annotations. The assisted parameters must exactly match one corresponding factory method within
  * the factory interface, but the parameters do not need to be in the same order. Constructors
- * annotated with AssistedInject <b>are</b> created by Guice and receive all the benefits
- * (such as AOP).
- * 
- * <p>
- * <strong>Obsolete Usage:</strong> When used in tandem with {@link FactoryProvider}, constructors
- * annotated with {@code @AssistedInject} trigger a "backwards compatibility mode". The assisted
- * parameters must exactly match one corresponding factory method within the factory interface and
- * all must be in the same order as listed in the factory. In this backwards compatable mode,
- * constructors annotated with AssistedInject <b>are not</b> created by Guice and thus receive
- * none of the benefits.
- * 
- * <p>
- * Constructor parameters must be either supplied by the factory interface and marked with
- * <code>@Assisted</code>, or they must be injectable.
- * 
+ * annotated with AssistedInject <b>are</b> created by Guice and receive all the benefits (such as
+ * AOP).
+ *
+ * <p><strong>Obsolete Usage:</strong> When used in tandem with {@link FactoryProvider},
+ * constructors annotated with {@code @AssistedInject} trigger a "backwards compatibility mode". The
+ * assisted parameters must exactly match one corresponding factory method within the factory
+ * interface and all must be in the same order as listed in the factory. In this backwards
+ * compatable mode, constructors annotated with AssistedInject <b>are not</b> created by Guice and
+ * thus receive none of the benefits.
+ *
+ * <p>Constructor parameters must be either supplied by the factory interface and marked with <code>
+ * @Assisted</code>, or they must be injectable.
+ *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  */
-@Target( { CONSTRUCTOR })
+@Target({CONSTRUCTOR})
 @Retention(RUNTIME)
-public @interface AssistedInject {
-}
+public @interface AssistedInject {}
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectBinding.java b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectBinding.java
index f598ba2..798621d 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectBinding.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,19 +17,17 @@
 package com.google.inject.assistedinject;
 
 import com.google.inject.Key;
-
 import java.util.Collection;
 
 /**
  * A binding for a factory created by FactoryModuleBuilder.
- * 
+ *
  * @param <T> The fully qualified type of the factory.
- *  
  * @since 3.0
  * @author ramakrishna@google.com (Ramakrishna Rajanna)
  */
 public interface AssistedInjectBinding<T> {
-  
+
   /** Returns the {@link Key} for the factory binding. */
   Key<T> getKey();
 
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectTargetVisitor.java b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectTargetVisitor.java
index 8e03a40..09fbc92 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectTargetVisitor.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInjectTargetVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,17 +20,15 @@
 
 /**
  * A visitor for the AssistedInject extension.
- * <p>
- * If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ *
+ * <p>If your {@link BindingTargetVisitor} implements this interface, bindings created by using
  * {@link FactoryModuleBuilder} will be visited through this interface.
  *
  * @since 3.0
  * @author ramakrishna@google.com (Ramakrishna Rajanna)
  */
 public interface AssistedInjectTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
-  
-  /**
-   * Visits an {@link AssistedInjectBinding} created through {@link FactoryModuleBuilder}.
-   */
+
+  /** Visits an {@link AssistedInjectBinding} created through {@link FactoryModuleBuilder}. */
   V visit(AssistedInjectBinding<? extends T> assistedInjectBinding);
 }
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedMethod.java b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedMethod.java
index 08d7d6c..75a5af7 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedMethod.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedMethod.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,39 +18,27 @@
 
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.Dependency;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.Set;
 
 /**
  * Details about how a method in an assisted inject factory will be assisted.
- * 
+ *
  * @since 3.0
  * @author ramakrishna@google.com (Ramakrishna Rajanna)
  */
 public interface AssistedMethod {
-  
-  /**
-   * Returns the factory method that is being assisted.
-   */
+
+  /** Returns the factory method that is being assisted. */
   Method getFactoryMethod();
-  
-  /**
-   * Returns the implementation type that will be created when the method is
-   * used.
-   */
+
+  /** Returns the implementation type that will be created when the method is used. */
   TypeLiteral<?> getImplementationType();
 
-  /**
-   * Returns the constructor that will be used to construct instances of the 
-   * implementation.
-   */
+  /** Returns the constructor that will be used to construct instances of the implementation. */
   Constructor<?> getImplementationConstructor();
-  
-  /**
-   * Returns all non-assisted dependencies required to construct and inject
-   * the implementation.
-   */
+
+  /** Returns all non-assisted dependencies required to construct and inject the implementation. */
   Set<Dependency<?>> getDependencies();
 }
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/BindingCollector.java b/extensions/assistedinject/src/com/google/inject/assistedinject/BindingCollector.java
index a90494b..92d3288 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/BindingCollector.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/BindingCollector.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
 import com.google.inject.Key;
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.Message;
-
 import java.util.Collections;
 import java.util.Map;
 
@@ -36,8 +35,8 @@
 
   public BindingCollector addBinding(Key<?> key, TypeLiteral<?> target) {
     if (bindings.containsKey(key)) {
-      throw new ConfigurationException(ImmutableSet.of(
-          new Message("Only one implementation can be specified for " + key)));
+      throw new ConfigurationException(
+          ImmutableSet.of(new Message("Only one implementation can be specified for " + key)));
     }
 
     bindings.put(key, target);
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryModuleBuilder.java b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryModuleBuilder.java
index 0ae096e..f014294 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryModuleBuilder.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryModuleBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
-
 import java.lang.annotation.Annotation;
 
 /**
@@ -29,6 +28,7 @@
  * construct objects.
  *
  * <h3>Defining a factory</h3>
+ *
  * Create an interface whose methods return the constructed type, or any of its supertypes. The
  * method's parameters are the arguments required to build the constructed type.
  *
@@ -40,6 +40,7 @@
  * or <i>newPayment</i>.
  *
  * <h3>Creating a type that accepts factory parameters</h3>
+ *
  * {@code constructedType} is a concrete class with an {@literal @}{@link com.google.inject.Inject
  * Inject}-annotated constructor. In addition to injector-supplied parameters, the constructor
  * should have parameters that match each of the factory method's parameters. Each factory-supplied
@@ -56,18 +57,18 @@
  *     ...
  *   }
  * }</pre>
- * 
+ *
  * <h3>Multiple factory methods for the same type</h3>
+ *
  * If the factory contains many methods that return the same type, you can create multiple
- * constructors in your concrete class, each constructor marked with with
- * {@literal @}{@link AssistedInject}, in order to match the different parameters types of the
- * factory methods. 
- * 
+ * constructors in your concrete class, each constructor marked with with {@literal @}{@link
+ * AssistedInject}, in order to match the different parameters types of the factory methods.
+ *
  * <pre>public interface PaymentFactory {
  *    Payment create(Date startDate, Money amount);
  *    Payment createWithoutDate(Money amount);
  * }
- * 
+ *
  * public class RealPayment implements Payment {
  *  {@literal @}AssistedInject
  *   public RealPayment(
@@ -77,19 +78,19 @@
  *     <strong>{@literal @}Assisted Money amount</strong>) {
  *     ...
  *   }
- *   
+ *
  *  {@literal @}AssistedInject
  *   public RealPayment(
  *      CreditService creditService,
  *      AuthService authService,
  *     <strong>{@literal @}Assisted Money amount</strong>) {
  *     ...
- *   }   
- * }</pre> 
+ *   }
+ * }</pre>
  *
  * <h3>Configuring simple factories</h3>
- * In your {@link Module module}, install a {@code FactoryModuleBuilder} that creates the
- * factory:
+ *
+ * In your {@link Module module}, install a {@code FactoryModuleBuilder} that creates the factory:
  *
  * <pre>install(new FactoryModuleBuilder()
  *     .implement(Payment.class, RealPayment.class)
@@ -97,30 +98,33 @@
  *
  * As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
  * factory cannot be used until the injector has been initialized.
- * 
+ *
  * <h3>Configuring complex factories</h3>
- * Factories can create an arbitrary number of objects, one per each method.  Each factory
- * method can be configured using <code>.implement</code>.
+ *
+ * Factories can create an arbitrary number of objects, one per each method. Each factory method can
+ * be configured using <code>.implement</code>.
  *
  * <pre>public interface OrderFactory {
  *    Payment create(Date startDate, Money amount);
  *    Shipment create(Customer customer, Item item);
  *    Receipt create(Payment payment, Shipment shipment);
  * }
- * 
+ *
  * [...]
- * 
+ *
  * install(new FactoryModuleBuilder()
  *     .implement(Payment.class, RealPayment.class)
  *     // excluding .implement for Shipment means the implementation class
  *     // will be 'Shipment' itself, which is legal if it's not an interface.
  *     .implement(Receipt.class, RealReceipt.class)
  *     .build(OrderFactory.class));</pre>
+ *
  * </pre>
  *
  * <h3>Using the factory</h3>
- * Inject your factory into your application classes. When you use the factory, your arguments
- * will be combined with values from the injector to construct an instance.
+ *
+ * Inject your factory into your application classes. When you use the factory, your arguments will
+ * be combined with values from the injector to construct an instance.
  *
  * <pre>public class PaymentAction {
  *   {@literal @}Inject private PaymentFactory paymentFactory;
@@ -132,9 +136,10 @@
  * }</pre>
  *
  * <h3>Making parameter types distinct</h3>
- * The types of the factory method's parameters must be distinct. To use multiple parameters of
- * the same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the
- * parameters. The names must be applied to the factory method's parameters:
+ *
+ * The types of the factory method's parameters must be distinct. To use multiple parameters of the
+ * same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the parameters.
+ * The names must be applied to the factory method's parameters:
  *
  * <pre>public interface PaymentFactory {
  *   Payment create(
@@ -158,15 +163,17 @@
  * }</pre>
  *
  * <h3>Values are created by Guice</h3>
+ *
  * Returned factories use child injectors to create values. The values are eligible for method
  * interception. In addition, {@literal @}{@literal Inject} members will be injected before they are
  * returned.
  *
  * <h3>More configuration options</h3>
+ *
  * In addition to simply specifying an implementation class for any returned type, factories' return
  * values can be automatic or can be configured to use annotations:
- * <p/>
- * If you just want to return the types specified in the factory, do not configure any
+ *
+ * <p>If you just want to return the types specified in the factory, do not configure any
  * implementations:
  *
  * <pre>public interface FruitFactory {
@@ -178,8 +185,8 @@
  * }</pre>
  *
  * Note that any type returned by the factory in this manner needs to be an implementation class.
- * <p/>
- * To return two different implementations for the same interface from your factory, use binding
+ *
+ * <p>To return two different implementations for the same interface from your factory, use binding
  * annotations on your return types:
  *
  * <pre>interface CarFactory {
@@ -193,10 +200,11 @@
  *       .implement(Car.class, Names.named("clean"), Prius.class)
  *       .build(CarFactory.class));
  * }</pre>
- * 
+ *
  * <h3>Implementation limitations</h3>
- * As a limitation of the implementation, it is prohibited to declare a factory method that
- * accepts a {@code Provider} as one of its arguments.
+ *
+ * As a limitation of the implementation, it is prohibited to declare a factory method that accepts
+ * a {@code Provider} as one of its arguments.
  *
  * @since 3.0
  * @author schmitt@google.com (Peter Schmitt)
@@ -205,133 +213,107 @@
 
   private final BindingCollector bindings = new BindingCollector();
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <T> FactoryModuleBuilder implement(Class<T> source, Class<? extends T> target) {
     return implement(source, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <T> FactoryModuleBuilder implement(Class<T> source, TypeLiteral<? extends T> target) {
     return implement(TypeLiteral.get(source), target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Class<? extends T> target) {
     return implement(source, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(TypeLiteral<T> source,
-      TypeLiteral<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      TypeLiteral<T> source, TypeLiteral<? extends T> target) {
     return implement(Key.get(source), target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(Class<T> source, Annotation annotation,
-      Class<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      Class<T> source, Annotation annotation, Class<? extends T> target) {
     return implement(source, annotation, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(Class<T> source, Annotation annotation,
-      TypeLiteral<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      Class<T> source, Annotation annotation, TypeLiteral<? extends T> target) {
     return implement(TypeLiteral.get(source), annotation, target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Annotation annotation,
-      Class<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      TypeLiteral<T> source, Annotation annotation, Class<? extends T> target) {
     return implement(source, annotation, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Annotation annotation,
-      TypeLiteral<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      TypeLiteral<T> source, Annotation annotation, TypeLiteral<? extends T> target) {
     return implement(Key.get(source, annotation), target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(Class<T> source,
-      Class<? extends Annotation> annotationType, Class<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      Class<T> source, Class<? extends Annotation> annotationType, Class<? extends T> target) {
     return implement(source, annotationType, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(Class<T> source,
-      Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      Class<T> source,
+      Class<? extends Annotation> annotationType,
+      TypeLiteral<? extends T> target) {
     return implement(TypeLiteral.get(source), annotationType, target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(TypeLiteral<T> source,
-      Class<? extends Annotation> annotationType, Class<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      TypeLiteral<T> source,
+      Class<? extends Annotation> annotationType,
+      Class<? extends T> target) {
     return implement(source, annotationType, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
-  public <T> FactoryModuleBuilder implement(TypeLiteral<T> source,
-      Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target) {
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
+  public <T> FactoryModuleBuilder implement(
+      TypeLiteral<T> source,
+      Class<? extends Annotation> annotationType,
+      TypeLiteral<? extends T> target) {
     return implement(Key.get(source, annotationType), target);
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <T> FactoryModuleBuilder implement(Key<T> source, Class<? extends T> target) {
     return implement(source, TypeLiteral.get(target));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <T> FactoryModuleBuilder implement(Key<T> source, TypeLiteral<? extends T> target) {
     bindings.addBinding(source, target);
     return this;
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <F> Module build(Class<F> factoryInterface) {
     return build(TypeLiteral.get(factoryInterface));
   }
 
-  /**
-   * See the factory configuration examples at {@link FactoryModuleBuilder}.
-   */
+  /** See the factory configuration examples at {@link FactoryModuleBuilder}. */
   public <F> Module build(TypeLiteral<F> factoryInterface) {
     return build(Key.get(factoryInterface));
   }
 
-
   public <F> Module build(final Key<F> factoryInterface) {
     return new AbstractModule() {
-      @Override protected void configure() {
-        Provider<F> provider = new FactoryProvider2<F>(factoryInterface, bindings);
+      @Override
+      protected void configure() {
+        Provider<F> provider = new FactoryProvider2<>(factoryInterface, bindings);
         bind(factoryInterface).toProvider(provider);
       }
     };
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
index b9619e3..cdce83e 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,7 +35,6 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.Message;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
@@ -54,20 +53,25 @@
  * construct objects.
  *
  * <h3>Defining a factory</h3>
+ *
  * Create an interface whose methods return the constructed type, or any of its supertypes. The
  * method's parameters are the arguments required to build the constructed type.
+ *
  * <pre>public interface PaymentFactory {
  *   Payment create(Date startDate, Money amount);
  * }</pre>
+ *
  * You can name your factory methods whatever you like, such as <i>create</i>, <i>createPayment</i>
  * or <i>newPayment</i>.
  *
  * <h3>Creating a type that accepts factory parameters</h3>
+ *
  * {@code constructedType} is a concrete class with an {@literal @}{@link Inject}-annotated
- * constructor. In addition to injector-supplied parameters, the constructor should have
- * parameters that match each of the factory method's parameters. Each factory-supplied parameter
- * requires an {@literal @}{@link Assisted} annotation. This serves to document that the parameter
- * is not bound by your application's modules.
+ * constructor. In addition to injector-supplied parameters, the constructor should have parameters
+ * that match each of the factory method's parameters. Each factory-supplied parameter requires an
+ * {@literal @}{@link Assisted} annotation. This serves to document that the parameter is not bound
+ * by your application's modules.
+ *
  * <pre>public class RealPayment implements Payment {
  *   {@literal @}Inject
  *   public RealPayment(
@@ -78,19 +82,25 @@
  *     ...
  *   }
  * }</pre>
+ *
  * Any parameter that permits a null value should also be annotated {@code @Nullable}.
  *
  * <h3>Configuring factories</h3>
+ *
  * In your {@link com.google.inject.Module module}, bind the factory interface to the returned
  * factory:
+ *
  * <pre>bind(PaymentFactory.class).toProvider(
  *     FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));</pre>
+ *
  * As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
  * factory cannot be used until the injector has been initialized.
  *
  * <h3>Using the factory</h3>
- * Inject your factory into your application classes. When you use the factory, your arguments
- * will be combined with values from the injector to construct an instance.
+ *
+ * Inject your factory into your application classes. When you use the factory, your arguments will
+ * be combined with values from the injector to construct an instance.
+ *
  * <pre>public class PaymentAction {
  *   {@literal @}Inject private PaymentFactory paymentFactory;
  *
@@ -101,9 +111,10 @@
  * }</pre>
  *
  * <h3>Making parameter types distinct</h3>
- * The types of the factory method's parameters must be distinct. To use multiple parameters of
- * the same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the
- * parameters. The names must be applied to the factory method's parameters:
+ *
+ * The types of the factory method's parameters must be distinct. To use multiple parameters of the
+ * same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the parameters.
+ * The names must be applied to the factory method's parameters:
  *
  * <pre>public interface PaymentFactory {
  *   Payment create(
@@ -111,7 +122,9 @@
  *       <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
  *       Money amount);
  * } </pre>
+ *
  * ...and to the concrete type's constructor parameters:
+ *
  * <pre>public class RealPayment implements Payment {
  *   {@literal @}Inject
  *   public RealPayment(
@@ -125,28 +138,27 @@
  * }</pre>
  *
  * <h3>Values are created by Guice</h3>
+ *
  * Returned factories use child injectors to create values. The values are eligible for method
  * interception. In addition, {@literal @}{@literal Inject} members will be injected before they are
  * returned.
  *
  * <h3>Backwards compatibility using {@literal @}AssistedInject</h3>
+ *
  * Instead of the {@literal @}Inject annotation, you may annotate the constructed classes with
  * {@literal @}{@link AssistedInject}. This triggers a limited backwards-compatability mode.
  *
  * <p>Instead of matching factory method arguments to constructor parameters using their names, the
- * <strong>parameters are matched by their order</strong>. The first factory method argument is
- * used for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no
- * effect.
+ * <strong>parameters are matched by their order</strong>. The first factory method argument is used
+ * for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no effect.
  *
  * <p>Returned values are <strong>not created by Guice</strong>. These types are not eligible for
  * method interception. They do receive post-construction member injection.
  *
  * @param <F> The factory interface
- *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  * @author dtm@google.com (Daniel Martin)
- * 
  * @deprecated use {@link FactoryModuleBuilder} instead.
  */
 @Deprecated
@@ -163,14 +175,14 @@
   private final TypeLiteral<?> implementationType;
   private final Map<Method, AssistedConstructor<?>> factoryMethodToConstructor;
 
-  public static <F> Provider<F> newFactory(Class<F> factoryType, Class<?> implementationType){
+  public static <F> Provider<F> newFactory(Class<F> factoryType, Class<?> implementationType) {
     return newFactory(TypeLiteral.get(factoryType), TypeLiteral.get(implementationType));
   }
 
   public static <F> Provider<F> newFactory(
       TypeLiteral<F> factoryType, TypeLiteral<?> implementationType) {
-    Map<Method, AssistedConstructor<?>> factoryMethodToConstructor
-        = createMethodMapping(factoryType, implementationType);
+    Map<Method, AssistedConstructor<?>> factoryMethodToConstructor =
+        createMethodMapping(factoryType, implementationType);
 
     if (!factoryMethodToConstructor.isEmpty()) {
       return new FactoryProvider<F>(factoryType, implementationType, factoryMethodToConstructor);
@@ -184,12 +196,12 @@
 
       try {
         for (Method method : factoryType.getRawType().getMethods()) {
-          Key<?> returnType = getKey(factoryType.getReturnType(method), method,
-              method.getAnnotations(), errors);
+          Key<?> returnType =
+              getKey(factoryType.getReturnType(method), method, method.getAnnotations(), errors);
           if (!implementationKey.equals(returnType)) {
             collector.addBinding(returnType, implementationType);
           }
-      }
+        }
       } catch (ErrorsException e) {
         throw new ConfigurationException(e.getErrors().getMessages());
       }
@@ -198,7 +210,8 @@
     }
   }
 
-  private FactoryProvider(TypeLiteral<F> factoryType,
+  private FactoryProvider(
+      TypeLiteral<F> factoryType,
       TypeLiteral<?> implementationType,
       Map<Method, AssistedConstructor<?>> factoryMethodToConstructor) {
     this.factoryType = factoryType;
@@ -212,12 +225,14 @@
     this.injector = injector;
     for (AssistedConstructor<?> c : factoryMethodToConstructor.values()) {
       for (Parameter p : c.getAllParameters()) {
-        if(!p.isProvidedByFactory() && !paramCanBeInjected(p, injector)) {
+        if (!p.isProvidedByFactory() && !paramCanBeInjected(p, injector)) {
           // this is lame - we're not using the proper mechanism to add an
           // error to the injector. Throughout this class we throw exceptions
           // to add errors, which isn't really the best way in Guice
-          throw newConfigurationException("Parameter of type '%s' is not injectable or annotated "
-                + "with @Assisted for Constructor '%s'", p, c);
+          throw newConfigurationException(
+              "Parameter of type '%s' is not injectable or annotated "
+                  + "with @Assisted for Constructor '%s'",
+              p, c);
         }
       }
     }
@@ -228,8 +243,10 @@
       for (Class<?> constructorException : entry.getValue().getDeclaredExceptions()) {
         if (!isConstructorExceptionCompatibleWithFactoryExeception(
             constructorException, entry.getKey().getExceptionTypes())) {
-          throw newConfigurationException("Constructor %s declares an exception, but no compatible "
-              + "exception is thrown by the factory method %s", entry.getValue(), entry.getKey());
+          throw newConfigurationException(
+              "Constructor %s declares an exception, but no compatible "
+                  + "exception is thrown by the factory method %s",
+              entry.getValue(), entry.getKey());
         }
       }
     }
@@ -255,8 +272,9 @@
 
     for (Constructor<?> constructor : implementationType.getRawType().getDeclaredConstructors()) {
       if (constructor.isAnnotationPresent(AssistedInject.class)) {
-        AssistedConstructor<?> assistedConstructor = AssistedConstructor.create(
-            constructor, implementationType.getParameterTypes(constructor));
+        AssistedConstructor<?> assistedConstructor =
+            AssistedConstructor.create(
+                constructor, implementationType.getParameterTypes(constructor));
         constructors.add(assistedConstructor);
       }
     }
@@ -268,9 +286,10 @@
     Method[] factoryMethods = factoryType.getRawType().getMethods();
 
     if (constructors.size() != factoryMethods.length) {
-      throw newConfigurationException("Constructor mismatch: %s has %s @AssistedInject "
-          + "constructors, factory %s has %s creation methods", implementationType,
-          constructors.size(), factoryType, factoryMethods.length);
+      throw newConfigurationException(
+          "Constructor mismatch: %s has %s @AssistedInject "
+              + "constructors, factory %s has %s creation methods",
+          implementationType, constructors.size(), factoryType, factoryMethods.length);
     }
 
     Map<ParameterListKey, AssistedConstructor<?>> paramsToConstructor = Maps.newHashMap();
@@ -285,8 +304,8 @@
     Map<Method, AssistedConstructor<?>> result = Maps.newHashMap();
     for (Method method : factoryMethods) {
       if (!method.getReturnType().isAssignableFrom(implementationType.getRawType())) {
-        throw newConfigurationException("Return type of method %s is not assignable from %s",
-            method, implementationType);
+        throw newConfigurationException(
+            "Return type of method %s is not assignable from %s", method, implementationType);
       }
 
       List<Type> parameterTypes = Lists.newArrayList();
@@ -296,8 +315,9 @@
       ParameterListKey methodParams = new ParameterListKey(parameterTypes);
 
       if (!paramsToConstructor.containsKey(methodParams)) {
-        throw newConfigurationException("%s has no @AssistInject constructor that takes the "
-            + "@Assisted parameters %s in that order. @AssistInject constructors are %s",
+        throw newConfigurationException(
+            "%s has no @AssistInject constructor that takes the "
+                + "@Assisted parameters %s in that order. @AssistInject constructors are %s",
             implementationType, methodParams, paramsToConstructor.values());
       }
 
@@ -305,9 +325,10 @@
       for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
         for (Annotation parameterAnnotation : parameterAnnotations) {
           if (parameterAnnotation.annotationType() == Assisted.class) {
-            throw newConfigurationException("Factory method %s has an @Assisted parameter, which "
-                + "is incompatible with the deprecated @AssistedInject annotation. Please replace "
-                + "@AssistedInject with @Inject on the %s constructor.",
+            throw newConfigurationException(
+                "Factory method %s has an @Assisted parameter, which "
+                    + "is incompatible with the deprecated @AssistedInject annotation. Please replace "
+                    + "@AssistedInject with @Inject on the %s constructor.",
                 method, implementationType);
           }
         }
@@ -320,6 +341,7 @@
     return result;
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     List<Dependency<?>> dependencies = Lists.newArrayList();
     for (AssistedConstructor<?> constructor : factoryMethodToConstructor.values()) {
@@ -332,51 +354,57 @@
     return ImmutableSet.copyOf(dependencies);
   }
 
+  @Override
   public F get() {
-    InvocationHandler invocationHandler = new InvocationHandler() {
-      public Object invoke(Object proxy, Method method, Object[] creationArgs) throws Throwable {
-        // pass methods from Object.class to the proxy
-        if (method.getDeclaringClass().equals(Object.class)) {
-          if ("equals".equals(method.getName())) {
-            return proxy == creationArgs[0];
-          } else if ("hashCode".equals(method.getName())) {
-            return System.identityHashCode(proxy);
-          } else {
-            return method.invoke(this, creationArgs);
+    InvocationHandler invocationHandler =
+        new InvocationHandler() {
+          @Override
+          public Object invoke(Object proxy, Method method, Object[] creationArgs)
+              throws Throwable {
+            // pass methods from Object.class to the proxy
+            if (method.getDeclaringClass().equals(Object.class)) {
+              if ("equals".equals(method.getName())) {
+                return proxy == creationArgs[0];
+              } else if ("hashCode".equals(method.getName())) {
+                return System.identityHashCode(proxy);
+              } else {
+                return method.invoke(this, creationArgs);
+              }
+            }
+
+            AssistedConstructor<?> constructor = factoryMethodToConstructor.get(method);
+            Object[] constructorArgs = gatherArgsForConstructor(constructor, creationArgs);
+            Object objectToReturn = constructor.newInstance(constructorArgs);
+            injector.injectMembers(objectToReturn);
+            return objectToReturn;
           }
-        }
 
-        AssistedConstructor<?> constructor = factoryMethodToConstructor.get(method);
-        Object[] constructorArgs = gatherArgsForConstructor(constructor, creationArgs);
-        Object objectToReturn = constructor.newInstance(constructorArgs);
-        injector.injectMembers(objectToReturn);
-        return objectToReturn;
-      }
+          public Object[] gatherArgsForConstructor(
+              AssistedConstructor<?> constructor, Object[] factoryArgs) {
+            int numParams = constructor.getAllParameters().size();
+            int argPosition = 0;
+            Object[] result = new Object[numParams];
 
-      public Object[] gatherArgsForConstructor(
-          AssistedConstructor<?> constructor,
-          Object[] factoryArgs) {
-        int numParams = constructor.getAllParameters().size();
-        int argPosition = 0;
-        Object[] result = new Object[numParams];
-
-        for (int i = 0; i < numParams; i++) {
-          Parameter parameter = constructor.getAllParameters().get(i);
-          if (parameter.isProvidedByFactory()) {
-            result[i] = factoryArgs[argPosition];
-            argPosition++;
-          } else {
-            result[i] = parameter.getValue(injector);
+            for (int i = 0; i < numParams; i++) {
+              Parameter parameter = constructor.getAllParameters().get(i);
+              if (parameter.isProvidedByFactory()) {
+                result[i] = factoryArgs[argPosition];
+                argPosition++;
+              } else {
+                result[i] = parameter.getValue(injector);
+              }
+            }
+            return result;
           }
-        }
-        return result;
-      }
-    };
+        };
 
     @SuppressWarnings("unchecked") // we imprecisely treat the class literal of T as a Class<T>
     Class<F> factoryRawType = (Class<F>) (Class<?>) factoryType.getRawType();
-    return factoryRawType.cast(Proxy.newProxyInstance(BytecodeGen.getClassLoader(factoryRawType),
-        new Class[] { factoryRawType }, invocationHandler));
+    return factoryRawType.cast(
+        Proxy.newProxyInstance(
+            BytecodeGen.getClassLoader(factoryRawType),
+            new Class[] {factoryRawType},
+            invocationHandler));
   }
 
   @Override
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
index b40e19f..c2c7ac0 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +19,7 @@
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.Iterables.getOnlyElement;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableList;
@@ -55,7 +56,6 @@
 import com.google.inject.spi.ProviderWithExtensionVisitor;
 import com.google.inject.spi.Toolable;
 import com.google.inject.util.Providers;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
@@ -74,16 +74,19 @@
 import java.util.logging.Logger;
 
 /**
- * The newer implementation of factory provider. This implementation uses a child injector to
- * create values.
+ * The newer implementation of factory provider. This implementation uses a child injector to create
+ * values.
  *
  * @author jessewilson@google.com (Jesse Wilson)
  * @author dtm@google.com (Daniel Martin)
  * @author schmitt@google.com (Peter Schmitt)
  * @author sameb@google.com (Sam Berlin)
  */
-final class FactoryProvider2 <F> implements InvocationHandler,
-    ProviderWithExtensionVisitor<F>, HasDependencies, AssistedInjectBinding<F> {
+final class FactoryProvider2<F>
+    implements InvocationHandler,
+        ProviderWithExtensionVisitor<F>,
+        HasDependencies,
+        AssistedInjectBinding<F> {
 
   /** A constant annotation to denote the return value, instead of creating a new one each time. */
   static final Annotation RETURN_ANNOTATION = UniqueAnnotations.create();
@@ -92,27 +95,37 @@
   static final Logger logger = Logger.getLogger(AssistedInject.class.getName());
 
   /** if a factory method parameter isn't annotated, it gets this annotation. */
-  static final Assisted DEFAULT_ANNOTATION = new Assisted() {
-    public String value() {
-      return "";
-    }
+  static final Assisted DEFAULT_ANNOTATION =
+      new Assisted() {
+        @Override
+        public String value() {
+          return "";
+        }
 
-    public Class<? extends Annotation> annotationType() {
-      return Assisted.class;
-    }
+        @Override
+        public Class<? extends Annotation> annotationType() {
+          return Assisted.class;
+        }
 
-    @Override public boolean equals(Object o) {
-      return o instanceof Assisted && ((Assisted) o).value().isEmpty();
-    }
+        @Override
+        public boolean equals(Object o) {
+          return o instanceof Assisted && ((Assisted) o).value().isEmpty();
+        }
 
-    @Override public int hashCode() {
-      return 127 * "value".hashCode() ^ "".hashCode();
-    }
+        @Override
+        public int hashCode() {
+          return 127 * "value".hashCode() ^ "".hashCode();
+        }
 
-    @Override public String toString() {
-      return "@" + Assisted.class.getName() + "(value=)";
-    }
-  };
+        @Override
+        public String toString() {
+          return "@"
+              + Assisted.class.getName()
+              + "(value="
+              + Annotations.memberValueString("")
+              + ")";
+        }
+      };
 
   /** All the data necessary to perform an assisted inject. */
   private static class AssistData implements AssistedMethod {
@@ -127,7 +140,7 @@
 
     /** All non-assisted dependencies required by this method. */
     final Set<Dependency<?>> dependencies;
-    /** The factory method associated with this data*/
+    /** The factory method associated with this data */
     final Method factoryMethod;
 
     /** true if {@link #isValidForOptimizedAssistedInject} returned true. */
@@ -137,10 +150,15 @@
     /** used to perform optimized factory creations. */
     volatile Binding<?> cachedBinding; // TODO: volatile necessary?
 
-    AssistData(Constructor<?> constructor, Key<?> returnType, ImmutableList<Key<?>> paramTypes,
-        TypeLiteral<?> implementationType, Method factoryMethod,
+    AssistData(
+        Constructor<?> constructor,
+        Key<?> returnType,
+        ImmutableList<Key<?>> paramTypes,
+        TypeLiteral<?> implementationType,
+        Method factoryMethod,
         Set<Dependency<?>> dependencies,
-        boolean optimized, List<ThreadLocalProvider> providers) {
+        boolean optimized,
+        List<ThreadLocalProvider> providers) {
       this.constructor = constructor;
       this.returnType = returnType;
       this.paramTypes = paramTypes;
@@ -153,31 +171,35 @@
 
     @Override
     public String toString() {
-      return Objects.toStringHelper(getClass())
-        .add("ctor", constructor)
-        .add("return type", returnType)
-        .add("param type", paramTypes)
-        .add("implementation type", implementationType)
-        .add("dependencies", dependencies)
-        .add("factory method", factoryMethod)
-        .add("optimized", optimized)
-        .add("providers", providers)
-        .add("cached binding", cachedBinding)
-        .toString();
+      return MoreObjects.toStringHelper(getClass())
+          .add("ctor", constructor)
+          .add("return type", returnType)
+          .add("param type", paramTypes)
+          .add("implementation type", implementationType)
+          .add("dependencies", dependencies)
+          .add("factory method", factoryMethod)
+          .add("optimized", optimized)
+          .add("providers", providers)
+          .add("cached binding", cachedBinding)
+          .toString();
     }
 
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return dependencies;
     }
 
+    @Override
     public Method getFactoryMethod() {
       return factoryMethod;
     }
 
+    @Override
     public Constructor<?> getImplementationConstructor() {
       return constructor;
     }
 
+    @Override
     public TypeLiteral<?> getImplementationType() {
       return implementationType;
     }
@@ -194,17 +216,16 @@
 
   /** the factory interface, implemented and provided */
   private final F factory;
-  
+
   /** The key that this is bound to. */
   private final Key<F> factoryKey;
-  
+
   /** The binding collector, for equality/hashing purposes. */
   private final BindingCollector collector;
 
   /**
    * @param factoryKey a key for a Java interface that defines one or more create methods.
-   * @param collector binding configuration that maps method return types to
-   *    implementation types.
+   * @param collector binding configuration that maps method return types to implementation types.
    */
   FactoryProvider2(Key<F> factoryKey, BindingCollector collector) {
     this.factoryKey = factoryKey;
@@ -217,7 +238,7 @@
     Class<F> factoryRawType = (Class<F>) (Class<?>) factoryType.getRawType();
 
     try {
-      if(!factoryRawType.isInterface()) {
+      if (!factoryRawType.isInterface()) {
         throw errors.addMessage("%s must be an interface.", factoryRawType).toException();
       }
 
@@ -226,6 +247,11 @@
       ImmutableMap.Builder<Method, AssistData> assistDataBuilder = ImmutableMap.builder();
       // TODO: also grab methods from superinterfaces
       for (Method method : factoryRawType.getMethods()) {
+        // Skip static methods
+        if (Modifier.isStatic(method.getModifiers())) {
+          continue;
+        }
+
         // Skip default methods that java8 may have created.
         if (isDefault(method) && (method.isBridge() || method.isSynthetic())) {
           // Even synthetic default methods need the return type validation...
@@ -239,11 +265,12 @@
         TypeLiteral<?> returnTypeLiteral = factoryType.getReturnType(method);
         Key<?> returnType;
         try {
-          returnType = Annotations.getKey(returnTypeLiteral, method, method.getAnnotations(), errors);
-        } catch(ConfigurationException ce) {
+          returnType =
+              Annotations.getKey(returnTypeLiteral, method, method.getAnnotations(), errors);
+        } catch (ConfigurationException ce) {
           // If this was an error due to returnTypeLiteral not being specified, rephrase
           // it as our factory not being specified, so it makes more sense to users.
-          if(isTypeNotSpecified(returnTypeLiteral, ce)) {
+          if (isTypeNotSpecified(returnTypeLiteral, ce)) {
             throw errors.keyNotFullySpecified(TypeLiteral.get(factoryRawType)).toException();
           } else {
             throw ce;
@@ -259,9 +286,10 @@
           Class<?> underlylingType = paramKey.getTypeLiteral().getRawType();
           if (underlylingType.equals(Provider.class)
               || underlylingType.equals(javax.inject.Provider.class)) {
-            errors.addMessage("A Provider may not be a type in a factory method of an AssistedInject."
+            errors.addMessage(
+                "A Provider may not be a type in a factory method of an AssistedInject."
                     + "\n  Offending instance is parameter [%s] with key [%s] on method [%s]",
-                    p, paramKey, method);
+                p, paramKey, method);
           }
           keys.add(assistKey(method, paramKey, errors));
         }
@@ -269,23 +297,25 @@
 
         // try to match up the method to the constructor
         TypeLiteral<?> implementation = collector.getBindings().get(returnType);
-        if(implementation == null) {
+        if (implementation == null) {
           implementation = returnType.getTypeLiteral();
         }
         Class<? extends Annotation> scope =
             Annotations.findScopeAnnotation(errors, implementation.getRawType());
         if (scope != null) {
-          errors.addMessage("Found scope annotation [%s] on implementation class "
-              + "[%s] of AssistedInject factory [%s].\nThis is not allowed, please"
-              + " remove the scope annotation.",
+          errors.addMessage(
+              "Found scope annotation [%s] on implementation class "
+                  + "[%s] of AssistedInject factory [%s].\nThis is not allowed, please"
+                  + " remove the scope annotation.",
               scope, implementation.getRawType(), factoryType);
         }
-        
+
         InjectionPoint ctorInjectionPoint;
         try {
           ctorInjectionPoint =
-            findMatchingConstructorInjectionPoint(method, returnType, implementation, immutableParamList);
-        } catch(ErrorsException ee) {
+              findMatchingConstructorInjectionPoint(
+                  method, returnType, implementation, immutableParamList);
+        } catch (ErrorsException ee) {
           errors.merge(ee.getErrors());
           continue;
         }
@@ -299,34 +329,41 @@
         // all injections directly inject the object itself (and not a Provider of the object,
         // or an Injector), because it caches a single child injector and mutates the Provider
         // of the arguments in a ThreadLocal.
-        if(isValidForOptimizedAssistedInject(deps, implementation.getRawType(), factoryType)) {
+        if (isValidForOptimizedAssistedInject(deps, implementation.getRawType(), factoryType)) {
           ImmutableList.Builder<ThreadLocalProvider> providerListBuilder = ImmutableList.builder();
-          for(int i = 0; i < params.size(); i++) {
+          for (int i = 0; i < params.size(); i++) {
             providerListBuilder.add(new ThreadLocalProvider());
           }
           providers = providerListBuilder.build();
           optimized = true;
         }
 
-        AssistData data = new AssistData(constructor,
-            returnType,
-            immutableParamList,
-            implementation,
-            method,
-            removeAssistedDeps(deps),
-            optimized,
-            providers);
+        AssistData data =
+            new AssistData(
+                constructor,
+                returnType,
+                immutableParamList,
+                implementation,
+                method,
+                removeAssistedDeps(deps),
+                optimized,
+                providers);
         assistDataBuilder.put(method, data);
       }
 
-      factory = factoryRawType.cast(Proxy.newProxyInstance(
-          BytecodeGen.getClassLoader(factoryRawType), new Class<?>[] {factoryRawType}, this));
+      factory =
+          factoryRawType.cast(
+              Proxy.newProxyInstance(
+                  BytecodeGen.getClassLoader(factoryRawType),
+                  new Class<?>[] {factoryRawType},
+                  this));
 
       // Now go back through default methods. Try to use MethodHandles to make things
       // work.  If that doesn't work, fallback to trying to find compatible method
       // signatures.
       Map<Method, AssistData> dataSoFar = assistDataBuilder.build();
-      ImmutableMap.Builder<Method, MethodHandleWrapper> methodHandleBuilder = ImmutableMap.builder();
+      ImmutableMap.Builder<Method, MethodHandleWrapper> methodHandleBuilder =
+          ImmutableMap.builder();
       for (Map.Entry<String, Method> entry : defaultMethods.entries()) {
         Method defaultMethod = entry.getValue();
         MethodHandleWrapper handle = MethodHandleWrapper.create(defaultMethod, factory);
@@ -337,10 +374,11 @@
           for (Method otherMethod : otherMethods.get(defaultMethod.getName())) {
             if (dataSoFar.containsKey(otherMethod) && isCompatible(defaultMethod, otherMethod)) {
               if (foundMatch) {
-                errors.addMessage("Generated default method %s with parameters %s is"
-                    + " signature-compatible with more than one non-default method."
-                    + " Unable to create factory. As a workaround, remove the override"
-                    + " so javac stops generating a default method.",
+                errors.addMessage(
+                    "Generated default method %s with parameters %s is"
+                        + " signature-compatible with more than one non-default method."
+                        + " Unable to create factory. As a workaround, remove the override"
+                        + " so javac stops generating a default method.",
                     defaultMethod, Arrays.asList(defaultMethod.getParameterTypes()));
               } else {
                 assistDataBuilder.put(defaultMethod, dataSoFar.get(otherMethod));
@@ -355,7 +393,7 @@
       }
 
       // If we generated any errors (from finding matching constructors, for instance), throw an exception.
-      if(errors.hasErrors()) {
+      if (errors.hasErrors()) {
         throw errors.toException();
       }
 
@@ -391,34 +429,39 @@
     return true;
   }
 
+  @Override
   public F get() {
     return factory;
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
-    Set<Dependency<?>> combinedDeps = new HashSet<Dependency<?>>();
-    for(AssistData data : assistDataByMethod.values()) {
+    Set<Dependency<?>> combinedDeps = new HashSet<>();
+    for (AssistData data : assistDataByMethod.values()) {
       combinedDeps.addAll(data.dependencies);
     }
     return ImmutableSet.copyOf(combinedDeps);
   }
-  
+
+  @Override
   public Key<F> getKey() {
     return factoryKey;
   }
 
   // Safe cast because values are typed to AssistedData, which is an AssistedMethod, and
   // the collection is immutable.
+  @Override
   @SuppressWarnings("unchecked")
   public Collection<AssistedMethod> getAssistedMethods() {
     return (Collection<AssistedMethod>) (Collection<?>) assistDataByMethod.values();
   }
 
+  @Override
   @SuppressWarnings("unchecked")
-  public <T, V> V acceptExtensionVisitor(BindingTargetVisitor<T, V> visitor,
-      ProviderInstanceBinding<? extends T> binding) {
+  public <T, V> V acceptExtensionVisitor(
+      BindingTargetVisitor<T, V> visitor, ProviderInstanceBinding<? extends T> binding) {
     if (visitor instanceof AssistedInjectTargetVisitor) {
-      return ((AssistedInjectTargetVisitor<T, V>)visitor).visit((AssistedInjectBinding<T>)this);
+      return ((AssistedInjectTargetVisitor<T, V>) visitor).visit((AssistedInjectBinding<T>) this);
     }
     return visitor.visit(binding);
   }
@@ -426,9 +469,10 @@
   private void validateFactoryReturnType(Errors errors, Class<?> returnType, Class<?> factoryType) {
     if (Modifier.isPublic(factoryType.getModifiers())
         && !Modifier.isPublic(returnType.getModifiers())) {
-      errors.addMessage("%s is public, but has a method that returns a non-public type: %s. "
-          + "Due to limitations with java.lang.reflect.Proxy, this is not allowed. "
-          + "Please either make the factory non-public or the return type public.",
+      errors.addMessage(
+          "%s is public, but has a method that returns a non-public type: %s. "
+              + "Due to limitations with java.lang.reflect.Proxy, this is not allowed. "
+              + "Please either make the factory non-public or the return type public.",
           factoryType, returnType);
     }
   }
@@ -440,8 +484,8 @@
   private boolean isTypeNotSpecified(TypeLiteral<?> typeLiteral, ConfigurationException ce) {
     Collection<Message> messages = ce.getErrorMessages();
     if (messages.size() == 1) {
-      Message msg = Iterables.getOnlyElement(
-          new Errors().keyNotFullySpecified(typeLiteral).getMessages());
+      Message msg =
+          Iterables.getOnlyElement(new Errors().keyNotFullySpecified(typeLiteral).getMessages());
       return msg.getMessage().equals(Iterables.getOnlyElement(messages).getMessage());
     } else {
       return false;
@@ -449,17 +493,17 @@
   }
 
   /**
-   * Finds a constructor suitable for the method.  If the implementation contained any constructors
+   * Finds a constructor suitable for the method. If the implementation contained any constructors
    * marked with {@link AssistedInject}, this requires all {@link Assisted} parameters to exactly
-   * match the parameters (in any order) listed in the method.  Otherwise, if no
-   * {@link AssistedInject} constructors exist, this will default to looking for an
-   * {@literal @}{@link Inject} constructor.
+   * match the parameters (in any order) listed in the method. Otherwise, if no {@link
+   * AssistedInject} constructors exist, this will default to looking for an {@literal @}{@link
+   * Inject} constructor.
    */
   private <T> InjectionPoint findMatchingConstructorInjectionPoint(
       Method method, Key<?> returnType, TypeLiteral<T> implementation, List<Key<?>> paramList)
       throws ErrorsException {
     Errors errors = new Errors(method);
-    if(returnType.getTypeLiteral().equals(implementation)) {
+    if (returnType.getTypeLiteral().equals(implementation)) {
       errors = errors.withSource(implementation);
     } else {
       errors = errors.withSource(returnType).withSource(implementation);
@@ -489,12 +533,11 @@
         anyAssistedInjectConstructors = true;
         if (constructorHasMatchingParams(implementation, constructor, paramList, errors)) {
           if (matchingConstructor != null) {
-            errors
-                .addMessage(
-                    "%s has more than one constructor annotated with @AssistedInject"
-                        + " that matches the parameters in method %s.  Unable to create "
-                        + "AssistedInject factory.",
-                    implementation, method);
+            errors.addMessage(
+                "%s has more than one constructor annotated with @AssistedInject"
+                    + " that matches the parameters in method %s.  Unable to create "
+                    + "AssistedInject factory.",
+                implementation, method);
             throw errors.toException();
           } else {
             matchingConstructor = constructor;
@@ -503,26 +546,27 @@
       }
     }
 
-    if(!anyAssistedInjectConstructors) {
+    if (!anyAssistedInjectConstructors) {
       // If none existed, use @Inject.
       try {
         return InjectionPoint.forConstructorOf(implementation);
-      } catch(ConfigurationException e) {
+      } catch (ConfigurationException e) {
         errors.merge(e.getErrorMessages());
         throw errors.toException();
       }
     } else {
       // Otherwise, use it or fail with a good error message.
-      if(matchingConstructor != null) {
-          // safe because we got the constructor from this implementation.
-          @SuppressWarnings("unchecked")
-          InjectionPoint ip = InjectionPoint.forConstructor(
-              (Constructor<? super T>) matchingConstructor, implementation);
-          return ip;
+      if (matchingConstructor != null) {
+        // safe because we got the constructor from this implementation.
+        @SuppressWarnings("unchecked")
+        InjectionPoint ip =
+            InjectionPoint.forConstructor(
+                (Constructor<? super T>) matchingConstructor, implementation);
+        return ip;
       } else {
         errors.addMessage(
             "%s has @AssistedInject constructors, but none of them match the"
-            + " parameters in method %s.  Unable to create AssistedInject factory.",
+                + " parameters in method %s.  Unable to create AssistedInject factory.",
             implementation, method);
         throw errors.toException();
       }
@@ -530,21 +574,19 @@
   }
 
   /**
-   * Matching logic for constructors annotated with AssistedInject.
-   * This returns true if and only if all @Assisted parameters in the
-   * constructor exactly match (in any order) all @Assisted parameters
-   * the method's parameter.
+   * Matching logic for constructors annotated with AssistedInject. This returns true if and only if
+   * all @Assisted parameters in the constructor exactly match (in any order) all @Assisted
+   * parameters the method's parameter.
    */
-  private boolean constructorHasMatchingParams(TypeLiteral<?> type,
-      Constructor<?> constructor, List<Key<?>> paramList, Errors errors)
+  private boolean constructorHasMatchingParams(
+      TypeLiteral<?> type, Constructor<?> constructor, List<Key<?>> paramList, Errors errors)
       throws ErrorsException {
     List<TypeLiteral<?>> params = type.getParameterTypes(constructor);
     Annotation[][] paramAnnotations = constructor.getParameterAnnotations();
     int p = 0;
     List<Key<?>> constructorKeys = Lists.newArrayList();
     for (TypeLiteral<?> param : params) {
-      Key<?> paramKey = Annotations.getKey(param, constructor, paramAnnotations[p++],
-          errors);
+      Key<?> paramKey = Annotations.getKey(param, constructor, paramAnnotations[p++], errors);
       constructorKeys.add(paramKey);
     }
     // Require that every key exist in the constructor to match up exactly.
@@ -565,7 +607,8 @@
   }
 
   /** Calculates all dependencies required by the implementation and constructor. */
-  private Set<Dependency<?>> getDependencies(InjectionPoint ctorPoint, TypeLiteral<?> implementation) {
+  private Set<Dependency<?>> getDependencies(
+      InjectionPoint ctorPoint, TypeLiteral<?> implementation) {
     ImmutableSet.Builder<Dependency<?>> builder = ImmutableSet.builder();
     builder.addAll(ctorPoint.getDependencies());
     if (!implementation.getRawType().isInterface()) {
@@ -579,7 +622,7 @@
   /** Return all non-assisted dependencies. */
   private Set<Dependency<?>> removeAssistedDeps(Set<Dependency<?>> deps) {
     ImmutableSet.Builder<Dependency<?>> builder = ImmutableSet.builder();
-    for(Dependency<?> dep : deps) {
+    for (Dependency<?> dep : deps) {
       Class<?> annotationType = dep.getKey().getAnnotationType();
       if (annotationType == null || !annotationType.equals(Assisted.class)) {
         builder.add(dep);
@@ -594,8 +637,8 @@
    * the assisted bindings are immediately provided. This looks for hints that the values may be
    * lazily retrieved, by looking for injections of Injector or a Provider for the assisted values.
    */
-  private boolean isValidForOptimizedAssistedInject(Set<Dependency<?>> dependencies,
-      Class<?> implementation, TypeLiteral<?> factoryType) {
+  private boolean isValidForOptimizedAssistedInject(
+      Set<Dependency<?>> dependencies, Class<?> implementation, TypeLiteral<?> factoryType) {
     Set<Dependency<?>> badDeps = null; // optimization: create lazily
     for (Dependency<?> dep : dependencies) {
       if (isInjectorOrAssistedProvider(dep)) {
@@ -606,37 +649,47 @@
       }
     }
     if (badDeps != null && !badDeps.isEmpty()) {
-      logger.log(Level.WARNING, "AssistedInject factory {0} will be slow "
-          + "because {1} has assisted Provider dependencies or injects the Injector. "
-          + "Stop injecting @Assisted Provider<T> (instead use @Assisted T) "
-          + "or Injector to speed things up. (It will be a ~6500% speed bump!)  "
-          + "The exact offending deps are: {2}",
-          new Object[] {factoryType, implementation, badDeps} );
+      logger.log(
+          Level.WARNING,
+          "AssistedInject factory {0} will be slow "
+              + "because {1} has assisted Provider dependencies or injects the Injector. "
+              + "Stop injecting @Assisted Provider<T> (instead use @Assisted T) "
+              + "or Injector to speed things up. (It will be a ~6500% speed bump!)  "
+              + "The exact offending deps are: {2}",
+          new Object[] {factoryType, implementation, badDeps});
       return false;
     }
     return true;
   }
 
   /**
-   * Returns true if the dependency is for {@link Injector} or if the dependency
-   * is a {@link Provider} for a parameter that is {@literal @}{@link Assisted}.
+   * Returns true if the dependency is for {@link Injector} or if the dependency is a {@link
+   * Provider} for a parameter that is {@literal @}{@link Assisted}.
    */
   private boolean isInjectorOrAssistedProvider(Dependency<?> dependency) {
     Class<?> annotationType = dependency.getKey().getAnnotationType();
     if (annotationType != null && annotationType.equals(Assisted.class)) { // If it's assisted..
-      if (dependency.getKey().getTypeLiteral().getRawType().equals(Provider.class)) { // And a Provider...
+      if (dependency
+          .getKey()
+          .getTypeLiteral()
+          .getRawType()
+          .equals(Provider.class)) { // And a Provider...
         return true;
       }
-    } else if (dependency.getKey().getTypeLiteral().getRawType().equals(Injector.class)) { // If it's the Injector...
+    } else if (dependency
+        .getKey()
+        .getTypeLiteral()
+        .getRawType()
+        .equals(Injector.class)) { // If it's the Injector...
       return true;
     }
     return false;
   }
 
   /**
-   * Returns a key similar to {@code key}, but with an {@literal @}Assisted binding annotation.
-   * This fails if another binding annotation is clobbered in the process. If the key already has
-   * the {@literal @}Assisted annotation, it is returned as-is to preserve any String value.
+   * Returns a key similar to {@code key}, but with an {@literal @}Assisted binding annotation. This
+   * fails if another binding annotation is clobbered in the process. If the key already has the
+   * {@literal @}Assisted annotation, it is returned as-is to preserve any String value.
    */
   private <T> Key<T> assistKey(Method method, Key<T> key, Errors errors) throws ErrorsException {
     if (key.getAnnotationType() == null) {
@@ -644,22 +697,28 @@
     } else if (key.getAnnotationType() == Assisted.class) {
       return key;
     } else {
-      errors.withSource(method).addMessage(
-          "Only @Assisted is allowed for factory parameters, but found @%s",
-          key.getAnnotationType());
+      errors
+          .withSource(method)
+          .addMessage(
+              "Only @Assisted is allowed for factory parameters, but found @%s",
+              key.getAnnotationType());
       throw errors.toException();
     }
   }
 
   /**
-   * At injector-creation time, we initialize the invocation handler. At this time we make sure
-   * all factory methods will be able to build the target types.
+   * At injector-creation time, we initialize the invocation handler. At this time we make sure all
+   * factory methods will be able to build the target types.
    */
-  @Inject @Toolable
+  @Inject
+  @Toolable
   void initialize(Injector injector) {
     if (this.injector != null) {
-      throw new ConfigurationException(ImmutableList.of(new Message(FactoryProvider2.class,
-          "Factories.create() factories may only be used in one Injector!")));
+      throw new ConfigurationException(
+          ImmutableList.of(
+              new Message(
+                  FactoryProvider2.class,
+                  "Factories.create() factories may only be used in one Injector!")));
     }
 
     this.injector = injector;
@@ -668,13 +727,14 @@
       Method method = entry.getKey();
       AssistData data = entry.getValue();
       Object[] args;
-      if(!data.optimized) {
+      if (!data.optimized) {
         args = new Object[method.getParameterTypes().length];
         Arrays.fill(args, "dummy object for validating Factories");
       } else {
         args = null; // won't be used -- instead will bind to data.providers.
       }
-      getBindingFromNewInjector(method, args, data); // throws if the binding isn't properly configured
+      getBindingFromNewInjector(
+          method, args, data); // throws if the binding isn't properly configured
     }
   }
 
@@ -683,7 +743,8 @@
    */
   public Binding<?> getBindingFromNewInjector(
       final Method method, final Object[] args, final AssistData data) {
-    checkState(injector != null,
+    checkState(
+        injector != null,
         "Factories.create() factories cannot be used until they're initialized by Guice.");
 
     final Key<?> returnType = data.returnType;
@@ -691,42 +752,46 @@
     // We ignore any pre-existing binding annotation.
     final Key<?> returnKey = Key.get(returnType.getTypeLiteral(), RETURN_ANNOTATION);
 
-    Module assistedModule = new AbstractModule() {
-      @Override
-      @SuppressWarnings({
-        "unchecked", "rawtypes"}) // raw keys are necessary for the args array and return value
-      protected void configure() {
-        Binder binder = binder().withSource(method);
+    Module assistedModule =
+        new AbstractModule() {
+          @Override
+          @SuppressWarnings({
+            "unchecked",
+            "rawtypes"
+          }) // raw keys are necessary for the args array and return value
+          protected void configure() {
+            Binder binder = binder().withSource(method);
 
-        int p = 0;
-        if(!data.optimized) {
-          for (Key<?> paramKey : data.paramTypes) {
-            // Wrap in a Provider to cover null, and to prevent Guice from injecting the parameter
-            binder.bind((Key) paramKey).toProvider(Providers.of(args[p++]));
-          }
-        } else {
-          for (Key<?> paramKey : data.paramTypes) {
-            // Bind to our ThreadLocalProviders.
-            binder.bind((Key) paramKey).toProvider(data.providers.get(p++));
-          }
-        }
+            int p = 0;
+            if (!data.optimized) {
+              for (Key<?> paramKey : data.paramTypes) {
+                // Wrap in a Provider to cover null, and to prevent Guice from injecting the parameter
+                binder.bind((Key) paramKey).toProvider(Providers.of(args[p++]));
+              }
+            } else {
+              for (Key<?> paramKey : data.paramTypes) {
+                // Bind to our ThreadLocalProviders.
+                binder.bind((Key) paramKey).toProvider(data.providers.get(p++));
+              }
+            }
 
-        Constructor constructor = data.constructor;
-        // Constructor *should* always be non-null here,
-        // but if it isn't, we'll end up throwing a fairly good error
-        // message for the user.
-        if(constructor != null) {
-          binder.bind(returnKey)
-              .toConstructor(constructor, (TypeLiteral)data.implementationType)
-              .in(Scopes.NO_SCOPE); // make sure we erase any scope on the implementation type
-        }
-      }
-    };
+            Constructor constructor = data.constructor;
+            // Constructor *should* always be non-null here,
+            // but if it isn't, we'll end up throwing a fairly good error
+            // message for the user.
+            if (constructor != null) {
+              binder
+                  .bind(returnKey)
+                  .toConstructor(constructor, (TypeLiteral) data.implementationType)
+                  .in(Scopes.NO_SCOPE); // make sure we erase any scope on the implementation type
+            }
+          }
+        };
 
     Injector forCreate = injector.createChildInjector(assistedModule);
     Binding<?> binding = forCreate.getBinding(returnKey);
     // If we have providers cached in data, cache the binding for future optimizations.
-    if(data.optimized) {
+    if (data.optimized) {
       data.cachedBinding = binding;
     }
     return binding;
@@ -736,6 +801,7 @@
    * When a factory method is invoked, we create a child injector that binds all parameters, then
    * use that to get an instance of the return type.
    */
+  @Override
   public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
     // If we setup a method handle earlier for this method, call it.
     // This is necessary for default methods that java8 creates, so we
@@ -757,14 +823,14 @@
     AssistData data = assistDataByMethod.get(method);
     checkState(data != null, "No data for method: %s", method);
     Provider<?> provider;
-    if(data.cachedBinding != null) { // Try to get optimized form...
+    if (data.cachedBinding != null) { // Try to get optimized form...
       provider = data.cachedBinding.getProvider();
     } else {
       provider = getBindingFromNewInjector(method, args, data).getProvider();
     }
     try {
       int p = 0;
-      for(ThreadLocalProvider tlp : data.providers) {
+      for (ThreadLocalProvider tlp : data.providers) {
         tlp.set(args[p++]);
       }
       return provider.get();
@@ -779,22 +845,24 @@
       }
       throw e;
     } finally {
-      for(ThreadLocalProvider tlp : data.providers) {
+      for (ThreadLocalProvider tlp : data.providers) {
         tlp.remove();
       }
     }
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return factory.getClass().getInterfaces()[0].getName();
   }
-  
+
   @Override
   public int hashCode() {
     return Objects.hashCode(factoryKey, collector);
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof FactoryProvider2)) {
       return false;
     }
@@ -829,11 +897,9 @@
 
   /** Wrapper around MethodHandles/MethodHandle, so we can compile+run on java6. */
   private static class MethodHandleWrapper {
-    static final int ALL_MODES = Modifier.PRIVATE
-        | Modifier.STATIC /* package */
-        | Modifier.PUBLIC
-        | Modifier.PROTECTED;
-    
+    static final int ALL_MODES =
+        Modifier.PRIVATE | Modifier.STATIC /* package */ | Modifier.PUBLIC | Modifier.PROTECTED;
+
     static final Method unreflectSpecial;
     static final Method bindTo;
     static final Method invokeWithArguments;
@@ -902,7 +968,8 @@
       return invokeWithArguments.invoke(handle, (Object) args);
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return handle.toString();
     }
   }
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java b/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
index 717d29c..7be47ba 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.internal.Annotations;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -35,7 +34,7 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 class Parameter {
-  
+
   private final Type type;
   private final boolean isAssisted;
   private final Annotation bindingAnnotation;
@@ -53,7 +52,7 @@
   public boolean isProvidedByFactory() {
     return isAssisted;
   }
-  
+
   public Type getType() {
     return type;
   }
@@ -79,16 +78,15 @@
     return false;
   }
 
-  /**
-   * Returns the Guice {@link Key} for this parameter.
-   */
+  /** Returns the Guice {@link Key} for this parameter. */
   public Object getValue(Injector injector) {
     if (null == provider) {
       synchronized (this) {
         if (null == provider) {
-          provider = isProvider
-              ? injector.getProvider(getBindingForType(getProvidedType(type)))
-              : injector.getProvider(getPrimaryBindingKey());
+          provider =
+              isProvider
+                  ? injector.getProvider(getBindingForType(getProvidedType(type)))
+                  : injector.getProvider(getPrimaryBindingKey());
         }
       }
     }
@@ -112,11 +110,10 @@
   }
 
   /**
-   * Replace annotation instances with annotation types, this is only
-   * appropriate for testing if a key is bound and not for injecting.
+   * Replace annotation instances with annotation types, this is only appropriate for testing if a
+   * key is bound and not for injecting.
    *
-   * See Guice bug 125,
-   * https://github.com/google/guice/issues/125
+   * <p>See Guice bug 125, https://github.com/google/guice/issues/125
    */
   public Key<?> fixAnnotations(Key<?> key) {
     return key.getAnnotation() == null
@@ -125,9 +122,7 @@
   }
 
   Key<?> getPrimaryBindingKey() {
-    return isProvider
-        ? getBindingForType(getProvidedType(type))
-        : getBindingForType(type);
+    return isProvider ? getBindingForType(getProvidedType(type)) : getBindingForType(type);
   }
 
   private Type getProvidedType(Type type) {
@@ -140,14 +135,12 @@
   }
 
   private Key<?> getBindingForType(Type type) {
-    return bindingAnnotation != null
-        ? Key.get(type, bindingAnnotation)
-        : Key.get(type);
+    return bindingAnnotation != null ? Key.get(type, bindingAnnotation) : Key.get(type);
   }
 
   /**
-   * Returns the unique binding annotation from the specified list, or
-   * {@code null} if there are none.
+   * Returns the unique binding annotation from the specified list, or {@code null} if there are
+   * none.
    *
    * @throws IllegalStateException if multiple binding annotations exist.
    */
@@ -155,8 +148,11 @@
     Annotation bindingAnnotation = null;
     for (Annotation annotation : annotations) {
       if (Annotations.isBindingAnnotation(annotation.annotationType())) {
-        checkArgument(bindingAnnotation == null,
-            "Parameter has multiple binding annotations: %s and %s", bindingAnnotation, annotation);
+        checkArgument(
+            bindingAnnotation == null,
+            "Parameter has multiple binding annotations: %s and %s",
+            bindingAnnotation,
+            annotation);
         bindingAnnotation = annotation;
       }
     }
diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/ParameterListKey.java b/extensions/assistedinject/src/com/google/inject/assistedinject/ParameterListKey.java
index 332b11d..c4ae9dd 100644
--- a/extensions/assistedinject/src/com/google/inject/assistedinject/ParameterListKey.java
+++ b/extensions/assistedinject/src/com/google/inject/assistedinject/ParameterListKey.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,31 +17,30 @@
 package com.google.inject.assistedinject;
 
 import com.google.inject.TypeLiteral;
-
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 /**
- * A list of {@link TypeLiteral}s to match an injectable Constructor's assited
- * parameter types to the corresponding factory method.
+ * A list of {@link TypeLiteral}s to match an injectable Constructor's assited parameter types to
+ * the corresponding factory method.
  *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  */
 class ParameterListKey {
-  
+
   private final List<Type> paramList;
-  
+
   public ParameterListKey(List<Type> paramList) {
-    this.paramList = new ArrayList<Type>(paramList);
+    this.paramList = new ArrayList<>(paramList);
   }
-  
+
   public ParameterListKey(Type[] types) {
     this(Arrays.asList(types));
   }
-  
+
   @Override
   public boolean equals(Object o) {
     if (o == this) {
@@ -53,7 +52,7 @@
     ParameterListKey other = (ParameterListKey) o;
     return paramList.equals(other.paramList);
   }
-  
+
   @Override
   public int hashCode() {
     return paramList.hashCode();
@@ -63,4 +62,4 @@
   public String toString() {
     return paramList.toString();
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/assistedinject/test/com/google/inject/assistedinject/ExtensionSpiTest.java b/extensions/assistedinject/test/com/google/inject/assistedinject/ExtensionSpiTest.java
index 051a50f..839de60 100644
--- a/extensions/assistedinject/test/com/google/inject/assistedinject/ExtensionSpiTest.java
+++ b/extensions/assistedinject/test/com/google/inject/assistedinject/ExtensionSpiTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,13 +35,11 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
 import java.util.List;
 import java.util.Set;
 import java.util.logging.Logger;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
 
 /**
  * Tests for AssistedInject Spi.
@@ -53,9 +51,9 @@
   public final void testSpiOnElements() throws Exception {
     AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
     Integer count = 0;
-    for(Element element : Elements.getElements(new Module())) {
-      if(element instanceof Binding) {
-        assertEquals(count++, ((Binding<?>)element).acceptTargetVisitor(visitor));
+    for (Element element : Elements.getElements(new Module())) {
+      if (element instanceof Binding) {
+        assertEquals(count++, ((Binding<?>) element).acceptTargetVisitor(visitor));
       }
     }
     validateVisitor(visitor);
@@ -65,7 +63,7 @@
     AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
     Integer count = 0;
     Injector injector = Guice.createInjector(new Module());
-    for(Binding<?> binding : injector.getBindings().values()) {
+    for (Binding<?> binding : injector.getBindings().values()) {
       assertEquals(count++, binding.acceptTargetVisitor(visitor));
     }
     validateVisitor(visitor);
@@ -74,52 +72,62 @@
   private void validateVisitor(AssistedInjectSpiVisitor visitor) throws Exception {
     assertEquals(1, visitor.assistedBindingCount);
     List<AssistedMethod> assistedMethods =
-        Lists.newArrayList(Iterables.getOnlyElement(
-            visitor.assistedInjectBindings).getAssistedMethods());
+        Lists.newArrayList(
+            Iterables.getOnlyElement(visitor.assistedInjectBindings).getAssistedMethods());
     assertEquals(7, assistedMethods.size());
     assertEquals(1, visitor.assistedBindingCount);
     assertEquals(1, visitor.assistedInjectBindings.size());
 
     // Validate for each of the methods in AnimalFactory
-    
+
     Set<String> names = Sets.newHashSet();
     for (AssistedMethod method : assistedMethods) {
       String name = method.getFactoryMethod().getName();
       names.add(name);
-      if (name.equals("createAStrangeCatAsAnimal")) {        
-        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());        
+      if (name.equals("createAStrangeCatAsAnimal")) {
+        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
       } else if (name.equals("createStrangeCatWithConstructorForOwner")) {
-        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());     
+        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
       } else if (name.equals("createStrangeCatWithConstructorForAge")) {
-        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());        
+        validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
       } else if (name.equals("createCatWithANonAssistedDependency")) {
-        validateAssistedMethod(method, name, CatWithAName.class,
-            ImmutableList.<Key<?>>of(Key.get(String.class, named("catName2"))));        
+        validateAssistedMethod(
+            method,
+            name,
+            CatWithAName.class,
+            ImmutableList.<Key<?>>of(Key.get(String.class, named("catName2"))));
       } else if (name.equals("createCat")) {
-        validateAssistedMethod(method, name, Cat.class, ImmutableList.<Key<?>>of());        
+        validateAssistedMethod(method, name, Cat.class, ImmutableList.<Key<?>>of());
       } else if (name.equals("createASimpleCatAsAnimal")) {
         validateAssistedMethod(method, name, SimpleCat.class, ImmutableList.<Key<?>>of());
       } else if (name.equals("createCatWithNonAssistedDependencies")) {
-        List<Key<?>> dependencyKeys = ImmutableList.<Key<?>>of(
-            Key.get(String.class, named("catName1")),
-            Key.get(String.class, named("petName")),        
-            Key.get(Integer.class, named("age")));
-        validateAssistedMethod(method, name, ExplodingCat.class, dependencyKeys);        
+        List<Key<?>> dependencyKeys =
+            ImmutableList.<Key<?>>of(
+                Key.get(String.class, named("catName1")),
+                Key.get(String.class, named("petName")),
+                Key.get(Integer.class, named("age")));
+        validateAssistedMethod(method, name, ExplodingCat.class, dependencyKeys);
       } else {
         fail("Invalid method: " + method);
       }
     }
-    assertEquals(names, ImmutableSet.of("createAStrangeCatAsAnimal",
-        "createStrangeCatWithConstructorForOwner",
-        "createStrangeCatWithConstructorForAge",
-        "createCatWithANonAssistedDependency",
-        "createCat",
-        "createASimpleCatAsAnimal",
-        "createCatWithNonAssistedDependencies"));
+    assertEquals(
+        names,
+        ImmutableSet.of(
+            "createAStrangeCatAsAnimal",
+            "createStrangeCatWithConstructorForOwner",
+            "createStrangeCatWithConstructorForAge",
+            "createCatWithANonAssistedDependency",
+            "createCat",
+            "createASimpleCatAsAnimal",
+            "createCatWithNonAssistedDependencies"));
   }
 
-  private void validateAssistedMethod(AssistedMethod assistedMethod, String factoryMethodName,
-                                      Class clazz, List<Key<?>> dependencyKeys){
+  private void validateAssistedMethod(
+      AssistedMethod assistedMethod,
+      String factoryMethodName,
+      Class clazz,
+      List<Key<?>> dependencyKeys) {
     assertEquals(factoryMethodName, assistedMethod.getFactoryMethod().getName());
     assertEquals(clazz, assistedMethod.getImplementationConstructor().getDeclaringClass());
     assertEquals(dependencyKeys.size(), assistedMethod.getDependencies().size());
@@ -129,70 +137,86 @@
     assertEquals(clazz, assistedMethod.getImplementationType().getType());
   }
 
-
   interface AnimalFactory {
     Cat createCat(String owner);
+
     CatWithAName createCatWithANonAssistedDependency(String owner);
-    @Named("SimpleCat") Animal createASimpleCatAsAnimal(String owner);
+
+    @Named("SimpleCat")
+    Animal createASimpleCatAsAnimal(String owner);
+
     Animal createAStrangeCatAsAnimal(String owner);
+
     StrangeCat createStrangeCatWithConstructorForOwner(String owner);
+
     StrangeCat createStrangeCatWithConstructorForAge(Integer age);
+
     ExplodingCat createCatWithNonAssistedDependencies(String owner);
   }
 
   interface Animal {}
 
   private static class Cat implements Animal {
-    @Inject Cat(@Assisted String owner) {}
+    @Inject
+    Cat(@Assisted String owner) {}
   }
 
   private static class SimpleCat implements Animal {
-    @Inject SimpleCat(@Assisted String owner) {
-    }
+    @Inject
+    SimpleCat(@Assisted String owner) {}
   }
 
   private static class StrangeCat implements Animal {
-    @AssistedInject StrangeCat(@Assisted String owner) {}
-    @AssistedInject StrangeCat(@Assisted Integer age) {}
+    @AssistedInject
+    StrangeCat(@Assisted String owner) {}
+
+    @AssistedInject
+    StrangeCat(@Assisted Integer age) {}
   }
 
   private static class ExplodingCat implements Animal {
-    @Inject public ExplodingCat(@Named("catName1") String name, @Assisted String owner,
-                                @Named("age") Integer age, @Named("petName") String petName) {}
+    @Inject
+    public ExplodingCat(
+        @Named("catName1") String name,
+        @Assisted String owner,
+        @Named("age") Integer age,
+        @Named("petName") String petName) {}
   }
 
   private static class CatWithAName extends Cat {
-    @Inject CatWithAName(@Assisted String owner, @Named("catName2") String name) {
+    @Inject
+    CatWithAName(@Assisted String owner, @Named("catName2") String name) {
       super(owner);
     }
   }
 
-  public class Module extends AbstractModule{
+  public static class Module extends AbstractModule {
     @Override
     protected void configure() {
       bind(String.class).annotatedWith(named("catName1")).toInstance("kitty1");
       bind(String.class).annotatedWith(named("catName2")).toInstance("kitty2");
       bind(String.class).annotatedWith(named("petName")).toInstance("pussy");
       bind(Integer.class).annotatedWith(named("age")).toInstance(12);
-      install(new FactoryModuleBuilder()
-        .implement(Animal.class, StrangeCat.class)
-        .implement(Animal.class, named("SimpleCat"), SimpleCat.class)
-        .build(AnimalFactory.class));
+      install(
+          new FactoryModuleBuilder()
+              .implement(Animal.class, StrangeCat.class)
+              .implement(Animal.class, named("SimpleCat"), SimpleCat.class)
+              .build(AnimalFactory.class));
     }
   }
 
-  public class AssistedInjectSpiVisitor extends DefaultBindingTargetVisitor<Object, Integer>
-      implements AssistedInjectTargetVisitor<Object, Integer>  {
+  public static class AssistedInjectSpiVisitor extends DefaultBindingTargetVisitor<Object, Integer>
+      implements AssistedInjectTargetVisitor<Object, Integer> {
 
-    private final Set<Class> allowedClasses = 
-      ImmutableSet.<Class> of(
-        Injector.class, Stage.class, Logger.class,
-        String.class, Integer.class);
-    
+    private final Set<Class> allowedClasses =
+        ImmutableSet.<Class>of(
+            Injector.class, Stage.class, Logger.class, String.class, Integer.class);
+
     private int assistedBindingCount = 0;
     private int currentCount = 0;
     private List<AssistedInjectBinding<?>> assistedInjectBindings = Lists.newArrayList();
 
+    @Override
     public Integer visit(AssistedInjectBinding assistedInjectBinding) {
       assistedInjectBindings.add(assistedInjectBinding);
       assistedBindingCount++;
@@ -201,7 +225,7 @@
 
     @Override
     protected Integer visitOther(Binding<? extends Object> binding) {
-      if(!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
+      if (!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
         throw new AssertionFailedError("invalid other binding: " + binding);
       }
       return currentCount++;
diff --git a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryModuleBuilderTest.java b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryModuleBuilderTest.java
index e047495..ad1011e 100644
--- a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryModuleBuilderTest.java
+++ b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryModuleBuilderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,51 +40,59 @@
 import com.google.inject.spi.Elements;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.Message;
-
-import junit.framework.TestCase;
-
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import junit.framework.TestCase;
 
 public class FactoryModuleBuilderTest extends TestCase {
-  
-  private enum Color { BLUE, GREEN, RED, GRAY, BLACK }
+
+  private enum Color {
+    BLUE,
+    GREEN,
+    RED,
+    GRAY,
+    BLACK
+  }
 
   public void testImplicitForwardingAssistedBindingFailsWithInterface() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(Car.class).to(Golf.class);
-          install(new FactoryModuleBuilder().build(ColoredCarFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Car.class).to(Golf.class);
+              install(new FactoryModuleBuilder().build(ColoredCarFactory.class));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertContains(
-          ce.getMessage(), "1) " + Car.class.getName() + " is an interface, not a concrete class.",
+          ce.getMessage(),
+          "1) " + Car.class.getName() + " is an interface, not a concrete class.",
           "Unable to create AssistedInject factory.",
           "while locating " + Car.class.getName(),
           "at " + ColoredCarFactory.class.getName() + ".create(");
       assertEquals(1, ce.getErrorMessages().size());
     }
   }
-  
+
   public void testImplicitForwardingAssistedBindingFailsWithAbstractClass() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(AbstractCar.class).to(ArtCar.class);
-          install(new FactoryModuleBuilder().build(ColoredAbstractCarFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(AbstractCar.class).to(ArtCar.class);
+              install(new FactoryModuleBuilder().build(ColoredAbstractCarFactory.class));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertContains(
-          ce.getMessage(), "1) " + AbstractCar.class.getName() + " is abstract, not a concrete class.",
+          ce.getMessage(),
+          "1) " + AbstractCar.class.getName() + " is abstract, not a concrete class.",
           "Unable to create AssistedInject factory.",
           "while locating " + AbstractCar.class.getName(),
           "at " + ColoredAbstractCarFactory.class.getName() + ".create(");
@@ -94,12 +102,19 @@
 
   public void testImplicitForwardingAssistedBindingCreatesNewObjects() {
     final Mustang providedMustang = new Mustang(Color.BLUE);
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new FactoryModuleBuilder().build(MustangFactory.class));
-      }
-      @Provides Mustang provide() { return providedMustang; }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(MustangFactory.class));
+              }
+
+              @Provides
+              Mustang provide() {
+                return providedMustang;
+              }
+            });
     assertSame(providedMustang, injector.getInstance(Mustang.class));
     MustangFactory factory = injector.getInstance(MustangFactory.class);
     Mustang created = factory.create(Color.GREEN);
@@ -110,19 +125,22 @@
 
   public void testExplicitForwardingAssistedBindingFailsWithInterface() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(Volkswagen.class).to(Golf.class);
-          install(new FactoryModuleBuilder()
-            .implement(Car.class, Volkswagen.class)
-            .build(ColoredCarFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Volkswagen.class).to(Golf.class);
+              install(
+                  new FactoryModuleBuilder()
+                      .implement(Car.class, Volkswagen.class)
+                      .build(ColoredCarFactory.class));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertContains(
-          ce.getMessage(), "1) " + Volkswagen.class.getName() + " is an interface, not a concrete class.",
+          ce.getMessage(),
+          "1) " + Volkswagen.class.getName() + " is an interface, not a concrete class.",
           "Unable to create AssistedInject factory.",
           "while locating " + Volkswagen.class.getName(),
           "while locating " + Car.class.getName(),
@@ -133,19 +151,22 @@
 
   public void testExplicitForwardingAssistedBindingFailsWithAbstractClass() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(AbstractCar.class).to(ArtCar.class);
-          install(new FactoryModuleBuilder()
-            .implement(Car.class, AbstractCar.class)
-            .build(ColoredCarFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(AbstractCar.class).to(ArtCar.class);
+              install(
+                  new FactoryModuleBuilder()
+                      .implement(Car.class, AbstractCar.class)
+                      .build(ColoredCarFactory.class));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertContains(
-          ce.getMessage(), "1) " + AbstractCar.class.getName() + " is abstract, not a concrete class.",
+          ce.getMessage(),
+          "1) " + AbstractCar.class.getName() + " is abstract, not a concrete class.",
           "Unable to create AssistedInject factory.",
           "while locating " + AbstractCar.class.getName(),
           "while locating " + Car.class.getName(),
@@ -153,37 +174,50 @@
       assertEquals(1, ce.getErrorMessages().size());
     }
   }
-  
+
   public void testExplicitForwardingAssistedBindingCreatesNewObjects() {
     final Mustang providedMustang = new Mustang(Color.BLUE);
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new FactoryModuleBuilder().implement(Car.class, Mustang.class).build(
-            ColoredCarFactory.class));
-      }
-      @Provides Mustang provide() { return providedMustang; }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Mustang.class)
+                        .build(ColoredCarFactory.class));
+              }
+
+              @Provides
+              Mustang provide() {
+                return providedMustang;
+              }
+            });
     assertSame(providedMustang, injector.getInstance(Mustang.class));
     ColoredCarFactory factory = injector.getInstance(ColoredCarFactory.class);
-    Mustang created = (Mustang)factory.create(Color.GREEN);
+    Mustang created = (Mustang) factory.create(Color.GREEN);
     assertNotSame(providedMustang, created);
     assertEquals(Color.BLUE, providedMustang.color);
     assertEquals(Color.GREEN, created.color);
   }
 
   public void testAnnotatedAndParentBoundReturnValue() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(Car.class).to(Golf.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Car.class).to(Golf.class);
 
-        bind(Integer.class).toInstance(911);
-        bind(Double.class).toInstance(5.0d);
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Names.named("german"), Beetle.class)
-            .implement(Car.class, Names.named("american"), Mustang.class)
-            .build(AnnotatedVersatileCarFactory.class));
-      }
-    });
+                bind(Integer.class).toInstance(911);
+                bind(Double.class).toInstance(5.0d);
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Names.named("german"), Beetle.class)
+                        .implement(Car.class, Names.named("american"), Mustang.class)
+                        .build(AnnotatedVersatileCarFactory.class));
+              }
+            });
 
     AnnotatedVersatileCarFactory factory = injector.getInstance(AnnotatedVersatileCarFactory.class);
     assertTrue(factory.getGermanCar(Color.BLACK) instanceof Beetle);
@@ -191,15 +225,19 @@
   }
 
   public void testParentBoundReturnValue() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(Car.class).to(Golf.class);
-        bind(Double.class).toInstance(5.0d);
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Mustang.class)
-            .build(ColoredCarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Car.class).to(Golf.class);
+                bind(Double.class).toInstance(5.0d);
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Mustang.class)
+                        .build(ColoredCarFactory.class));
+              }
+            });
 
     ColoredCarFactory factory = injector.getInstance(ColoredCarFactory.class);
     assertTrue(factory.create(Color.RED) instanceof Mustang);
@@ -207,14 +245,18 @@
   }
 
   public void testConfigureAnnotatedReturnValue() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Names.named("german"), Beetle.class)
-            .implement(Car.class, Names.named("american"), Mustang.class)
-            .build(AnnotatedVersatileCarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Names.named("german"), Beetle.class)
+                        .implement(Car.class, Names.named("american"), Mustang.class)
+                        .build(AnnotatedVersatileCarFactory.class));
+              }
+            });
 
     AnnotatedVersatileCarFactory factory = injector.getInstance(AnnotatedVersatileCarFactory.class);
     assertTrue(factory.getGermanCar(Color.GRAY) instanceof Beetle);
@@ -222,12 +264,14 @@
   }
 
   public void testNoBindingAssistedInject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(MustangFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(MustangFactory.class));
+              }
+            });
 
     MustangFactory factory = injector.getInstance(MustangFactory.class);
 
@@ -236,14 +280,17 @@
   }
 
   public void testBindingAssistedInject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Mustang.class)
-            .build(ColoredCarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Mustang.class)
+                        .build(ColoredCarFactory.class));
+              }
+            });
 
     ColoredCarFactory factory = injector.getInstance(ColoredCarFactory.class);
 
@@ -252,17 +299,21 @@
   }
 
   public void testDuplicateBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Mustang.class)
-            .build(ColoredCarFactory.class));
-        install(new FactoryModuleBuilder()
-            .implement(Car.class, Mustang.class)
-            .build(ColoredCarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Mustang.class)
+                        .build(ColoredCarFactory.class));
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Car.class, Mustang.class)
+                        .build(ColoredCarFactory.class));
+              }
+            });
 
     ColoredCarFactory factory = injector.getInstance(ColoredCarFactory.class);
 
@@ -272,34 +323,41 @@
 
   public void testSimilarBindingsWithConflictingImplementations() {
     try {
-      Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder()
-              .implement(Car.class, Mustang.class)
-              .build(ColoredCarFactory.class));
-          install(new FactoryModuleBuilder()
-              .implement(Car.class, Golf.class)
-              .build(ColoredCarFactory.class));
-        }
-      });
+      Injector injector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  install(
+                      new FactoryModuleBuilder()
+                          .implement(Car.class, Mustang.class)
+                          .build(ColoredCarFactory.class));
+                  install(
+                      new FactoryModuleBuilder()
+                          .implement(Car.class, Golf.class)
+                          .build(ColoredCarFactory.class));
+                }
+              });
       injector.getInstance(ColoredCarFactory.class);
       fail();
     } catch (CreationException ce) {
-      assertContains(ce.getMessage(),
+      assertContains(
+          ce.getMessage(),
           "A binding to " + ColoredCarFactory.class.getName() + " was already configured");
       assertEquals(1, ce.getErrorMessages().size());
     }
   }
 
   public void testMultipleReturnTypes() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        install(new FactoryModuleBuilder().build(VersatileCarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                install(new FactoryModuleBuilder().build(VersatileCarFactory.class));
+              }
+            });
 
     VersatileCarFactory factory = injector.getInstance(VersatileCarFactory.class);
 
@@ -309,34 +367,39 @@
     Beetle beetle = factory.getBeetle(Color.GREEN);
     assertEquals(Color.GREEN, beetle.color);
   }
-  
+
   public void testParameterizedClassesWithNoImplements() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(new TypeLiteral<Foo.Factory<String>>() {}));
-      }
-    });
-    
-    Foo.Factory<String> factory = injector.getInstance(Key.get(new TypeLiteral<Foo.Factory<String>>() {}));
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder().build(new TypeLiteral<Foo.Factory<String>>() {}));
+              }
+            });
+
+    Foo.Factory<String> factory =
+        injector.getInstance(Key.get(new TypeLiteral<Foo.Factory<String>>() {}));
     @SuppressWarnings("unused")
     Foo<String> foo = factory.create(new Bar());
   }
-  
+
   public void testGenericErrorMessageMakesSense() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-         install(new FactoryModuleBuilder().build(Key.get(Foo.Factory.class))); 
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(new FactoryModuleBuilder().build(Key.get(Foo.Factory.class)));
+            }
+          });
       fail();
-    } catch(CreationException ce ) {
+    } catch (CreationException ce) {
       // Assert not only that it's the correct message, but also that it's the *only* message.
       Collection<Message> messages = ce.getErrorMessages();
       assertEquals(
-          Foo.Factory.class.getName() + " cannot be used as a key; It is not fully specified.", 
+          Foo.Factory.class.getName() + " cannot be used as a key; It is not fully specified.",
           Iterables.getOnlyElement(messages).getMessage());
     }
   }
@@ -355,18 +418,23 @@
 
   interface VersatileCarFactory {
     Mustang getMustang(Color color);
+
     Beetle getBeetle(Color color);
   }
 
   interface AnnotatedVersatileCarFactory {
-    @Named("german") Car getGermanCar(Color color);
-    @Named("american") Car getAmericanCar(Color color);
+    @Named("german")
+    Car getGermanCar(Color color);
+
+    @Named("american")
+    Car getAmericanCar(Color color);
   }
 
   public static class Golf implements Volkswagen {}
 
   public static class Mustang implements Car {
     private final Color color;
+
     @Inject
     public Mustang(@Assisted Color color) {
       this.color = color;
@@ -375,73 +443,81 @@
 
   public static class Beetle implements Car {
     private final Color color;
+
     @Inject
     public Beetle(@Assisted Color color) {
       this.color = color;
     }
   }
-  
+
   public static class Foo<E> {
     static interface Factory<E> {
       Foo<E> create(Bar bar);
     }
+
     @SuppressWarnings("unused")
-    @Inject Foo(@Assisted Bar bar, Baz<E> baz) {}
+    @Inject
+    Foo(@Assisted Bar bar, Baz<E> baz) {}
   }
-  
+
   public static class Bar {}
+
   @SuppressWarnings("unused")
   public static class Baz<E> {}
-  
-  abstract static class AbstractCar implements Car {}  
+
+  abstract static class AbstractCar implements Car {}
+
   interface ColoredAbstractCarFactory {
     AbstractCar create(Color color);
-  }  
+  }
+
   public static class ArtCar extends AbstractCar {}
-    
+
   public void testFactoryBindingDependencies() {
     // validate dependencies work in all stages & as a raw element,
     // and that dependencies work for methods, fields, constructors,
     // and for @AssistedInject constructors too.
-    Module module = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Integer.class).toInstance(42);
-        bind(Double.class).toInstance(4.2d);
-        bind(Float.class).toInstance(4.2f);
-        bind(String.class).annotatedWith(named("dog")).toInstance("dog");
-        bind(String.class).annotatedWith(named("cat1")).toInstance("cat1");
-        bind(String.class).annotatedWith(named("cat2")).toInstance("cat2");
-        bind(String.class).annotatedWith(named("cat3")).toInstance("cat3");
-        bind(String.class).annotatedWith(named("arbitrary")).toInstance("fail!");
-        install(new FactoryModuleBuilder()
-                .implement(Animal.class, Dog.class)
-                .build(AnimalHouse.class));
-      }
-    };
+    Module module =
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Integer.class).toInstance(42);
+            bind(Double.class).toInstance(4.2d);
+            bind(Float.class).toInstance(4.2f);
+            bind(String.class).annotatedWith(named("dog")).toInstance("dog");
+            bind(String.class).annotatedWith(named("cat1")).toInstance("cat1");
+            bind(String.class).annotatedWith(named("cat2")).toInstance("cat2");
+            bind(String.class).annotatedWith(named("cat3")).toInstance("cat3");
+            bind(String.class).annotatedWith(named("arbitrary")).toInstance("fail!");
+            install(
+                new FactoryModuleBuilder()
+                    .implement(Animal.class, Dog.class)
+                    .build(AnimalHouse.class));
+          }
+        };
 
-    Set<Key<?>> expectedKeys = ImmutableSet.<Key<?>>of(
-        Key.get(Integer.class),
-        Key.get(Double.class),
-        Key.get(Float.class),
-        Key.get(String.class, named("dog")),
-        Key.get(String.class, named("cat1")),
-        Key.get(String.class, named("cat2")),
-        Key.get(String.class, named("cat3"))
-    );
-    
+    Set<Key<?>> expectedKeys =
+        ImmutableSet.<Key<?>>of(
+            Key.get(Integer.class),
+            Key.get(Double.class),
+            Key.get(Float.class),
+            Key.get(String.class, named("dog")),
+            Key.get(String.class, named("cat1")),
+            Key.get(String.class, named("cat2")),
+            Key.get(String.class, named("cat3")));
+
     Injector injector = Guice.createInjector(module);
     validateDependencies(expectedKeys, injector.getBinding(AnimalHouse.class));
-    
+
     injector = Guice.createInjector(Stage.TOOL, module);
     validateDependencies(expectedKeys, injector.getBinding(AnimalHouse.class));
-    
+
     List<Element> elements = Elements.getElements(module);
     boolean found = false;
-    for(Element element : elements) {
-      if(element instanceof Binding) {
+    for (Element element : elements) {
+      if (element instanceof Binding) {
         Binding<?> binding = (Binding<?>) element;
-        if(binding.getKey().equals(Key.get(AnimalHouse.class))) {
+        if (binding.getKey().equals(Key.get(AnimalHouse.class))) {
           found = true;
           validateDependencies(expectedKeys, binding);
           break;
@@ -450,81 +526,113 @@
     }
     assertTrue(found);
   }
-  
+
   private void validateDependencies(Set<Key<?>> expectedKeys, Binding<?> binding) {
-    Set<Dependency<?>> dependencies = ((HasDependencies)binding).getDependencies();
-    Set<Key<?>> actualKeys = new HashSet<Key<?>>();
+    Set<Dependency<?>> dependencies = ((HasDependencies) binding).getDependencies();
+    Set<Key<?>> actualKeys = new HashSet<>();
     for (Dependency<?> dependency : dependencies) {
       actualKeys.add(dependency.getKey());
     }
     assertEquals(expectedKeys, actualKeys);
   }
-  
+
   interface AnimalHouse {
     Animal createAnimal(String name);
+
     Cat createCat(String name);
+
     Cat createCat(int age);
   }
-  
+
   interface Animal {}
+
   @SuppressWarnings("unused")
   private static class Dog implements Animal {
     @Inject int a;
-    @Inject Dog(@Assisted String a, double b) {}
-    @Inject void register(@Named("dog") String a) {}
+
+    @Inject
+    Dog(@Assisted String a, double b) {}
+
+    @Inject
+    void register(@Named("dog") String a) {}
   }
+
   @SuppressWarnings("unused")
   private static class Cat implements Animal {
     @Inject float a;
-    @AssistedInject Cat(@Assisted String a, @Named("cat1") String b) {}
-    @AssistedInject Cat(@Assisted int a, @Named("cat2") String b) {}
-    @AssistedInject Cat(@Assisted byte a, @Named("catfail") String b) {} // not a dependency!
-    @Inject void register(@Named("cat3") String a) {}
+
+    @AssistedInject
+    Cat(@Assisted String a, @Named("cat1") String b) {}
+
+    @AssistedInject
+    Cat(@Assisted int a, @Named("cat2") String b) {}
+
+    @AssistedInject
+    Cat(@Assisted byte a, @Named("catfail") String b) {} // not a dependency!
+
+    @Inject
+    void register(@Named("cat3") String a) {}
   }
-  
+
   public void testFactoryPublicAndReturnTypeNotPublic() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder()
-              .implement(Hidden.class, HiddenImpl.class)
-              .build(NotHidden.class));
-        }
-      });
-    } catch(CreationException ce) {
-      assertEquals(NotHidden.class.getName() + " is public, but has a method that returns a non-public type: "
-          + Hidden.class.getName() + ". Due to limitations with java.lang.reflect.Proxy, this is not allowed. "
-          + "Please either make the factory non-public or the return type public.",           
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(
+                  new FactoryModuleBuilder()
+                      .implement(Hidden.class, HiddenImpl.class)
+                      .build(NotHidden.class));
+            }
+          });
+      fail("Expected CreationException");
+    } catch (CreationException ce) {
+      assertEquals(
+          NotHidden.class.getName()
+              + " is public, but has a method that returns a non-public type: "
+              + Hidden.class.getName()
+              + ". Due to limitations with java.lang.reflect.Proxy, this is not allowed. "
+              + "Please either make the factory non-public or the return type public.",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   interface Hidden {}
+
   public static class HiddenImpl implements Hidden {}
+
   public interface NotHidden {
     Hidden create();
   }
-  
+
   public void testSingletonScopeOnAssistedClassIsIgnored() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder().build(SingletonFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(new FactoryModuleBuilder().build(SingletonFactory.class));
+            }
+          });
       fail();
     } catch (CreationException ce) {
       assertEquals(1, ce.getErrorMessages().size());
-      assertEquals("Found scope annotation [" + Singleton.class.getName() + "]"
-          + " on implementation class [" + AssistedSingleton.class.getName() + "]"
-          + " of AssistedInject factory [" + SingletonFactory.class.getName() + "]."
-          + "\nThis is not allowed, please remove the scope annotation.",
+      assertEquals(
+          "Found scope annotation ["
+              + Singleton.class.getName()
+              + "]"
+              + " on implementation class ["
+              + AssistedSingleton.class.getName()
+              + "]"
+              + " of AssistedInject factory ["
+              + SingletonFactory.class.getName()
+              + "]."
+              + "\nThis is not allowed, please remove the scope annotation.",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   interface SingletonFactory {
     AssistedSingleton create(String string);
   }
@@ -533,8 +641,6 @@
   @Singleton
   static class AssistedSingleton {
     @Inject
-    public AssistedSingleton(@SuppressWarnings("unused") @Assisted String string) {
-    }
+    public AssistedSingleton(@SuppressWarnings("unused") @Assisted String string) {}
   }
-  
 }
diff --git a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
index c0e9bbd..050edb1 100644
--- a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
+++ b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,52 +31,63 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.assistedinject.FactoryProvider2Test.Equals.ComparisonMethod;
 import com.google.inject.assistedinject.FactoryProvider2Test.Equals.Impl;
+import com.google.inject.internal.Annotations;
 import com.google.inject.matcher.Matchers;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import junit.framework.TestCase;
 
 @SuppressWarnings("deprecation")
 public class FactoryProvider2Test extends TestCase {
 
-  private enum Color { BLUE, GREEN, RED, GRAY, BLACK, ORANGE, PINK }
-  
+  private enum Color {
+    BLUE,
+    GREEN,
+    RED,
+    GRAY,
+    BLACK,
+    ORANGE,
+    PINK
+  }
+
   public void testAssistedFactory() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Mustang redMustang = (Mustang) carFactory.create(Color.RED);
     assertEquals(Color.RED, redMustang.color);
-    assertEquals(5.0d, redMustang.engineSize);
+    assertEquals(5.0d, redMustang.engineSize, 0.0);
   }
 
   public void testAssistedFactoryWithAnnotations() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
-        bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+                bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
@@ -131,20 +142,22 @@
   }
 
   public void testFactoryUsesInjectedConstructor() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(float.class).toInstance(140f);
-        bind(SummerCarFactory.class).toProvider(
-            FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(float.class).toInstance(140f);
+                bind(SummerCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
+              }
+            });
 
     SummerCarFactory carFactory = injector.getInstance(SummerCarFactory.class);
 
     Corvette redCorvette = (Corvette) carFactory.create(Color.RED, false);
     assertEquals(Color.RED, redCorvette.color);
-    assertEquals(140f, redCorvette.maxMph);
+    assertEquals(140f, redCorvette.maxMph, 0.0f);
     assertFalse(redCorvette.isConvertable);
   }
 
@@ -167,13 +180,15 @@
   }
 
   public void testConstructorDoesntNeedAllFactoryMethodArguments() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(SummerCarFactory.class).toProvider(
-            FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(SummerCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class));
+              }
+            });
     SummerCarFactory factory = injector.getInstance(SummerCarFactory.class);
 
     Beetle beetle = (Beetle) factory.create(Color.RED, true);
@@ -182,6 +197,7 @@
 
   public static class Beetle implements Car {
     private final Color color;
+
     @Inject
     public Beetle(@Assisted Color color) {
       this.color = color;
@@ -189,21 +205,23 @@
   }
 
   public void testMethodsAndFieldsGetInjected() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("turbo");
-        bind(int.class).toInstance(911);
-        bind(double.class).toInstance(50000d);
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Porsche.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("turbo");
+                bind(int.class).toInstance(911);
+                bind(double.class).toInstance(50000d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porsche.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Porsche grayPorsche = (Porsche) carFactory.create(Color.GRAY);
     assertEquals(Color.GRAY, grayPorsche.color);
-    assertEquals(50000d, grayPorsche.price);
+    assertEquals(50000d, grayPorsche.price, 0.0);
     assertEquals(911, grayPorsche.model);
     assertEquals("turbo", grayPorsche.name);
   }
@@ -220,20 +238,24 @@
       this.price = price;
     }
 
-    @Inject void setModel(int model) {
+    @Inject
+    void setModel(int model) {
       this.model = model;
     }
   }
 
   public void testProviderInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("trans am");
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("trans am");
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Firebird blackFirebird = (Firebird) carFactory.create(Color.BLACK);
@@ -251,56 +273,64 @@
       this.color = color;
     }
   }
-  
+
   public void testAssistedProviderInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("trans am");
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Flamingbird.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("trans am");
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, Flamingbird.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Flamingbird flamingbird = (Flamingbird) carFactory.create(Color.BLACK);
     assertEquals(Color.BLACK, flamingbird.colorProvider.get());
     assertEquals("trans am", flamingbird.modifiersProvider.get());
-    
+
     Flamingbird flamingbird2 = (Flamingbird) carFactory.create(Color.RED);
     assertEquals(Color.RED, flamingbird2.colorProvider.get());
     assertEquals("trans am", flamingbird2.modifiersProvider.get());
     // Make sure the original flamingbird is black still.
     assertEquals(Color.BLACK, flamingbird.colorProvider.get());
-  }  
-  
+  }
+
   public static class Flamingbird implements Car {
     private final Provider<String> modifiersProvider;
     private final Provider<Color> colorProvider;
 
     @Inject
-    public Flamingbird(Provider<String> modifiersProvider, @Assisted Provider<Color> colorProvider) {
+    public Flamingbird(
+        Provider<String> modifiersProvider, @Assisted Provider<Color> colorProvider) {
       this.modifiersProvider = modifiersProvider;
       this.colorProvider = colorProvider;
     }
   }
 
   public void testTypeTokenInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Flux Capacitor"));
-        bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(new TypeLiteral<Set<String>>() {})
+                    .toInstance(Collections.singleton("Flux Capacitor"));
+                bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     DeLorean deLorean = (DeLorean) carFactory.create(Color.GRAY);
     assertEquals(Color.GRAY, deLorean.color);
     assertEquals("Flux Capacitor", deLorean.features.iterator().next());
-    assertEquals(new Integer(88), deLorean.featureActivationSpeeds.iterator().next());
+    assertEquals(Integer.valueOf(88), deLorean.featureActivationSpeeds.iterator().next());
   }
 
   public static class DeLorean implements Car {
@@ -318,14 +348,16 @@
   }
 
   public void testTypeTokenProviderInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(new TypeLiteral<Set<String>>() { }).toInstance(Collections.singleton("Datsun"));
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Datsun"));
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Z orangeZ = (Z) carFactory.create(Color.ORANGE);
@@ -354,13 +386,15 @@
   }
 
   public void testAssistInjectionInNonPublicConstructor() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
+              }
+            });
     Prius prius = (Prius) injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
     assertEquals(prius.color, Color.ORANGE);
   }
@@ -373,13 +407,16 @@
   }
 
   public void testExceptionDuringConstruction() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
+              }
+            });
     try {
       injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
       fail();
@@ -395,8 +432,9 @@
     }
   }
 
-  public static class ExplosionException extends Exception { }
-  public static class FireException extends Exception { }
+  public static class ExplosionException extends Exception {}
+
+  public static class FireException extends Exception {}
 
   public interface DefectiveCarFactoryWithNoExceptions {
     Car createCar();
@@ -411,13 +449,17 @@
   }
 
   public void testConstructorExceptionsAreThrownByFactory() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(CorrectDefectiveCarFactory.class).toProvider(
-            FactoryProvider.newFactory(CorrectDefectiveCarFactory.class, DefectiveCar.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(CorrectDefectiveCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            CorrectDefectiveCarFactory.class, DefectiveCar.class));
+              }
+            });
     try {
       injector.getInstance(CorrectDefectiveCarFactory.class).createCar();
       fail();
@@ -434,17 +476,21 @@
     }
 
     @Inject
-    public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) { }
+    public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) {}
   }
 
   public void testWildcardGenerics() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(WildcardCollection.Factory.class).toProvider(
-            FactoryProvider.newFactory(WildcardCollection.Factory.class, WildcardCollection.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(WildcardCollection.Factory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            WildcardCollection.Factory.class, WildcardCollection.class));
+              }
+            });
     WildcardCollection.Factory factory = injector.getInstance(WildcardCollection.Factory.class);
     factory.create(Collections.emptyList());
   }
@@ -463,13 +509,15 @@
   }
 
   public void testFactoryWithImplicitBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Fiat.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Fiat.class));
+              }
+            });
 
     ColoredCarFactory coloredCarFactory = injector.getInstance(ColoredCarFactory.class);
     Fiat fiat = (Fiat) coloredCarFactory.create(Color.GREEN);
@@ -479,44 +527,54 @@
 
   public void testFactoryFailsWithMissingBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(ColoredCarFactory.class).toProvider(
-              FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(ColoredCarFactory.class)
+                  .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Could not find a suitable constructor in java.lang.Double.",
           "at " + ColoredCarFactory.class.getName() + ".create(FactoryProvider2Test.java");
     }
   }
-  
+
   public void testFactoryFailsWithMissingBindingInToolStage() {
     try {
-      Guice.createInjector(Stage.TOOL, new AbstractModule() {
-        @Override protected void configure() {
-          bind(ColoredCarFactory.class).toProvider(
-              FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        }
-      });
+      Guice.createInjector(
+          Stage.TOOL,
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(ColoredCarFactory.class)
+                  .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Could not find a suitable constructor in java.lang.Double.",
           "at " + ColoredCarFactory.class.getName() + ".create(FactoryProvider2Test.java");
     }
   }
 
   public void testMethodsDeclaredInObject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(Double.class).toInstance(5.0d);
-          bind(ColoredCarFactory.class).toProvider(
-              FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        }
-      });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
@@ -528,34 +586,40 @@
   }
 
   public void testInjectingProviderOfParameter() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(ColoredCarFactory.class).toProvider(
-              FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class));
-        }
-      });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
     Subaru subaru = (Subaru) carFactory.create(Color.RED);
 
     assertSame(Color.RED, subaru.colorProvider.get());
     assertSame(Color.RED, subaru.colorProvider.get());
-    
-    Subaru sedan  = (Subaru) carFactory.create(Color.BLUE);
+
+    Subaru sedan = (Subaru) carFactory.create(Color.BLUE);
     assertSame(Color.BLUE, sedan.colorProvider.get());
     assertSame(Color.BLUE, sedan.colorProvider.get());
-    
+
     // and make sure the subaru is still red
     assertSame(Color.RED, subaru.colorProvider.get());
   }
 
   public void testInjectingNullParameter() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(ColoredCarFactory.class).toProvider(
-              FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class));
-        }
-      });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
     Subaru subaru = (Subaru) carFactory.create(null);
@@ -566,91 +630,129 @@
 
   interface ProviderBasedColoredCarFactory {
     Car createCar(Provider<Color> colorProvider, Provider<String> stringProvider);
+
     Mustang createMustang(@Assisted("color") Provider<Color> colorProvider);
   }
 
   public void testAssistedProviderIsDisallowed() {
     try {
-      Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(ProviderBasedColoredCarFactory.class).toProvider(
-                FactoryProvider.newFactory(ProviderBasedColoredCarFactory.class, Subaru.class));
-          }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(ProviderBasedColoredCarFactory.class)
+                  .toProvider(
+                      FactoryProvider.newFactory(
+                          ProviderBasedColoredCarFactory.class, Subaru.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
       assertEquals(expected.getMessage(), 4, expected.getErrorMessages().size());
       // Assert each method individually, because JDK7 doesn't guarantee method ordering.
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [1] with key"
-            + " [com.google.inject.Provider<" + Color.class.getName() + ">] on method ["
-            + ProviderBasedColoredCarFactory.class.getName() + ".createCar()]");
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [1] with key"
+              + " [com.google.inject.Provider<"
+              + Color.class.getName()
+              + ">] on method ["
+              + ProviderBasedColoredCarFactory.class.getName()
+              + ".createCar()]");
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [2] with key"
-            + " [com.google.inject.Provider<java.lang.String>] on method ["
-            + ProviderBasedColoredCarFactory.class.getName() + ".createCar()]");
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [2] with key"
+              + " [com.google.inject.Provider<java.lang.String>] on method ["
+              + ProviderBasedColoredCarFactory.class.getName()
+              + ".createCar()]");
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [1] with key"
-            + " [com.google.inject.Provider<" + Color.class.getName() + ">"
-            + " annotated with @com.google.inject.assistedinject.Assisted(value=color)]"
-            + " on method [" + ProviderBasedColoredCarFactory.class.getName() + ".createMustang()]"
-      );
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [1] with key"
+              + " [com.google.inject.Provider<"
+              + Color.class.getName()
+              + ">"
+              + " annotated with @com.google.inject.assistedinject.Assisted(value="
+              + Annotations.memberValueString("color")
+              + ")]"
+              + " on method ["
+              + ProviderBasedColoredCarFactory.class.getName()
+              + ".createMustang()]");
+      assertContains(
+          expected.getMessage(),
           ") No implementation for com.google.inject.assistedinject."
-            + "FactoryProvider2Test$ProviderBasedColoredCarFactory was bound.");
+              + "FactoryProvider2Test$ProviderBasedColoredCarFactory was bound.");
     }
   }
 
   interface JavaxProviderBasedColoredCarFactory {
-    Car createCar(javax.inject.Provider<Color> colorProvider, javax.inject.Provider<String> stringProvider);
+    Car createCar(
+        javax.inject.Provider<Color> colorProvider, javax.inject.Provider<String> stringProvider);
+
     Mustang createMustang(@Assisted("color") javax.inject.Provider<Color> colorProvider);
   }
 
   public void testAssistedJavaxProviderIsDisallowed() {
     try {
-      Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(JavaxProviderBasedColoredCarFactory.class).toProvider(
-                FactoryProvider.newFactory(JavaxProviderBasedColoredCarFactory.class, Subaru.class));
-          }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(JavaxProviderBasedColoredCarFactory.class)
+                  .toProvider(
+                      FactoryProvider.newFactory(
+                          JavaxProviderBasedColoredCarFactory.class, Subaru.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
       assertEquals(expected.getMessage(), 4, expected.getErrorMessages().size());
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [1] with key"
-            + " [com.google.inject.Provider<" + Color.class.getName() + ">] on method ["
-            + JavaxProviderBasedColoredCarFactory.class.getName() + ".createCar()]");
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [1] with key"
+              + " [com.google.inject.Provider<"
+              + Color.class.getName()
+              + ">] on method ["
+              + JavaxProviderBasedColoredCarFactory.class.getName()
+              + ".createCar()]");
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [2] with key"
-            + " [com.google.inject.Provider<java.lang.String>] on method ["
-            + JavaxProviderBasedColoredCarFactory.class.getName() + ".createCar()]");
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [2] with key"
+              + " [com.google.inject.Provider<java.lang.String>] on method ["
+              + JavaxProviderBasedColoredCarFactory.class.getName()
+              + ".createCar()]");
+      assertContains(
+          expected.getMessage(),
           ") A Provider may not be a type in a factory method of an AssistedInject."
-            + "\n  Offending instance is parameter [1] with key"
-            + " [com.google.inject.Provider<" + Color.class.getName() + ">"
-            + " annotated with @com.google.inject.assistedinject.Assisted(value=color)]"
-            + " on method [" + JavaxProviderBasedColoredCarFactory.class.getName() + ".createMustang()]"
-      );
-      assertContains(expected.getMessage(),
+              + "\n  Offending instance is parameter [1] with key"
+              + " [com.google.inject.Provider<"
+              + Color.class.getName()
+              + ">"
+              + " annotated with @com.google.inject.assistedinject.Assisted(value="
+              + Annotations.memberValueString("color")
+              + ")]"
+              + " on method ["
+              + JavaxProviderBasedColoredCarFactory.class.getName()
+              + ".createMustang()]");
+      assertContains(
+          expected.getMessage(),
           ") No implementation for com.google.inject.assistedinject."
-            + "FactoryProvider2Test$JavaxProviderBasedColoredCarFactory was bound.");
+              + "FactoryProvider2Test$JavaxProviderBasedColoredCarFactory was bound.");
     }
   }
 
   public void testFactoryUseBeforeInitialization() {
-    ColoredCarFactory carFactory = FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class)
-        .get();
+    ColoredCarFactory carFactory =
+        FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class).get();
     try {
       carFactory.create(Color.RED);
       fail();
     } catch (IllegalStateException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "Factories.create() factories cannot be used until they're initialized by Guice.");
     }
   }
@@ -660,20 +762,22 @@
   }
 
   public void testFactoryBuildingConcreteTypes() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(double.class).toInstance(5.0d);
-        // note there is no 'thatMakes()' call here:
-        bind(MustangFactory.class).toProvider(
-            FactoryProvider.newFactory(MustangFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(double.class).toInstance(5.0d);
+                // note there is no 'thatMakes()' call here:
+                bind(MustangFactory.class)
+                    .toProvider(FactoryProvider.newFactory(MustangFactory.class, Mustang.class));
+              }
+            });
     MustangFactory factory = injector.getInstance(MustangFactory.class);
 
     Mustang mustang = factory.create(Color.RED);
     assertSame(Color.RED, mustang.color);
-    assertEquals(5.0d, mustang.engineSize);
+    assertEquals(5.0d, mustang.engineSize, 0.0);
   }
 
   static class Fleet {
@@ -686,22 +790,24 @@
   }
 
   public void testInjectDeepIntoConstructedObjects() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(double.class).toInstance(5.0d);
-        bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
-        bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
-        bind(FleetFactory.class).toProvider(FactoryProvider.newFactory(FleetFactory.class,
-            Fleet.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(double.class).toInstance(5.0d);
+                bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+                bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+                bind(FleetFactory.class)
+                    .toProvider(FactoryProvider.newFactory(FleetFactory.class, Fleet.class));
+              }
+            });
 
     FleetFactory fleetFactory = injector.getInstance(FleetFactory.class);
     Fleet fleet = fleetFactory.createFleet(Color.RED);
 
     assertSame(Color.RED, fleet.mustang.color);
-    assertEquals(5.0d, fleet.mustang.engineSize);
+    assertEquals(5.0d, fleet.mustang.engineSize, 0.0);
     assertSame(Color.RED, fleet.camaro.color);
     assertEquals(250, fleet.camaro.horsePower);
     assertEquals(1984, fleet.camaro.modelYear);
@@ -712,18 +818,25 @@
   }
 
   static class Maxima implements Car {
-    @Inject @Assisted("paint") Color paint;
-    @Inject @Assisted("fabric") Color fabric;
+    @Inject
+    @Assisted("paint")
+    Color paint;
+
+    @Inject
+    @Assisted("fabric")
+    Color fabric;
   }
 
   public void testDistinctKeys() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(TwoToneCarFactory.class).toProvider(
-            FactoryProvider.newFactory(TwoToneCarFactory.class, Maxima.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(TwoToneCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(TwoToneCarFactory.class, Maxima.class));
+              }
+            });
 
     TwoToneCarFactory factory = injector.getInstance(TwoToneCarFactory.class);
     Maxima maxima = (Maxima) factory.create(Color.BLACK, Color.GRAY);
@@ -737,40 +850,52 @@
 
   public void testDuplicateKeys() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(DoubleToneCarFactory.class).toProvider(
-              FactoryProvider.newFactory(DoubleToneCarFactory.class, Maxima.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(DoubleToneCarFactory.class)
+                  .toProvider(FactoryProvider.newFactory(DoubleToneCarFactory.class, Maxima.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "A binding to " + Color.class.getName() + " annotated with @"
-          + Assisted.class.getName() + "(value=paint) was already configured at");
+      assertContains(
+          expected.getMessage(),
+          "A binding to "
+              + Color.class.getName()
+              + " annotated with @"
+              + Assisted.class.getName()
+              + "(value="
+              + Annotations.memberValueString("paint")
+              + ") was already configured at");
     }
   }
 
   /*if[AOP]*/
   public void testMethodInterceptorsOnAssistedTypes() {
     final AtomicInteger invocationCount = new AtomicInteger();
-    final org.aopalliance.intercept.MethodInterceptor interceptor
-        = new org.aopalliance.intercept.MethodInterceptor() {
-      public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation)
-          throws Throwable {
-        invocationCount.incrementAndGet();
-        return methodInvocation.proceed();
-      }
-    };
+    final org.aopalliance.intercept.MethodInterceptor interceptor =
+        new org.aopalliance.intercept.MethodInterceptor() {
+          @Override
+          public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation)
+              throws Throwable {
+            invocationCount.incrementAndGet();
+            return methodInvocation.proceed();
+          }
+        };
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
 
     ColoredCarFactory factory = injector.getInstance(ColoredCarFactory.class);
     Mustang mustang = (Mustang) factory.create(Color.GREEN);
@@ -785,27 +910,31 @@
    * like, I have a test case to make sure the error message is pretty.
    */
   public void testFactoryReuseErrorMessageIsPretty() {
-    final Provider<ColoredCarFactory> factoryProvider
-        = FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class);
+    final Provider<ColoredCarFactory> factoryProvider =
+        FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class);
 
-    Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class).toProvider(factoryProvider);
-      }
-    });
+    Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Double.class).toInstance(5.0d);
+            bind(ColoredCarFactory.class).toProvider(factoryProvider);
+          }
+        });
 
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(Double.class).toInstance(5.0d);
-          bind(ColoredCarFactory.class).toProvider(factoryProvider);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Double.class).toInstance(5.0d);
+              bind(ColoredCarFactory.class).toProvider(factoryProvider);
+            }
+          });
       fail();
-    } catch(CreationException expected) {
-      assertContains(expected.getMessage(),
-          "Factories.create() factories may only be used in one Injector!");
+    } catch (CreationException expected) {
+      assertContains(
+          expected.getMessage(), "Factories.create() factories may only be used in one Injector!");
     }
   }
 
@@ -813,8 +942,9 @@
     try {
       FactoryProvider.newFactory(NamedParameterFactory.class, Mustang.class);
       fail();
-    } catch(ConfigurationException expected) {
-      assertContains(expected.getMessage(),
+    } catch (ConfigurationException expected) {
+      assertContains(
+          expected.getMessage(),
           "Only @Assisted is allowed for factory parameters, but found @" + Named.class.getName());
     }
   }
@@ -823,10 +953,9 @@
     Car create(@Named("seats") int seats, double engineSize);
   }
 
-
   public void testDefaultAssistedAnnotation() throws NoSuchFieldException {
-    Assisted plainAssisted
-        = Subaru.class.getDeclaredField("colorProvider").getAnnotation(Assisted.class);
+    Assisted plainAssisted =
+        Subaru.class.getDeclaredField("colorProvider").getAnnotation(Assisted.class);
     assertEqualsBothWays(FactoryProvider2.DEFAULT_ANNOTATION, plainAssisted);
     assertEquals(FactoryProvider2.DEFAULT_ANNOTATION.toString(), plainAssisted.toString());
   }
@@ -836,32 +965,38 @@
   }
 
   public void testGenericAssistedFactory() {
-    final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
-        = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
-    final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
-        = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
+    final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral =
+        new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
+    final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral =
+        new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
-        bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
-        bind(mustangTypeLiteral)
-            .toProvider(FactoryProvider.newFactory(mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
-        bind(camaroTypeLiteral)
-            .toProvider(FactoryProvider.newFactory(camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+                bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+                bind(mustangTypeLiteral)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
+                bind(camaroTypeLiteral)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
+              }
+            });
 
-    GenericColoredCarFactory<Mustang> mustangFactory
-        = injector.getInstance(Key.get(mustangTypeLiteral));
-    GenericColoredCarFactory<Camaro> camaroFactory
-        = injector.getInstance(Key.get(camaroTypeLiteral));
+    GenericColoredCarFactory<Mustang> mustangFactory =
+        injector.getInstance(Key.get(mustangTypeLiteral));
+    GenericColoredCarFactory<Camaro> camaroFactory =
+        injector.getInstance(Key.get(camaroTypeLiteral));
 
     Mustang blueMustang = mustangFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Camaro redCamaro = camaroFactory.create(Color.RED);
     assertEquals(Color.RED, redCamaro.color);
@@ -870,17 +1005,18 @@
   }
 
   @SuppressWarnings("unused")
-  public interface Insurance<T extends Car> {
-  }
+  public interface Insurance<T extends Car> {}
 
   public static class MustangInsurance implements Insurance<Mustang> {
     private final double premium;
     private final double limit;
-    @SuppressWarnings("unused") private Mustang car;
+
+    @SuppressWarnings("unused")
+    private Mustang car;
 
     @Inject
-    public MustangInsurance(@Named("lowLimit") double limit, @Assisted Mustang car,
-        @Assisted double premium) {
+    public MustangInsurance(
+        @Named("lowLimit") double limit, @Assisted Mustang car, @Assisted double premium) {
       this.premium = premium;
       this.limit = limit;
       this.car = car;
@@ -892,11 +1028,13 @@
   public static class CamaroInsurance implements Insurance<Camaro> {
     private final double premium;
     private final double limit;
-    @SuppressWarnings("unused") private Camaro car;
+
+    @SuppressWarnings("unused")
+    private Camaro car;
 
     @Inject
-    public CamaroInsurance(@Named("highLimit") double limit, @Assisted Camaro car,
-        @Assisted double premium) {
+    public CamaroInsurance(
+        @Named("highLimit") double limit, @Assisted Camaro car, @Assisted double premium) {
       this.premium = premium;
       this.limit = limit;
       this.car = car;
@@ -915,17 +1053,23 @@
 
   public void testAssistedFactoryForConcreteType() {
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
-        bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
-        bind(MustangInsuranceFactory.class).toProvider(
-            FactoryProvider.newFactory(MustangInsuranceFactory.class, MustangInsurance.class));
-        bind(CamaroInsuranceFactory.class).toProvider(
-            FactoryProvider.newFactory(CamaroInsuranceFactory.class, CamaroInsurance.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+                bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+                bind(MustangInsuranceFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            MustangInsuranceFactory.class, MustangInsurance.class));
+                bind(CamaroInsuranceFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            CamaroInsuranceFactory.class, CamaroInsurance.class));
+              }
+            });
 
     MustangInsuranceFactory mustangInsuranceFactory =
         injector.getInstance(MustangInsuranceFactory.class);
@@ -935,13 +1079,13 @@
     Mustang mustang = new Mustang(5000d, Color.BLACK);
     MustangInsurance mustangPolicy =
         (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
-    assertEquals(800.0d, mustangPolicy.premium);
-    assertEquals(50000.0d, mustangPolicy.limit);
+    assertEquals(800.0d, mustangPolicy.premium, 0.0);
+    assertEquals(50000.0d, mustangPolicy.limit, 0.0);
 
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(100000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(100000.0d, camaroPolicy.limit, 0.0);
   }
 
   public interface InsuranceFactory<T extends Car> {
@@ -954,17 +1098,23 @@
     final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
         new TypeLiteral<InsuranceFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
-        bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
-        bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
-        bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+                bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+                bind(mustangInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
+                bind(camaroInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
+              }
+            });
 
     InsuranceFactory<Mustang> mustangInsuranceFactory =
         injector.getInstance(Key.get(mustangInsuranceFactoryType));
@@ -974,13 +1124,13 @@
     Mustang mustang = new Mustang(5000d, Color.BLACK);
     MustangInsurance mustangPolicy =
         (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
-    assertEquals(800.0d, mustangPolicy.premium);
-    assertEquals(50000.0d, mustangPolicy.limit);
+    assertEquals(800.0d, mustangPolicy.premium, 0.0);
+    assertEquals(50000.0d, mustangPolicy.limit, 0.0);
 
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(100000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(100000.0d, camaroPolicy.limit, 0.0);
   }
 
   public static class AutoInsurance<T extends Car> implements Insurance<T> {
@@ -1002,14 +1152,19 @@
     final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
         new TypeLiteral<InsuranceFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(50000.0d);
-        bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            camaroInsuranceFactoryType, new TypeLiteral<AutoInsurance<Camaro>>() {}));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(50000.0d);
+                bind(camaroInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroInsuranceFactoryType,
+                            new TypeLiteral<AutoInsurance<Camaro>>() {}));
+              }
+            });
 
     InsuranceFactory<Camaro> camaroInsuranceFactory =
         injector.getInstance(Key.get(camaroInsuranceFactoryType));
@@ -1017,55 +1172,63 @@
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     AutoInsurance<?> camaroPolicy =
         (AutoInsurance<?>) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(50000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(50000.0d, camaroPolicy.limit, 0.0);
     assertEquals(camaro, camaroPolicy.car);
   }
 
   public void testInjectingAndUsingInjector() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Segway.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Segway.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
-    Segway green = (Segway)carFactory.create(Color.GREEN);
+    Segway green = (Segway) carFactory.create(Color.GREEN);
     assertSame(Color.GREEN, green.getColor());
     assertSame(Color.GREEN, green.getColor());
-    
-    Segway pink = (Segway)carFactory.create(Color.PINK);
+
+    Segway pink = (Segway) carFactory.create(Color.PINK);
     assertSame(Color.PINK, pink.getColor());
     assertSame(Color.PINK, pink.getColor());
     assertSame(Color.GREEN, green.getColor());
   }
-  
+
   public void testDuplicateAssistedFactoryBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Mustang redMustang = (Mustang) carFactory.create(Color.RED);
     assertEquals(Color.RED, redMustang.color);
-    assertEquals(5.0d, redMustang.engineSize);
+    assertEquals(5.0d, redMustang.engineSize, 0.0);
   }
 
   public interface Equals {
 
-    enum ComparisonMethod { SHALLOW, DEEP; }
+    enum ComparisonMethod {
+      SHALLOW,
+      DEEP;
+    }
 
     interface Factory {
       Equals equals(Equals.ComparisonMethod comparisonMethod);
@@ -1084,33 +1247,40 @@
   }
 
   public void testFactoryMethodCalledEquals() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(0.01d);
-        bind(Equals.Factory.class).toProvider(
-            FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(0.01d);
+                bind(Equals.Factory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class));
+              }
+            });
     Equals.Factory equalsFactory = injector.getInstance(Equals.Factory.class);
     Equals.Impl shallowEquals = (Impl) equalsFactory.equals(ComparisonMethod.SHALLOW);
     assertEquals(ComparisonMethod.SHALLOW, shallowEquals.comparisonMethod);
-    assertEquals(0.01d, shallowEquals.sigma);
+    assertEquals(0.01d, shallowEquals.sigma, 0.0);
   }
 
   static class Segway implements Car {
     @Inject Injector injector;
 
-    Color getColor() { return injector.getInstance(Key.get(Color.class, FactoryProvider2.DEFAULT_ANNOTATION)); }
+    Color getColor() {
+      return injector.getInstance(Key.get(Color.class, FactoryProvider2.DEFAULT_ANNOTATION));
+    }
   }
 
   public void testReturnValueMatchesParamValue() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      public void configure() {
-        install(new FactoryModuleBuilder().build(Delegater.Factory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              public void configure() {
+                install(new FactoryModuleBuilder().build(Delegater.Factory.class));
+              }
+            });
     Delegater delegate = new Delegater();
     Delegater user = injector.getInstance(Delegater.Factory.class).create(delegate);
     assertSame(delegate, user.delegate);
@@ -1123,7 +1293,8 @@
 
     private final Delegater delegate;
 
-    @Inject Delegater(@Assisted Delegater delegater) {
+    @Inject
+    Delegater(@Assisted Delegater delegater) {
       this.delegate = delegater;
     }
 
@@ -1132,14 +1303,15 @@
     }
   }
 
-  public static abstract class AbstractAssisted {
+  public abstract static class AbstractAssisted {
     interface Factory<O extends AbstractAssisted, I extends CharSequence> {
       O create(I string);
     }
   }
 
   static class ConcreteAssisted extends AbstractAssisted {
-    @Inject ConcreteAssisted(@SuppressWarnings("unused") @Assisted String string) {}
+    @Inject
+    ConcreteAssisted(@SuppressWarnings("unused") @Assisted String string) {}
   }
 
   static class ConcreteAssistedWithOverride extends AbstractAssisted {
@@ -1150,26 +1322,36 @@
     ConcreteAssistedWithOverride(@SuppressWarnings("unused") @Assisted StringBuilder sb) {}
 
     interface Factory extends AbstractAssisted.Factory<ConcreteAssistedWithOverride, String> {
-      @Override ConcreteAssistedWithOverride create(String string);
+      @Override
+      ConcreteAssistedWithOverride create(String string);
     }
 
     interface Factory2 extends AbstractAssisted.Factory<ConcreteAssistedWithOverride, String> {
-      @Override ConcreteAssistedWithOverride create(String string);
+      @Override
+      ConcreteAssistedWithOverride create(String string);
+
       ConcreteAssistedWithOverride create(StringBuilder sb);
     }
   }
 
   static class ConcreteAssistedWithoutOverride extends AbstractAssisted {
-    @Inject ConcreteAssistedWithoutOverride(@SuppressWarnings("unused") @Assisted String string) {}
+    @Inject
+    ConcreteAssistedWithoutOverride(@SuppressWarnings("unused") @Assisted String string) {}
+
     interface Factory extends AbstractAssisted.Factory<ConcreteAssistedWithoutOverride, String> {}
   }
 
   public static class Public extends AbstractAssisted {
-    @AssistedInject Public(@SuppressWarnings("unused") @Assisted String string) {}
-    @AssistedInject Public(@SuppressWarnings("unused") @Assisted StringBuilder sb) {}
+    @AssistedInject
+    Public(@SuppressWarnings("unused") @Assisted String string) {}
+
+    @AssistedInject
+    Public(@SuppressWarnings("unused") @Assisted StringBuilder sb) {}
 
     public interface Factory extends AbstractAssisted.Factory<Public, String> {
-      @Override Public create(String string);
+      @Override
+      Public create(String string);
+
       Public create(StringBuilder sb);
     }
   }
@@ -1178,15 +1360,22 @@
   public void testGeneratedDefaultMethodsForwardCorrectly() {
     final Key<AbstractAssisted.Factory<ConcreteAssisted, String>> concreteKey =
         new Key<AbstractAssisted.Factory<ConcreteAssisted, String>>() {};
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new FactoryModuleBuilder().build(ConcreteAssistedWithOverride.Factory.class));
-        install(new FactoryModuleBuilder().build(ConcreteAssistedWithOverride.Factory2.class));
-        install(new FactoryModuleBuilder().build(ConcreteAssistedWithoutOverride.Factory.class));
-        install(new FactoryModuleBuilder().build(Public.Factory.class));
-        install(new FactoryModuleBuilder().build(concreteKey));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder().build(ConcreteAssistedWithOverride.Factory.class));
+                install(
+                    new FactoryModuleBuilder().build(ConcreteAssistedWithOverride.Factory2.class));
+                install(
+                    new FactoryModuleBuilder()
+                        .build(ConcreteAssistedWithoutOverride.Factory.class));
+                install(new FactoryModuleBuilder().build(Public.Factory.class));
+                install(new FactoryModuleBuilder().build(concreteKey));
+              }
+            });
 
     ConcreteAssistedWithOverride.Factory factory1 =
         injector.getInstance(ConcreteAssistedWithOverride.Factory.class);
@@ -1213,8 +1402,7 @@
     AbstractAssisted.Factory<Public, String> factory4Abstract = factory4;
     factory4Abstract.create("foo");
 
-    AbstractAssisted.Factory<ConcreteAssisted, String> factory5 =
-        injector.getInstance(concreteKey);
+    AbstractAssisted.Factory<ConcreteAssisted, String> factory5 = injector.getInstance(concreteKey);
     factory5.create("foo");
   }
 }
diff --git a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
index c8f4b12..9177d3f 100644
--- a/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
+++ b/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,12 +35,10 @@
 import com.google.inject.name.Names;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
-
-import junit.framework.TestCase;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * @author jmourits@google.com (Jerome Mourits)
@@ -48,55 +46,70 @@
  */
 @SuppressWarnings("deprecation")
 public class FactoryProviderTest extends TestCase {
-  
-  private enum Color { BLUE, GREEN, RED, GRAY, BLACK, ORANGE, PINK }
+
+  private enum Color {
+    BLUE,
+    GREEN,
+    RED,
+    GRAY,
+    BLACK,
+    ORANGE,
+    PINK
+  }
 
   public void testAssistedFactory() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Mustang redMustang = (Mustang) carFactory.create(Color.RED);
     assertEquals(Color.RED, redMustang.color);
-    assertEquals(5.0d, redMustang.engineSize);
+    assertEquals(5.0d, redMustang.engineSize, 0.0);
   }
 
   public void testFactoryBindingDependencies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
 
     Binding<?> binding = injector.getBinding(ColoredCarFactory.class);
     HasDependencies hasDependencies = (HasDependencies) binding;
-    assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(double.class))),
+    assertEquals(
+        ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(double.class))),
         hasDependencies.getDependencies());
   }
 
   public void testAssistedFactoryWithAnnotations() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
-        bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+                bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
+              }
+            });
 
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
@@ -111,8 +124,7 @@
     assertEquals(250, redCamaro.horsePower);
   }
 
-  interface Car {
-  }
+  interface Car {}
 
   interface ColoredCarFactory {
     Car create(Color color);
@@ -136,8 +148,8 @@
 
     @AssistedInject
     public Camaro(
-        @Named("horsePower")int horsePower,
-        @Named("modelYear")int modelYear,
+        @Named("horsePower") int horsePower,
+        @Named("modelYear") int modelYear,
         @Assisted Color color) {
       this.horsePower = horsePower;
       this.modelYear = modelYear;
@@ -147,29 +159,32 @@
 
   interface SummerCarFactory {
     Car create(Color color, boolean convertable);
+
     Car createConvertible(Color color);
   }
 
   public void testFactoryWithMultipleMethods() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(float.class).toInstance(140f);
-        bind(SummerCarFactory.class).toProvider(
-            FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(float.class).toInstance(140f);
+                bind(SummerCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
+              }
+            });
 
     SummerCarFactory carFactory = injector.getInstance(SummerCarFactory.class);
 
     Corvette blueCorvette = (Corvette) carFactory.createConvertible(Color.BLUE);
     assertEquals(Color.BLUE, blueCorvette.color);
-    assertEquals(100f, blueCorvette.maxMph);
+    assertEquals(100f, blueCorvette.maxMph, 0.0f);
     assertTrue(blueCorvette.isConvertable);
 
     Corvette redCorvette = (Corvette) carFactory.create(Color.RED, false);
     assertEquals(Color.RED, redCorvette.color);
-    assertEquals(140f, redCorvette.maxMph);
+    assertEquals(140f, redCorvette.maxMph, 0.0f);
     assertFalse(redCorvette.isConvertable);
   }
 
@@ -200,7 +215,7 @@
     try {
       FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class);
       fail();
-    } catch(ConfigurationException e) {
+    } catch (ConfigurationException e) {
       assertContains(e.getMessage(), "Constructor mismatch");
     }
   }
@@ -211,11 +226,13 @@
     public Beetle(@Assisted Color color) {
       throw new IllegalStateException("Conflicting constructors");
     }
+
     @AssistedInject
     @SuppressWarnings("unused")
     public Beetle(@Assisted Color color, @Assisted boolean isConvertable) {
       throw new IllegalStateException("Conflicting constructors");
     }
+
     @AssistedInject
     @SuppressWarnings("unused")
     public Beetle(@Assisted Color color, @Assisted boolean isConvertable, float maxMph) {
@@ -224,21 +241,23 @@
   }
 
   public void testMethodsAndFieldsGetInjected() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("turbo");
-        bind(int.class).toInstance(911);
-        bind(double.class).toInstance(50000d);
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porshe.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("turbo");
+                bind(int.class).toInstance(911);
+                bind(double.class).toInstance(50000d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porshe.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Porshe grayPorshe = (Porshe) carFactory.create(Color.GRAY);
     assertEquals(Color.GRAY, grayPorshe.color);
-    assertEquals(50000d, grayPorshe.price);
+    assertEquals(50000d, grayPorshe.price, 0.0);
     assertEquals(911, grayPorshe.model);
     assertEquals("turbo", grayPorshe.name);
   }
@@ -255,20 +274,24 @@
       this.price = price;
     }
 
-    @Inject void setModel(int model) {
+    @Inject
+    void setModel(int model) {
       this.model = model;
     }
   }
 
   public void testProviderInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("trans am");
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("trans am");
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Firebird blackFirebird = (Firebird) carFactory.create(Color.BLACK);
@@ -288,21 +311,25 @@
   }
 
   public void testTypeTokenInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Flux Capacitor"));
-        bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(new TypeLiteral<Set<String>>() {})
+                    .toInstance(Collections.singleton("Flux Capacitor"));
+                bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     DeLorean deLorean = (DeLorean) carFactory.create(Color.GRAY);
     assertEquals(Color.GRAY, deLorean.color);
     assertEquals("Flux Capacitor", deLorean.features.iterator().next());
-    assertEquals(new Integer(88), deLorean.featureActivationSpeeds.iterator().next());
+    assertEquals(Integer.valueOf(88), deLorean.featureActivationSpeeds.iterator().next());
   }
 
   public static class DeLorean implements Car {
@@ -320,14 +347,16 @@
   }
 
   public void testTypeTokenProviderInjection() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(new TypeLiteral<Set<String>>() { }).toInstance(Collections.singleton("Datsun"));
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Datsun"));
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Z orangeZ = (Z) carFactory.create(Color.ORANGE);
@@ -345,25 +374,27 @@
       this.color = color;
     }
   }
-  
+
   public static class Prius implements Car {
     @SuppressWarnings("unused")
     private final Color color;
-    
+
     @AssistedInject
     private Prius(@Assisted Color color) {
       this.color = color;
     }
   }
-  
+
   public void testAssistInjectionInNonPublicConstructor() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
+              }
+            });
     injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
   }
 
@@ -375,13 +406,16 @@
   }
 
   public void testExceptionDuringConstruction() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
+              }
+            });
     try {
       injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
       fail();
@@ -389,17 +423,18 @@
       assertEquals("kaboom!", e.getMessage());
     }
   }
-  
+
   public static class DefectiveCar implements Car {
     @AssistedInject
     public DefectiveCar() throws ExplosionException {
       throw new ExplosionException();
     }
   }
-  
-  public static class ExplosionException extends Exception { }
-  public static class FireException extends Exception { }
-  
+
+  public static class ExplosionException extends Exception {}
+
+  public static class FireException extends Exception {}
+
   public interface DefectiveCarFactoryWithNoExceptions {
     Car createCar();
   }
@@ -420,16 +455,19 @@
   public interface CorrectDefectiveCarFactory {
     Car createCar() throws FireException, ExplosionException;
   }
-  
+
   public void testConstructorExceptionsAreThrownByFactory() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(CorrectDefectiveCarFactory.class).toProvider(
-            FactoryProvider.newFactory(
-                CorrectDefectiveCarFactory.class, DefectiveCar.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(CorrectDefectiveCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            CorrectDefectiveCarFactory.class, DefectiveCar.class));
+              }
+            });
     try {
       injector.getInstance(CorrectDefectiveCarFactory.class).createCar();
       fail();
@@ -454,21 +492,25 @@
 
   public interface MultipleConstructorDefectiveCarFactory {
     Car createCar() throws ExplosionException;
+
     Car createCar(Color r) throws FireException;
   }
 
   public void testMultipleConstructorExceptionMatching() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(MultipleConstructorDefectiveCarFactory.class).toProvider(
-            FactoryProvider.newFactory(
-                MultipleConstructorDefectiveCarFactory.class,
-                MultipleConstructorDefectiveCar.class));
-      }
-    });
-    MultipleConstructorDefectiveCarFactory factory
-        = injector.getInstance(MultipleConstructorDefectiveCarFactory.class);
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(MultipleConstructorDefectiveCarFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            MultipleConstructorDefectiveCarFactory.class,
+                            MultipleConstructorDefectiveCar.class));
+              }
+            });
+    MultipleConstructorDefectiveCarFactory factory =
+        injector.getInstance(MultipleConstructorDefectiveCarFactory.class);
     try {
       factory.createCar();
       fail();
@@ -481,89 +523,99 @@
     } catch (FireException expected) {
     }
   }
-  
+
   public static class WildcardCollection {
-    
+
     public interface Factory {
       WildcardCollection create(Collection<?> items);
     }
 
     @AssistedInject
-    public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) { }
+    public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) {}
   }
-  
+
   public void testWildcardGenerics() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(WildcardCollection.Factory.class).toProvider(
-            FactoryProvider.newFactory(
-                WildcardCollection.Factory.class,
-                WildcardCollection.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(WildcardCollection.Factory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            WildcardCollection.Factory.class, WildcardCollection.class));
+              }
+            });
     WildcardCollection.Factory factory = injector.getInstance(WildcardCollection.Factory.class);
     factory.create(Collections.emptyList());
   }
-  
+
   public static class SteeringWheel {}
-  
+
   public static class Fiat implements Car {
     @SuppressWarnings("unused")
     private final SteeringWheel steeringWheel;
+
     @SuppressWarnings("unused")
     private final Color color;
-    
+
     @AssistedInject
     public Fiat(SteeringWheel steeringWheel, @Assisted Color color) {
       this.steeringWheel = steeringWheel;
       this.color = color;
     }
   }
-  
+
   public void testFactoryWithImplicitBindings() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(ColoredCarFactory.class).toProvider(
-            FactoryProvider.newFactory(
-                ColoredCarFactory.class, 
-                Fiat.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Fiat.class));
+              }
+            });
 
     ColoredCarFactory coloredCarFactory = injector.getInstance(ColoredCarFactory.class);
     Fiat fiat = (Fiat) coloredCarFactory.create(Color.GREEN);
     assertEquals(Color.GREEN, fiat.color);
     assertNotNull(fiat.steeringWheel);
   }
-  
+
   public void testFactoryFailsWithMissingBinding() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(ColoredCarFactory.class)
-              .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(ColoredCarFactory.class)
+                  .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
+      assertContains(
+          expected.getMessage(),
           "1) Parameter of type 'double' is not injectable or annotated with @Assisted");
     }
   }
-  
+
+  @SuppressWarnings("SelfEquals")
   public void testMethodsDeclaredInObject() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(Double.class).toInstance(5.0d);
-          bind(ColoredCarFactory.class)
-              .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        }
-      });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
+
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
-    
+
     carFactory.equals(carFactory);
     carFactory.hashCode();
     carFactory.toString();
@@ -571,18 +623,24 @@
 
   public void testAssistedInjectConstructorAndAssistedFactoryParameterMustNotMix() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(Double.class).toInstance(5.0d);
-          bind(AssistedParamsFactory.class)
-              .toProvider(FactoryProvider.newFactory(AssistedParamsFactory.class, Mustang.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Double.class).toInstance(5.0d);
+              bind(AssistedParamsFactory.class)
+                  .toProvider(
+                      FactoryProvider.newFactory(AssistedParamsFactory.class, Mustang.class));
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "Factory method "
-          + AssistedParamsFactory.class.getName() + ".create() has an @Assisted parameter, which "
-          + "is incompatible with the deprecated @AssistedInject annotation.");
+      assertContains(
+          expected.getMessage(),
+          "Factory method "
+              + AssistedParamsFactory.class.getName()
+              + ".create() has an @Assisted parameter, which "
+              + "is incompatible with the deprecated @AssistedInject annotation.");
     }
   }
 
@@ -595,32 +653,38 @@
   }
 
   public void testGenericAssistedFactory() {
-    final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
-        = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
-    final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
-        = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
+    final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral =
+        new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
+    final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral =
+        new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
-        bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
-        bind(mustangTypeLiteral).toProvider(
-            FactoryProvider.newFactory(mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
-        bind(camaroTypeLiteral).toProvider(
-            FactoryProvider.newFactory(camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+                bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+                bind(mustangTypeLiteral)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
+                bind(camaroTypeLiteral)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
+              }
+            });
 
-    GenericColoredCarFactory<Mustang> mustangFactory
-        = injector.getInstance(Key.get(mustangTypeLiteral));
-    GenericColoredCarFactory<Camaro> camaroFactory
-        = injector.getInstance(Key.get(camaroTypeLiteral));
+    GenericColoredCarFactory<Mustang> mustangFactory =
+        injector.getInstance(Key.get(mustangTypeLiteral));
+    GenericColoredCarFactory<Camaro> camaroFactory =
+        injector.getInstance(Key.get(camaroTypeLiteral));
 
     Mustang blueMustang = mustangFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Camaro redCamaro = camaroFactory.create(Color.RED);
     assertEquals(Color.RED, redCamaro.color);
@@ -629,17 +693,18 @@
   }
 
   @SuppressWarnings("unused")
-  public interface Insurance<T extends Car> {
-  }
+  public interface Insurance<T extends Car> {}
 
   public static class MustangInsurance implements Insurance<Mustang> {
     private final double premium;
     private final double limit;
-    @SuppressWarnings("unused") private Mustang car;
+
+    @SuppressWarnings("unused")
+    private Mustang car;
 
     @AssistedInject
-    public MustangInsurance(@Named("lowLimit") double limit, @Assisted Mustang car,
-        @Assisted double premium) {
+    public MustangInsurance(
+        @Named("lowLimit") double limit, @Assisted Mustang car, @Assisted double premium) {
       this.premium = premium;
       this.limit = limit;
       this.car = car;
@@ -651,11 +716,13 @@
   public static class CamaroInsurance implements Insurance<Camaro> {
     private final double premium;
     private final double limit;
-    @SuppressWarnings("unused") private Camaro car;
+
+    @SuppressWarnings("unused")
+    private Camaro car;
 
     @AssistedInject
-    public CamaroInsurance(@Named("highLimit") double limit, @Assisted Camaro car,
-        @Assisted double premium) {
+    public CamaroInsurance(
+        @Named("highLimit") double limit, @Assisted Camaro car, @Assisted double premium) {
       this.premium = premium;
       this.limit = limit;
       this.car = car;
@@ -674,17 +741,23 @@
 
   public void testAssistedFactoryForConcreteType() {
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
-        bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
-        bind(MustangInsuranceFactory.class).toProvider(
-            FactoryProvider.newFactory(MustangInsuranceFactory.class, MustangInsurance.class));
-        bind(CamaroInsuranceFactory.class).toProvider(
-            FactoryProvider.newFactory(CamaroInsuranceFactory.class, CamaroInsurance.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+                bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+                bind(MustangInsuranceFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            MustangInsuranceFactory.class, MustangInsurance.class));
+                bind(CamaroInsuranceFactory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            CamaroInsuranceFactory.class, CamaroInsurance.class));
+              }
+            });
 
     MustangInsuranceFactory mustangInsuranceFactory =
         injector.getInstance(MustangInsuranceFactory.class);
@@ -694,13 +767,13 @@
     Mustang mustang = new Mustang(5000d, Color.BLACK);
     MustangInsurance mustangPolicy =
         (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
-    assertEquals(800.0d, mustangPolicy.premium);
-    assertEquals(50000.0d, mustangPolicy.limit);
+    assertEquals(800.0d, mustangPolicy.premium, 0.0);
+    assertEquals(50000.0d, mustangPolicy.limit, 0.0);
 
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(100000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(100000.0d, camaroPolicy.limit, 0.0);
   }
 
   public interface InsuranceFactory<T extends Car> {
@@ -713,17 +786,23 @@
     final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
         new TypeLiteral<InsuranceFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
-        bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
-        bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
-        bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+                bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+                bind(mustangInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
+                bind(camaroInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
+              }
+            });
 
     InsuranceFactory<Mustang> mustangInsuranceFactory =
         injector.getInstance(Key.get(mustangInsuranceFactoryType));
@@ -733,13 +812,13 @@
     Mustang mustang = new Mustang(5000d, Color.BLACK);
     MustangInsurance mustangPolicy =
         (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
-    assertEquals(800.0d, mustangPolicy.premium);
-    assertEquals(50000.0d, mustangPolicy.limit);
+    assertEquals(800.0d, mustangPolicy.premium, 0.0);
+    assertEquals(50000.0d, mustangPolicy.limit, 0.0);
 
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(100000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(100000.0d, camaroPolicy.limit, 0.0);
   }
 
   public static class AutoInsurance<T extends Car> implements Insurance<T> {
@@ -761,14 +840,19 @@
     final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
         new TypeLiteral<InsuranceFactory<Camaro>>() {};
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(50000.0d);
-        bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
-            camaroInsuranceFactoryType, new TypeLiteral<AutoInsurance<Camaro>>() {}));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(50000.0d);
+                bind(camaroInsuranceFactoryType)
+                    .toProvider(
+                        FactoryProvider.newFactory(
+                            camaroInsuranceFactoryType,
+                            new TypeLiteral<AutoInsurance<Camaro>>() {}));
+              }
+            });
 
     InsuranceFactory<Camaro> camaroInsuranceFactory =
         injector.getInstance(Key.get(camaroInsuranceFactoryType));
@@ -776,36 +860,41 @@
     Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
     AutoInsurance<?> camaroPolicy =
         (AutoInsurance<?>) camaroInsuranceFactory.create(camaro, 800.0d);
-    assertEquals(800.0d, camaroPolicy.premium);
-    assertEquals(50000.0d, camaroPolicy.limit);
+    assertEquals(800.0d, camaroPolicy.premium, 0.0);
+    assertEquals(50000.0d, camaroPolicy.limit, 0.0);
     assertEquals(camaro, camaroPolicy.car);
   }
 
   public void testDuplicateAssistedFactoryBinding() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(5.0d);
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-        bind(ColoredCarFactory.class)
-            .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(5.0d);
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+                bind(ColoredCarFactory.class)
+                    .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
+              }
+            });
     ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
 
     Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
     assertEquals(Color.BLUE, blueMustang.color);
-    assertEquals(5.0d, blueMustang.engineSize);
+    assertEquals(5.0d, blueMustang.engineSize, 0.0);
 
     Mustang redMustang = (Mustang) carFactory.create(Color.RED);
     assertEquals(Color.RED, redMustang.color);
-    assertEquals(5.0d, redMustang.engineSize);
+    assertEquals(5.0d, redMustang.engineSize, 0.0);
   }
 
   public interface Equals {
 
-    enum ComparisonMethod { SHALLOW, DEEP; }
+    enum ComparisonMethod {
+      SHALLOW,
+      DEEP;
+    }
 
     interface Factory {
       Equals equals(Equals.ComparisonMethod comparisonMethod);
@@ -824,17 +913,20 @@
   }
 
   public void testFactoryMethodCalledEquals() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Double.class).toInstance(0.01d);
-        bind(Equals.Factory.class).toProvider(
-            FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(Double.class).toInstance(0.01d);
+                bind(Equals.Factory.class)
+                    .toProvider(
+                        FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class));
+              }
+            });
     Equals.Factory equalsFactory = injector.getInstance(Equals.Factory.class);
     Equals.Impl shallowEquals = (Impl) equalsFactory.equals(ComparisonMethod.SHALLOW);
     assertEquals(ComparisonMethod.SHALLOW, shallowEquals.comparisonMethod);
-    assertEquals(0.01d, shallowEquals.sigma);
+    assertEquals(0.01d, shallowEquals.sigma, 0.0);
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/assistedinject/test/com/google/inject/assistedinject/ManyConstructorsTest.java b/extensions/assistedinject/test/com/google/inject/assistedinject/ManyConstructorsTest.java
index f360f06..a6e2146 100644
--- a/extensions/assistedinject/test/com/google/inject/assistedinject/ManyConstructorsTest.java
+++ b/extensions/assistedinject/test/com/google/inject/assistedinject/ManyConstructorsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,21 +21,20 @@
 import com.google.inject.CreationException;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import junit.framework.TestCase;
 
-/**
- * @author sameb@google.com (Sam Berlin)
- */
+/** @author sameb@google.com (Sam Berlin) */
 public class ManyConstructorsTest extends TestCase {
-  
+
   public void testTwoConstructors() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(Factory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(Factory.class));
+              }
+            });
     Factory factory = injector.getInstance(Factory.class);
     Foo noIndex = factory.create("no index");
     assertEquals("no index", noIndex.name);
@@ -44,14 +43,16 @@
     assertEquals("index", index.name);
     assertEquals(1, index.index.intValue());
   }
-  
+
   public void testDifferentOrderParameters() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(OtherFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(OtherFactory.class));
+              }
+            });
     OtherFactory factory = injector.getInstance(OtherFactory.class);
     Foo noIndex = factory.create("no index");
     assertEquals("no index", noIndex.name);
@@ -63,16 +64,19 @@
     assertEquals("index", index2.name);
     assertEquals(2, index2.index.intValue());
   }
-  
+
   public void testInterfaceToImpl() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder()
-          .implement(Bar.class, Foo.class)
-          .build(BarFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(
+                    new FactoryModuleBuilder()
+                        .implement(Bar.class, Foo.class)
+                        .build(BarFactory.class));
+              }
+            });
     BarFactory factory = injector.getInstance(BarFactory.class);
     Bar noIndex = factory.create("no index");
     assertEquals("no index", noIndex.getName());
@@ -81,159 +85,190 @@
     assertEquals("index", index.getName());
     assertEquals(1, index.getIndex().intValue());
   }
-  
+
   public void testUsingOneConstructor() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(SimpleFactory.class));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(SimpleFactory.class));
+              }
+            });
     SimpleFactory factory = injector.getInstance(SimpleFactory.class);
     Foo noIndex = factory.create("no index");
     assertEquals("no index", noIndex.name);
     assertNull(noIndex.index);
-    
-    injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(SimpleFactory2.class));
-      }
-    });
+
+    injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(SimpleFactory2.class));
+              }
+            });
     SimpleFactory2 factory2 = injector.getInstance(SimpleFactory2.class);
     Foo index = factory2.create("index", 1);
     assertEquals("index", index.name);
     assertEquals(1, index.index.intValue());
   }
-  
+
   public void testTooManyMatchingConstructors() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder()
-            .implement(Foo.class, TooManyMatches.class)
-            .build(SimpleFactory2.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(
+                  new FactoryModuleBuilder()
+                      .implement(Foo.class, TooManyMatches.class)
+                      .build(SimpleFactory2.class));
+            }
+          });
       fail("should have failed");
     } catch (CreationException expected) {
-      Asserts.assertContains(expected.getMessage(), "1) " + TooManyMatches.class.getName()
-          + " has more than one constructor annotated with @AssistedInject that "
-          + "matches the parameters in method " + SimpleFactory2.class.getName());
+      Asserts.assertContains(
+          expected.getMessage(),
+          "1) "
+              + TooManyMatches.class.getName()
+              + " has more than one constructor annotated with @AssistedInject that "
+              + "matches the parameters in method "
+              + SimpleFactory2.class.getName());
     }
   }
 
   public void testNoMatchingConstructorsBecauseTooManyParams() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder().build(ComplexFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(new FactoryModuleBuilder().build(ComplexFactory.class));
+            }
+          });
       fail("should have failed");
     } catch (CreationException expected) {
-      Asserts.assertContains(expected.getMessage(), "1) " + Foo.class.getName()
-          + " has @AssistedInject constructors, but none of them match the parameters in method "
-          + ComplexFactory.class.getName());
+      Asserts.assertContains(
+          expected.getMessage(),
+          "1) "
+              + Foo.class.getName()
+              + " has @AssistedInject constructors, but none of them match the parameters in method "
+              + ComplexFactory.class.getName());
     }
   }
-  
+
   public void testNoMatchingConstrucotsBecauseTooLittleParams() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(new FactoryModuleBuilder().build(NullFactory.class));
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(new FactoryModuleBuilder().build(NullFactory.class));
+            }
+          });
       fail("should have failed");
     } catch (CreationException expected) {
-      Asserts.assertContains(expected.getMessage(), "1) " + Foo.class.getName()
-          + " has @AssistedInject constructors, but none of them match the parameters in method "
-          + NullFactory.class.getName());
+      Asserts.assertContains(
+          expected.getMessage(),
+          "1) "
+              + Foo.class.getName()
+              + " has @AssistedInject constructors, but none of them match the parameters in method "
+              + NullFactory.class.getName());
     }
   }
 
   public static interface ComplexFactory {
     Foo create(String name, int idx, float weight);
   }
-  
+
   public static interface NullFactory {
     Foo create();
   }
-  
+
   public static interface OtherFactory {
     Foo create(String name, int idx);
+
     Foo create(int idx, String name);
+
     Foo create(String name);
   }
 
-  
   public static interface Factory {
     Foo create(String name);
+
     Foo create(String name, int idx);
   }
-  
+
   public static interface BarFactory {
     Bar create(String name);
+
     Bar create(String name, int idx);
   }
-  
+
   public static interface SimpleFactory {
     Foo create(String name);
   }
-  
+
   public static interface SimpleFactory2 {
     Foo create(String name, int idx);
   }
-  
+
   public static class TooManyMatches extends Foo {
-    @AssistedInject TooManyMatches(@Assisted String name, @Assisted int index) {
-    }
-    
-    @AssistedInject TooManyMatches(@Assisted int index, @Assisted String name) {
-    }    
+    @AssistedInject
+    TooManyMatches(@Assisted String name, @Assisted int index) {}
+
+    @AssistedInject
+    TooManyMatches(@Assisted int index, @Assisted String name) {}
   }
-  
+
   public static class Foo implements Bar {
     private String name;
     private Integer index;
-    
+
     Foo() {}
-    
-    @AssistedInject Foo(@Assisted String name) {
+
+    @AssistedInject
+    Foo(@Assisted String name) {
       this.name = name;
       this.index = null;
     }
-    
-    @AssistedInject Foo(@Assisted String name, @Assisted int index) {
+
+    @AssistedInject
+    Foo(@Assisted String name, @Assisted int index) {
       this.name = name;
       this.index = index;
     }
-    
-    Foo(String a, String b, String c) {
-      
+
+    Foo(String a, String b, String c) {}
+
+    @Override
+    public String getName() {
+      return name;
     }
-    
-    public String getName() { return name; }
-    public Integer getIndex() { return index; }
+
+    @Override
+    public Integer getIndex() {
+      return index;
+    }
   }
-  
+
   public static interface Bar {
     String getName();
+
     Integer getIndex();
   }
-  
+
   public void testDependenciesAndOtherAnnotations() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new FactoryModuleBuilder().build(FamilyFarmFactory.class));
-      }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(FamilyFarmFactory.class));
+              }
+            });
+
     FamilyFarmFactory factory = injector.getInstance(FamilyFarmFactory.class);
     Farm pops = factory.popsFarm("Pop");
     assertEquals("Pop", pops.pop);
@@ -245,33 +280,37 @@
     assertEquals("Pop", momAndPop.pop);
     assertEquals("Mom", momAndPop.mom);
   }
-  
 
   public static interface FamilyFarmFactory {
     Farm popsFarm(String pop);
+
     Farm momsFarm(@Assisted("mom") String mom);
+
     Farm momAndPopsFarm(@Assisted("mom") String mom, @Assisted("pop") String pop);
   }
-  
+
   public static class Farm {
     String pop;
     String mom;
-    
-    @AssistedInject Farm(@Assisted String pop, Dog dog) {
+
+    @AssistedInject
+    Farm(@Assisted String pop, Dog dog) {
       this.pop = pop;
     }
-    
-    @AssistedInject Farm(@Assisted("mom") String mom, @Assisted("pop") String pop, Cow cow, Dog dog) {
+
+    @AssistedInject
+    Farm(@Assisted("mom") String mom, @Assisted("pop") String pop, Cow cow, Dog dog) {
       this.pop = pop;
       this.mom = mom;
     }
-    
-    @AssistedInject Farm(@Assisted("mom") String mom, Cow cow) {
+
+    @AssistedInject
+    Farm(@Assisted("mom") String mom, Cow cow) {
       this.mom = mom;
     }
   }
-  
+
   public static class Cow {}
+
   public static class Dog {}
-  
 }
diff --git a/extensions/dagger-adapter/build.xml b/extensions/dagger-adapter/build.xml
index 27eb429..1353ea3 100644
--- a/extensions/dagger-adapter/build.xml
+++ b/extensions/dagger-adapter/build.xml
@@ -8,7 +8,6 @@
     <fileset dir="${lib.dir}" includes="*.jar"/>
     <fileset dir="${ext.lib.dir}" includes="*.jar"/>
     <pathelement path="../../build/classes"/>
-    <fileset dir="../multibindings/build" includes="*.jar"/>
   </path>
 
   <target name="jar" depends="compile, manifest" description="Build jar.">
diff --git a/extensions/dagger-adapter/lib/dagger-2.0.jar b/extensions/dagger-adapter/lib/dagger-2.0.jar
deleted file mode 100644
index a7257df..0000000
--- a/extensions/dagger-adapter/lib/dagger-2.0.jar
+++ /dev/null
Binary files differ
diff --git a/extensions/dagger-adapter/lib/dagger-2.4.jar b/extensions/dagger-adapter/lib/dagger-2.4.jar
new file mode 100644
index 0000000..d62c1ee
--- /dev/null
+++ b/extensions/dagger-adapter/lib/dagger-2.4.jar
Binary files differ
diff --git a/extensions/dagger-adapter/pom.xml b/extensions/dagger-adapter/pom.xml
index 38692f4..07d8656 100644
--- a/extensions/dagger-adapter/pom.xml
+++ b/extensions/dagger-adapter/pom.xml
@@ -5,20 +5,29 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
   <artifactId>guice-dagger-adapter</artifactId>
   <name>Google Guice - Extensions - Dagger Adapter</name>
   <dependencies>
     <dependency>
-      <groupId>com.google.inject.extensions</groupId>
-      <artifactId>guice-multibindings</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>com.google.dagger</groupId>
       <artifactId>dagger</artifactId>
-      <version>2.0</version>
+      <version>2.4</version>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.daggeradapter</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerAdapter.java b/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerAdapter.java
index eb7aac5..ed4fb3b 100644
--- a/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerAdapter.java
+++ b/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerAdapter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,38 +15,39 @@
  */
 package com.google.inject.daggeradapter;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.Binder;
 import com.google.inject.Module;
 import com.google.inject.internal.ProviderMethodsModule;
 import com.google.inject.spi.ModuleAnnotatedMethodScanner;
-
 import java.util.Arrays;
 
 /**
  * A utility to adapt classes annotated with {@link @dagger.Module} such that their
- * {@link @dagger.Provides} methods can be properly invoked by Guice to perform their
- * provision operations.
+ * {@link @dagger.Provides} methods can be properly invoked by Guice to perform their provision
+ * operations.
  *
- * <p>Simple example: <pre>{@code
- *   Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter()));
+ * <p>Simple example:
+ *
+ * <pre>{@code
+ * Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter()));
  * }</pre>
  *
  * <p>Some notes on usage and compatibility.
- *   <ul>
- *     <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice.
- *     <li>MapBindings are not yet implemented (pending).
- *     <li>Be careful about stateful modules. In contrast to Dagger (where components are
- *         expected to be recreated on-demand with new Module instances), Guice typically
- *         has a single injector with a long lifetime, so your module instance will be used
- *         throughout the lifetime of the entire app.
- *     <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes
- *         like per-request or per-activity.  Using modules written with Dagger 1.x usage
- *         in mind may result in mis-scoped objects.
- *     <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope
- *         implementation must be registered in order to support the custom lifetime of that
- *         annotation.
- *   </ul>
+ *
+ * <ul>
+ * <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice.
+ * <li>MapBindings are not yet implemented (pending).
+ * <li>Be careful about stateful modules. In contrast to Dagger (where components are expected to be
+ *     recreated on-demand with new Module instances), Guice typically has a single injector with a
+ *     long lifetime, so your module instance will be used throughout the lifetime of the entire
+ *     app.
+ * <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes like
+ *     per-request or per-activity. Using modules written with Dagger 1.x usage in mind may result
+ *     in mis-scoped objects.
+ * <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope
+ *     implementation must be registered in order to support the custom lifetime of that annotation.
+ * </ul>
  *
  * @author cgruber@google.com (Christian Gruber)
  */
@@ -62,9 +63,9 @@
   }
 
   /**
-   * A Module that adapts Dagger {@code @Module}-annotated types to contribute configuration
-   * to an {@link com.google.inject.Injector} using a dagger-specific
-   * {@link ModuleAnnotatedMethodScanner}.
+   * A Module that adapts Dagger {@code @Module}-annotated types to contribute configuration to an
+   * {@link com.google.inject.Injector} using a dagger-specific {@link
+   * ModuleAnnotatedMethodScanner}.
    */
   private static final class DaggerCompatibilityModule implements Module {
     private final Object[] daggerModuleObjects;
@@ -73,14 +74,16 @@
       this.daggerModuleObjects = daggerModuleObjects;
     }
 
-    @Override public void configure(Binder binder) {
+    @Override
+    public void configure(Binder binder) {
       for (Object module : daggerModuleObjects) {
         binder.install(ProviderMethodsModule.forModule(module, DaggerMethodScanner.INSTANCE));
       }
     }
 
-    @Override public String toString() {
-      return Objects.toStringHelper(this)
+    @Override
+    public String toString() {
+      return MoreObjects.toStringHelper(this)
           .add("modules", Arrays.asList(daggerModuleObjects))
           .toString();
     }
diff --git a/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerMethodScanner.java b/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerMethodScanner.java
index 0dbdda2..620b242 100644
--- a/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerMethodScanner.java
+++ b/extensions/dagger-adapter/src/com/google/inject/daggeradapter/DaggerMethodScanner.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,10 +22,11 @@
 import com.google.inject.multibindings.Multibinder;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.ModuleAnnotatedMethodScanner;
-
 import dagger.Provides;
 import dagger.Provides.Type;
-
+import dagger.multibindings.ElementsIntoSet;
+import dagger.multibindings.IntoMap;
+import dagger.multibindings.IntoSet;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.Set;
@@ -36,27 +37,39 @@
  * @author cgruber@google.com (Christian Gruber)
  */
 final class DaggerMethodScanner extends ModuleAnnotatedMethodScanner {
-  static DaggerMethodScanner INSTANCE = new DaggerMethodScanner();
+  static final DaggerMethodScanner INSTANCE = new DaggerMethodScanner();
+  private static final ImmutableSet<Class<Provides>> ANNOTATIONS =
+      ImmutableSet.of(dagger.Provides.class);
 
-  @Override public Set<? extends Class<? extends Annotation>> annotationClasses() {
-    return ImmutableSet.of(dagger.Provides.class);
+  @Override
+  public Set<? extends Class<? extends Annotation>> annotationClasses() {
+    return ANNOTATIONS;
   }
 
-  @Override public <T> Key<T> prepareMethod(
+  @Override
+  public <T> Key<T> prepareMethod(
       Binder binder, Annotation rawAnnotation, Key<T> key, InjectionPoint injectionPoint) {
     Method providesMethod = (Method) injectionPoint.getMember();
     Provides annotation = (Provides) rawAnnotation;
+    if (providesMethod.isAnnotationPresent(IntoSet.class)) {
+      return processSetBinding(binder, key);
+    } else if (providesMethod.isAnnotationPresent(ElementsIntoSet.class)) {
+      binder.addError("@ElementsIntoSet contributions are not suppored by Guice.", providesMethod);
+      return key;
+    } else if (providesMethod.isAnnotationPresent(IntoMap.class)) {
+      /* TODO(cgruber) implement map bindings */
+      binder.addError("Map bindings are not yet supported.");
+      return key;
+    }
+
     switch (annotation.type()) {
       case UNIQUE:
         return key;
-      case MAP:
-        /* TODO(cgruber) implement map bindings */
-        binder.addError("Map bindings are not yet supported.");
       case SET:
         return processSetBinding(binder, key);
       case SET_VALUES:
-        binder.addError(Type.SET_VALUES.name() + " contributions are not supported by Guice.",
-            providesMethod);
+        binder.addError(
+            Type.SET_VALUES.name() + " contributions are not supported by Guice.", providesMethod);
         return key;
       default:
         binder.addError("Unknown @Provides type " + annotation.type() + ".", providesMethod);
@@ -65,11 +78,15 @@
   }
 
   private static <T> Key<T> processSetBinding(Binder binder, Key<T> key) {
-    Multibinder<T> setBinder = Multibinder.newSetBinder(binder, key.getTypeLiteral());
+    Annotation annotation = key.getAnnotation();
+    Multibinder<T> setBinder =
+        (annotation != null)
+            ? Multibinder.newSetBinder(binder, key.getTypeLiteral(), annotation)
+            : Multibinder.newSetBinder(binder, key.getTypeLiteral());
     Key<T> newKey = Key.get(key.getTypeLiteral(), UniqueAnnotations.create());
     setBinder.addBinding().to(newKey);
     return newKey;
   }
 
   private DaggerMethodScanner() {}
-}
\ No newline at end of file
+}
diff --git a/extensions/dagger-adapter/test/com/google/inject/daggeradapter/DaggerAdapterTest.java b/extensions/dagger-adapter/test/com/google/inject/daggeradapter/DaggerAdapterTest.java
index 30e1d18..187a454 100644
--- a/extensions/dagger-adapter/test/com/google/inject/daggeradapter/DaggerAdapterTest.java
+++ b/extensions/dagger-adapter/test/com/google/inject/daggeradapter/DaggerAdapterTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +15,6 @@
  */
 package com.google.inject.daggeradapter;
 
-import static dagger.Provides.Type.SET;
-
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
@@ -25,12 +23,15 @@
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
 import com.google.inject.multibindings.Multibinder;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
+import dagger.multibindings.IntoSet;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Set;
+import javax.inject.Qualifier;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link DaggerAdapter}.
@@ -39,8 +40,10 @@
  */
 
 public class DaggerAdapterTest extends TestCase {
-  @dagger.Module static class SimpleDaggerModule {
-    @dagger.Provides Integer anInteger() {
+  @dagger.Module
+  static class SimpleDaggerModule {
+    @dagger.Provides
+    Integer anInteger() {
       return 1;
     }
   }
@@ -51,39 +54,68 @@
   }
 
   static class SimpleGuiceModule extends AbstractModule {
-    @Provides String aString(Integer i) {
+    @Provides
+    String aString(Integer i) {
       return i.toString();
     }
-    @Override protected void configure() {}
   }
 
   public void testInteractionWithGuiceModules() {
-     Injector i = Guice.createInjector(
-         new SimpleGuiceModule(),
-         DaggerAdapter.from(new SimpleDaggerModule()));
-     assertEquals("1", i.getInstance(String.class));
+    Injector i =
+        Guice.createInjector(new SimpleGuiceModule(), DaggerAdapter.from(new SimpleDaggerModule()));
+    assertEquals("1", i.getInstance(String.class));
   }
 
-  @dagger.Module static class SetBindingDaggerModule1 {
-    @dagger.Provides(type=SET) Integer anInteger() {
+  @dagger.Module
+  static class SetBindingDaggerModule1 {
+    @dagger.Provides
+    @IntoSet
+    Integer anInteger() {
       return 5;
     }
   }
 
-  @dagger.Module static class SetBindingDaggerModule2 {
-    @dagger.Provides(type=SET) Integer anInteger() {
+  @dagger.Module
+  static class SetBindingDaggerModule2 {
+    @dagger.Provides
+    @IntoSet
+    Integer anInteger() {
       return 3;
     }
   }
 
   public void testSetBindings() {
-    Injector i = Guice.createInjector(
-        DaggerAdapter.from(new SetBindingDaggerModule1(), new SetBindingDaggerModule2()));
+    Injector i =
+        Guice.createInjector(
+            DaggerAdapter.from(new SetBindingDaggerModule1(), new SetBindingDaggerModule2()));
     assertEquals(ImmutableSet.of(3, 5), i.getInstance(new Key<Set<Integer>>() {}));
   }
 
+  @Qualifier
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface AnnotationOnSet {}
+
+  @dagger.Module
+  static class SetBindingWithAnnotationDaggerModule {
+    @dagger.Provides
+    @IntoSet
+    @AnnotationOnSet
+    Integer anInteger() {
+      return 4;
+    }
+  }
+
+  public void testSetBindingsWithAnnotation() {
+    Injector i =
+        Guice.createInjector(DaggerAdapter.from(new SetBindingWithAnnotationDaggerModule()));
+    assertEquals(
+        ImmutableSet.of(4),
+        i.getInstance(Key.get(new TypeLiteral<Set<Integer>>() {}, AnnotationOnSet.class)));
+  }
+
   static class MultibindingGuiceModule implements Module {
-    @Override public void configure(Binder binder) {
+    @Override
+    public void configure(Binder binder) {
       Multibinder<Integer> mb = Multibinder.newSetBinder(binder, Integer.class);
       mb.addBinding().toInstance(13);
       mb.addBinding().toProvider(Providers.of(8)); // mix'n'match.
@@ -91,9 +123,10 @@
   }
 
   public void testSetBindingsWithGuiceModule() {
-    Injector i = Guice.createInjector(
-        new MultibindingGuiceModule(),
-        DaggerAdapter.from(new SetBindingDaggerModule1(), new SetBindingDaggerModule2()));
+    Injector i =
+        Guice.createInjector(
+            new MultibindingGuiceModule(),
+            DaggerAdapter.from(new SetBindingDaggerModule1(), new SetBindingDaggerModule2()));
     assertEquals(ImmutableSet.of(13, 3, 5, 8), i.getInstance(new Key<Set<Integer>>() {}));
   }
 }
diff --git a/extensions/grapher/pom.xml b/extensions/grapher/pom.xml
index 715f80d..6951b8c 100644
--- a/extensions/grapher/pom.xml
+++ b/extensions/grapher/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-grapher</artifactId>
@@ -20,11 +20,6 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>com.google.inject.extensions</groupId>
-      <artifactId>guice-multibindings</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
       <version>3.0</version>
@@ -32,4 +27,18 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.grapher</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/grapher/src/com/google/inject/grapher/AbstractInjectorGrapher.java b/extensions/grapher/src/com/google/inject/grapher/AbstractInjectorGrapher.java
index 940caab..e20b525 100644
--- a/extensions/grapher/src/com/google/inject/grapher/AbstractInjectorGrapher.java
+++ b/extensions/grapher/src/com/google/inject/grapher/AbstractInjectorGrapher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,6 +42,7 @@
 
   /**
    * Parameters used to override default settings of the grapher.
+   *
    * @since 4.0
    */
   public static final class GrapherParameters {
@@ -98,11 +99,13 @@
     this.edgeCreator = options.getEdgeCreator();
   }
 
-  @Override public final void graph(Injector injector) throws IOException {
+  @Override
+  public final void graph(Injector injector) throws IOException {
     graph(injector, rootKeySetCreator.getRootKeys(injector));
   }
 
-  @Override public final void graph(Injector injector, Set<Key<?>> root) throws IOException {
+  @Override
+  public final void graph(Injector injector, Set<Key<?>> root) throws IOException {
     reset();
 
     Iterable<Binding<?>> bindings = getBindings(injector, root);
@@ -154,8 +157,8 @@
 
   private void createEdges(Iterable<Edge> edges, Map<NodeId, NodeId> aliases) throws IOException {
     for (Edge edge : edges) {
-      edge = edge.copy(resolveAlias(aliases, edge.getFromId()),
-          resolveAlias(aliases, edge.getToId()));
+      edge =
+          edge.copy(resolveAlias(aliases, edge.getFromId()), resolveAlias(aliases, edge.getToId()));
       if (!edge.getFromId().equals(edge.getToId())) {
         if (edge instanceof BindingEdge) {
           newBindingEdge((BindingEdge) edge);
@@ -171,8 +174,8 @@
   }
 
   /**
-   * Transitively resolves aliases. Given aliases (X to Y) and (Y to Z), it will return mappings
-   * (X to Z) and (Y to Z).
+   * Transitively resolves aliases. Given aliases (X to Y) and (Y to Z), it will return mappings (X
+   * to Z) and (Y to Z).
    */
   private Map<NodeId, NodeId> resolveAliases(Iterable<Alias> aliases) {
     Map<NodeId, NodeId> resolved = Maps.newHashMap();
diff --git a/extensions/grapher/src/com/google/inject/grapher/Alias.java b/extensions/grapher/src/com/google/inject/grapher/Alias.java
index bc20ca9..32a4e4e 100644
--- a/extensions/grapher/src/com/google/inject/grapher/Alias.java
+++ b/extensions/grapher/src/com/google/inject/grapher/Alias.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/AliasCreator.java b/extensions/grapher/src/com/google/inject/grapher/AliasCreator.java
index cd428ac..2238ecf 100644
--- a/extensions/grapher/src/com/google/inject/grapher/AliasCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/AliasCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/BindingEdge.java b/extensions/grapher/src/com/google/inject/grapher/BindingEdge.java
index 92d72ba..e0464b3 100644
--- a/extensions/grapher/src/com/google/inject/grapher/BindingEdge.java
+++ b/extensions/grapher/src/com/google/inject/grapher/BindingEdge.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,9 +25,7 @@
  * @since 4.0 (since 2.0 as an interface)
  */
 public class BindingEdge extends Edge {
-  /**
-   * Classification for what kind of binding this edge represents.
-   */
+  /** Classification for what kind of binding this edge represents. */
   public enum Type {
     /** Binding is to an instance or class of the binding's same type. */
     NORMAL,
@@ -48,7 +46,8 @@
     return type;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof BindingEdge)) {
       return false;
     }
@@ -56,15 +55,18 @@
     return super.equals(other) && Objects.equal(type, other.type);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return 31 * super.hashCode() + Objects.hashCode(type);
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "BindingEdge{fromId=" + getFromId() + " toId=" + getToId() + " type=" + type + "}";
   }
 
-  @Override public Edge copy(NodeId fromId, NodeId toId) {
+  @Override
+  public Edge copy(NodeId fromId, NodeId toId) {
     return new BindingEdge(fromId, toId, type);
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/DefaultEdgeCreator.java b/extensions/grapher/src/com/google/inject/grapher/DefaultEdgeCreator.java
index 5ba402d..34dd2b5 100644
--- a/extensions/grapher/src/com/google/inject/grapher/DefaultEdgeCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/DefaultEdgeCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,7 +39,8 @@
  */
 final class DefaultEdgeCreator implements EdgeCreator {
 
-  @Override public Iterable<Edge> getEdges(Iterable<Binding<?>> bindings) {
+  @Override
+  public Iterable<Edge> getEdges(Iterable<Binding<?>> bindings) {
     List<Edge> edges = Lists.newArrayList();
     EdgeVisitor visitor = new EdgeVisitor();
     for (Binding<?> binding : bindings) {
@@ -58,8 +59,7 @@
      * Returns a dependency edge for each {@link Dependency} in the binding. These will be from the
      * given node ID to the {@link Dependency}'s {@link Key}.
      *
-     * @param nodeId ID of the node that should be the tail of the dependency
-     *     edges
+     * @param nodeId ID of the node that should be the tail of the dependency edges
      * @param binding {@link Binding} for the dependencies
      */
     private <T extends Binding<?> & HasDependencies> Collection<Edge> newDependencyEdges(
@@ -76,7 +76,8 @@
      * Visitor for {@link ConstructorBinding}s. These are for classes that Guice will instantiate to
      * satisfy injection requests.
      */
-    @Override public Collection<Edge> visit(ConstructorBinding<?> binding) {
+    @Override
+    public Collection<Edge> visit(ConstructorBinding<?> binding) {
       return newDependencyEdges(NodeId.newTypeId(binding.getKey()), binding);
     }
 
@@ -85,10 +86,13 @@
      * annotated primitive type, and the value of {@link ConvertedConstantBinding#getSourceKey()}
      * will be of a {@link String} with the same annotation.
      */
-    @Override public Collection<Edge> visit(ConvertedConstantBinding<?> binding) {
-      return ImmutableList.<Edge>of(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-          NodeId.newTypeId(binding.getSourceKey()),
-          BindingEdge.Type.CONVERTED_CONSTANT));
+    @Override
+    public Collection<Edge> visit(ConvertedConstantBinding<?> binding) {
+      return ImmutableList.<Edge>of(
+          new BindingEdge(
+              NodeId.newTypeId(binding.getKey()),
+              NodeId.newTypeId(binding.getSourceKey()),
+              BindingEdge.Type.CONVERTED_CONSTANT));
     }
 
     /**
@@ -97,57 +101,76 @@
      * or on {@link Dependency}s the instance declares through the {@link HasDependencies}
      * interface.
      */
-    @Override public Collection<Edge> visit(InstanceBinding<?> binding) {
+    @Override
+    public Collection<Edge> visit(InstanceBinding<?> binding) {
       return new ImmutableList.Builder<Edge>()
-          .add(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-              NodeId.newInstanceId(binding.getKey()),
-              BindingEdge.Type.NORMAL))
+          .add(
+              new BindingEdge(
+                  NodeId.newTypeId(binding.getKey()),
+                  NodeId.newInstanceId(binding.getKey()),
+                  BindingEdge.Type.NORMAL))
           .addAll(newDependencyEdges(NodeId.newInstanceId(binding.getKey()), binding))
           .build();
     }
 
     /**
      * Visitor for {@link LinkedKeyBinding}. This is the standard {@link Binding} you get from
-     * binding an interface class to an implementation class. We  draw a {@link BindingEdge} from
-     * the interface node to the node of the implementing class.
+     * binding an interface class to an implementation class. We draw a {@link BindingEdge} from the
+     * interface node to the node of the implementing class.
      */
-    @Override public Collection<Edge> visit(LinkedKeyBinding<?> binding) {
-      return ImmutableList.<Edge>of(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-          NodeId.newTypeId(binding.getLinkedKey()),
-          BindingEdge.Type.NORMAL));
+    @Override
+    public Collection<Edge> visit(LinkedKeyBinding<?> binding) {
+      return ImmutableList.<Edge>of(
+          new BindingEdge(
+              NodeId.newTypeId(binding.getKey()),
+              NodeId.newTypeId(binding.getLinkedKey()),
+              BindingEdge.Type.NORMAL));
     }
 
     /**
-     * Visitor for {@link ProviderBinding}. These {@link Binding}s arise from an
-     * {@link InjectionPoint} for the {@link Provider} interface.
+     * Visitor for {@link ProviderBinding}. These {@link Binding}s arise from an {@link
+     * InjectionPoint} for the {@link Provider} interface.
      */
-    @Override public Collection<Edge> visit(ProviderBinding<?> binding) {
-      return ImmutableList.<Edge>of(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-          NodeId.newTypeId(binding.getProvidedKey()), BindingEdge.Type.PROVIDER));
+    @Override
+    public Collection<Edge> visit(ProviderBinding<?> binding) {
+      return ImmutableList.<Edge>of(
+          new BindingEdge(
+              NodeId.newTypeId(binding.getKey()),
+              NodeId.newTypeId(binding.getProvidedKey()),
+              BindingEdge.Type.PROVIDER));
     }
 
     /**
-     * Same as {@link #visit(InstanceBinding)}, but the binding edge is
-     * {@link BindingEdge.Type#PROVIDER}.
+     * Same as {@link #visit(InstanceBinding)}, but the binding edge is {@link
+     * BindingEdge.Type#PROVIDER}.
      */
-    @Override public Collection<Edge> visit(ProviderInstanceBinding<?> binding) {
+    @Override
+    public Collection<Edge> visit(ProviderInstanceBinding<?> binding) {
       return new ImmutableList.Builder<Edge>()
-          .add(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-              NodeId.newInstanceId(binding.getKey()), BindingEdge.Type.PROVIDER))
+          .add(
+              new BindingEdge(
+                  NodeId.newTypeId(binding.getKey()),
+                  NodeId.newInstanceId(binding.getKey()),
+                  BindingEdge.Type.PROVIDER))
           .addAll(newDependencyEdges(NodeId.newInstanceId(binding.getKey()), binding))
           .build();
     }
 
     /**
-     * Same as {@link #visit(LinkedKeyBinding)}, but the binding edge is
-     * {@link BindingEdge.Type#PROVIDER}.
+     * Same as {@link #visit(LinkedKeyBinding)}, but the binding edge is {@link
+     * BindingEdge.Type#PROVIDER}.
      */
-    @Override public Collection<Edge> visit(ProviderKeyBinding<?> binding) {
-      return ImmutableList.<Edge>of(new BindingEdge(NodeId.newTypeId(binding.getKey()),
-          NodeId.newTypeId(binding.getProviderKey()), BindingEdge.Type.PROVIDER));
+    @Override
+    public Collection<Edge> visit(ProviderKeyBinding<?> binding) {
+      return ImmutableList.<Edge>of(
+          new BindingEdge(
+              NodeId.newTypeId(binding.getKey()),
+              NodeId.newTypeId(binding.getProviderKey()),
+              BindingEdge.Type.PROVIDER));
     }
 
-    @Override public Collection<Edge> visitOther(Binding<?> binding) {
+    @Override
+    public Collection<Edge> visitOther(Binding<?> binding) {
       return ImmutableList.of();
     }
   }
diff --git a/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java b/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
index e97f111..1fa85f2 100644
--- a/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,7 +26,6 @@
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.InstanceBinding;
 import com.google.inject.spi.ProviderInstanceBinding;
-
 import java.lang.reflect.Member;
 import java.util.Collection;
 import java.util.List;
@@ -37,7 +36,8 @@
  * @author bojand@google.com (Bojan Djordjevic)
  */
 final class DefaultNodeCreator implements NodeCreator {
-  @Override public Iterable<Node> getNodes(Iterable<Binding<?>> bindings) {
+  @Override
+  public Iterable<Node> getNodes(Iterable<Binding<?>> bindings) {
     List<Node> nodes = Lists.newArrayList();
     NodeVisitor visitor = new NodeVisitor();
     for (Binding<?> binding : bindings) {
@@ -64,10 +64,10 @@
      * @param members members to add to the node
      * @return implementation node for the given binding
      */
-    private ImplementationNode newImplementationNode(Binding<?> binding,
-        Collection<Member> members) {
-      return new ImplementationNode(NodeId.newTypeId(binding.getKey()), binding.getSource(),
-          members);
+    private ImplementationNode newImplementationNode(
+        Binding<?> binding, Collection<Member> members) {
+      return new ImplementationNode(
+          NodeId.newTypeId(binding.getKey()), binding.getSource(), members);
     }
 
     /**
@@ -77,8 +77,8 @@
      * @param instance value of the instance
      * @return instance node for the given binding
      */
-    private <T extends Binding<?> & HasDependencies> InstanceNode newInstanceNode(T binding,
-        Object instance) {
+    private <T extends Binding<?> & HasDependencies> InstanceNode newInstanceNode(
+        T binding, Object instance) {
       Collection<Member> members = Lists.newArrayList();
       for (Dependency<?> dependency : binding.getDependencies()) {
         InjectionPoint injectionPoint = dependency.getInjectionPoint();
@@ -87,15 +87,16 @@
           members.add(injectionPoint.getMember());
         }
       }
-      return new InstanceNode(NodeId.newInstanceId(binding.getKey()), binding.getSource(), instance,
-          members);
+      return new InstanceNode(
+          NodeId.newInstanceId(binding.getKey()), binding.getSource(), instance, members);
     }
 
     /**
      * Visitor for {@link ConstructorBinding}s. These are for classes that Guice will instantiate to
      * satisfy injection requests.
      */
-    @Override public Collection<Node> visit(ConstructorBinding<?> binding) {
+    @Override
+    public Collection<Node> visit(ConstructorBinding<?> binding) {
       Collection<Member> members = Lists.newArrayList();
       members.add(binding.getConstructor().getMember());
       for (InjectionPoint injectionPoint : binding.getInjectableMembers()) {
@@ -110,21 +111,24 @@
      * the binding's {@link Key}, and then an implementation node for the instance {@link Object}
      * itself.
      */
-    @Override public Collection<Node> visit(InstanceBinding<?> binding) {
-      return ImmutableList.<Node>of(newInterfaceNode(binding), newInstanceNode(binding,
-          binding.getInstance()));
+    @Override
+    public Collection<Node> visit(InstanceBinding<?> binding) {
+      return ImmutableList.<Node>of(
+          newInterfaceNode(binding), newInstanceNode(binding, binding.getInstance()));
     }
 
     /**
-     * Same as {@link #visit(InstanceBinding)}, but the binding edge is
-     * {@link BindingEdgeType#PROVIDER}.
+     * Same as {@link #visit(InstanceBinding)}, but the binding edge is {@link
+     * BindingEdgeType#PROVIDER}.
      */
-    @Override public Collection<Node> visit(ProviderInstanceBinding<?> binding) {
-      return ImmutableList.<Node>of(newInterfaceNode(binding), newInstanceNode(binding,
-          binding.getUserSuppliedProvider()));
+    @Override
+    public Collection<Node> visit(ProviderInstanceBinding<?> binding) {
+      return ImmutableList.<Node>of(
+          newInterfaceNode(binding), newInstanceNode(binding, binding.getUserSuppliedProvider()));
     }
 
-    @Override public Collection<Node> visitOther(Binding<?> binding) {
+    @Override
+    public Collection<Node> visitOther(Binding<?> binding) {
       return ImmutableList.<Node>of(newInterfaceNode(binding));
     }
   }
diff --git a/extensions/grapher/src/com/google/inject/grapher/DefaultRootKeySetCreator.java b/extensions/grapher/src/com/google/inject/grapher/DefaultRootKeySetCreator.java
index cf44d46..7482c90 100644
--- a/extensions/grapher/src/com/google/inject/grapher/DefaultRootKeySetCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/DefaultRootKeySetCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +20,12 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
 import java.util.Set;
 import java.util.logging.Logger;
 
 /**
- * Root key set creator that starts with all types that are not Guice internal types or the
- * {@link Logger} type.
+ * Root key set creator that starts with all types that are not Guice internal types or the {@link
+ * Logger} type.
  *
  * @author bojand@google.com (Bojan Djordjevic)
  * @since 4.0
@@ -34,11 +33,12 @@
 public class DefaultRootKeySetCreator implements RootKeySetCreator {
   private static final Key<Logger> loggerKey = Key.get(Logger.class);
 
-  @Override public Set<Key<?>> getRootKeys(Injector injector) {
+  @Override
+  public Set<Key<?>> getRootKeys(Injector injector) {
     Set<Key<?>> root = Sets.newHashSet();
     for (Key<?> key : injector.getBindings().keySet()) {
       if (key.getTypeLiteral().getRawType().getPackage() != Guice.class.getPackage()
-        && !loggerKey.equals(key)) {
+          && !loggerKey.equals(key)) {
         root.add(key);
       }
     }
diff --git a/extensions/grapher/src/com/google/inject/grapher/DependencyEdge.java b/extensions/grapher/src/com/google/inject/grapher/DependencyEdge.java
index a8fe7bb..d4d5c54 100644
--- a/extensions/grapher/src/com/google/inject/grapher/DependencyEdge.java
+++ b/extensions/grapher/src/com/google/inject/grapher/DependencyEdge.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,7 +42,8 @@
     return injectionPoint;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof DependencyEdge)) {
       return false;
     }
@@ -50,16 +51,24 @@
     return super.equals(other) && Objects.equal(injectionPoint, other.injectionPoint);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return 31 * super.hashCode() + Objects.hashCode(injectionPoint);
   }
 
-  @Override public String toString() {
-    return "DependencyEdge{fromId=" + getFromId() + " toId=" + getToId()
-        + " injectionPoint=" + injectionPoint + "}";
+  @Override
+  public String toString() {
+    return "DependencyEdge{fromId="
+        + getFromId()
+        + " toId="
+        + getToId()
+        + " injectionPoint="
+        + injectionPoint
+        + "}";
   }
 
-  @Override public Edge copy(NodeId fromId, NodeId toId) {
+  @Override
+  public Edge copy(NodeId fromId, NodeId toId) {
     return new DependencyEdge(fromId, toId, injectionPoint);
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/Edge.java b/extensions/grapher/src/com/google/inject/grapher/Edge.java
index 40a3df0..cc7156e 100644
--- a/extensions/grapher/src/com/google/inject/grapher/Edge.java
+++ b/extensions/grapher/src/com/google/inject/grapher/Edge.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,7 +41,8 @@
     return toId;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof Edge)) {
       return false;
     }
@@ -49,7 +50,8 @@
     return Objects.equal(fromId, other.fromId) && Objects.equal(toId, other.toId);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return Objects.hashCode(fromId, toId);
   }
 
diff --git a/extensions/grapher/src/com/google/inject/grapher/EdgeCreator.java b/extensions/grapher/src/com/google/inject/grapher/EdgeCreator.java
index f14e71f..fc07333 100644
--- a/extensions/grapher/src/com/google/inject/grapher/EdgeCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/EdgeCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/ImplementationNode.java b/extensions/grapher/src/com/google/inject/grapher/ImplementationNode.java
index 424ee1a..b373e85 100644
--- a/extensions/grapher/src/com/google/inject/grapher/ImplementationNode.java
+++ b/extensions/grapher/src/com/google/inject/grapher/ImplementationNode.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,9 +21,9 @@
 import java.util.Collection;
 
 /**
- * Node for types that have {@link com.google.inject.spi.Dependency}s and are
- * bound to {@link InterfaceNode}s. These nodes will often have fields for
- * {@link Member}s that are {@link com.google.inject.spi.InjectionPoint}s.
+ * Node for types that have {@link com.google.inject.spi.Dependency}s and are bound to {@link
+ * InterfaceNode}s. These nodes will often have fields for {@link Member}s that are {@link
+ * com.google.inject.spi.InjectionPoint}s.
  *
  * @see DependencyEdge
  * @author phopkins@gmail.com (Pete Hopkins)
@@ -41,7 +41,8 @@
     return members;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof ImplementationNode)) {
       return false;
     }
@@ -49,16 +50,24 @@
     return super.equals(other) && Objects.equal(members, other.members);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return 31 * super.hashCode() + Objects.hashCode(members);
   }
 
-  @Override public String toString() {
-    return "ImplementationNode{id=" + getId() + " source=" + getSource()
-        + " members=" + members + "}";
+  @Override
+  public String toString() {
+    return "ImplementationNode{id="
+        + getId()
+        + " source="
+        + getSource()
+        + " members="
+        + members
+        + "}";
   }
 
-  @Override public Node copy(NodeId id) {
+  @Override
+  public Node copy(NodeId id) {
     return new ImplementationNode(id, getSource(), getMembers());
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/InjectorGrapher.java b/extensions/grapher/src/com/google/inject/grapher/InjectorGrapher.java
index 2d9efcd..ebbbe1c 100644
--- a/extensions/grapher/src/com/google/inject/grapher/InjectorGrapher.java
+++ b/extensions/grapher/src/com/google/inject/grapher/InjectorGrapher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,6 @@
 
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
 import java.io.IOException;
 import java.util.Set;
 
@@ -31,9 +30,7 @@
  */
 public interface InjectorGrapher {
 
-  /**
-   * Graphs the guice dependency graph for the given injector using default starting keys.
-   */
+  /** Graphs the guice dependency graph for the given injector using default starting keys. */
   void graph(Injector injector) throws IOException;
 
   /**
diff --git a/extensions/grapher/src/com/google/inject/grapher/InstanceNode.java b/extensions/grapher/src/com/google/inject/grapher/InstanceNode.java
index 0aaa19b..019ee57 100644
--- a/extensions/grapher/src/com/google/inject/grapher/InstanceNode.java
+++ b/extensions/grapher/src/com/google/inject/grapher/InstanceNode.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,25 +43,37 @@
     return members;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof InstanceNode)) {
       return false;
     }
     InstanceNode other = (InstanceNode) obj;
-    return super.equals(other) && Objects.equal(instance, other.instance)
+    return super.equals(other)
+        && Objects.equal(instance, other.instance)
         && Objects.equal(members, other.members);
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return 31 * super.hashCode() + Objects.hashCode(instance, members);
   }
 
-  @Override public String toString() {
-    return "InstanceNode{id=" + getId() + " source=" + getSource() + " instance=" + instance
-        + " members=" + members + "}";
+  @Override
+  public String toString() {
+    return "InstanceNode{id="
+        + getId()
+        + " source="
+        + getSource()
+        + " instance="
+        + instance
+        + " members="
+        + members
+        + "}";
   }
 
-  @Override public Node copy(NodeId id) {
+  @Override
+  public Node copy(NodeId id) {
     return new InstanceNode(id, getSource(), getInstance(), getMembers());
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/InterfaceNode.java b/extensions/grapher/src/com/google/inject/grapher/InterfaceNode.java
index c23008d..e0aafd7 100644
--- a/extensions/grapher/src/com/google/inject/grapher/InterfaceNode.java
+++ b/extensions/grapher/src/com/google/inject/grapher/InterfaceNode.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,15 +28,18 @@
     super(id, source);
   }
 
-  @Override public Node copy(NodeId id) {
+  @Override
+  public Node copy(NodeId id) {
     return new InterfaceNode(id, getSource());
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     return (obj instanceof InterfaceNode) && super.equals(obj);
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "InterfaceNode{id=" + getId() + " source=" + getSource() + "}";
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/NameFactory.java b/extensions/grapher/src/com/google/inject/grapher/NameFactory.java
index 20e740a..d99990b 100644
--- a/extensions/grapher/src/com/google/inject/grapher/NameFactory.java
+++ b/extensions/grapher/src/com/google/inject/grapher/NameFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,20 +17,22 @@
 package com.google.inject.grapher;
 
 import com.google.inject.Key;
-
 import java.lang.reflect.Member;
 
 /**
- * Interface for a service that provides nice {@link String}s that we can
- * display in the graph for the types that come up in
- * {@link com.google.inject.Binding}s.
+ * Interface for a service that provides nice {@link String}s that we can display in the graph for
+ * the types that come up in {@link com.google.inject.Binding}s.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public interface NameFactory {
   String getMemberName(Member member);
+
   String getClassName(Key<?> key);
+
   String getInstanceName(Object instance);
+
   String getAnnotationName(Key<?> key);
+
   String getSourceName(Object source);
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/Node.java b/extensions/grapher/src/com/google/inject/grapher/Node.java
index ace85a5..a52978a 100644
--- a/extensions/grapher/src/com/google/inject/grapher/Node.java
+++ b/extensions/grapher/src/com/google/inject/grapher/Node.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,8 +26,8 @@
  */
 public abstract class Node {
   /**
-   * When set to true, the source object is ignored in {@link #equals} and {@link #hashCode}.
-   * Only used in tests.
+   * When set to true, the source object is ignored in {@link #equals} and {@link #hashCode}. Only
+   * used in tests.
    */
   static boolean ignoreSourceInComparisons = false;
 
@@ -47,7 +47,8 @@
     return source;
   }
 
-  @Override public boolean equals(Object obj) {
+  @Override
+  public boolean equals(Object obj) {
     if (!(obj instanceof Node)) {
       return false;
     }
@@ -56,7 +57,8 @@
         && (ignoreSourceInComparisons || Objects.equal(source, other.source));
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return ignoreSourceInComparisons ? id.hashCode() : Objects.hashCode(id, source);
   }
 
diff --git a/extensions/grapher/src/com/google/inject/grapher/NodeCreator.java b/extensions/grapher/src/com/google/inject/grapher/NodeCreator.java
index d448370..bdb8e41 100644
--- a/extensions/grapher/src/com/google/inject/grapher/NodeCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/NodeCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/NodeId.java b/extensions/grapher/src/com/google/inject/grapher/NodeId.java
index 33df33d..872416c 100644
--- a/extensions/grapher/src/com/google/inject/grapher/NodeId.java
+++ b/extensions/grapher/src/com/google/inject/grapher/NodeId.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,10 +21,9 @@
 
 /**
  * ID of a node in the graph. An ID is given by a {@link Key} and a node type, which is used to
- * distinguish instances and implementation classes for the same key. For example
- * {@code bind(Integer.class).toInstance(42)} produces two nodes: an
- * interface node with the key of {@code Key<Integer>} and an instance node with the same
- * {@link Key} and value of 42.
+ * distinguish instances and implementation classes for the same key. For example {@code
+ * bind(Integer.class).toInstance(42)} produces two nodes: an interface node with the key of {@code
+ * Key<Integer>} and an instance node with the same {@link Key} and value of 42.
  *
  * @author bojand@google.com (Bojan Djordjevic)
  * @since 4.0
@@ -64,19 +63,22 @@
     return key;
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return Objects.hashCode(key, nodeType);
   }
 
-  @Override public boolean equals(Object obj) {
-    if (!(obj.getClass().equals(NodeId.class))) {
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null || !(obj.getClass().equals(NodeId.class))) {
       return false;
     }
     NodeId other = (NodeId) obj;
     return Objects.equal(key, other.key) && Objects.equal(nodeType, other.nodeType);
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "NodeId{nodeType=" + nodeType + " key=" + key + "}";
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/ProviderAliasCreator.java b/extensions/grapher/src/com/google/inject/grapher/ProviderAliasCreator.java
index d55ea7f..a7a785d 100644
--- a/extensions/grapher/src/com/google/inject/grapher/ProviderAliasCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/ProviderAliasCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,19 +23,21 @@
 
 /**
  * Alias creator that creates an alias for each {@link ProviderBinding}. These {@link Binding}s
- * arise from an {@link InjectionPoint} for the {@link Provider} interface. Since this isn't
- * very interesting information, we don't render this binding on the graph, and just alias the two
- * nodes.
+ * arise from an {@link InjectionPoint} for the {@link Provider} interface. Since this isn't very
+ * interesting information, we don't render this binding on the graph, and just alias the two nodes.
  *
  * @author bojand@google.com (Bojan Djordjevic)
  */
 final class ProviderAliasCreator implements AliasCreator {
-  @Override public Iterable<Alias> createAliases(Iterable<Binding<?>> bindings) {
+  @Override
+  public Iterable<Alias> createAliases(Iterable<Binding<?>> bindings) {
     List<Alias> aliases = Lists.newArrayList();
     for (Binding<?> binding : bindings) {
       if (binding instanceof ProviderBinding) {
-        aliases.add(new Alias(NodeId.newTypeId(binding.getKey()),
-            NodeId.newTypeId(((ProviderBinding<?>) binding).getProvidedKey())));
+        aliases.add(
+            new Alias(
+                NodeId.newTypeId(binding.getKey()),
+                NodeId.newTypeId(((ProviderBinding<?>) binding).getProvidedKey())));
       }
     }
     return aliases;
diff --git a/extensions/grapher/src/com/google/inject/grapher/RootKeySetCreator.java b/extensions/grapher/src/com/google/inject/grapher/RootKeySetCreator.java
index 12114d8..c329d3b 100644
--- a/extensions/grapher/src/com/google/inject/grapher/RootKeySetCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/RootKeySetCreator.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/ShortNameFactory.java b/extensions/grapher/src/com/google/inject/grapher/ShortNameFactory.java
index e8c6d57..9dbaef4 100644
--- a/extensions/grapher/src/com/google/inject/grapher/ShortNameFactory.java
+++ b/extensions/grapher/src/com/google/inject/grapher/ShortNameFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.inject.internal.ProviderMethod;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.spi.ElementSource;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
@@ -31,23 +30,24 @@
 import java.util.List;
 
 /**
- * Reasonable implementation for {@link NameFactory}. Mostly takes various
- * {@link Object#toString()}s and strips package names out of them so that
- * they'll fit on the graph.
+ * Reasonable implementation for {@link NameFactory}. Mostly takes various {@link
+ * Object#toString()}s and strips package names out of them so that they'll fit on the graph.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class ShortNameFactory implements NameFactory {
+  @Override
   public String getMemberName(Member member) {
     if (member instanceof Constructor) {
       return "<init>";
     } else if (member instanceof Method) {
       return "#" + member.getName() + "(...)";
     } else {
-      return member.getName();      
+      return member.getName();
     }
   }
 
+  @Override
   public String getAnnotationName(Key<?> key) {
     Annotation annotation = key.getAnnotation();
     Class<? extends Annotation> annotationType = key.getAnnotationType();
@@ -57,7 +57,7 @@
       String annotationString = annotation.toString();
       String canonicalName = annotationType.getName();
       String simpleName = annotationType.getSimpleName();
- 
+
       return annotationString.replace(canonicalName, simpleName).replace("()", "");
     } else if (annotationType != null) {
       return "@" + annotationType.getSimpleName();
@@ -66,11 +66,13 @@
     }
   }
 
+  @Override
   public String getClassName(Key<?> key) {
     TypeLiteral<?> typeLiteral = key.getTypeLiteral();
     return stripPackages(typeLiteral.toString());
   }
 
+  @Override
   public String getInstanceName(Object instance) {
     if (instance instanceof ProviderMethod) {
       return getMethodString(((ProviderMethod<?>) instance).getMethod());
@@ -94,10 +96,11 @@
   }
 
   /**
-   * Returns a name for a Guice "source" object. This will typically be either
-   * a {@link StackTraceElement} for when the binding is made to the instance,
-   * or a {@link Method} when a provider method is used.
+   * Returns a name for a Guice "source" object. This will typically be either a {@link
+   * StackTraceElement} for when the binding is made to the instance, or a {@link Method} when a
+   * provider method is used.
    */
+  @Override
   public String getSourceName(Object source) {
     if (source instanceof ElementSource) {
       source = ((ElementSource) source).getDeclaringSource();
@@ -128,8 +131,8 @@
   }
 
   /**
-   * Eliminates runs of lowercase characters and numbers separated by periods.
-   * Seems to remove packages from fully-qualified type names pretty well.
+   * Eliminates runs of lowercase characters and numbers separated by periods. Seems to remove
+   * packages from fully-qualified type names pretty well.
    */
   private String stripPackages(String str) {
     return str.replaceAll("(^|[< .\\(])([a-z0-9]+\\.)*", "$1");
diff --git a/extensions/grapher/src/com/google/inject/grapher/TransitiveDependencyVisitor.java b/extensions/grapher/src/com/google/inject/grapher/TransitiveDependencyVisitor.java
index c2da39f..66d9fb1 100644
--- a/extensions/grapher/src/com/google/inject/grapher/TransitiveDependencyVisitor.java
+++ b/extensions/grapher/src/com/google/inject/grapher/TransitiveDependencyVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,15 +30,13 @@
 import com.google.inject.spi.ProviderBinding;
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderKeyBinding;
-
 import java.util.Collection;
 import java.util.Set;
 
 /**
- * {@link com.google.inject.spi.BindingTargetVisitor} that returns a
- * {@link Collection} of the {@link Key}s of each {@link Binding}'s
- * dependencies. Used by {@link InjectorGrapher} to walk the dependency graph
- * from a starting set of {@link Binding}s.
+ * {@link com.google.inject.spi.BindingTargetVisitor} that returns a {@link Collection} of the
+ * {@link Key}s of each {@link Binding}'s dependencies. Used by {@link InjectorGrapher} to walk the
+ * dependency graph from a starting set of {@link Binding}s.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
@@ -47,44 +45,52 @@
 
   private Collection<Key<?>> visitHasDependencies(HasDependencies hasDependencies) {
     Set<Key<?>> dependencies = Sets.newHashSet();
-    
+
     for (Dependency<?> dependency : hasDependencies.getDependencies()) {
       dependencies.add(dependency.getKey());
     }
 
     return dependencies;
   }
-  
-  @Override public Collection<Key<?>> visit(ConstructorBinding<?> binding) {
+
+  @Override
+  public Collection<Key<?>> visit(ConstructorBinding<?> binding) {
     return visitHasDependencies(binding);
   }
 
-  @Override public Collection<Key<?>> visit(ConvertedConstantBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(ConvertedConstantBinding<?> binding) {
     return visitHasDependencies(binding);
   }
 
-  @Override public Collection<Key<?>> visit(InstanceBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(InstanceBinding<?> binding) {
     return visitHasDependencies(binding);
   }
 
-  @Override public Collection<Key<?>> visit(LinkedKeyBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(LinkedKeyBinding<?> binding) {
     return ImmutableSet.<Key<?>>of(binding.getLinkedKey());
   }
 
-  @Override public Collection<Key<?>> visit(ProviderBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(ProviderBinding<?> binding) {
     return ImmutableSet.<Key<?>>of(binding.getProvidedKey());
   }
 
-  @Override public Collection<Key<?>> visit(ProviderInstanceBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(ProviderInstanceBinding<?> binding) {
     return visitHasDependencies(binding);
   }
 
-  @Override public Collection<Key<?>> visit(ProviderKeyBinding<?> binding) {
+  @Override
+  public Collection<Key<?>> visit(ProviderKeyBinding<?> binding) {
     return ImmutableSet.<Key<?>>of(binding.getProviderKey());
   }
 
   /** @since 4.0 */
-  @Override public Collection<Key<?>> visitOther(Binding<?> binding) {
+  @Override
+  public Collection<Key<?>> visitOther(Binding<?> binding) {
     return ImmutableSet.of();
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/ArrowType.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/ArrowType.java
index 3f1d807..b2a55fe 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/ArrowType.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/ArrowType.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,10 +17,10 @@
 package com.google.inject.grapher.graphviz;
 
 /**
- * Arrow symbols that are available from Graphviz. These can be composed by
- * concatenation to make double arrows and such.
- * <p>
- * See: http://www.graphviz.org/doc/info/arrows.html
+ * Arrow symbols that are available from Graphviz. These can be composed by concatenation to make
+ * double arrows and such.
+ *
+ * <p>See: http://www.graphviz.org/doc/info/arrows.html
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/CompassPoint.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/CompassPoint.java
index 7e6945b..db6f3c3 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/CompassPoint.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/CompassPoint.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,10 +17,9 @@
 package com.google.inject.grapher.graphviz;
 
 /**
- * Enum for the "compass point" values used to control where edge
- * end points appear on the graph.
- * <p>
- * See: http://www.graphviz.org/doc/info/attrs.html#k:portPos
+ * Enum for the "compass point" values used to control where edge end points appear on the graph.
+ *
+ * <p>See: http://www.graphviz.org/doc/info/attrs.html#k:portPos
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/EdgeStyle.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/EdgeStyle.java
index 121dbbf..69cb468 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/EdgeStyle.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/EdgeStyle.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +18,8 @@
 
 /**
  * Styles for edges.
- * <p>
- * See: http://www.graphviz.org/doc/info/attrs.html#k:style
+ *
+ * <p>See: http://www.graphviz.org/doc/info/attrs.html#k:style
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/Graphviz.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/Graphviz.java
index b86eadf..d79ad75 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/Graphviz.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/Graphviz.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizEdge.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizEdge.java
index 0a8ff98..cb9636f 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizEdge.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizEdge.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,12 +18,10 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.grapher.NodeId;
-
 import java.util.List;
 
 /**
- * Data object to encapsulate the attributes of Graphviz edges that we're
- * interested in drawing.
+ * Data object to encapsulate the attributes of Graphviz edges that we're interested in drawing.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
@@ -32,7 +30,7 @@
   private String headPortId;
   private CompassPoint headCompassPoint;
   private List<ArrowType> arrowHead = ImmutableList.of(ArrowType.NORMAL);
-  
+
   private final NodeId tailNodeId;
   private String tailPortId;
   private CompassPoint tailCompassPoint;
@@ -61,7 +59,7 @@
   public CompassPoint getHeadCompassPoint() {
     return headCompassPoint;
   }
-  
+
   public void setHeadCompassPoint(CompassPoint headCompassPoint) {
     this.headCompassPoint = headCompassPoint;
   }
@@ -90,7 +88,7 @@
   public CompassPoint getTailCompassPoint() {
     return tailCompassPoint;
   }
-  
+
   public void setTailCompassPoint(CompassPoint tailCompassPoint) {
     this.tailCompassPoint = tailCompassPoint;
   }
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizGrapher.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizGrapher.java
index 71edd09..a9b6301 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizGrapher.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizGrapher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,8 +40,8 @@
 /**
  * {@link com.google.inject.grapher.InjectorGrapher} implementation that writes out a Graphviz DOT
  * file of the graph. Dependencies are bound in {@link GraphvizModule}.
- * <p>
- * Specify the {@link PrintWriter} to output to with {@link #setOut(PrintWriter)}.
+ *
+ * <p>Specify the {@link PrintWriter} to output to with {@link #setOut(PrintWriter)}.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  * @since 4.0
@@ -55,13 +55,14 @@
   private PrintWriter out;
   private String rankdir = "TB";
 
-  @Inject GraphvizGrapher(@Graphviz NameFactory nameFactory,
-      @Graphviz PortIdFactory portIdFactory) {
+  @Inject
+  GraphvizGrapher(@Graphviz NameFactory nameFactory, @Graphviz PortIdFactory portIdFactory) {
     this.nameFactory = nameFactory;
     this.portIdFactory = portIdFactory;
   }
 
-  @Override protected void reset() {
+  @Override
+  protected void reset() {
     nodes.clear();
     edges.clear();
   }
@@ -74,9 +75,10 @@
     this.rankdir = rankdir;
   }
 
-  @Override protected void postProcess() {
+  @Override
+  protected void postProcess() {
     start();
-    
+
     for (GraphvizNode node : nodes.values()) {
       renderNode(node);
     }
@@ -84,9 +86,9 @@
     for (GraphvizEdge edge : edges) {
       renderEdge(edge);
     }
-    
+
     finish();
-    
+
     out.flush();
   }
 
@@ -98,7 +100,7 @@
 
   protected void start() {
     out.println("digraph injector {");
-    
+
     Map<String, String> attrs = getGraphAttributes();
     out.println("graph " + getAttrString(attrs) + ";");
   }
@@ -111,7 +113,7 @@
     Map<String, String> attrs = getNodeAttributes(node);
     out.println(node.getIdentifier() + " " + getAttrString(attrs));
   }
-  
+
   protected Map<String, String> getNodeAttributes(GraphvizNode node) {
     Map<String, String> attrs = Maps.newHashMap();
 
@@ -120,26 +122,25 @@
     attrs.put("margin", "\"0.02,0\"");
     attrs.put("shape", node.getShape().toString());
     attrs.put("style", node.getStyle().toString());
-    
+
     return attrs;
   }
 
   /**
-   * Creates the "label" for a node. This is a string of HTML that defines a
-   * table with a heading at the top and (in the case of
-   * {@link ImplementationNode}s) rows for each of the member fields.
+   * Creates the "label" for a node. This is a string of HTML that defines a table with a heading at
+   * the top and (in the case of {@link ImplementationNode}s) rows for each of the member fields.
    */
   protected String getNodeLabel(GraphvizNode node) {
     String cellborder = node.getStyle() == NodeStyle.INVISIBLE ? "1" : "0";
-    
+
     StringBuilder html = new StringBuilder();
     html.append("<");
     html.append("<table cellspacing=\"0\" cellpadding=\"5\" cellborder=\"");
     html.append(cellborder).append("\" border=\"0\">");
-    
+
     html.append("<tr>").append("<td align=\"left\" port=\"header\" ");
     html.append("bgcolor=\"" + node.getHeaderBackgroundColor() + "\">");
-    
+
     String subtitle = Joiner.on("<br align=\"left\"/>").join(node.getSubtitles());
     if (subtitle.length() != 0) {
       html.append("<font color=\"").append(node.getHeaderTextColor());
@@ -165,29 +166,35 @@
 
   protected void renderEdge(GraphvizEdge edge) {
     Map<String, String> attrs = getEdgeAttributes(edge);
-    
-    String tailId = getEdgeEndPoint(nodes.get(edge.getTailNodeId()).getIdentifier(),
-        edge.getTailPortId(), edge.getTailCompassPoint());
 
-    String headId = getEdgeEndPoint(nodes.get(edge.getHeadNodeId()).getIdentifier(),
-        edge.getHeadPortId(), edge.getHeadCompassPoint());
-    
+    String tailId =
+        getEdgeEndPoint(
+            nodes.get(edge.getTailNodeId()).getIdentifier(),
+            edge.getTailPortId(),
+            edge.getTailCompassPoint());
+
+    String headId =
+        getEdgeEndPoint(
+            nodes.get(edge.getHeadNodeId()).getIdentifier(),
+            edge.getHeadPortId(),
+            edge.getHeadCompassPoint());
+
     out.println(tailId + " -> " + headId + " " + getAttrString(attrs));
   }
 
   protected Map<String, String> getEdgeAttributes(GraphvizEdge edge) {
     Map<String, String> attrs = Maps.newHashMap();
-    
+
     attrs.put("arrowhead", getArrowString(edge.getArrowHead()));
     attrs.put("arrowtail", getArrowString(edge.getArrowTail()));
     attrs.put("style", edge.getStyle().toString());
-    
+
     return attrs;
   }
-  
+
   private String getAttrString(Map<String, String> attrs) {
     List<String> attrList = Lists.newArrayList();
-    
+
     for (Entry<String, String> attr : attrs.entrySet()) {
       String value = attr.getValue();
 
@@ -195,14 +202,13 @@
         attrList.add(attr.getKey() + "=" + value);
       }
     }
-    
+
     return "[" + Joiner.on(", ").join(attrList) + "]";
   }
 
   /**
-   * Turns a {@link List} of {@link ArrowType}s into a {@link String} that
-   * represents combining them. With Graphviz, that just means concatenating
-   * them.
+   * Turns a {@link List} of {@link ArrowType}s into a {@link String} that represents combining
+   * them. With Graphviz, that just means concatenating them.
    */
   protected String getArrowString(List<ArrowType> arrows) {
     return Joiner.on("").join(arrows);
@@ -210,15 +216,15 @@
 
   protected String getEdgeEndPoint(String nodeId, String portId, CompassPoint compassPoint) {
     List<String> portStrings = Lists.newArrayList(nodeId);
-    
+
     if (portId != null) {
       portStrings.add(portId);
     }
-    
+
     if (compassPoint != null) {
       portStrings.add(compassPoint.toString());
     }
-    
+
     return Joiner.on(":").join(portStrings);
   }
 
@@ -234,7 +240,8 @@
     return escaped;
   }
 
-  @Override protected void newInterfaceNode(InterfaceNode node) {
+  @Override
+  protected void newInterfaceNode(InterfaceNode node) {
     // TODO(phopkins): Show the Module on the graph, which comes from the
     // class name when source is a StackTraceElement.
 
@@ -247,7 +254,8 @@
     addNode(gnode);
   }
 
-  @Override protected void newImplementationNode(ImplementationNode node) {
+  @Override
+  protected void newImplementationNode(ImplementationNode node) {
     NodeId nodeId = node.getId();
     GraphvizNode gnode = new GraphvizNode(nodeId);
     gnode.setStyle(NodeStyle.SOLID);
@@ -263,7 +271,8 @@
     addNode(gnode);
   }
 
-  @Override protected void newInstanceNode(InstanceNode node) {
+  @Override
+  protected void newInstanceNode(InstanceNode node) {
     NodeId nodeId = node.getId();
     GraphvizNode gnode = new GraphvizNode(nodeId);
     gnode.setStyle(NodeStyle.SOLID);
@@ -285,7 +294,8 @@
     addNode(gnode);
   }
 
-  @Override protected void newDependencyEdge(DependencyEdge edge) {
+  @Override
+  protected void newDependencyEdge(DependencyEdge edge) {
     GraphvizEdge gedge = new GraphvizEdge(edge.getFromId(), edge.getToId());
     InjectionPoint fromPoint = edge.getInjectionPoint();
     if (fromPoint == null) {
@@ -299,7 +309,8 @@
     edges.add(gedge);
   }
 
-  @Override protected void newBindingEdge(BindingEdge edge) {
+  @Override
+  protected void newBindingEdge(BindingEdge edge) {
     GraphvizEdge gedge = new GraphvizEdge(edge.getFromId(), edge.getToId());
     gedge.setStyle(EdgeStyle.DASHED);
     switch (edge.getType()) {
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizModule.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizModule.java
index db7f3f3..e970326 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizModule.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,12 +26,9 @@
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class GraphvizModule extends AbstractModule {
-  @Override protected void configure() {
-    bind(NameFactory.class)
-        .annotatedWith(Graphviz.class)
-        .to(ShortNameFactory.class);
-    bind(PortIdFactory.class)
-        .annotatedWith(Graphviz.class)
-        .to(PortIdFactoryImpl.class);
+  @Override
+  protected void configure() {
+    bind(NameFactory.class).annotatedWith(Graphviz.class).to(ShortNameFactory.class);
+    bind(PortIdFactory.class).annotatedWith(Graphviz.class).to(PortIdFactoryImpl.class);
   }
 }
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizNode.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizNode.java
index 37a1f79..959c56a 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizNode.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/GraphvizNode.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +20,11 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.inject.grapher.NodeId;
-
 import java.util.List;
 import java.util.Map;
 
 /**
- * Data object to encapsulate the attributes of Graphviz nodes that we're
- * interested in drawing.
+ * Data object to encapsulate the attributes of Graphviz nodes that we're interested in drawing.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
@@ -35,10 +33,10 @@
 
   private NodeStyle style = NodeStyle.SOLID;
   private NodeShape shape = NodeShape.BOX;
-  
+
   private String title = "";
   private Map<Integer, String> subtitles = Maps.newTreeMap();
-  
+
   private String headerTextColor = "#000000";
   private String headerBackgroundColor = "#ffffff";
 
@@ -60,11 +58,11 @@
   public NodeShape getShape() {
     return shape;
   }
-  
+
   public void setShape(NodeShape shape) {
     this.shape = shape;
   }
-  
+
   public NodeStyle getStyle() {
     return style;
   }
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeShape.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeShape.java
index 25e4286..ccde54c 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeShape.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeShape.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,18 +18,18 @@
 
 /**
  * Enum for the shapes that are most interesting for Guice graphing.
- * <p>
- * See: http://www.graphviz.org/doc/info/shapes.html
- * 
+ *
+ * <p>See: http://www.graphviz.org/doc/info/shapes.html
+ *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public enum NodeShape {
   BOX("box"),
   ELLIPSE("ellipse"),
   NONE("none");
-  
+
   private final String shape;
-  
+
   NodeShape(String shape) {
     this.shape = shape;
   }
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeStyle.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeStyle.java
index bd9652d..5d99af6 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeStyle.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/NodeStyle.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +18,8 @@
 
 /**
  * Styles for nodes. Similar to {@link EdgeStyle} but with a few more options.
- * <p>
- * See: http://www.graphviz.org/doc/info/attrs.html#k:style
+ *
+ * <p>See: http://www.graphviz.org/doc/info/attrs.html#k:style
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactory.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactory.java
index 1883fc8..8489352 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactory.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,8 +19,8 @@
 import java.lang.reflect.Member;
 
 /**
- * Interface for a service that returns Graphviz port IDs, used for naming the
- * rows in {@link com.google.inject.grapher.ImplementationNode}-displaying {@link GraphvizNode}s.
+ * Interface for a service that returns Graphviz port IDs, used for naming the rows in {@link
+ * com.google.inject.grapher.ImplementationNode}-displaying {@link GraphvizNode}s.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
diff --git a/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactoryImpl.java b/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactoryImpl.java
index 71b30d6..a319699 100644
--- a/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactoryImpl.java
+++ b/extensions/grapher/src/com/google/inject/grapher/graphviz/PortIdFactoryImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +24,7 @@
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class PortIdFactoryImpl implements PortIdFactory {
+  @Override
   public String getPortId(Member member) {
     return "m_" + Integer.toHexString(member.hashCode());
   }
diff --git a/extensions/grapher/test/com/google/inject/grapher/AbstractInjectorGrapherTest.java b/extensions/grapher/test/com/google/inject/grapher/AbstractInjectorGrapherTest.java
index a8a35e3..15ad68f 100644
--- a/extensions/grapher/test/com/google/inject/grapher/AbstractInjectorGrapherTest.java
+++ b/extensions/grapher/test/com/google/inject/grapher/AbstractInjectorGrapherTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,13 +26,11 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.spi.InjectionPoint;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Member;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * Test cases for {@link AbstractInjectorGrapher}. This indirectly tests most classes in this
@@ -48,37 +46,44 @@
     final Set<Node> nodes = Sets.newHashSet();
     final Set<Edge> edges = Sets.newHashSet();
 
-    @Override protected void reset() {
+    @Override
+    protected void reset() {
       nodes.clear();
       edges.clear();
     }
 
-    @Override protected void newInterfaceNode(InterfaceNode node) {
+    @Override
+    protected void newInterfaceNode(InterfaceNode node) {
       assertFalse(nodes.contains(node));
       nodes.add(node);
     }
 
-    @Override protected void newImplementationNode(ImplementationNode node) {
+    @Override
+    protected void newImplementationNode(ImplementationNode node) {
       assertFalse(nodes.contains(node));
       nodes.add(node);
     }
 
-    @Override protected void newInstanceNode(InstanceNode node) {
+    @Override
+    protected void newInstanceNode(InstanceNode node) {
       assertFalse(nodes.contains(node));
       nodes.add(node);
     }
 
-    @Override protected void newDependencyEdge(DependencyEdge edge) {
+    @Override
+    protected void newDependencyEdge(DependencyEdge edge) {
       assertFalse(edges.contains(edge));
       edges.add(edge);
     }
 
-    @Override protected void newBindingEdge(BindingEdge edge) {
+    @Override
+    protected void newBindingEdge(BindingEdge edge) {
       assertFalse(edges.contains(edge));
       edges.add(edge);
     }
 
-    @Override protected void postProcess() {}
+    @Override
+    protected void postProcess() {}
   }
 
   private static final class Wrapper<T> {
@@ -88,12 +93,17 @@
   @BindingAnnotation
   @Retention(RetentionPolicy.RUNTIME)
   private static @interface Ann {}
+
   private static interface IA {}
+
   private static class A implements IA {
-    @Inject public A(String str) {}
+    @Inject
+    public A(String str) {}
   }
+
   private static class A2 implements IA {
-    @Inject public A2(Provider<String> strProvider) {}
+    @Inject
+    public A2(Provider<String> strProvider) {}
   }
 
   private Node aNode;
@@ -105,79 +115,114 @@
 
   private FakeGrapher grapher;
 
-  @Override protected void setUp() throws Exception {
+  @Override
+  protected void setUp() throws Exception {
     super.setUp();
     grapher = new FakeGrapher();
     Node.ignoreSourceInComparisons = true;
-    aNode = new ImplementationNode(NodeId.newTypeId(Key.get(A.class)), null,
-        ImmutableList.<Member>of(A.class.getConstructor(String.class)));
-    a2Node = new ImplementationNode(NodeId.newTypeId(Key.get(A2.class)), null,
-        ImmutableList.<Member>of(A2.class.getConstructor(Provider.class)));
+    aNode =
+        new ImplementationNode(
+            NodeId.newTypeId(Key.get(A.class)),
+            null,
+            ImmutableList.<Member>of(A.class.getConstructor(String.class)));
+    a2Node =
+        new ImplementationNode(
+            NodeId.newTypeId(Key.get(A2.class)),
+            null,
+            ImmutableList.<Member>of(A2.class.getConstructor(Provider.class)));
     iaNode = new InterfaceNode(NodeId.newTypeId(Key.get(IA.class)), null);
     iaAnnNode = new InterfaceNode(NodeId.newTypeId(Key.get(IA.class, Ann.class)), null);
     stringNode = new InterfaceNode(NodeId.newTypeId(Key.get(String.class)), null);
-    stringInstanceNode = new InstanceNode(NodeId.newInstanceId(Key.get(String.class)), null,
-        TEST_STRING, ImmutableList.<Member>of());
+    stringInstanceNode =
+        new InstanceNode(
+            NodeId.newInstanceId(Key.get(String.class)),
+            null,
+            TEST_STRING,
+            ImmutableList.<Member>of());
   }
 
   public void testLinkedAndInstanceBindings() throws Exception {
-    grapher.graph(Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(IA.class).to(A.class);
-          bind(IA.class).annotatedWith(Ann.class).to(A.class);
-          bind(String.class).toInstance(TEST_STRING);
-        }
-    }));
+    grapher.graph(
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(IA.class).to(A.class);
+                bind(IA.class).annotatedWith(Ann.class).to(A.class);
+                bind(String.class).toInstance(TEST_STRING);
+              }
+            }));
 
     Set<Node> expectedNodes =
         ImmutableSet.<Node>of(iaNode, iaAnnNode, aNode, stringNode, stringInstanceNode);
-    Set<Edge> expectedEdges = ImmutableSet.<Edge>of(
-        new BindingEdge(iaNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL),
-        new BindingEdge(iaAnnNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL),
-        new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL),
-        new DependencyEdge(aNode.getId(), stringNode.getId(),
-            InjectionPoint.forConstructor(A.class.getConstructor(String.class))));
+    Set<Edge> expectedEdges =
+        ImmutableSet.<Edge>of(
+            new BindingEdge(iaNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL),
+            new BindingEdge(iaAnnNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL),
+            new BindingEdge(
+                stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL),
+            new DependencyEdge(
+                aNode.getId(),
+                stringNode.getId(),
+                InjectionPoint.forConstructor(A.class.getConstructor(String.class))));
     assertEquals(expectedNodes, grapher.nodes);
     assertEquals(expectedEdges, grapher.edges);
   }
 
   public void testProviderBindings() throws Exception {
-    final Wrapper<Provider<A2>> wrapper = new Wrapper<Provider<A2>>();
-    grapher.graph(Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          wrapper.value = getProvider(A2.class);
-          bind(IA.class).toProvider(wrapper.value);
-          bind(A2.class);
-          bind(String.class).toInstance(TEST_STRING);
-        }
-    }));
+    final Wrapper<Provider<A2>> wrapper = new Wrapper<>();
+    grapher.graph(
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                wrapper.value = getProvider(A2.class);
+                bind(IA.class).toProvider(wrapper.value);
+                bind(A2.class);
+                bind(String.class).toInstance(TEST_STRING);
+              }
+            }));
 
-    Node a2ProviderNode = new InstanceNode(NodeId.newInstanceId(Key.get(IA.class)), null,
-        wrapper.value, ImmutableList.<Member>of());
+    Node a2ProviderNode =
+        new InstanceNode(
+            NodeId.newInstanceId(Key.get(IA.class)),
+            null,
+            wrapper.value,
+            ImmutableList.<Member>of());
     Set<Node> expectedNodes =
         ImmutableSet.<Node>of(iaNode, stringNode, a2Node, stringInstanceNode, a2ProviderNode);
-    Set<Edge> expectedEdges = ImmutableSet.<Edge>of(
-        new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL),
-        new BindingEdge(iaNode.getId(), a2ProviderNode.getId(), BindingEdge.Type.PROVIDER),
-        new DependencyEdge(a2Node.getId(), stringNode.getId(),
-            InjectionPoint.forConstructor(A2.class.getConstructor(Provider.class))),
-        new DependencyEdge(a2ProviderNode.getId(), a2Node.getId(), null));
+    Set<Edge> expectedEdges =
+        ImmutableSet.<Edge>of(
+            new BindingEdge(
+                stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL),
+            new BindingEdge(iaNode.getId(), a2ProviderNode.getId(), BindingEdge.Type.PROVIDER),
+            new DependencyEdge(
+                a2Node.getId(),
+                stringNode.getId(),
+                InjectionPoint.forConstructor(A2.class.getConstructor(Provider.class))),
+            new DependencyEdge(a2ProviderNode.getId(), a2Node.getId(), null));
     assertEquals("wrong nodes", expectedNodes, grapher.nodes);
     assertEquals("wrong edges", expectedEdges, grapher.edges);
   }
 
   public void testGraphWithGivenRoot() throws Exception {
-    grapher.graph(Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          bind(IA.class).to(A.class);
-          bind(IA.class).annotatedWith(Ann.class).to(A.class);
-          bind(String.class).toInstance(TEST_STRING);
-        }
-    }), ImmutableSet.<Key<?>>of(Key.get(String.class)));
+    grapher.graph(
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(IA.class).to(A.class);
+                bind(IA.class).annotatedWith(Ann.class).to(A.class);
+                bind(String.class).toInstance(TEST_STRING);
+              }
+            }),
+        ImmutableSet.<Key<?>>of(Key.get(String.class)));
 
     Set<Node> expectedNodes = ImmutableSet.<Node>of(stringNode, stringInstanceNode);
-    Set<Edge> expectedEdges = ImmutableSet.<Edge>of(
-        new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL));
+    Set<Edge> expectedEdges =
+        ImmutableSet.<Edge>of(
+            new BindingEdge(
+                stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL));
     assertEquals(expectedNodes, grapher.nodes);
     assertEquals(expectedEdges, grapher.edges);
   }
diff --git a/extensions/grapher/test/com/google/inject/grapher/AllTests.java b/extensions/grapher/test/com/google/inject/grapher/AllTests.java
index af81398..fec5cc0 100644
--- a/extensions/grapher/test/com/google/inject/grapher/AllTests.java
+++ b/extensions/grapher/test/com/google/inject/grapher/AllTests.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,9 +19,7 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
-/**
- * @author phopkins@gmail.com (Pete Hopkins)
- */
+/** @author phopkins@gmail.com (Pete Hopkins) */
 public class AllTests {
 
   public static Test suite() {
diff --git a/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java b/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
index 867a5a8..59a43cc 100644
--- a/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
+++ b/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,18 +26,17 @@
 import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Annotations;
 import com.google.inject.internal.ProviderMethod;
 import com.google.inject.internal.util.StackTraceElements;
 import com.google.inject.name.Names;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
 import com.google.inject.spi.ProviderInstanceBinding;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.lang.reflect.Member;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link ShortNameFactory}.
@@ -47,9 +46,10 @@
 public class ShortNameFactoryTest extends TestCase {
   // Helper objects are up here because their line numbers are tested below.
   private static class Obj {
-    @Annotated
-    public String field;
+    @Annotated public String field;
+
     Obj() {}
+
     void method(String parameter) {}
   }
 
@@ -59,9 +59,9 @@
       return "I'm a ToStringObj";
     }
   }
-  
+
   @Retention(RUNTIME)
-  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
   @BindingAnnotation
   private @interface Annotated {}
 
@@ -95,81 +95,101 @@
   }
 
   public void testGetAnnotationName_annotationInstance() throws Exception {
-    Key<?> key = Key.get(String.class,
-        Obj.class.getDeclaredField("field").getDeclaredAnnotations()[0]);
+    Key<?> key =
+        Key.get(String.class, Obj.class.getDeclaredField("field").getDeclaredAnnotations()[0]);
     assertEquals("@Annotated", nameFactory.getAnnotationName(key));
   }
 
   public void testGetAnnotationName_annotationInstanceWithParameters() throws Exception {
     Key<?> key = Key.get(String.class, Names.named("name"));
-    assertEquals("@Named(value=name)", nameFactory.getAnnotationName(key));
+    assertEquals(
+        "@Named(value=" + Annotations.memberValueString("name") + ")",
+        nameFactory.getAnnotationName(key));
   }
 
   public void testGetClassName_key() throws Exception {
     Key<?> key = Key.get(Obj.class);
-    assertEquals("Class name should not have the package",
-        "ShortNameFactoryTest$Obj", nameFactory.getClassName(key));
+    assertEquals(
+        "Class name should not have the package",
+        "ShortNameFactoryTest$Obj",
+        nameFactory.getClassName(key));
   }
-  
+
   public void testGetClassName_keyWithTypeParameters() throws Exception {
     Key<?> key = Key.get(new TypeLiteral<Provider<String>>() {});
-    assertEquals("Class name and type values should not have packages",
-        "Provider<String>", nameFactory.getClassName(key));
+    assertEquals(
+        "Class name and type values should not have packages",
+        "Provider<String>",
+        nameFactory.getClassName(key));
   }
 
   /**
-   * Tests the case where a provider method is the source of the 
+   * Tests the case where a provider method is the source of the
+   *
    * @throws Exception
    */
   public void testGetSourceName_method() throws Exception {
     Member method = Obj.class.getDeclaredMethod("method", String.class);
-    assertEquals("Method should be identified by its file name and line number",
-        "ShortNameFactoryTest.java:53", nameFactory.getSourceName(method));
+    assertEquals(
+        "Method should be identified by its file name and line number",
+        "ShortNameFactoryTest.java:53",
+        nameFactory.getSourceName(method));
   }
 
   public void testGetSourceName_stackTraceElement() throws Exception {
-    StackTraceElement element = 
+    StackTraceElement element =
         (StackTraceElement) StackTraceElements.forMember(Obj.class.getField("field"));
-    assertEquals("Stack trace element should be identified by its file name and line number",
-        "ShortNameFactoryTest.java:52", nameFactory.getSourceName(element));
+    assertEquals(
+        "Stack trace element should be identified by its file name and line number",
+        "ShortNameFactoryTest.java:51",
+        nameFactory.getSourceName(element));
   }
 
   public void testGetInstanceName_defaultToString() throws Exception {
-    assertEquals("Should use class name instead of Object#toString()",
-        "ShortNameFactoryTest$Obj", nameFactory.getInstanceName(new Obj()));
+    assertEquals(
+        "Should use class name instead of Object#toString()",
+        "ShortNameFactoryTest$Obj",
+        nameFactory.getInstanceName(new Obj()));
   }
-  
+
   public void testGetInstanceName_customToString() throws Exception {
-    assertEquals("Should use class's toString() method since it's defined",
-        "I'm a ToStringObj", nameFactory.getInstanceName(new ToStringObj()));
+    assertEquals(
+        "Should use class's toString() method since it's defined",
+        "I'm a ToStringObj",
+        nameFactory.getInstanceName(new ToStringObj()));
   }
-  
+
   public void testGetInstanceName_string() throws Exception {
-    assertEquals("String should have quotes to evoke a string literal",
-        "\"My String Instance\"", nameFactory.getInstanceName("My String Instance"));
+    assertEquals(
+        "String should have quotes to evoke a string literal",
+        "\"My String Instance\"",
+        nameFactory.getInstanceName("My String Instance"));
   }
-  
+
   public void testGetInstanceName_providerMethod() throws Exception {
     final ProviderMethod<?>[] methodHolder = new ProviderMethod[1];
-    
+
     Injector injector = Guice.createInjector(new ProvidingModule());
-    injector.getBinding(Integer.class).acceptTargetVisitor(
-        new DefaultBindingTargetVisitor<Object, Void>() {
-          @SuppressWarnings("unchecked") @Override
-          public Void visit(ProviderInstanceBinding<?> binding) {
-            methodHolder[0] = (ProviderMethod) binding.getUserSuppliedProvider();
-            return null;
-          }
-        });
-    
-    assertEquals("Method provider should pretty print as the method signature",
-        "#provideInteger(String)", nameFactory.getInstanceName(methodHolder[0]));
+    injector
+        .getBinding(Integer.class)
+        .acceptTargetVisitor(
+            new DefaultBindingTargetVisitor<Object, Void>() {
+              @SuppressWarnings("unchecked")
+              @Override
+              public Void visit(ProviderInstanceBinding<?> binding) {
+                methodHolder[0] = (ProviderMethod) binding.getUserSuppliedProvider();
+                return null;
+              }
+            });
+
+    assertEquals(
+        "Method provider should pretty print as the method signature",
+        "#provideInteger(String)",
+        nameFactory.getInstanceName(methodHolder[0]));
   }
-  
+
   private static class ProvidingModule extends AbstractModule {
-    @Override
-    protected void configure() {}
-    
+
     @Provides
     public Integer provideInteger(String string) {
       return Integer.valueOf(string);
diff --git a/extensions/grapher/test/com/google/inject/grapher/TransitiveDependencyVisitorTest.java b/extensions/grapher/test/com/google/inject/grapher/TransitiveDependencyVisitorTest.java
index 23ebbc0..39ea491 100644
--- a/extensions/grapher/test/com/google/inject/grapher/TransitiveDependencyVisitorTest.java
+++ b/extensions/grapher/test/com/google/inject/grapher/TransitiveDependencyVisitorTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,11 +35,9 @@
 import com.google.inject.spi.ProviderBinding;
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderKeyBinding;
-
-import junit.framework.TestCase;
-
 import java.util.Collection;
 import java.util.Set;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link TransitiveDependencyVisitor}.
@@ -48,45 +46,42 @@
  */
 public class TransitiveDependencyVisitorTest extends TestCase {
   private TransitiveDependencyVisitor visitor;
-  
+
   @Override
   protected void setUp() throws Exception {
     super.setUp();
-    
+
     visitor = new TransitiveDependencyVisitor();
   }
 
   public void testVisitConstructor() {
     Binding<?> binding = getBinding(Key.get(ConstructedClass.class));
     Collection<Key<?>> dependencies = visitor.visit((ConstructorBinding<?>) binding);
-    
-    assertDependencies(dependencies, Key.get(A.class), Key.get(B.class), Key.get(C.class),
-        Key.get(D.class));
+
+    assertDependencies(
+        dependencies, Key.get(A.class), Key.get(B.class), Key.get(C.class), Key.get(D.class));
   }
 
   public void testVisitConvertedConstant() {
-    Binding<?> binding = getBinding(Key.get(Integer.class, Names.named("number")),
-        new ConvertedConstantModule());
-    Collection<Key<?>> dependencies = visitor.visit(
-        (ConvertedConstantBinding<?>) binding);
-    
+    Binding<?> binding =
+        getBinding(Key.get(Integer.class, Names.named("number")), new ConvertedConstantModule());
+    Collection<Key<?>> dependencies = visitor.visit((ConvertedConstantBinding<?>) binding);
+
     assertDependencies(dependencies, Key.get(String.class, Names.named("number")));
   }
 
   public void testVisitInstance() {
     Binding<?> binding = getBinding(Key.get(ConstructedClass.class), new InstanceModule());
-    Collection<Key<?>> dependencies = visitor.visit(
-        (InstanceBinding<?>) binding);
-    
+    Collection<Key<?>> dependencies = visitor.visit((InstanceBinding<?>) binding);
+
     // Dependencies will only be on the field- and method-injected classes.
     assertDependencies(dependencies, Key.get(A.class), Key.get(D.class));
   }
 
   public void testVisitInstance_instanceHasDependencies() {
     Binding<?> binding = getBinding(Key.get(Interface.class), new HasDependenciesModule());
-    Collection<Key<?>> dependencies = visitor.visit(
-        (InstanceBinding<?>) binding);
-    
+    Collection<Key<?>> dependencies = visitor.visit((InstanceBinding<?>) binding);
+
     // Dependencies should only be on the stated
     // HasDependencies#getDependencies() values
     assertDependencies(dependencies, Key.get(G.class));
@@ -103,16 +98,14 @@
   public void testVisitProviderBinding() {
     Binding<?> binding = getBinding(Key.get(new TypeLiteral<Provider<ConstructedClass>>() {}));
     Collection<Key<?>> dependencies = visitor.visit((ProviderBinding<?>) binding);
-    
+
     assertDependencies(dependencies, Key.get(ConstructedClass.class));
   }
 
   public void testVisitProviderInstance() {
-    Binding<?> binding = getBinding(Key.get(ConstructedClass.class),
-        new ProviderInstanceModule());
-    Collection<Key<?>> dependencies = visitor.visit(
-        (ProviderInstanceBinding<?>) binding);
-    
+    Binding<?> binding = getBinding(Key.get(ConstructedClass.class), new ProviderInstanceModule());
+    Collection<Key<?>> dependencies = visitor.visit((ProviderInstanceBinding<?>) binding);
+
     // Dependencies will only be on the field- and method-injected classes.
     assertDependencies(dependencies, Key.get(E.class), Key.get(F.class));
   }
@@ -124,15 +117,15 @@
     // Dependency should be to the class that provides this one.
     assertDependencies(dependencies, Key.get(ConstructedClassProvider.class));
   }
-  
+
   private Binding<?> getBinding(Key<?> key, Module... modules) {
     return Guice.createInjector(modules).getBinding(key);
   }
-  
+
   private void assertDependencies(Collection<Key<?>> dependencies, Key<?>... keys) {
     assertNotNull("Dependencies should not be null", dependencies);
-    assertEquals("There should be " + keys.length + " dependencies",
-        keys.length, dependencies.size());
+    assertEquals(
+        "There should be " + keys.length + " dependencies", keys.length, dependencies.size());
 
     for (Key<?> key : keys) {
       assertTrue("Dependencies should contain " + key, dependencies.contains(key));
@@ -140,28 +133,45 @@
   }
 
   private static class A {}
+
   private static class B {}
+
   private static class C {}
+
   private static class D {}
+
   private static class E {}
+
   private static class F {}
+
   private static class G {}
-  
+
   private static interface Interface {}
-  
+
   private static class ConstructedClass implements Interface {
     @Inject A a;
+
     ConstructedClass() {}
-    @Inject ConstructedClass(B b, C c) {}
-    @Inject void setD(D d) {}
+
+    @Inject
+    ConstructedClass(B b, C c) {}
+
+    @Inject
+    void setD(D d) {}
   }
 
   private static class ConstructedClassProvider implements Provider<ConstructedClass> {
     @Inject E e;
+
     ConstructedClassProvider() {}
-    @Inject ConstructedClassProvider(A a, B b, C c) {}
-    @Inject void setF(F f) {}
-    
+
+    @Inject
+    ConstructedClassProvider(A a, B b, C c) {}
+
+    @Inject
+    void setF(F f) {}
+
+    @Override
     public ConstructedClass get() {
       return null;
     }
@@ -170,7 +180,8 @@
   private static class HasDependenciesClass implements Interface, HasDependencies {
     @Inject A a;
     @Inject B b;
-    
+
+    @Override
     public Set<Dependency<?>> getDependencies() {
       return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(G.class)));
     }
@@ -196,7 +207,7 @@
       bind(Interface.class).to(ConstructedClass.class);
     }
   }
-  
+
   private static class ProviderInstanceModule extends AbstractModule {
     @Override
     protected void configure() {
@@ -210,7 +221,7 @@
       bind(Interface.class).toInstance(new HasDependenciesClass());
     }
   }
-  
+
   private static class ProviderKeyModule extends AbstractModule {
     @Override
     protected void configure() {
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/AssistedInjectModule.java b/extensions/grapher/test/com/google/inject/grapher/demo/AssistedInjectModule.java
index 95a83c1..d836503 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/AssistedInjectModule.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/AssistedInjectModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,16 +20,16 @@
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 
 /**
- * Module to add {@link AssistedInject}-based elements to the demo
- * {@link Injector}.
+ * Module to add {@link AssistedInject}-based elements to the demo {@link Injector}.
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class AssistedInjectModule extends AbstractModule {
   @Override
   protected void configure() {
-    install(new FactoryModuleBuilder()
-        .implement(DanceParty.class, DancePartyImpl.class)
-        .build(DancePartyFactory.class));
+    install(
+        new FactoryModuleBuilder()
+            .implement(DanceParty.class, DancePartyImpl.class)
+            .build(DancePartyFactory.class));
   }
 }
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/BackToTheFutureModule.java b/extensions/grapher/test/com/google/inject/grapher/demo/BackToTheFutureModule.java
index f594169..a2b4dba 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/BackToTheFutureModule.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/BackToTheFutureModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,11 +21,10 @@
 import com.google.inject.name.Names;
 
 /**
- * Module that adds a variety of different kinds of {@link Bindings} to be used
- * to generate a comprehensive sample graph.
- * 
- * @see InjectorGrapherDemo
+ * Module that adds a variety of different kinds of {@link Bindings} to be used to generate a
+ * comprehensive sample graph.
  *
+ * @see InjectorGrapherDemo
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class BackToTheFutureModule extends AbstractModule {
@@ -41,12 +40,12 @@
 
     bind(Person.class).annotatedWith(Driver.class).to(MartyMcFly.class).in(Singleton.class);
     bind(Person.class).annotatedWith(Inventor.class).to(DocBrown.class).in(Singleton.class);
-    
+
     bindConstant().annotatedWith(Names.named("year")).to("1955");
   }
-  
+
   @Provides
   public FluxCapacitor provideFluxCapacitor(EnergySource energySource) {
     return null;
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/DanceParty.java b/extensions/grapher/test/com/google/inject/grapher/demo/DanceParty.java
index 930cd5f..62facb5 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/DanceParty.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/DanceParty.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyFactory.java b/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyFactory.java
index b131566..48882a4 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyFactory.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyImpl.java b/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyImpl.java
index 14185ec..bb47f69 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyImpl.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/DancePartyImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/DeLorian.java b/extensions/grapher/test/com/google/inject/grapher/demo/DeLorian.java
index cf3537e..729c601 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/DeLorian.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/DeLorian.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,11 +21,11 @@
 
 class DeLorian {
   // We @Inject a Provider to demonstrate that the graph doesn't differentiate
-  // between a Provider<T> and just @Injecting T. 
+  // between a Provider<T> and just @Injecting T.
   @Inject @Driver Provider<Person> driver;
   @Inject FluxCapacitor fluxCapacitor;
   @Inject PrivateTestModule.Exposed exposed;
-  
+
   @Inject
   public void setEnergySource(EnergySource energySource) {}
 }
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/DocBrown.java b/extensions/grapher/test/com/google/inject/grapher/demo/DocBrown.java
index 31c9678..74a6058 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/DocBrown.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/DocBrown.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Driver.java b/extensions/grapher/test/com/google/inject/grapher/demo/Driver.java
index 1187c68..fc38d48 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Driver.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Driver.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
-@interface Driver {}
\ No newline at end of file
+@interface Driver {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/EnergySource.java b/extensions/grapher/test/com/google/inject/grapher/demo/EnergySource.java
index 47c1f01..4149a31 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/EnergySource.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/EnergySource.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,4 +19,4 @@
 import com.google.inject.ProvidedBy;
 
 @ProvidedBy(EnergySourceProvider.class)
-interface EnergySource {}
\ No newline at end of file
+interface EnergySource {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/EnergySourceProvider.java b/extensions/grapher/test/com/google/inject/grapher/demo/EnergySourceProvider.java
index 7e8f3ca..5858aeb 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/EnergySourceProvider.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/EnergySourceProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,11 +21,14 @@
 import com.google.inject.name.Named;
 
 class EnergySourceProvider implements Provider<EnergySource> {
-  @Inject void setSources(@Nuclear EnergySource nuclear, @Renewable EnergySource renewable) {}
-  
+  @Inject
+  void setSources(@Nuclear EnergySource nuclear, @Renewable EnergySource renewable) {}
+
   // This will demonstrate a ConvertedConstantBinding.
-  @Inject void setYear(@Named("year") int year) {}
-  
+  @Inject
+  void setYear(@Named("year") int year) {}
+
+  @Override
   public EnergySource get() {
     return null;
   }
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/FluxCapacitor.java b/extensions/grapher/test/com/google/inject/grapher/demo/FluxCapacitor.java
index 8dce4cd..f31b336 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/FluxCapacitor.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/FluxCapacitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +16,4 @@
 
 package com.google.inject.grapher.demo;
 
-class FluxCapacitor {}
\ No newline at end of file
+class FluxCapacitor {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/InjectorGrapherDemo.java b/extensions/grapher/test/com/google/inject/grapher/demo/InjectorGrapherDemo.java
index 1e36dd5..74e3234 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/InjectorGrapherDemo.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/InjectorGrapherDemo.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,22 +21,24 @@
 import com.google.inject.Stage;
 import com.google.inject.grapher.graphviz.GraphvizGrapher;
 import com.google.inject.grapher.graphviz.GraphvizModule;
-
 import java.io.File;
 import java.io.PrintWriter;
 
 /**
- * Application that instantiates {@link BackToTheFutureModule} and graphs it,
- * writing the output to a DOT-formatted file (filename specified on the
- * command line).
+ * Application that instantiates {@link BackToTheFutureModule} and graphs it, writing the output to
+ * a DOT-formatted file (filename specified on the command line).
  *
  * @author phopkins@gmail.com (Pete Hopkins)
  */
 public class InjectorGrapherDemo {
   public static void main(String[] args) throws Exception {
     // TODO(phopkins): Switch to Stage.TOOL when issue 297 is fixed.
-    Injector demoInjector = Guice.createInjector(Stage.DEVELOPMENT,
-        new BackToTheFutureModule(), new MultibinderModule(), new PrivateTestModule());
+    Injector demoInjector =
+        Guice.createInjector(
+            Stage.DEVELOPMENT,
+            new BackToTheFutureModule(),
+            new MultibinderModule(),
+            new PrivateTestModule());
     PrintWriter out = new PrintWriter(new File(args[0]), "UTF-8");
 
     Injector injector = Guice.createInjector(new GraphvizModule());
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Inventor.java b/extensions/grapher/test/com/google/inject/grapher/demo/Inventor.java
index f9c8ab8..ab1ba6c 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Inventor.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Inventor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
-@interface Inventor {}
\ No newline at end of file
+@interface Inventor {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Lightning.java b/extensions/grapher/test/com/google/inject/grapher/demo/Lightning.java
index 6df5539..98f2e67 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Lightning.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Lightning.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,5 +20,7 @@
 import com.google.inject.name.Named;
 
 class Lightning implements EnergySource {
-  @Inject @Named("year") String yearOfStrike;
-}
\ No newline at end of file
+  @Inject
+  @Named("year")
+  String yearOfStrike;
+}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/MartyMcFly.java b/extensions/grapher/test/com/google/inject/grapher/demo/MartyMcFly.java
index 96a8510..bf9720e 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/MartyMcFly.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/MartyMcFly.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +16,4 @@
 
 package com.google.inject.grapher.demo;
 
-class MartyMcFly implements Person {}
\ No newline at end of file
+class MartyMcFly implements Person {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/MultibinderModule.java b/extensions/grapher/test/com/google/inject/grapher/demo/MultibinderModule.java
index bf8f7ec..c5ffcfe 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/MultibinderModule.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/MultibinderModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Nuclear.java b/extensions/grapher/test/com/google/inject/grapher/demo/Nuclear.java
index e273dd6..d470718 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Nuclear.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Nuclear.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
-@interface Nuclear {}
\ No newline at end of file
+@interface Nuclear {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Person.java b/extensions/grapher/test/com/google/inject/grapher/demo/Person.java
index 60a38dc..47a09f9 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Person.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Person.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +16,4 @@
 
 package com.google.inject.grapher.demo;
 
-interface Person {}
\ No newline at end of file
+interface Person {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/PinballParts.java b/extensions/grapher/test/com/google/inject/grapher/demo/PinballParts.java
index 9ad9745..2ddfe1a 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/PinballParts.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/PinballParts.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Plutonium.java b/extensions/grapher/test/com/google/inject/grapher/demo/Plutonium.java
index 6594324..d2a4772 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Plutonium.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Plutonium.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +16,4 @@
 
 package com.google.inject.grapher.demo;
 
-class Plutonium implements EnergySource {}
\ No newline at end of file
+class Plutonium implements EnergySource {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/PlutoniumProvider.java b/extensions/grapher/test/com/google/inject/grapher/demo/PlutoniumProvider.java
index 3b8600a..ba8c18d 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/PlutoniumProvider.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/PlutoniumProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,8 +20,10 @@
 import com.google.inject.Provider;
 
 class PlutoniumProvider implements Provider<Plutonium> {
-  @Inject public PlutoniumProvider(@Inventor Person inventor, @Used PinballParts parts) {}
+  @Inject
+  public PlutoniumProvider(@Inventor Person inventor, @Used PinballParts parts) {}
 
+  @Override
   public Plutonium get() {
     return null;
   }
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/PrivateTestModule.java b/extensions/grapher/test/com/google/inject/grapher/demo/PrivateTestModule.java
index 7619897..def1bfc 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/PrivateTestModule.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/PrivateTestModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,9 +25,11 @@
  */
 public class PrivateTestModule extends PrivateModule {
   interface Exposed {}
+
   static class Hidden implements Exposed {}
 
-  @Override protected void configure() {
+  @Override
+  protected void configure() {
     bind(Exposed.class).to(Hidden.class);
     expose(Exposed.class);
   }
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Renewable.java b/extensions/grapher/test/com/google/inject/grapher/demo/Renewable.java
index d97a78c..b212c27 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Renewable.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Renewable.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
-@interface Renewable {}
\ No newline at end of file
+@interface Renewable {}
diff --git a/extensions/grapher/test/com/google/inject/grapher/demo/Used.java b/extensions/grapher/test/com/google/inject/grapher/demo/Used.java
index d103505..aa897c8 100644
--- a/extensions/grapher/test/com/google/inject/grapher/demo/Used.java
+++ b/extensions/grapher/test/com/google/inject/grapher/demo/Used.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
-@interface Used {}
\ No newline at end of file
+@interface Used {}
diff --git a/extensions/jmx/pom.xml b/extensions/jmx/pom.xml
index b7f9d90..f6fdd65 100644
--- a/extensions/jmx/pom.xml
+++ b/extensions/jmx/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-jmx</artifactId>
@@ -21,6 +21,17 @@
           <skip>true</skip> <!-- Test is not actually a unit test. -->
         </configuration>
       </plugin>
+
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.jmx</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBinding.java b/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBinding.java
index 798b8f9..b0fd5bf 100644
--- a/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBinding.java
+++ b/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,14 +26,17 @@
     this.binding = binding;
   }
 
+  @Override
   public String getSource() {
     return binding.getSource().toString();
   }
 
+  @Override
   public String getKey() {
     return binding.getKey().toString();
   }
 
+  @Override
   public String getProvider() {
     return binding.getProvider().toString();
   }
diff --git a/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBindingMBean.java b/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBindingMBean.java
index 6f9469a..31c2129 100644
--- a/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBindingMBean.java
+++ b/extensions/jmx/src/com/google/inject/tools/jmx/ManagedBindingMBean.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,18 +23,12 @@
  */
 public interface ManagedBindingMBean {
 
-  /**
-   * Gets the source of this binding.
-   */
+  /** Gets the source of this binding. */
   String getSource();
 
-  /**
-   * Gets the provider to which this binding is bound.
-   */
+  /** Gets the provider to which this binding is bound. */
   String getProvider();
 
-  /**
-   * Gets the binding key.
-   */
+  /** Gets the binding key. */
   String getKey();
 }
diff --git a/extensions/jmx/src/com/google/inject/tools/jmx/Manager.java b/extensions/jmx/src/com/google/inject/tools/jmx/Manager.java
index 03cbdb8..c360bec 100644
--- a/extensions/jmx/src/com/google/inject/tools/jmx/Manager.java
+++ b/extensions/jmx/src/com/google/inject/tools/jmx/Manager.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,10 +21,8 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
-
 import java.lang.annotation.Annotation;
 import java.lang.management.ManagementFactory;
-
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
@@ -37,21 +35,18 @@
 public class Manager {
 
   /**
-   * Registers all the bindings of an Injector with the platform MBean server.
-   * Consider using the name of your root {@link Module} class as the domain.
+   * Registers all the bindings of an Injector with the platform MBean server. Consider using the
+   * name of your root {@link Module} class as the domain.
    */
-  public static void manage(
-      String domain,
-      Injector injector) {
+  public static void manage(String domain, Injector injector) {
     manage(ManagementFactory.getPlatformMBeanServer(), domain, injector);
   }
 
   /**
-   * Registers all the bindings of an Injector with the given MBean server.
-   * Consider using the name of your root {@link Module} class as the domain.
+   * Registers all the bindings of an Injector with the given MBean server. Consider using the name
+   * of your root {@link Module} class as the domain.
    */
-  public static void manage(MBeanServer server, String domain,
-      Injector injector) {
+  public static void manage(MBeanServer server, String domain, Injector injector) {
     // Register each binding independently.
     for (Binding<?> binding : injector.getBindings().values()) {
       // Construct the name manually so we can ensure proper ordering of the
@@ -63,23 +58,18 @@
       Annotation annotation = key.getAnnotation();
       if (annotation != null) {
         name.append(",annotation=").append(quote(annotation.toString()));
-      }
-      else {
+      } else {
         Class<? extends Annotation> annotationType = key.getAnnotationType();
         if (annotationType != null) {
-          name.append(",annotation=")
-              .append(quote("@" + annotationType.getName()));
+          name.append(",annotation=").append(quote("@" + annotationType.getName()));
         }
       }
 
       try {
-        server.registerMBean(new ManagedBinding(binding),
-            new ObjectName(name.toString()));
-      }
-      catch (MalformedObjectNameException e) {
+        server.registerMBean(new ManagedBinding(binding), new ObjectName(name.toString()));
+      } catch (MalformedObjectNameException e) {
         throw new RuntimeException("Bad object name: " + name, e);
-      }
-      catch (Exception e) {
+      } catch (Exception e) {
         throw new RuntimeException(e);
       }
     }
@@ -90,13 +80,13 @@
     return ObjectName.quote(value).replace(',', ';');
   }
 
-  /**
-   * Run with no arguments for usage instructions.
-   */
+  /** Run with no arguments for usage instructions. */
   public static void main(String[] args) throws Exception {
     if (args.length != 1) {
-      System.err.println("Usage: java -Dcom.sun.management.jmxremote "
-          + Manager.class.getName() + " [module class name]");
+      System.err.println(
+          "Usage: java -Dcom.sun.management.jmxremote "
+              + Manager.class.getName()
+              + " [module class name]");
       System.err.println("Then run 'jconsole' to connect.");
       System.exit(1);
     }
diff --git a/extensions/jmx/src/com/google/inject/tools/jmx/package-info.java b/extensions/jmx/src/com/google/inject/tools/jmx/package-info.java
index e21f864..137e9f6 100644
--- a/extensions/jmx/src/com/google/inject/tools/jmx/package-info.java
+++ b/extensions/jmx/src/com/google/inject/tools/jmx/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * JMX integration; this extension requires {@code guice-jmx.jar}.
- */
+/** JMX integration; this extension requires {@code guice-jmx.jar}. */
 package com.google.inject.tools.jmx;
diff --git a/extensions/jmx/test/com/google/inject/tools/jmx/JmxTest.java b/extensions/jmx/test/com/google/inject/tools/jmx/JmxTest.java
index bb10f95..bf09e60 100644
--- a/extensions/jmx/test/com/google/inject/tools/jmx/JmxTest.java
+++ b/extensions/jmx/test/com/google/inject/tools/jmx/JmxTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,12 +23,9 @@
 import com.google.inject.Key;
 import com.google.inject.Singleton;
 import com.google.inject.name.Names;
-
 import java.lang.annotation.Retention;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class JmxTest {
 
   interface Foo {}
@@ -40,24 +37,24 @@
 
   static class Bar {}
 
-  @BindingAnnotation @Retention(RUNTIME)
+  @BindingAnnotation
+  @Retention(RUNTIME)
   @interface Transactional {}
 
   public static void main(String[] args) throws Exception {
-    Manager.main(new String[] { TestModule.class.getName() });
+    Manager.main(new String[] {TestModule.class.getName()});
   }
-  
+
   public static class TestModule extends AbstractModule {
 
+    @Override
     protected void configure() {
       bind(Foo.class).to(FooImpl.class);
       bind(Bar.class);
-      bind(Foo.class)
-          .annotatedWith(Transactional.class)
-          .to(FooImpl.class);
+      bind(Foo.class).annotatedWith(Transactional.class).to(FooImpl.class);
       bindConstant().annotatedWith(Names.named("port")).to(8080);
       bind(Key.get(Object.class)).to(Key.get(Bar.class));
-//      install(new ServletModule());
+      //      install(new ServletModule());
     }
   }
 }
diff --git a/extensions/jndi/pom.xml b/extensions/jndi/pom.xml
index 1eb2a18..d67ea15 100644
--- a/extensions/jndi/pom.xml
+++ b/extensions/jndi/pom.xml
@@ -6,11 +6,25 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-jndi</artifactId>
 
   <name>Google Guice - Extensions - JNDI</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.jndi</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/jndi/src/com/google/inject/jndi/JndiIntegration.java b/extensions/jndi/src/com/google/inject/jndi/JndiIntegration.java
index 7907841..31b7fd7 100644
--- a/extensions/jndi/src/com/google/inject/jndi/JndiIntegration.java
+++ b/extensions/jndi/src/com/google/inject/jndi/JndiIntegration.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,13 +18,11 @@
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
 import javax.naming.Context;
 import javax.naming.NamingException;
 
 /**
- * Integrates Guice with JNDI. Requires a binding to 
- * {@link javax.naming.Context}.
+ * Integrates Guice with JNDI. Requires a binding to {@link javax.naming.Context}.
  *
  * @author crazybob@google.com (Bob Lee)
  */
@@ -33,8 +31,7 @@
   private JndiIntegration() {}
 
   /**
-   * Creates a provider which looks up objects in JNDI using the given name.
-   * Example usage:
+   * Creates a provider which looks up objects in JNDI using the given name. Example usage:
    *
    * <pre>
    * bind(DataSource.class).toProvider(fromJndi(DataSource.class, "java:..."));
@@ -55,11 +52,11 @@
       this.name = name;
     }
 
+    @Override
     public T get() {
       try {
         return type.cast(context.lookup(name));
-      }
-      catch (NamingException e) {
+      } catch (NamingException e) {
         throw new RuntimeException(e);
       }
     }
diff --git a/extensions/jndi/src/com/google/inject/jndi/package-info.java b/extensions/jndi/src/com/google/inject/jndi/package-info.java
index f2f0af4..56df3a3 100644
--- a/extensions/jndi/src/com/google/inject/jndi/package-info.java
+++ b/extensions/jndi/src/com/google/inject/jndi/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * JNDI integration; this extension requires {@code guice-jndi.jar}.
- */
+/** JNDI integration; this extension requires {@code guice-jndi.jar}. */
 package com.google.inject.jndi;
diff --git a/extensions/mini/pom.xml b/extensions/mini/pom.xml
index fdaa91d..ea4746d 100644
--- a/extensions/mini/pom.xml
+++ b/extensions/mini/pom.xml
@@ -13,4 +13,18 @@
 
   <name>Google Guice - Extensions - Mini</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.mini</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/mini/src/com/google/inject/mini/MiniGuice.java b/extensions/mini/src/com/google/inject/mini/MiniGuice.java
index 4dd242d..5f02ebc 100644
--- a/extensions/mini/src/com/google/inject/mini/MiniGuice.java
+++ b/extensions/mini/src/com/google/inject/mini/MiniGuice.java
@@ -32,7 +32,6 @@
 import java.util.Map;
 import java.util.Queue;
 import java.util.Set;
-
 import javax.inject.Provider;
 
 /**
@@ -43,34 +42,33 @@
  */
 public final class MiniGuice {
   private static final Object UNINITIALIZED = new Object();
+
   private MiniGuice() {}
 
-  private final Map<Key, Provider<?>> bindings = new HashMap<Key, Provider<?>>();
-  private final Queue<RequiredKey> requiredKeys = new ArrayDeque<RequiredKey>();
-  private final Set<Key> singletons = new HashSet<Key>();
+  private final Map<Key, Provider<?>> bindings = new HashMap<>();
+  private final Queue<RequiredKey> requiredKeys = new ArrayDeque<>();
+  private final Set<Key> singletons = new HashSet<>();
 
   /**
-   * Creates an injector defined by {@code modules} and immediately uses it to
-   * create an instance of {@code type}. The modules can be of any type, and
-   * must contain {@code @Provides} methods.
+   * Creates an injector defined by {@code modules} and immediately uses it to create an instance of
+   * {@code type}. The modules can be of any type, and must contain {@code @Provides} methods.
    *
    * <p>The following injection features are supported:
+   *
    * <ul>
-   *   <li>Field injection. A class may have any number of field injections, and
-   *       fields may be of any visibility. Static fields will be injected each
-   *       time an instance is injected.
-   *   <li>Constructor injection. A class may have a single {@code
-   *       @Inject}-annotated constructor. Classes that have fields injected
-   *       may omit the {@link @Inject} annotation if they have a public
-   *       no-arguments constructor.
-   *   <li>Injection of {@code @Provides} method parameters.
-   *   <li>{@code @Provides} methods annotated {@code @Singleton}.
-   *   <li>Constructor-injected classes annotated {@code @Singleton}.
-   *   <li>Injection of {@link Provider}s.
-   *   <li>Binding annotations on injected parameters and fields.
-   *   <li>Guice annotations.
-   *   <li>JSR 330 annotations.
-   *   <li>Eager loading of singletons.
+   * <li>Field injection. A class may have any number of field injections, and fields may be of any
+   *     visibility. Static fields will be injected each time an instance is injected.
+   * <li>Constructor injection. A class may have a single {@code @Inject}-annotated constructor.
+   *     Classes that have fields injected may omit the {@link @Inject} annotation if they have a
+   *     public no-arguments constructor.
+   * <li>Injection of {@code @Provides} method parameters.
+   * <li>{@code @Provides} methods annotated {@code @Singleton}.
+   * <li>Constructor-injected classes annotated {@code @Singleton}.
+   * <li>Injection of {@link Provider}s.
+   * <li>Binding annotations on injected parameters and fields.
+   * <li>Guice annotations.
+   * <li>JSR 330 annotations.
+   * <li>Eager loading of singletons.
    * </ul>
    *
    * <p><strong>Note that method injection is not supported.</strong>
@@ -90,17 +88,20 @@
   }
 
   private void addProviderBindings() {
-    Map<Key, Provider<?>> providerBindings = new HashMap<Key, Provider<?>>();
+    Map<Key, Provider<?>> providerBindings = new HashMap<>();
     for (final Map.Entry<Key, Provider<?>> binding : bindings.entrySet()) {
       Key key = binding.getKey();
       final Provider<?> value = binding.getValue();
-      Provider<Provider<?>> providerProvider = new Provider<Provider<?>>() {
-        public Provider<?> get() {
-          return value;
-        }
-      };
-      providerBindings.put(new Key(new ProviderType(javax.inject.Provider.class, key.type),
-          key.annotation), providerProvider);
+      Provider<Provider<?>> providerProvider =
+          new Provider<Provider<?>>() {
+            @Override
+            public Provider<?> get() {
+              return value;
+            }
+          };
+      providerBindings.put(
+          new Key(new ProviderType(javax.inject.Provider.class, key.type), key.annotation),
+          providerProvider);
     }
     bindings.putAll(providerBindings);
   }
@@ -108,7 +109,7 @@
   private void requireKey(Key key, Object requiredBy) {
     if (key.type instanceof ParameterizedType
         && (((ParameterizedType) key.type).getRawType() == Provider.class
-        || ((ParameterizedType) key.type).getRawType() == javax.inject.Provider.class)) {
+            || ((ParameterizedType) key.type).getRawType() == javax.inject.Provider.class)) {
       Type type = ((ParameterizedType) key.type).getActualTypeArguments()[0];
       key = new Key(type, key.annotation);
     }
@@ -120,11 +121,14 @@
     for (Key key : singletons) {
       Provider<?> provider = bindings.get(key);
       final Object onlyInstance = provider.get();
-      bindings.put(key, new Provider<Object>() {
-        public Object get() {
-          return onlyInstance;
-        }
-      });
+      bindings.put(
+          key,
+          new Provider<Object>() {
+            @Override
+            public Object get() {
+              return onlyInstance;
+            }
+          });
     }
   }
 
@@ -145,21 +149,24 @@
   }
 
   private void addProviderMethodBinding(Key key, final Object instance, final Method method) {
-    final Key[] parameterKeys = parametersToKeys(
-        method, method.getGenericParameterTypes(), method.getParameterAnnotations());
+    final Key[] parameterKeys =
+        parametersToKeys(
+            method, method.getGenericParameterTypes(), method.getParameterAnnotations());
     method.setAccessible(true);
-    final Provider<Object> unscoped = new Provider<Object>() {
-      public Object get() {
-        Object[] parameters = keysToValues(parameterKeys);
-        try {
-          return method.invoke(instance, parameters);
-        } catch (IllegalAccessException e) {
-          throw new RuntimeException(e);
-        } catch (InvocationTargetException e) {
-          throw new RuntimeException(e.getCause());
-        }
-      }
-    };
+    final Provider<Object> unscoped =
+        new Provider<Object>() {
+          @Override
+          public Object get() {
+            Object[] parameters = keysToValues(parameterKeys);
+            try {
+              return method.invoke(instance, parameters);
+            } catch (IllegalAccessException e) {
+              throw new RuntimeException(e);
+            } catch (InvocationTargetException e) {
+              throw new RuntimeException(e.getCause());
+            }
+          }
+        };
 
     boolean singleton = method.isAnnotationPresent(javax.inject.Singleton.class);
     putBinding(key, unscoped, singleton);
@@ -185,8 +192,8 @@
     /*
      * Lookup the injectable fields and their corresponding keys.
      */
-    final List<Field> injectedFields = new ArrayList<Field>();
-    List<Object> fieldKeysList = new ArrayList<Object>();
+    final List<Field> injectedFields = new ArrayList<>();
+    List<Object> fieldKeysList = new ArrayList<>();
     for (Class<?> c = type; c != Object.class; c = c.getSuperclass()) {
       for (Field field : c.getDeclaredFields()) {
         if (!field.isAnnotationPresent(javax.inject.Inject.class)) {
@@ -218,14 +225,14 @@
     }
     if (injectedConstructor == null) {
       if (fieldKeys.length == 0) {
-        throw new IllegalArgumentException("No injectable constructor on "
-            + type + " required by " + requiredBy);
+        throw new IllegalArgumentException(
+            "No injectable constructor on " + type + " required by " + requiredBy);
       }
       try {
         injectedConstructor = type.getConstructor();
       } catch (NoSuchMethodException e) {
-        throw new IllegalArgumentException("No injectable constructor on "
-            + type + " required by " + requiredBy);
+        throw new IllegalArgumentException(
+            "No injectable constructor on " + type + " required by " + requiredBy);
       }
     }
 
@@ -233,27 +240,32 @@
      * Create a provider that invokes the constructor and sets its fields.
      */
     final Constructor<?> constructor = injectedConstructor;
-    final Key[] parameterKeys = parametersToKeys(
-        constructor, constructor.getGenericParameterTypes(), constructor.getParameterAnnotations());
-    final Provider<Object> unscoped = new Provider<Object>() {
-      public Object get() {
-        Object[] constructorParameters = keysToValues(parameterKeys);
-        try {
-          Object result = constructor.newInstance(constructorParameters);
-          Object[] fieldValues = keysToValues(fieldKeys);
-          for (int i = 0; i < fieldValues.length; i++) {
-            injectedFields.get(i).set(result, fieldValues[i]);
+    final Key[] parameterKeys =
+        parametersToKeys(
+            constructor,
+            constructor.getGenericParameterTypes(),
+            constructor.getParameterAnnotations());
+    final Provider<Object> unscoped =
+        new Provider<Object>() {
+          @Override
+          public Object get() {
+            Object[] constructorParameters = keysToValues(parameterKeys);
+            try {
+              Object result = constructor.newInstance(constructorParameters);
+              Object[] fieldValues = keysToValues(fieldKeys);
+              for (int i = 0; i < fieldValues.length; i++) {
+                injectedFields.get(i).set(result, fieldValues[i]);
+              }
+              return result;
+            } catch (IllegalAccessException e) {
+              throw new RuntimeException(e.getCause());
+            } catch (InvocationTargetException e) {
+              throw new RuntimeException(e.getCause());
+            } catch (InstantiationException e) {
+              throw new RuntimeException(e);
+            }
           }
-          return result;
-        } catch (IllegalAccessException e) {
-          throw new RuntimeException(e.getCause());
-        } catch (InvocationTargetException e) {
-          throw new RuntimeException(e.getCause());
-        } catch (InstantiationException e) {
-          throw new RuntimeException(e);
-        }
-      }
-    };
+        };
 
     boolean singleton = type.isAnnotationPresent(javax.inject.Singleton.class);
     putBinding(new Key(type, null), unscoped, singleton);
@@ -263,15 +275,18 @@
     if (singleton) {
       singletons.add(key);
       final Provider<Object> unscoped = provider;
-      provider = new Provider<Object>() {
-        private Object onlyInstance = UNINITIALIZED;
-        public Object get() {
-          if (onlyInstance == UNINITIALIZED) {
-            onlyInstance = unscoped.get();
-          }
-          return onlyInstance;
-        }
-      };
+      provider =
+          new Provider<Object>() {
+            private Object onlyInstance = UNINITIALIZED;
+
+            @Override
+            public Object get() {
+              if (onlyInstance == UNINITIALIZED) {
+                onlyInstance = unscoped.get();
+              }
+              return onlyInstance;
+            }
+          };
     }
 
     if (bindings.put(key, provider) != null) {
@@ -324,13 +339,15 @@
       this.annotation = annotation;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
       return o instanceof Key
           && ((Key) o).type.equals(type)
           && equal(annotation, ((Key) o).annotation);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       int result = type.hashCode();
       if (annotation != null) {
         result += (37 * annotation.hashCode());
@@ -338,12 +355,13 @@
       return result;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
       return "key[type=" + type + ",annotation=" + annotation + "]";
     }
   }
 
-  private class RequiredKey {
+  private static class RequiredKey {
     private final Key key;
     private final Object requiredBy;
 
@@ -362,19 +380,23 @@
       this.typeArgument = typeArgument;
     }
 
+    @Override
     public Type getRawType() {
       return rawType;
     }
 
+    @Override
     public Type[] getActualTypeArguments() {
-      return new Type[] { typeArgument };
+      return new Type[] {typeArgument};
     }
 
+    @Override
     public Type getOwnerType() {
       return null;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
       if (o instanceof ParameterizedType) {
         ParameterizedType that = (ParameterizedType) o;
         return Arrays.equals(getActualTypeArguments(), that.getActualTypeArguments())
@@ -383,7 +405,8 @@
       return false;
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
       return Arrays.hashCode(getActualTypeArguments()) ^ rawType.hashCode();
     }
   }
diff --git a/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java b/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
index e6df593..9ded45f 100644
--- a/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
+++ b/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
@@ -16,28 +16,32 @@
 package com.google.inject.mini;
 
 import com.google.inject.Provides;
-
-import junit.framework.TestCase;
-
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
-
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
+import junit.framework.TestCase;
 
+@SuppressWarnings("ProvidesMethodOutsideOfModule")
 public final class MiniGuiceTest extends TestCase {
 
   public void testBasicInjection() {
-    G g = MiniGuice.inject(G.class, new Object() {
-      @Provides E provideE(F f) {
-        return new E(f);
-      }
-      @Provides F provideF() {
-        return new F();
-      }
-    });
+    G g =
+        MiniGuice.inject(
+            G.class,
+            new Object() {
+              @Provides
+              E provideE(F f) {
+                return new E(f);
+              }
+
+              @Provides
+              F provideF() {
+                return new F();
+              }
+            });
 
     assertNotNull(g.a);
     assertNotNull(g.b);
@@ -48,25 +52,30 @@
   }
 
   static class A {
-    @Inject A() {}
+    @Inject
+    A() {}
   }
 
   static class B {
-    @Inject B() {}
+    @Inject
+    B() {}
   }
 
   @Singleton
   static class C {
-    @Inject C() {}
+    @Inject
+    C() {}
   }
 
   @Singleton
   static class D {
-    @Inject D() {}
+    @Inject
+    D() {}
   }
 
   static class E {
     F f;
+
     E(F f) {
       this.f = f;
     }
@@ -80,12 +89,14 @@
     C c;
     D d;
     @Inject E e;
-    @Inject G(C c, D d) {
+
+    @Inject
+    G(C c, D d) {
       this.c = c;
       this.d = d;
     }
   }
-  
+
   public void testProviderInjection() {
     H h = MiniGuice.inject(H.class);
     assertNotNull(h.aProvider.get());
@@ -95,42 +106,60 @@
 
   static class H {
     @Inject Provider<A> aProvider;
-    @Inject H() {}
+
+    @Inject
+    H() {}
   }
-  
+
   public void testSingletons() {
-    J j = MiniGuice.inject(J.class, new Object() {
-      @Provides @Singleton F provideK() {
-        return new F();
-      }
-    });
+    J j =
+        MiniGuice.inject(
+            J.class,
+            new Object() {
+              @Provides
+              @Singleton
+              F provideK() {
+                return new F();
+              }
+            });
     assertSame(j.fProvider.get(), j.fProvider.get());
     assertSame(j.iProvider.get(), j.iProvider.get());
   }
 
   @Singleton
   static class I {
-    @Inject I() {}
+    @Inject
+    I() {}
   }
 
   static class J {
     @Inject Provider<F> fProvider;
     @Inject Provider<I> iProvider;
-    @Inject J() {}
+
+    @Inject
+    J() {}
   }
 
   public void testBindingAnnotations() {
     final A one = new A();
     final A two = new A();
 
-    K k = MiniGuice.inject(K.class, new Object() {
-      @Provides @Named("one") A getOne() {
-        return one;
-      }
-      @Provides @Named("two") A getTwo() {
-        return two;
-      }
-    });
+    K k =
+        MiniGuice.inject(
+            K.class,
+            new Object() {
+              @Provides
+              @Named("one")
+              A getOne() {
+                return one;
+              }
+
+              @Provides
+              @Named("two")
+              A getTwo() {
+                return two;
+              }
+            });
 
     assertNotNull(k.a);
     assertSame(one, k.aOne);
@@ -139,21 +168,33 @@
 
   public static class K {
     @Inject A a;
-    @Inject @Named("one") A aOne;
-    @Inject @Named("two") A aTwo;
-  }
-  
-  public void testSingletonBindingAnnotationAndProvider() {
-    final AtomicReference<A> a1 = new AtomicReference<A>();
-    final AtomicReference<A> a2 = new AtomicReference<A>();
 
-    L l = MiniGuice.inject(L.class, new Object() {
-      @Provides @Singleton @Named("one") F provideF(Provider<A> aProvider) {
-        a1.set(aProvider.get());
-        a2.set(aProvider.get());
-        return new F();
-      }
-    });
+    @Inject
+    @Named("one")
+    A aOne;
+
+    @Inject
+    @Named("two")
+    A aTwo;
+  }
+
+  public void testSingletonBindingAnnotationAndProvider() {
+    final AtomicReference<A> a1 = new AtomicReference<>();
+    final AtomicReference<A> a2 = new AtomicReference<>();
+
+    L l =
+        MiniGuice.inject(
+            L.class,
+            new Object() {
+              @Provides
+              @Singleton
+              @Named("one")
+              F provideF(Provider<A> aProvider) {
+                a1.set(aProvider.get());
+                a2.set(aProvider.get());
+                return new F();
+              }
+            });
 
     assertNotNull(a1.get());
     assertNotNull(a2.get());
@@ -163,16 +204,24 @@
 
   @Singleton
   public static class L {
-    @Inject @Named("one") F f;
+    @Inject
+    @Named("one")
+    F f;
+
     @Inject Provider<L> lProvider;
   }
 
   public void testSingletonInGraph() {
-    M m = MiniGuice.inject(M.class, new Object() {
-      @Provides @Singleton F provideF() {
-        return new F();
-      }
-    });
+    M m =
+        MiniGuice.inject(
+            M.class,
+            new Object() {
+              @Provides
+              @Singleton
+              F provideF() {
+                return new F();
+              }
+            });
 
     assertSame(m.f1, m.f2);
     assertSame(m.f1, m.n1.f1);
@@ -205,41 +254,53 @@
   }
 
   public static class O {
-    @Inject @Named("a") A a;
+    @Inject
+    @Named("a")
+    A a;
   }
 
   public void testSubclasses() {
-    Q q = MiniGuice.inject(Q.class, new Object() {
-      @Provides F provideF() {
-        return new F();
-      }
-    });
+    Q q =
+        MiniGuice.inject(
+            Q.class,
+            new Object() {
+              @Provides
+              F provideF() {
+                return new F();
+              }
+            });
 
     assertNotNull(q.f);
   }
-  
+
   public static class P {
     @Inject F f;
   }
 
   public static class Q extends P {
-    @Inject Q() {}
+    @Inject
+    Q() {}
   }
-  
+
   public void testSingletonsAreEager() {
     final AtomicBoolean sInjected = new AtomicBoolean();
 
     R.injected = false;
-    MiniGuice.inject(A.class, new Object() {
-      @Provides F provideF(R r) {
-        return new F();
-      }
+    MiniGuice.inject(
+        A.class,
+        new Object() {
+          @Provides
+          F provideF(R r) {
+            return new F();
+          }
 
-      @Provides @Singleton S provideS() {
-        sInjected.set(true);
-        return new S();
-      }
-    });
+          @Provides
+          @Singleton
+          S provideS() {
+            sInjected.set(true);
+            return new S();
+          }
+        });
 
     assertTrue(R.injected);
     assertTrue(sInjected.get());
@@ -248,7 +309,9 @@
   @Singleton
   static class R {
     static boolean injected = false;
-    @Inject R() {
+
+    @Inject
+    R() {
       injected = true;
     }
   }
diff --git a/extensions/multibindings/.gitignore b/extensions/multibindings/.gitignore
deleted file mode 100644
index 84c048a..0000000
--- a/extensions/multibindings/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build/
diff --git a/extensions/multibindings/build.properties b/extensions/multibindings/build.properties
deleted file mode 100644
index 77228a8..0000000
--- a/extensions/multibindings/build.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-lib.dir=../../lib
-src.dir=src
-test.dir=test
-build.dir=build
-test.class=com.google.inject.multibindings.AllTests
-module=com.google.inject.multibindings
-fragment=true
diff --git a/extensions/multibindings/build.xml b/extensions/multibindings/build.xml
deleted file mode 100644
index f78a8e3..0000000
--- a/extensions/multibindings/build.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-
-<project name="guice-multibindings" basedir="." default="jar">
-
-  <import file="../../common.xml"/>
-  
-  <path id="compile.classpath">
-    <fileset dir="${lib.dir}" includes="*.jar"/>
-    <fileset dir="${lib.dir}/build" includes="*.jar"/>
-    <pathelement path="../../build/classes"/>
-  </path>
-
-  <target name="jar" depends="compile, manifest" description="Build jar.">
-    <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-        manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes" />
-    </jar>
-  </target>
-
-</project>
diff --git a/extensions/multibindings/pom.xml b/extensions/multibindings/pom.xml
index 4f75b28..185be35 100644
--- a/extensions/multibindings/pom.xml
+++ b/extensions/multibindings/pom.xml
@@ -6,11 +6,50 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-multibindings</artifactId>
 
   <name>Google Guice - Extensions - MultiBindings</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.multibindings</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <!--
+         | Re-attach empty sources jar as javadoc to satisfy Maven Central requirements
+        -->
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
+        <executions>
+          <execution>
+            <id>reattach-sources-as-javadoc</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
+                  <classifier>javadoc</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/multibindings/src/README b/extensions/multibindings/src/README
new file mode 100644
index 0000000..2d3b189
--- /dev/null
+++ b/extensions/multibindings/src/README
@@ -0,0 +1,4 @@
+This extension intentionally has no files in it. The multibindings functionality
+is now part of Guice core.  This extension still exists in order to ease the
+transition.  A future release will delete this extension.  You can remove your
+dependency on multibindings to avoid problems after the extension is deleted.
\ No newline at end of file
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java b/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java
deleted file mode 100644
index 4edcf76..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * 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.google.inject.multibindings;
-
-import com.google.common.base.Objects;
-import com.google.inject.Binding;
-import com.google.inject.Injector;
-import com.google.inject.Scope;
-import com.google.inject.Scopes;
-import com.google.inject.TypeLiteral;
-import com.google.inject.spi.BindingScopingVisitor;
-import com.google.inject.spi.ConstructorBinding;
-import com.google.inject.spi.ConvertedConstantBinding;
-import com.google.inject.spi.DefaultBindingTargetVisitor;
-import com.google.inject.spi.ExposedBinding;
-import com.google.inject.spi.InstanceBinding;
-import com.google.inject.spi.LinkedKeyBinding;
-import com.google.inject.spi.ProviderBinding;
-import com.google.inject.spi.ProviderInstanceBinding;
-import com.google.inject.spi.ProviderKeyBinding;
-import com.google.inject.spi.UntargettedBinding;
-
-import java.lang.annotation.Annotation;
-
-/**
- * Visits bindings to return a {@code IndexedBinding} that can be used to emulate the binding
- * deduplication that Guice internally performs.
- */
-class Indexer extends DefaultBindingTargetVisitor<Object, Indexer.IndexedBinding>
-    implements BindingScopingVisitor<Object> {
-  enum BindingType {
-    INSTANCE,
-    PROVIDER_INSTANCE,
-    PROVIDER_KEY,
-    LINKED_KEY,
-    UNTARGETTED,
-    CONSTRUCTOR,
-    CONSTANT,
-    EXPOSED,
-    PROVIDED_BY,
-  }
-
-  static class IndexedBinding {
-    final String annotationName;
-    final Element.Type annotationType;
-    final TypeLiteral<?> typeLiteral;
-    final Object scope;
-    final BindingType type;
-    final Object extraEquality;
-
-    IndexedBinding(Binding<?> binding, BindingType type, Object scope, Object extraEquality) {
-      this.scope = scope;
-      this.type = type;
-      this.extraEquality = extraEquality;
-      this.typeLiteral = binding.getKey().getTypeLiteral();
-      Element annotation = (Element) binding.getKey().getAnnotation();
-      this.annotationName = annotation.setName();
-      this.annotationType = annotation.type();
-    }
-
-    @Override public boolean equals(Object obj) {
-      if (!(obj instanceof IndexedBinding)) {
-        return false;
-      }
-      IndexedBinding o = (IndexedBinding) obj;
-      return type == o.type
-          && Objects.equal(scope, o.scope)
-          && typeLiteral.equals(o.typeLiteral)
-          && annotationType == o.annotationType
-          && annotationName.equals(o.annotationName)
-          && Objects.equal(extraEquality, o.extraEquality);
-    }
-
-    @Override public int hashCode() {
-      return Objects.hashCode(type, scope, typeLiteral, annotationType, annotationName,
-          extraEquality);
-    }
-  }
-
-  final Injector injector;
-
-  Indexer(Injector injector) {
-    this.injector = injector;
-  }
-
-  boolean isIndexable(Binding<?> binding) {
-    return binding.getKey().getAnnotation() instanceof Element;
-  }
-
-  private Object scope(Binding<?> binding) {
-    return binding.acceptScopingVisitor(this);
-  }
-
-  @Override public Indexer.IndexedBinding visit(ConstructorBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.CONSTRUCTOR, scope(binding),
-        binding.getConstructor());
-  }
-
-  @Override public Indexer.IndexedBinding visit(
-      ConvertedConstantBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.CONSTANT, scope(binding),
-        binding.getValue());
-  }
-
-  @Override public Indexer.IndexedBinding visit(ExposedBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.EXPOSED, scope(binding), binding);
-  }
-
-  @Override public Indexer.IndexedBinding visit(InstanceBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.INSTANCE, scope(binding),
-        binding.getInstance());
-  }
-
-  @Override public Indexer.IndexedBinding visit(LinkedKeyBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.LINKED_KEY, scope(binding),
-        binding.getLinkedKey());
-  }
-
-  @Override public Indexer.IndexedBinding visit(ProviderBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.PROVIDED_BY, scope(binding),
-        injector.getBinding(binding.getProvidedKey()));
-  }
-
-  @Override public Indexer.IndexedBinding visit(ProviderInstanceBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.PROVIDER_INSTANCE, scope(binding),
-        binding.getUserSuppliedProvider());
-  }
-
-  @Override public Indexer.IndexedBinding visit(ProviderKeyBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.PROVIDER_KEY, scope(binding),
-        binding.getProviderKey());
-  }
-
-  @Override public Indexer.IndexedBinding visit(UntargettedBinding<? extends Object> binding) {
-    return new Indexer.IndexedBinding(binding, BindingType.UNTARGETTED, scope(binding), null);
-  }
-  
-  private static final Object EAGER_SINGLETON = new Object();
-  
-  @Override public Object visitEagerSingleton() {
-    return EAGER_SINGLETON;
-  }
-
-  @Override public Object visitNoScoping() {
-    return Scopes.NO_SCOPE;
-  }
-
-  @Override public Object visitScope(Scope scope) {
-    return scope;
-  }
-
-  @Override public Object visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
-    return scopeAnnotation;
-  }
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
deleted file mode 100644
index fc3d74f..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import static com.google.inject.multibindings.Element.Type.MAPBINDER;
-import static com.google.inject.multibindings.Multibinder.checkConfiguration;
-import static com.google.inject.multibindings.Multibinder.checkNotNull;
-import static com.google.inject.multibindings.Multibinder.setOf;
-import static com.google.inject.util.Types.newParameterizedType;
-import static com.google.inject.util.Types.newParameterizedTypeWithOwner;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Supplier;
-import com.google.common.collect.HashMultimap;
-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 com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import com.google.inject.Binder;
-import com.google.inject.Binding;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.internal.Errors;
-import com.google.inject.multibindings.Indexer.IndexedBinding;
-import com.google.inject.multibindings.Multibinder.RealMultibinder;
-import com.google.inject.spi.BindingTargetVisitor;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.Element;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.ProviderInstanceBinding;
-import com.google.inject.spi.ProviderLookup;
-import com.google.inject.spi.ProviderWithDependencies;
-import com.google.inject.spi.ProviderWithExtensionVisitor;
-import com.google.inject.spi.Toolable;
-import com.google.inject.util.Types;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * An API to bind multiple map entries separately, only to later inject them as
- * a complete map. MapBinder is intended for use in your application's module:
- * <pre><code>
- * public class SnacksModule extends AbstractModule {
- *   protected void configure() {
- *     MapBinder&lt;String, Snack&gt; mapbinder
- *         = MapBinder.newMapBinder(binder(), String.class, Snack.class);
- *     mapbinder.addBinding("twix").toInstance(new Twix());
- *     mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
- *     mapbinder.addBinding("skittles").to(Skittles.class);
- *   }
- * }</code></pre>
- *
- * <p>With this binding, a {@link Map}{@code <String, Snack>} can now be
- * injected:
- * <pre><code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Map&lt;String, Snack&gt; snacks) { ... }
- * }</code></pre>
- *
- * <p>In addition to binding {@code Map<K, V>}, a mapbinder will also bind
- * {@code Map<K, Provider<V>>} for lazy value provision:
- * <pre><code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Map&lt;String, Provider&lt;Snack&gt;&gt; snackProviders) { ... }
- * }</code></pre>
- *
- * <p>Contributing mapbindings from different modules is supported. For example,
- * it is okay to have both {@code CandyModule} and {@code ChipsModule} both
- * create their own {@code MapBinder<String, Snack>}, and to each contribute
- * bindings to the snacks map. When that map is injected, it will contain
- * entries from both modules.
- *
- * <p>The map's iteration order is consistent with the binding order. This is
- * convenient when multiple elements are contributed by the same module because
- * that module can order its bindings appropriately. Avoid relying on the
- * iteration order of elements contributed by different modules, since there is
- * no equivalent mechanism to order modules.
- *
- * <p>The map is unmodifiable.  Elements can only be added to the map by
- * configuring the MapBinder.  Elements can never be removed from the map.
- *
- * <p>Values are resolved at map injection time. If a value is bound to a
- * provider, that provider's get method will be called each time the map is
- * injected (unless the binding is also scoped, or a map of providers is injected).
- *
- * <p>Annotations are used to create different maps of the same key/value
- * type. Each distinct annotation gets its own independent map.
- *
- * <p><strong>Keys must be distinct.</strong> If the same key is bound more than
- * once, map injection will fail. However, use {@link #permitDuplicates()} in
- * order to allow duplicate keys; extra bindings to {@code Map<K, Set<V>>} and
- * {@code Map<K, Set<Provider<V>>} will be added.
- *
- * <p><strong>Keys must be non-null.</strong> {@code addBinding(null)} will
- * throw an unchecked exception.
- *
- * <p><strong>Values must be non-null to use map injection.</strong> If any
- * value is null, map injection will fail (although injecting a map of providers
- * will not).
- *
- * @author dpb@google.com (David P. Baker)
- */
-public abstract class MapBinder<K, V> {
-  private MapBinder() {}
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with no binding annotation.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder,
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-    return newRealMapBinder(binder, keyType, valueType, Key.get(mapOf(keyType, valueType)),
-        Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType)));
-  }
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with no binding annotation.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder,
-      Class<K> keyType, Class<V> valueType) {
-    return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType));
-  }
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with {@code annotation}.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder,
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType, Annotation annotation) {
-    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-    return newRealMapBinder(binder, keyType, valueType,
-        Key.get(mapOf(keyType, valueType), annotation),
-        Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotation));
-  }
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with {@code annotation}.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder,
-      Class<K> keyType, Class<V> valueType, Annotation annotation) {
-    return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotation);
-  }
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with {@code annotationType}.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType,
-      TypeLiteral<V> valueType, Class<? extends Annotation> annotationType) {
-    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-    return newRealMapBinder(binder, keyType, valueType,
-        Key.get(mapOf(keyType, valueType), annotationType),
-        Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotationType));
-  }
-
-  /**
-   * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
-   * {@link Map} that is itself bound with {@code annotationType}.
-   */
-  public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType,
-      Class<V> valueType, Class<? extends Annotation> annotationType) {
-    return newMapBinder(
-        binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotationType);
-  }
-
-  @SuppressWarnings("unchecked") // a map of <K, V> is safely a Map<K, V>
-  static <K, V> TypeLiteral<Map<K, V>> mapOf(
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    return (TypeLiteral<Map<K, V>>) TypeLiteral.get(
-        Types.mapOf(keyType.getType(), valueType.getType()));
-  }
-
-  @SuppressWarnings("unchecked") // a provider map <K, V> is safely a Map<K, Provider<V>>
-  static <K, V> TypeLiteral<Map<K, Provider<V>>> mapOfProviderOf(
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    return (TypeLiteral<Map<K, Provider<V>>>) TypeLiteral.get(
-        Types.mapOf(keyType.getType(), Types.providerOf(valueType.getType())));
-  }
-  
-  // provider map <K, V> is safely a Map<K, javax.inject.Provider<V>>>
-  @SuppressWarnings("unchecked")
-  static <K, V> TypeLiteral<Map<K, javax.inject.Provider<V>>> mapOfJavaxProviderOf(
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    return (TypeLiteral<Map<K, javax.inject.Provider<V>>>) TypeLiteral.get(
-        Types.mapOf(keyType.getType(),
-            newParameterizedType(javax.inject.Provider.class, valueType.getType())));
-  }
-
-  @SuppressWarnings("unchecked") // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
-  static <K, V> TypeLiteral<Map<K, Set<Provider<V>>>> mapOfSetOfProviderOf(
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    return (TypeLiteral<Map<K, Set<Provider<V>>>>) TypeLiteral.get(
-        Types.mapOf(keyType.getType(), Types.setOf(Types.providerOf(valueType.getType()))));
-  }
-
-  @SuppressWarnings("unchecked") // a provider entry <K, V> is safely a Map.Entry<K, Provider<V>>
-  static <K, V> TypeLiteral<Map.Entry<K, Provider<V>>> entryOfProviderOf(
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-    return (TypeLiteral<Entry<K, Provider<V>>>) TypeLiteral.get(newParameterizedTypeWithOwner(
-        Map.class, Entry.class, keyType.getType(), Types.providerOf(valueType.getType())));
-  }
-
-  // Note: We use valueTypeAndAnnotation effectively as a Pair<TypeLiteral, Annotation|Class>
-  // since it's an easy way to group a type and an optional annotation type or instance.
-  static <K, V> RealMapBinder<K, V> newRealMapBinder(Binder binder, TypeLiteral<K> keyType,
-      Key<V> valueTypeAndAnnotation) {
-    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-    TypeLiteral<V> valueType = valueTypeAndAnnotation.getTypeLiteral();
-    return newRealMapBinder(binder, keyType, valueType,
-        valueTypeAndAnnotation.ofType(mapOf(keyType, valueType)),
-        Multibinder.newSetBinder(binder,
-            valueTypeAndAnnotation.ofType(entryOfProviderOf(keyType, valueType))));
-  }
-
-  private static <K, V> RealMapBinder<K, V> newRealMapBinder(Binder binder,
-      TypeLiteral<K> keyType, TypeLiteral<V> valueType, Key<Map<K, V>> mapKey,
-      Multibinder<Entry<K, Provider<V>>> entrySetBinder) {
-    RealMapBinder<K, V> mapBinder =
-        new RealMapBinder<K, V>(binder, keyType, valueType, mapKey, entrySetBinder);
-    binder.install(mapBinder);
-    return mapBinder;
-  }
-
-  /**
-   * Configures the {@code MapBinder} to handle duplicate entries.
-   * <p>When multiple equal keys are bound, the value that gets included in the map is
-   * arbitrary.
-   * <p>In addition to the {@code Map<K, V>} and {@code Map<K, Provider<V>>}
-   * maps that are normally bound, a {@code Map<K, Set<V>>} and
-   * {@code Map<K, Set<Provider<V>>>} are <em>also</em> bound, which contain
-   * all values bound to each key.
-   * <p>
-   * When multiple modules contribute elements to the map, this configuration
-   * option impacts all of them.
-   *
-   * @return this map binder
-   * @since 3.0
-   */
-  public abstract MapBinder<K, V> permitDuplicates();
-
-  /**
-   * Returns a binding builder used to add a new entry in the map. Each
-   * key must be distinct (and non-null). Bound providers will be evaluated each
-   * time the map is injected.
-   *
-   * <p>It is an error to call this method without also calling one of the
-   * {@code to} methods on the returned binding builder.
-   *
-   * <p>Scoping elements independently is supported. Use the {@code in} method
-   * to specify a binding scope.
-   */
-  public abstract LinkedBindingBuilder<V> addBinding(K key);
-
-  /**
-   * The actual mapbinder plays several roles:
-   *
-   * <p>As a MapBinder, it acts as a factory for LinkedBindingBuilders for
-   * each of the map's values. It delegates to a {@link Multibinder} of
-   * entries (keys to value providers).
-   *
-   * <p>As a Module, it installs the binding to the map itself, as well as to
-   * a corresponding map whose values are providers. It uses the entry set
-   * multibinder to construct the map and the provider map.
-   *
-   * <p>As a module, this implements equals() and hashcode() in order to trick
-   * Guice into executing its configure() method only once. That makes it so
-   * that multiple mapbinders can be created for the same target map, but
-   * only one is bound. Since the list of bindings is retrieved from the
-   * injector itself (and not the mapbinder), each mapbinder has access to
-   * all contributions from all equivalent mapbinders.
-   *
-   * <p>Rather than binding a single Map.Entry&lt;K, V&gt;, the map binder
-   * binds keys and values independently. This allows the values to be properly
-   * scoped.
-   *
-   * <p>We use a subclass to hide 'implements Module' from the public API.
-   */
-  static final class RealMapBinder<K, V> extends MapBinder<K, V> implements Module {
-    private final TypeLiteral<K> keyType;
-    private final TypeLiteral<V> valueType;
-    private final Key<Map<K, V>> mapKey;
-    private final Key<Map<K, javax.inject.Provider<V>>> javaxProviderMapKey;
-    private final Key<Map<K, Provider<V>>> providerMapKey;
-    private final Key<Map<K, Set<V>>> multimapKey;
-    private final Key<Map<K, Set<Provider<V>>>> providerMultimapKey;
-    private final RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder;
-    private final Map<K, String> duplicateKeyErrorMessages;
-
-    /* the target injector's binder. non-null until initialization, null afterwards */
-    private Binder binder;
-
-    private boolean permitDuplicates;
-    private ImmutableList<Map.Entry<K, Binding<V>>> mapBindings;
-
-    private RealMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType,
-        Key<Map<K, V>> mapKey, Multibinder<Map.Entry<K, Provider<V>>> entrySetBinder) {
-      this.keyType = keyType;
-      this.valueType = valueType;
-      this.mapKey = mapKey;
-      this.providerMapKey = mapKey.ofType(mapOfProviderOf(keyType, valueType));
-      this.javaxProviderMapKey = mapKey.ofType(mapOfJavaxProviderOf(keyType, valueType));
-      this.multimapKey = mapKey.ofType(mapOf(keyType, setOf(valueType)));
-      this.providerMultimapKey = mapKey.ofType(mapOfSetOfProviderOf(keyType, valueType));
-      this.entrySetBinder = (RealMultibinder<Entry<K, Provider<V>>>) entrySetBinder;
-      this.binder = binder;
-      this.duplicateKeyErrorMessages = Maps.newHashMap();
-    }
-    
-    /** Sets the error message to be shown if the key had duplicate non-equal bindings. */
-    void updateDuplicateKeyMessage(K k, String errMsg) {
-      duplicateKeyErrorMessages.put(k, errMsg);
-    }
-
-    @Override
-    public MapBinder<K, V> permitDuplicates() {
-      entrySetBinder.permitDuplicates();
-      binder.install(new MultimapBinder<K, V>(
-          multimapKey, providerMultimapKey, entrySetBinder.getSetKey()));
-      return this;
-    }
-    
-    Key<V> getKeyForNewValue(K key) {
-      checkNotNull(key, "key");
-      checkConfiguration(!isInitialized(), "MapBinder was already initialized");
-
-      Key<V> valueKey = Key.get(valueType,
-          new RealElement(entrySetBinder.getSetName(), MAPBINDER, keyType.toString()));
-      entrySetBinder.addBinding().toProvider(new ProviderMapEntry<K, V>(
-          key, binder.getProvider(valueKey), valueKey));
-      return valueKey;
-    }
-
-    /**
-     * This creates two bindings. One for the {@code Map.Entry<K, Provider<V>>}
-     * and another for {@code V}.
-     */
-    @Override public LinkedBindingBuilder<V> addBinding(K key) {
-      return binder.bind(getKeyForNewValue(key));
-    }
-
-    @Override public void configure(Binder binder) {
-      checkConfiguration(!isInitialized(), "MapBinder was already initialized");
-
-      ImmutableSet<Dependency<?>> dependencies
-          = ImmutableSet.<Dependency<?>>of(Dependency.get(entrySetBinder.getSetKey()));
-
-      // Binds a Map<K, Provider<V>> from a collection of Set<Entry<K, Provider<V>>.
-      Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder
-          .getProvider(entrySetBinder.getSetKey());
-
-      binder.bind(providerMapKey).toProvider(
-          new RealProviderMapProvider(dependencies, entrySetProvider));
-
-      // The map this exposes is internally an ImmutableMap, so it's OK to massage
-      // the guice Provider to javax Provider in the value (since Guice provider
-      // implements javax Provider).
-      @SuppressWarnings("unchecked")
-      Key massagedProviderMapKey = (Key)providerMapKey;
-      binder.bind(javaxProviderMapKey).to(massagedProviderMapKey);
-
-      Provider<Map<K, Provider<V>>> mapProvider = binder.getProvider(providerMapKey);
-      binder.bind(mapKey).toProvider(new RealMapProvider(dependencies, mapProvider));
-    }
-
-    boolean containsElement(Element element) {
-      if (entrySetBinder.containsElement(element)) {
-        return true;
-      } else {
-        Key<?> key;
-        if (element instanceof Binding) {
-          key = ((Binding<?>)element).getKey();
-        } else if (element instanceof ProviderLookup) {
-          key = ((ProviderLookup<?>)element).getKey();
-        } else {
-          return false; // cannot match;
-        }
-
-        return key.equals(mapKey)
-            || key.equals(providerMapKey)
-            || key.equals(javaxProviderMapKey)
-            || key.equals(multimapKey)
-            || key.equals(providerMultimapKey)
-            || key.equals(entrySetBinder.getSetKey())
-            || matchesValueKey(key);
-        }
-    }
-
-    /** Returns true if the key indicates this is a value in the map. */
-    private boolean matchesValueKey(Key<?> key) {
-      return key.getAnnotation() instanceof RealElement
-          && ((RealElement) key.getAnnotation()).setName().equals(entrySetBinder.getSetName())
-          && ((RealElement) key.getAnnotation()).type() == MAPBINDER
-          && ((RealElement) key.getAnnotation()).keyType().equals(keyType.toString())
-          && key.getTypeLiteral().equals(valueType);
-    }
-
-    private boolean isInitialized() {
-      return binder == null;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o instanceof RealMapBinder
-          && ((RealMapBinder<?, ?>) o).mapKey.equals(mapKey);
-    }
-
-    @Override public int hashCode() {
-      return mapKey.hashCode();
-    }
-
-    final class RealProviderMapProvider
-        extends RealMapBinderProviderWithDependencies<Map<K, Provider<V>>> {
-      private final ImmutableSet<Dependency<?>> dependencies;
-      private final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider;
-      private Map<K, Provider<V>> providerMap;
-
-      private RealProviderMapProvider(
-          ImmutableSet<Dependency<?>> dependencies,
-          Provider<Set<Entry<K, Provider<V>>>> entrySetProvider) {
-        super(mapKey);
-        this.dependencies = dependencies;
-        this.entrySetProvider = entrySetProvider;
-      }
-
-      @Toolable @Inject void initialize(Injector injector) {
-        RealMapBinder.this.binder = null;
-        permitDuplicates = entrySetBinder.permitsDuplicates(injector);
-
-        Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K, Provider<V>>();
-        List<Map.Entry<K, Binding<V>>> bindingsMutable = Lists.newArrayList();
-        Indexer indexer = new Indexer(injector);
-        Multimap<K, IndexedBinding> index = HashMultimap.create();
-        Set<K> duplicateKeys = null;
-        for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-          ProviderMapEntry<K, V> providerEntry = (ProviderMapEntry<K, V>) entry;
-          Key<V> valueKey = providerEntry.getValueKey();
-          Binding<V> valueBinding = injector.getBinding(valueKey);
-          // If this isn't a dup due to an exact same binding, add it.
-          if (index.put(providerEntry.getKey(), valueBinding.acceptTargetVisitor(indexer))) {
-            Provider<V> previous = providerMapMutable.put(providerEntry.getKey(),
-                new ValueProvider<V>(providerEntry.getValue(), valueBinding));
-            if (previous != null && !permitDuplicates) {
-              if (duplicateKeys == null) {
-                duplicateKeys = Sets.newHashSet();
-              }
-              duplicateKeys.add(providerEntry.getKey());
-            }
-            bindingsMutable.add(Maps.immutableEntry(providerEntry.getKey(), valueBinding));
-          }
-        }
-        if (duplicateKeys != null) {
-          // Must use a ListMultimap in case more than one binding has the same source
-          // and is listed multiple times.
-          Multimap<K, String> dups = newLinkedKeyArrayValueMultimap();
-          for (Map.Entry<K, Binding<V>> entry : bindingsMutable) {
-            if (duplicateKeys.contains(entry.getKey())) {
-              dups.put(entry.getKey(), "\t at " + Errors.convert(entry.getValue().getSource()));
-            }
-          }
-          StringBuilder sb = new StringBuilder("Map injection failed due to duplicated key ");
-          boolean first = true;
-          for (K key : dups.keySet()) {
-            if (first) {
-              first = false;
-              if (duplicateKeyErrorMessages.containsKey(key)) {
-                sb.setLength(0);
-                sb.append(duplicateKeyErrorMessages.get(key));
-              } else {
-                sb.append("\"" + key + "\", from bindings:\n");
-              }
-            } else {
-              if (duplicateKeyErrorMessages.containsKey(key)) {
-                sb.append("\n and " + duplicateKeyErrorMessages.get(key));
-              } else {
-                sb.append("\n and key: \"" + key + "\", from bindings:\n");
-              }
-            }
-            Joiner.on('\n').appendTo(sb, dups.get(key)).append("\n");
-          }
-          checkConfiguration(false, sb.toString());
-        }
-
-        providerMap = ImmutableMap.copyOf(providerMapMutable);
-        mapBindings = ImmutableList.copyOf(bindingsMutable);
-      }
-
-      @Override public Map<K, Provider<V>> get() {
-        return providerMap;
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return dependencies;
-      }
-    }
-
-    final class RealMapProvider extends RealMapWithExtensionProvider<Map<K, V>> {
-      private final ImmutableSet<Dependency<?>> dependencies;
-      private final Provider<Map<K, Provider<V>>> mapProvider;
-
-      private RealMapProvider(
-          ImmutableSet<Dependency<?>> dependencies,
-          Provider<Map<K, Provider<V>>> mapProvider) {
-        super(mapKey);
-        this.dependencies = dependencies;
-        this.mapProvider = mapProvider;
-      }
-
-      @Override public Map<K, V> get() {
-        // We can initialize the internal table efficiently this way and then swap the values
-        // one by one.
-        Map<K, Object> map = new LinkedHashMap<K, Object>(mapProvider.get());
-        for (Entry<K, Object> entry : map.entrySet()) {
-          @SuppressWarnings("unchecked")  // we initialized the entries with providers
-          ValueProvider<V> provider = (ValueProvider<V>)entry.getValue();
-          V value = provider.get();
-          checkConfiguration(value != null,
-              "Map injection failed due to null value for key \"%s\", bound at: %s",
-              entry.getKey(),
-              provider.getValueBinding().getSource());
-          entry.setValue(value);
-        }
-        @SuppressWarnings("unchecked")  // if we exited the loop then we replaced all Providers
-        Map<K, V> typedMap = (Map<K, V>) map;
-        return Collections.unmodifiableMap(typedMap);
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return dependencies;
-      }
-
-      @SuppressWarnings("unchecked")
-      @Override
-      public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
-          ProviderInstanceBinding<? extends B> binding) {
-        if (visitor instanceof MultibindingsTargetVisitor) {
-          return ((MultibindingsTargetVisitor<Map<K, V>, R>)visitor).visit(this);
-        } else {
-          return visitor.visit(binding);
-        }
-      }
-
-      @Override public Key<Map<K, V>> getMapKey() {
-        return mapKey;
-      }
-
-      @Override public TypeLiteral<?> getKeyTypeLiteral() {
-        return keyType;
-      }
-
-      @Override public TypeLiteral<?> getValueTypeLiteral() {
-        return valueType;
-      }
-
-      @SuppressWarnings("unchecked")
-      @Override
-      public List<Entry<?, Binding<?>>> getEntries() {
-        if (isInitialized()) {
-          return (List)mapBindings; // safe because mapBindings is immutable
-        } else {
-          throw new UnsupportedOperationException(
-              "getElements() not supported for module bindings");
-        }
-      }
-
-      @Override public boolean permitsDuplicates() {
-        if (isInitialized()) {
-          return permitDuplicates;
-        } else {
-          throw new UnsupportedOperationException(
-              "permitsDuplicates() not supported for module bindings");
-        }
-      }
-
-      @Override public boolean containsElement(Element element) {
-        return RealMapBinder.this.containsElement(element);
-      }
-    }
-
-    /**
-     * Binds {@code Map<K, Set<V>>} and {{@code Map<K, Set<Provider<V>>>}.
-     */
-    static final class MultimapBinder<K, V> implements Module {
-
-      private final Key<Map<K, Set<V>>> multimapKey;
-      private final Key<Map<K, Set<Provider<V>>>> providerMultimapKey;
-      private final Key<Set<Entry<K,Provider<V>>>> entrySetKey;
-
-      public MultimapBinder(
-          Key<Map<K, Set<V>>> multimapKey,
-          Key<Map<K, Set<Provider<V>>>> providerMultimapKey,
-          Key<Set<Entry<K,Provider<V>>>> entrySetKey) {
-        this.multimapKey = multimapKey;
-        this.providerMultimapKey = providerMultimapKey;
-        this.entrySetKey = entrySetKey;
-      }
-
-      @Override public void configure(Binder binder) {
-        ImmutableSet<Dependency<?>> dependencies
-            = ImmutableSet.<Dependency<?>>of(Dependency.get(entrySetKey));
-
-        Provider<Set<Entry<K, Provider<V>>>> entrySetProvider =
-            binder.getProvider(entrySetKey);
-        // Binds a Map<K, Set<Provider<V>>> from a collection of Map<Entry<K, Provider<V>> if
-        // permitDuplicates was called.
-        binder.bind(providerMultimapKey).toProvider(
-            new RealProviderMultimapProvider(dependencies, entrySetProvider));
-
-        Provider<Map<K, Set<Provider<V>>>> multimapProvider =
-            binder.getProvider(providerMultimapKey);
-        binder.bind(multimapKey).toProvider(
-            new RealMultimapProvider(dependencies, multimapProvider));
-      }
-
-      @Override public int hashCode() {
-        return multimapKey.hashCode();
-      }
-
-      @Override public boolean equals(Object o) {
-        return o instanceof MultimapBinder
-            && ((MultimapBinder<?, ?>) o).multimapKey.equals(multimapKey);
-      }
-
-      final class RealProviderMultimapProvider
-          extends RealMapBinderProviderWithDependencies<Map<K, Set<Provider<V>>>> {
-        private final ImmutableSet<Dependency<?>> dependencies;
-        private final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider;
-        private Map<K, Set<Provider<V>>> providerMultimap;
-
-        private RealProviderMultimapProvider(ImmutableSet<Dependency<?>> dependencies,
-            Provider<Set<Entry<K, Provider<V>>>> entrySetProvider) {
-          super(multimapKey);
-          this.dependencies = dependencies;
-          this.entrySetProvider = entrySetProvider;
-        }
-
-        @SuppressWarnings("unused")
-        @Inject void initialize(Injector injector) {
-          Map<K, ImmutableSet.Builder<Provider<V>>> providerMultimapMutable =
-              new LinkedHashMap<K, ImmutableSet.Builder<Provider<V>>>();
-          for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-            if (!providerMultimapMutable.containsKey(entry.getKey())) {
-              providerMultimapMutable.put(
-                  entry.getKey(), ImmutableSet.<Provider<V>>builder());
-            }
-            providerMultimapMutable.get(entry.getKey()).add(entry.getValue());
-          }
-
-          ImmutableMap.Builder<K, Set<Provider<V>>> providerMultimapBuilder =
-              ImmutableMap.builder();
-          for (Entry<K, ImmutableSet.Builder<Provider<V>>> entry
-              : providerMultimapMutable.entrySet()) {
-            providerMultimapBuilder.put(entry.getKey(), entry.getValue().build());
-          }
-          providerMultimap = providerMultimapBuilder.build();
-        }
-
-        @Override public Map<K, Set<Provider<V>>> get() {
-          return providerMultimap;
-        }
-
-        @Override public Set<Dependency<?>> getDependencies() {
-          return dependencies;
-        }
-      }
-
-      final class RealMultimapProvider
-          extends RealMapBinderProviderWithDependencies<Map<K, Set<V>>> {
-        private final ImmutableSet<Dependency<?>> dependencies;
-        private final Provider<Map<K, Set<Provider<V>>>> multimapProvider;
-
-        RealMultimapProvider(
-            ImmutableSet<Dependency<?>> dependencies,
-            Provider<Map<K, Set<Provider<V>>>> multimapProvider) {
-          super(multimapKey);
-          this.dependencies = dependencies;
-          this.multimapProvider = multimapProvider;
-        }
-
-        @Override public Map<K, Set<V>> get() {
-          ImmutableMap.Builder<K, Set<V>> multimapBuilder = ImmutableMap.builder();
-          for (Entry<K, Set<Provider<V>>> entry : multimapProvider.get().entrySet()) {
-            K key = entry.getKey();
-            ImmutableSet.Builder<V> valuesBuilder = ImmutableSet.builder();
-            for (Provider<V> valueProvider : entry.getValue()) {
-              V value = valueProvider.get();
-              checkConfiguration(value != null,
-                  "Multimap injection failed due to null value for key \"%s\"", key);
-              valuesBuilder.add(value);
-            }
-            multimapBuilder.put(key, valuesBuilder.build());
-          }
-          return multimapBuilder.build();
-        }
-
-        @Override public Set<Dependency<?>> getDependencies() {
-          return dependencies;
-        }
-      }
-    }
-
-    static final class ValueProvider<V> implements Provider<V> {
-      private final Provider<V> delegate;
-      private final Binding<V> binding;
-
-      ValueProvider(Provider<V> delegate, Binding<V> binding) {
-        this.delegate = delegate;
-        this.binding = binding;
-      }
-
-      @Override public V get() {
-        return delegate.get();
-      }
-
-      public Binding<V> getValueBinding() {
-        return binding;
-      }
-    }
-
-    /**
-     * A Provider that Map.Entry that is also a Provider.  The key is the entry in the
-     * map this corresponds to and the value is the provider of the user's binding.
-     * This returns itself as the Provider.get value.
-     */
-    static final class ProviderMapEntry<K, V> implements
-        ProviderWithDependencies<Map.Entry<K, Provider<V>>>, Map.Entry<K, Provider<V>> {
-      private final K key;
-      private final Provider<V> provider;
-      private final Key<V> valueKey;
-
-      private ProviderMapEntry(K key, Provider<V> provider, Key<V> valueKey) {
-        this.key = key;
-        this.provider = provider;
-        this.valueKey = valueKey;
-      }
-
-      @Override public Entry<K, Provider<V>> get() {
-        return this;
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return ((HasDependencies) provider).getDependencies();
-      }
-
-      public Key<V> getValueKey() {
-        return valueKey;
-      }
-
-      @Override public K getKey() {
-        return key;
-      }
-
-      @Override public Provider<V> getValue() {
-        return provider;
-      }
-
-      @Override public Provider<V> setValue(Provider<V> value) {
-        throw new UnsupportedOperationException();
-      }
-
-       @Override public boolean equals(Object obj) {
-         if (obj instanceof Map.Entry) {
-           Map.Entry o = (Map.Entry)obj;
-           return Objects.equal(key, o.getKey())
-               && Objects.equal(provider, o.getValue());
-         }
-         return false;
-      }
-
-      @Override public int hashCode() {
-        return key.hashCode() ^ provider.hashCode();
-      }
-
-      @Override public String toString() {
-        return "ProviderMapEntry(" + key + ", " + provider + ")";
-      }
-    }
-
-    private static abstract class RealMapWithExtensionProvider<T>
-        extends RealMapBinderProviderWithDependencies<T>
-        implements ProviderWithExtensionVisitor<T>, MapBinderBinding<T> {
-      public RealMapWithExtensionProvider(Object equality) {
-        super(equality);
-      }
-    }
-
-    /**
-     * A base class for ProviderWithDependencies that need equality
-     * based on a specific object.
-     */
-    private static abstract class RealMapBinderProviderWithDependencies<T> implements ProviderWithDependencies<T> {
-      private final Object equality;
-
-      public RealMapBinderProviderWithDependencies(Object equality) {
-        this.equality = equality;
-      }
-
-      @Override
-      public boolean equals(Object obj) {
-        return this.getClass() == obj.getClass() &&
-          equality.equals(((RealMapBinderProviderWithDependencies<?>)obj).equality);
-      }
-
-      @Override
-      public int hashCode() {
-        return equality.hashCode();
-      }
-    }
-
-    private Multimap<K, String> newLinkedKeyArrayValueMultimap() {
-      return Multimaps.newListMultimap(
-          new LinkedHashMap<K, Collection<String>>(),
-          new Supplier<List<String>>() {
-            @Override public List<String> get() {
-              return Lists.newArrayList();
-            }
-          });
-    }
-  }
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinderBinding.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinderBinding.java
deleted file mode 100644
index 46d303c..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinderBinding.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import com.google.inject.Binding;
-import com.google.inject.Key;
-import com.google.inject.TypeLiteral;
-import com.google.inject.spi.Element;
-import com.google.inject.spi.Elements;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * A binding for a MapBinder.
- * <p>
- * Although MapBinders may be injected through a variety of generic types (Map&lt;K, V>, Map
- * &lt;K, Provider&lt;V>>, Map&lt;K, Set&lt;V>>, Map<K, Set&lt;
- * Provider&lt;V>>, and even Set&lt;Map.Entry&lt;K, Provider&lt;V>>), a
- * MapBinderBinding exists only on the Binding associated with the Map&lt;K, V> key. Other
- * bindings can be validated to be derived from this MapBinderBinding using
- * {@link #containsElement(Element)}.
- * 
- * @param <T> The fully qualified type of the map, including Map. For example:
- *          <code>MapBinderBinding&lt;Map&lt;String, Snack>></code>
- * 
- * @since 3.0
- * @author sameb@google.com (Sam Berlin)
- */
-public interface MapBinderBinding<T> {
-
-  /** Returns the {@link Key} for the map. */
-  Key<T> getMapKey();
-
-  /**
-   * Returns the TypeLiteral describing the keys of the map.
-   * <p>
-   * The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
-   * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a
-   * <code>TypeLiteral&lt;String></code>.
-   */
-  TypeLiteral<?> getKeyTypeLiteral();
-
-  /**
-   * Returns the TypeLiteral describing the values of the map.
-   * <p>
-   * The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
-   * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a
-   * <code>TypeLiteral&lt;Snack></code>.
-   */
-  TypeLiteral<?> getValueTypeLiteral();
-
-  /**
-   * Returns all entries in the Map. The returned list of Map.Entries contains the key and a binding
-   * to the value. Duplicate keys or values will exist as separate Map.Entries in the returned list.
-   * This is only supported on bindings returned from an injector. This will throw
-   * {@link UnsupportedOperationException} if it is called on an element retrieved from
-   * {@link Elements#getElements}.
-   * <p>
-   * The elements will always match the type Map's generic type. For example, if getMapKey returns a
-   * key of <code>Map&lt;String, Snack></code>, then this will always return a list of type
-   * <code>List&lt;Map.Entry&lt;String, Binding&lt;Snack>>></code>.
-   */
-  List<Map.Entry<?, Binding<?>>> getEntries();
-
-  /**
-   * Returns true if the MapBinder permits duplicates. This is only supported on bindings returned
-   * from an injector. This will throw {@link UnsupportedOperationException} if it is called on a
-   * MapBinderBinding retrieved from {@link Elements#getElements}.
-   */
-  boolean permitsDuplicates();
-
-  /**
-   * Returns true if this MapBinder contains the given Element in order to build the map or uses the
-   * given Element in order to support building and injecting the map. This will work for
-   * MapBinderBindings retrieved from an injector and {@link Elements#getElements}. Usually this is
-   * only necessary if you are working with elements retrieved from modules (without an Injector),
-   * otherwise {@link #getEntries} and {@link #permitsDuplicates} are better options.
-   * <p>
-   * If you need to introspect the details of the map, such as the keys, values or if it permits
-   * duplicates, it is necessary to pass the elements through an Injector and use
-   * {@link #getEntries()} and {@link #permitsDuplicates()}.
-   */
-  boolean containsElement(Element element);
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
deleted file mode 100644
index f3fd552..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import static com.google.common.base.Predicates.equalTo;
-import static com.google.common.primitives.Ints.MAX_POWER_OF_TWO;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.inject.multibindings.Element.Type.MULTIBINDER;
-import static com.google.inject.name.Names.named;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
-import com.google.inject.Binding;
-import com.google.inject.ConfigurationException;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.internal.Errors;
-import com.google.inject.spi.BindingTargetVisitor;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.Message;
-import com.google.inject.spi.ProviderInstanceBinding;
-import com.google.inject.spi.ProviderWithDependencies;
-import com.google.inject.spi.ProviderWithExtensionVisitor;
-import com.google.inject.spi.Toolable;
-import com.google.inject.util.Types;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An API to bind multiple values separately, only to later inject them as a
- * complete collection. Multibinder is intended for use in your application's
- * module:
- * <pre><code>
- * public class SnacksModule extends AbstractModule {
- *   protected void configure() {
- *     Multibinder&lt;Snack&gt; multibinder
- *         = Multibinder.newSetBinder(binder(), Snack.class);
- *     multibinder.addBinding().toInstance(new Twix());
- *     multibinder.addBinding().toProvider(SnickersProvider.class);
- *     multibinder.addBinding().to(Skittles.class);
- *   }
- * }</code></pre>
- *
- * <p>With this binding, a {@link Set}{@code <Snack>} can now be injected:
- * <pre><code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Set&lt;Snack&gt; snacks) { ... }
- * }</code></pre>
- *
- * If desired, {@link Collection}{@code <Provider<Snack>>} can also be injected.
- *
- * <p>Contributing multibindings from different modules is supported. For
- * example, it is okay for both {@code CandyModule} and {@code ChipsModule}
- * to create their own {@code Multibinder<Snack>}, and to each contribute
- * bindings to the set of snacks. When that set is injected, it will contain
- * elements from both modules.
- *
- * <p>The set's iteration order is consistent with the binding order. This is
- * convenient when multiple elements are contributed by the same module because
- * that module can order its bindings appropriately. Avoid relying on the
- * iteration order of elements contributed by different modules, since there is
- * no equivalent mechanism to order modules.
- *
- * <p>The set is unmodifiable.  Elements can only be added to the set by
- * configuring the multibinder.  Elements can never be removed from the set.
- *
- * <p>Elements are resolved at set injection time. If an element is bound to a
- * provider, that provider's get method will be called each time the set is
- * injected (unless the binding is also scoped).
- *
- * <p>Annotations are be used to create different sets of the same element
- * type. Each distinct annotation gets its own independent collection of
- * elements.
- *
- * <p><strong>Elements must be distinct.</strong> If multiple bound elements
- * have the same value, set injection will fail.
- *
- * <p><strong>Elements must be non-null.</strong> If any set element is null,
- * set injection will fail.
- *
- * @author jessewilson@google.com (Jesse Wilson)
- */
-public abstract class Multibinder<T> {
-  private Multibinder() {}
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with no binding annotation.
-   */
-  public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type) {
-    return newRealSetBinder(binder, Key.get(type));
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with no binding annotation.
-   */
-  public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type) {
-    return newRealSetBinder(binder, Key.get(type));
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with {@code annotation}.
-   */
-  public static <T> Multibinder<T> newSetBinder(
-      Binder binder, TypeLiteral<T> type, Annotation annotation) {
-    return newRealSetBinder(binder, Key.get(type, annotation));
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with {@code annotation}.
-   */
-  public static <T> Multibinder<T> newSetBinder(
-      Binder binder, Class<T> type, Annotation annotation) {
-    return newRealSetBinder(binder, Key.get(type, annotation));
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with {@code annotationType}.
-   */
-  public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type,
-      Class<? extends Annotation> annotationType) {
-    return newRealSetBinder(binder, Key.get(type, annotationType));
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of the key's type in a {@link Set} that is
-   * itself bound with the annotation (if any) of the key.
-   *
-   * @since 4.0
-   */
-  public static <T> Multibinder<T> newSetBinder(Binder binder, Key<T> key) {
-    return newRealSetBinder(binder, key);
-  }
-
-  /**
-   * Implementation of newSetBinder.
-   */
-  static <T> RealMultibinder<T> newRealSetBinder(Binder binder, Key<T> key) {
-    binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
-    RealMultibinder<T> result = new RealMultibinder<T>(binder, key.getTypeLiteral(),
-        key.ofType(setOf(key.getTypeLiteral())));
-    binder.install(result);
-    return result;
-  }
-
-  /**
-   * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
-   * itself bound with {@code annotationType}.
-   */
-  public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type,
-      Class<? extends Annotation> annotationType) {
-    return newSetBinder(binder, Key.get(type, annotationType));
-  }
-
-  @SuppressWarnings("unchecked") // wrapping a T in a Set safely returns a Set<T>
-  static <T> TypeLiteral<Set<T>> setOf(TypeLiteral<T> elementType) {
-    Type type = Types.setOf(elementType.getType());
-    return (TypeLiteral<Set<T>>) TypeLiteral.get(type);
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> TypeLiteral<Collection<Provider<T>>> collectionOfProvidersOf(
-      TypeLiteral<T> elementType) {
-    Type providerType = Types.providerOf(elementType.getType());
-    Type type = Types.newParameterizedType(Collection.class, providerType);
-    return (TypeLiteral<Collection<Provider<T>>>) TypeLiteral.get(type);
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> TypeLiteral<Collection<javax.inject.Provider<T>>> collectionOfJavaxProvidersOf(
-      TypeLiteral<T> elementType) {
-    Type providerType =
-        Types.newParameterizedType(javax.inject.Provider.class, elementType.getType());
-    Type type = Types.newParameterizedType(Collection.class, providerType);
-    return (TypeLiteral<Collection<javax.inject.Provider<T>>>) TypeLiteral.get(type);
-  }
-
-  /**
-   * Configures the bound set to silently discard duplicate elements. When multiple equal values are
-   * bound, the one that gets included is arbitrary. When multiple modules contribute elements to
-   * the set, this configuration option impacts all of them.
-   *
-   * @return this multibinder
-   * @since 3.0
-   */
-  public abstract Multibinder<T> permitDuplicates();
-
-  /**
-   * Returns a binding builder used to add a new element in the set. Each
-   * bound element must have a distinct value. Bound providers will be
-   * evaluated each time the set is injected.
-   *
-   * <p>It is an error to call this method without also calling one of the
-   * {@code to} methods on the returned binding builder.
-   *
-   * <p>Scoping elements independently is supported. Use the {@code in} method
-   * to specify a binding scope.
-   */
-  public abstract LinkedBindingBuilder<T> addBinding();
-
-  /**
-   * The actual multibinder plays several roles:
-   *
-   * <p>As a Multibinder, it acts as a factory for LinkedBindingBuilders for
-   * each of the set's elements. Each binding is given an annotation that
-   * identifies it as a part of this set.
-   *
-   * <p>As a Module, it installs the binding to the set itself. As a module,
-   * this implements equals() and hashcode() in order to trick Guice into
-   * executing its configure() method only once. That makes it so that
-   * multiple multibinders can be created for the same target collection, but
-   * only one is bound. Since the list of bindings is retrieved from the
-   * injector itself (and not the multibinder), each multibinder has access to
-   * all contributions from all multibinders.
-   *
-   * <p>As a Provider, this constructs the set instances.
-   *
-   * <p>We use a subclass to hide 'implements Module, Provider' from the public
-   * API.
-   */
-  static final class RealMultibinder<T> extends Multibinder<T>
-      implements Module, ProviderWithExtensionVisitor<Set<T>>, HasDependencies,
-          MultibinderBinding<Set<T>> {
-
-    private final TypeLiteral<T> elementType;
-    private final String setName;
-    private final Key<Set<T>> setKey;
-    private final Key<Collection<Provider<T>>> collectionOfProvidersKey;
-    private final Key<Collection<javax.inject.Provider<T>>> collectionOfJavaxProvidersKey;
-    private final Key<Boolean> permitDuplicatesKey;
-
-    /* the target injector's binder. non-null until initialization, null afterwards */
-    private Binder binder;
-
-    /* a binding for each element in the set. null until initialization, non-null afterwards */
-    private ImmutableList<Binding<T>> bindings;
-    private Set<Dependency<?>> dependencies;
-
-    /** whether duplicates are allowed. Possibly configured by a different instance */
-    private boolean permitDuplicates;
-
-    private RealMultibinder(Binder binder, TypeLiteral<T> elementType, Key<Set<T>> setKey) {
-      this.binder = checkNotNull(binder, "binder");
-      this.elementType = checkNotNull(elementType, "elementType");
-      this.setKey = checkNotNull(setKey, "setKey");
-      this.collectionOfProvidersKey = setKey.ofType(collectionOfProvidersOf(elementType));
-      this.collectionOfJavaxProvidersKey = setKey.ofType(collectionOfJavaxProvidersOf(elementType));
-      this.setName = RealElement.nameOf(setKey);
-      this.permitDuplicatesKey = Key.get(Boolean.class, named(toString() + " permits duplicates"));
-    }
-
-    public void configure(Binder binder) {
-      checkConfiguration(!isInitialized(), "Multibinder was already initialized");
-
-      binder.bind(setKey).toProvider(this);
-      binder.bind(collectionOfProvidersKey).toProvider(
-          new RealMultibinderCollectionOfProvidersProvider());
-
-      // The collection this exposes is internally an ImmutableList, so it's OK to massage
-      // the guice Provider to javax Provider in the value (since the guice Provider implements
-      // javax Provider).
-      @SuppressWarnings("unchecked")
-      Key key = (Key) collectionOfProvidersKey;
-      binder.bind(collectionOfJavaxProvidersKey).to(key);
-    }
-
-    @Override public Multibinder<T> permitDuplicates() {
-      binder.install(new PermitDuplicatesModule(permitDuplicatesKey));
-      return this;
-    }
-    
-    Key<T> getKeyForNewItem() {
-      checkConfiguration(!isInitialized(), "Multibinder was already initialized");
-      return Key.get(elementType, new RealElement(setName, MULTIBINDER, ""));
-    }
-
-    @Override public LinkedBindingBuilder<T> addBinding() {
-      return binder.bind(getKeyForNewItem());
-    }
-
-    /**
-     * Invoked by Guice at Injector-creation time to prepare providers for each
-     * element in this set. At this time the set's size is known, but its
-     * contents are only evaluated when get() is invoked.
-     */
-    @Toolable @Inject void initialize(Injector injector) {
-      List<Binding<T>> bindings = Lists.newArrayList();
-      Set<Indexer.IndexedBinding> index = Sets.newHashSet();
-      Indexer indexer = new Indexer(injector);
-      List<Dependency<?>> dependencies = Lists.newArrayList();
-      for (Binding<?> entry : injector.findBindingsByType(elementType)) {
-        if (keyMatches(entry.getKey())) {
-          @SuppressWarnings("unchecked") // protected by findBindingsByType()
-          Binding<T> binding = (Binding<T>) entry;
-          if (index.add(binding.acceptTargetVisitor(indexer))) {
-            bindings.add(binding);
-            dependencies.add(Dependency.get(binding.getKey()));
-          }
-        }
-      }
-
-      this.bindings = ImmutableList.copyOf(bindings);
-      this.dependencies = ImmutableSet.copyOf(dependencies);
-      this.permitDuplicates = permitsDuplicates(injector);
-      this.binder = null;
-    }
-
-    // This is forked from com.google.common.collect.Maps.capacity 
-    private static int mapCapacity(int numBindings) {
-      if (numBindings < 3) {
-        return numBindings + 1;
-      } else  if (numBindings < MAX_POWER_OF_TWO) {
-        return (int) (numBindings / 0.75F + 1.0F);
-      }
-      return Integer.MAX_VALUE;
-    }
-
-    boolean permitsDuplicates(Injector injector) {
-      return injector.getBindings().containsKey(permitDuplicatesKey);
-    }
-
-    private boolean keyMatches(Key<?> key) {
-      return key.getTypeLiteral().equals(elementType)
-          && key.getAnnotation() instanceof Element
-          && ((Element) key.getAnnotation()).setName().equals(setName)
-          && ((Element) key.getAnnotation()).type() == MULTIBINDER;
-    }
-
-    private boolean isInitialized() {
-      return binder == null;
-    }
-
-    public Set<T> get() {
-      checkConfiguration(isInitialized(), "Multibinder is not initialized");
-
-      Map<T, Binding<T>> result = new LinkedHashMap<T, Binding<T>>(mapCapacity(bindings.size()));
-      for (Binding<T> binding : bindings) {
-        final T newValue = binding.getProvider().get();
-        checkConfiguration(newValue != null,
-            "Set injection failed due to null element bound at: %s",
-            binding.getSource());
-        Binding<T> duplicateBinding = result.put(newValue, binding);
-        if (!permitDuplicates && duplicateBinding != null) {
-          throw newDuplicateValuesException(result, binding, newValue, duplicateBinding);
-        }
-      }
-      return ImmutableSet.copyOf(result.keySet());
-    }
-
-    @SuppressWarnings("unchecked")
-    public <B, V> V acceptExtensionVisitor(
-        BindingTargetVisitor<B, V> visitor,
-        ProviderInstanceBinding<? extends B> binding) {
-      if (visitor instanceof MultibindingsTargetVisitor) {
-        return ((MultibindingsTargetVisitor<Set<T>, V>) visitor).visit(this);
-      } else {
-        return visitor.visit(binding);
-      }
-    }
-
-    String getSetName() {
-      return setName;
-    }
-
-    public TypeLiteral<?> getElementTypeLiteral() {
-      return elementType;
-    }
-
-    public Key<Set<T>> getSetKey() {
-      return setKey;
-    }
-
-    @SuppressWarnings("unchecked")
-    public List<Binding<?>> getElements() {
-      if (isInitialized()) {
-        return (List<Binding<?>>) (List<?>) bindings; // safe because bindings is immutable.
-      } else {
-        throw new UnsupportedOperationException("getElements() not supported for module bindings");
-      }
-    }
-
-    public boolean permitsDuplicates() {
-      if (isInitialized()) {
-        return permitDuplicates;
-      } else {
-        throw new UnsupportedOperationException(
-            "permitsDuplicates() not supported for module bindings");
-      }
-    }
-
-    public boolean containsElement(com.google.inject.spi.Element element) {
-      if (element instanceof Binding) {
-        Binding<?> binding = (Binding<?>) element;
-        return keyMatches(binding.getKey())
-            || binding.getKey().equals(permitDuplicatesKey)
-            || binding.getKey().equals(setKey)
-            || binding.getKey().equals(collectionOfProvidersKey)
-            || binding.getKey().equals(collectionOfJavaxProvidersKey);
-      } else {
-        return false;
-      }
-    }
-
-    public Set<Dependency<?>> getDependencies() {
-      if (!isInitialized()) {
-        return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
-      } else {
-        return dependencies;
-      }
-    }
-
-    @Override public boolean equals(Object o) {
-      return o instanceof RealMultibinder
-          && ((RealMultibinder<?>) o).setKey.equals(setKey);
-    }
-
-    @Override public int hashCode() {
-      return setKey.hashCode();
-    }
-
-    @Override public String toString() {
-      return (setName.isEmpty() ? "" : setName + " ") + "Multibinder<" + elementType + ">";
-    }
-
-    final class RealMultibinderCollectionOfProvidersProvider
-        implements ProviderWithDependencies<Collection<Provider<T>>> {
-      @Override public Collection<Provider<T>> get() {
-        checkConfiguration(isInitialized(), "Multibinder is not initialized");
-        int size = bindings.size();
-        @SuppressWarnings("unchecked")  // safe because we only put Provider<T> into it.
-        Provider<T>[] providers = new Provider[size];
-        for (int i = 0; i < size; i++) {
-          providers[i] = bindings.get(i).getProvider();
-        }
-        return ImmutableList.copyOf(providers);
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        if (!isInitialized()) {
-          return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
-        }
-        ImmutableSet.Builder<Dependency<?>> setBuilder = ImmutableSet.builder();
-        for (Dependency<?> dependency : dependencies) {
-          Key key = dependency.getKey();
-          setBuilder.add(
-              Dependency.get(key.ofType(Types.providerOf(key.getTypeLiteral().getType()))));
-        }
-        return setBuilder.build();
-      }
-
-      Key getCollectionKey() {
-        return RealMultibinder.this.collectionOfProvidersKey;
-      }
-
-      @Override public boolean equals(Object o) {
-        return o instanceof Multibinder.RealMultibinder.RealMultibinderCollectionOfProvidersProvider
-            && ((Multibinder.RealMultibinder.RealMultibinderCollectionOfProvidersProvider) o)
-                .getCollectionKey().equals(getCollectionKey());
-      }
-
-      @Override public int hashCode() {
-        return getCollectionKey().hashCode();
-      }
-    }
-  }
-
-  /**
-   * We install the permit duplicates configuration as its own binding, all by itself. This way,
-   * if only one of a multibinder's users remember to call permitDuplicates(), they're still
-   * permitted.
-   */
-  private static class PermitDuplicatesModule extends AbstractModule {
-    private final Key<Boolean> key;
-
-    PermitDuplicatesModule(Key<Boolean> key) {
-      this.key = key;
-    }
-
-    @Override protected void configure() {
-      bind(key).toInstance(true);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o instanceof PermitDuplicatesModule
-          && ((PermitDuplicatesModule) o).key.equals(key);
-    }
-
-    @Override public int hashCode() {
-      return getClass().hashCode() ^ key.hashCode();
-    }
-  }
-
-  static void checkConfiguration(boolean condition, String format, Object... args) {
-    if (condition) {
-      return;
-    }
-
-    throw new ConfigurationException(ImmutableSet.of(new Message(Errors.format(format, args))));
-  }
-
-  private static <T> ConfigurationException newDuplicateValuesException(
-      Map<T, Binding<T>> existingBindings,
-      Binding<T> binding,
-      final T newValue,
-      Binding<T> duplicateBinding) {
-    T oldValue = getOnlyElement(filter(existingBindings.keySet(), equalTo(newValue)));
-    String oldString = oldValue.toString();
-    String newString = newValue.toString();
-    if (Objects.equal(oldString, newString)) {
-      // When the value strings match, just show the source of the bindings
-      return new ConfigurationException(ImmutableSet.of(new Message(Errors.format(
-          "Set injection failed due to duplicated element \"%s\""
-              + "\n    Bound at %s\n    Bound at %s",
-          newValue,
-          duplicateBinding.getSource(),
-          binding.getSource()))));
-    } else {
-      // When the value strings don't match, include them both as they may be useful for debugging
-      return new ConfigurationException(ImmutableSet.of(new Message(Errors.format(
-          "Set injection failed due to multiple elements comparing equal:"
-              + "\n    \"%s\"\n        bound at %s"
-              + "\n    \"%s\"\n        bound at %s",
-          oldValue,
-          duplicateBinding.getSource(),
-          newValue,
-          binding.getSource()))));
-    }
-  }
-
-  static <T> T checkNotNull(T reference, String name) {
-    if (reference != null) {
-      return reference;
-    }
-
-    NullPointerException npe = new NullPointerException(name);
-    throw new ConfigurationException(ImmutableSet.of(
-        new Message(npe.toString(), npe)));
-  }
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MultibindingsScanner.java b/extensions/multibindings/src/com/google/inject/multibindings/MultibindingsScanner.java
deleted file mode 100644
index 95b4d5f..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/MultibindingsScanner.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * 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 com.google.inject.multibindings;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.TypeLiteral;
-import com.google.inject.spi.InjectionPoint;
-import com.google.inject.spi.ModuleAnnotatedMethodScanner;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-/**
- * Scans a module for annotations that signal multibindings, mapbindings, and optional bindings.
- *
- * @since 4.0
- */
-public class MultibindingsScanner {
-
-  private MultibindingsScanner() {}
-
-  /**
-   * Returns a module that, when installed, will scan all modules for methods with the annotations
-   * {@literal @}{@link ProvidesIntoMap}, {@literal @}{@link ProvidesIntoSet}, and
-   * {@literal @}{@link ProvidesIntoOptional}.
-   * 
-   * <p>This is a convenience method, equivalent to doing
-   * {@code binder().scanModulesForAnnotatedMethods(MultibindingsScanner.scanner())}.
-   */
-  public static Module asModule() {
-    return new AbstractModule() {
-      @Override protected void configure() {
-        binder().scanModulesForAnnotatedMethods(Scanner.INSTANCE);
-      }
-    };
-  }
-  
-  /**
-   * Returns a {@link ModuleAnnotatedMethodScanner} that, when bound, will scan all modules for
-   * methods with the annotations {@literal @}{@link ProvidesIntoMap},
-   * {@literal @}{@link ProvidesIntoSet}, and {@literal @}{@link ProvidesIntoOptional}.
-   */
-  public static ModuleAnnotatedMethodScanner scanner() {
-    return Scanner.INSTANCE;
-  }
-
-  private static class Scanner extends ModuleAnnotatedMethodScanner {
-    private static final Scanner INSTANCE = new Scanner();
-    
-    @Override
-    public Set<? extends Class<? extends Annotation>> annotationClasses() {
-      return ImmutableSet.of(
-          ProvidesIntoSet.class, ProvidesIntoMap.class, ProvidesIntoOptional.class);
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"}) // mapKey doesn't know its key type
-    @Override
-    public <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key,
-        InjectionPoint injectionPoint) {
-      Method method = (Method) injectionPoint.getMember();
-      AnnotationOrError mapKey = findMapKeyAnnotation(binder, method);
-      if (annotation instanceof ProvidesIntoSet) {
-        if (mapKey.annotation != null) {
-          binder.addError("Found a MapKey annotation on non map binding at %s.", method);
-        }
-        return Multibinder.newRealSetBinder(binder, key).getKeyForNewItem();
-      } else if (annotation instanceof ProvidesIntoMap) {
-        if (mapKey.error) {
-          // Already failed on the MapKey, don't bother doing more work.
-          return key;
-        }
-        if (mapKey.annotation == null) {
-          // If no MapKey, make an error and abort.
-          binder.addError("No MapKey found for map binding at %s.", method);
-          return key;
-        }
-        TypeAndValue typeAndValue = typeAndValueOfMapKey(mapKey.annotation);
-        return MapBinder.newRealMapBinder(binder, typeAndValue.type, key)
-            .getKeyForNewValue(typeAndValue.value);
-      } else if (annotation instanceof ProvidesIntoOptional) {
-        if (mapKey.annotation != null) {
-          binder.addError("Found a MapKey annotation on non map binding at %s.", method);
-        }
-        switch (((ProvidesIntoOptional)annotation).value()) {
-          case DEFAULT:
-            return OptionalBinder.newRealOptionalBinder(binder, key).getKeyForDefaultBinding();
-          case ACTUAL:
-            return OptionalBinder.newRealOptionalBinder(binder, key).getKeyForActualBinding();
-        }
-      }
-      throw new IllegalStateException("Invalid annotation: " + annotation);
-    }
-  }
-  
-  private static class AnnotationOrError {
-    final Annotation annotation;
-    final boolean error;
-    AnnotationOrError(Annotation annotation, boolean error) {
-      this.annotation = annotation;
-      this.error = error;
-    }
-
-    static AnnotationOrError forPossiblyNullAnnotation(Annotation annotation) {
-      return new AnnotationOrError(annotation, false);
-    }
-    
-    static AnnotationOrError forError() {
-      return new AnnotationOrError(null, true);
-    }
-  }
-
-  private static AnnotationOrError findMapKeyAnnotation(Binder binder, Method method) {
-    Annotation foundAnnotation = null;
-    for (Annotation annotation : method.getAnnotations()) {
-      MapKey mapKey = annotation.annotationType().getAnnotation(MapKey.class);
-      if (mapKey != null) {
-        if (foundAnnotation != null) {
-          binder.addError("Found more than one MapKey annotations on %s.", method);
-          return AnnotationOrError.forError();
-        }
-        if (mapKey.unwrapValue()) {
-          try {
-            // validate there's a declared method called "value"
-            Method valueMethod = annotation.annotationType().getDeclaredMethod("value");
-            if (valueMethod.getReturnType().isArray()) {
-              binder.addError("Array types are not allowed in a MapKey with unwrapValue=true: %s",                    
-                  annotation.annotationType());
-              return AnnotationOrError.forError();
-            }
-          } catch (NoSuchMethodException invalid) {
-            binder.addError("No 'value' method in MapKey with unwrapValue=true: %s",
-                annotation.annotationType());
-            return AnnotationOrError.forError();
-          }
-        }
-        foundAnnotation = annotation;
-      }
-    }
-    return AnnotationOrError.forPossiblyNullAnnotation(foundAnnotation);
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  static TypeAndValue<?> typeAndValueOfMapKey(Annotation mapKeyAnnotation) {
-    if (!mapKeyAnnotation.annotationType().getAnnotation(MapKey.class).unwrapValue()) {
-      return new TypeAndValue(TypeLiteral.get(mapKeyAnnotation.annotationType()), mapKeyAnnotation);
-    } else {
-      try {
-        Method valueMethod = mapKeyAnnotation.annotationType().getDeclaredMethod("value");
-        valueMethod.setAccessible(true);
-        TypeLiteral<?> returnType =
-            TypeLiteral.get(mapKeyAnnotation.annotationType()).getReturnType(valueMethod);
-        return new TypeAndValue(returnType, valueMethod.invoke(mapKeyAnnotation));
-      } catch (NoSuchMethodException e) {
-        throw new IllegalStateException(e);
-      } catch (SecurityException e) {
-        throw new IllegalStateException(e);
-      } catch (IllegalAccessException e) {
-        throw new IllegalStateException(e);
-      } catch (InvocationTargetException e) {
-        throw new IllegalStateException(e);
-      }
-    }
-  }
-
-  private static class TypeAndValue<T> {
-    final TypeLiteral<T> type;
-    final T value;
-
-    TypeAndValue(TypeLiteral<T> type, T value) {
-      this.type = type;
-      this.value = value;
-    }
-  }
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinder.java
deleted file mode 100644
index 1986e7c..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinder.java
+++ /dev/null
@@ -1,754 +0,0 @@
-/**
- * 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.google.inject.multibindings;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.inject.multibindings.Multibinder.checkConfiguration;
-import static com.google.inject.util.Types.newParameterizedType;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Binder;
-import com.google.inject.Binding;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.spi.BindingTargetVisitor;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.Element;
-import com.google.inject.spi.ProviderInstanceBinding;
-import com.google.inject.spi.ProviderLookup;
-import com.google.inject.spi.ProviderWithDependencies;
-import com.google.inject.spi.ProviderWithExtensionVisitor;
-import com.google.inject.spi.Toolable;
-import com.google.inject.util.Types;
-
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Retention;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-import javax.inject.Qualifier;
-
-
-/**
- * An API to bind optional values, optionally with a default value.
- * OptionalBinder fulfills two roles: <ol>
- * <li>It allows a framework to define an injection point that may or
- *     may not be bound by users.
- * <li>It allows a framework to supply a default value that can be changed
- *     by users.
- * </ol>
- * 
- * <p>When an OptionalBinder is added, it will always supply the bindings:
- * {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
- * {@link #setBinding} or {@link #setDefault} are called, it will also
- * bind {@code T}.
- * 
- * <p>{@code setDefault} is intended for use by frameworks that need a default
- * value.  User code can call {@code setBinding} to override the default.
- * <b>Warning: Even if setBinding is called, the default binding
- * will still exist in the object graph.  If it is a singleton, it will be
- * instantiated in {@code Stage.PRODUCTION}.</b>
- * 
- * <p>If setDefault or setBinding are linked to Providers, the Provider may return
- * {@code null}.  If it does, the Optional bindings will be absent.  Binding
- * setBinding to a Provider that returns null will not cause OptionalBinder
- * to fall back to the setDefault binding.
- * 
- * <p>If neither setDefault nor setBinding are called, it will try to link to a
- * user-supplied binding of the same type.  If no binding exists, the optionals
- * will be absent.  Otherwise, if a user-supplied binding of that type exists,
- * or if setBinding or setDefault are called, the optionals will return present
- * if they are bound to a non-null value.
- *
- * <p>Values are resolved at injection time. If a value is bound to a
- * provider, that provider's get method will be called each time the optional
- * is injected (unless the binding is also scoped, or an optional of provider is
- * injected).
- * 
- * <p>Annotations are used to create different optionals of the same key/value
- * type. Each distinct annotation gets its own independent binding.
- *  
- * <pre><code>
- * public class FrameworkModule extends AbstractModule {
- *   protected void configure() {
- *     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
- *   }
- * }</code></pre>
- *
- * <p>With this module, an {@link Optional}{@code <Renamer>} can now be
- * injected.  With no other bindings, the optional will be absent.
- * Users can specify bindings in one of two ways:
- * 
- * <p>Option 1:
- * <pre><code>
- * public class UserRenamerModule extends AbstractModule {
- *   protected void configure() {
- *     bind(Renamer.class).to(ReplacingRenamer.class);
- *   }
- * }</code></pre>
- * 
- * <p>or Option 2:
- * <pre><code>
- * public class UserRenamerModule extends AbstractModule {
- *   protected void configure() {
- *     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
- *         .setBinding().to(ReplacingRenamer.class);
- *   }
- * }</code></pre>
- * With both options, the {@code Optional<Renamer>} will be present and supply the
- * ReplacingRenamer. 
- * 
- * <p>Default values can be supplied using:
- * <pre><code>
- * public class FrameworkModule extends AbstractModule {
- *   protected void configure() {
- *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
- *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
- *   }
- * }</code></pre>
- * With the above module, code can inject an {@code @LookupUrl String} and it
- * will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
- * <pre><code>
- * public class UserLookupModule extends AbstractModule {
- *   protected void configure() {
- *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
- *         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
- *   }
- * }</code></pre>
- * ... which will override the default value.
- * 
- * <p>If one module uses setDefault the only way to override the default is to use setBinding.
- * It is an error for a user to specify the binding without using OptionalBinder if
- * setDefault or setBinding are called.  For example, 
- * <pre><code>
- * public class FrameworkModule extends AbstractModule {
- *   protected void configure() {
- *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
- *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
- *   }
- * }
- * public class UserLookupModule extends AbstractModule {
- *   protected void configure() {
- *     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
- *   } 
- * }</code></pre>
- * ... would generate an error, because both the framework and the user are trying to bind
- * {@code @LookupUrl String}. 
- *
- * @author sameb@google.com (Sam Berlin)
- * @since 4.0
- */
-public abstract class OptionalBinder<T> {
-
-  /* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */
-  private static final Class<?> JAVA_OPTIONAL_CLASS;
-  private static final Method JAVA_EMPTY_METHOD;
-  private static final Method JAVA_OF_NULLABLE_METHOD;
-  static {
-    Class<?> optional = null;
-    Method empty = null;
-    Method ofNullable = null;
-    boolean useJavaOptional = false;
-    try {
-      optional = Class.forName("java.util.Optional");
-      empty = optional.getDeclaredMethod("empty");
-      ofNullable = optional.getDeclaredMethod("ofNullable", Object.class);
-      useJavaOptional = true;
-    } catch (ClassNotFoundException ignored) {
-    } catch (NoSuchMethodException ignored) {
-    } catch (SecurityException ignored) {
-    }
-    JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null;
-    JAVA_EMPTY_METHOD = useJavaOptional ? empty : null;
-    JAVA_OF_NULLABLE_METHOD = useJavaOptional ? ofNullable : null;
-  }
-
-  private OptionalBinder() {}
-
-  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type) {
-    return newRealOptionalBinder(binder, Key.get(type));
-  }
-  
-  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type) {
-    return newRealOptionalBinder(binder, Key.get(type));
-  }
-  
-  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type) {
-    return newRealOptionalBinder(binder, type);
-  }
-  
-  static <T> RealOptionalBinder<T> newRealOptionalBinder(Binder binder, Key<T> type) {
-    binder = binder.skipSources(OptionalBinder.class, RealOptionalBinder.class);
-    RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<T>(binder, type);
-    binder.install(optionalBinder);
-    return optionalBinder;
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> TypeLiteral<Optional<T>> optionalOf(
-      TypeLiteral<T> type) {
-    return (TypeLiteral<Optional<T>>) TypeLiteral.get(
-        Types.newParameterizedType(Optional.class,  type.getType()));
-  }
-
-  static <T> TypeLiteral<?> javaOptionalOf(
-      TypeLiteral<T> type) {
-    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
-    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType()));
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider(
-      TypeLiteral<T> type) {
-    return (TypeLiteral<Optional<javax.inject.Provider<T>>>) TypeLiteral.get(
-        Types.newParameterizedType(Optional.class,
-            newParameterizedType(javax.inject.Provider.class, type.getType())));
-  }
-
-  static <T> TypeLiteral<?> javaOptionalOfJavaxProvider(
-      TypeLiteral<T> type) {
-    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
-    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
-        newParameterizedType(javax.inject.Provider.class, type.getType())));
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) {
-    return (TypeLiteral<Optional<Provider<T>>>) TypeLiteral.get(Types.newParameterizedType(
-        Optional.class, newParameterizedType(Provider.class, type.getType())));
-  }
-
-  static <T> TypeLiteral<?> javaOptionalOfProvider(TypeLiteral<T> type) {
-    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
-    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
-        newParameterizedType(Provider.class, type.getType())));
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> Key<Provider<T>> providerOf(Key<T> key) {
-    Type providerT = Types.providerOf(key.getTypeLiteral().getType());
-    return (Key<Provider<T>>) key.ofType(providerT);
-  }
-
-  /**
-   * Returns a binding builder used to set the default value that will be injected.
-   * The binding set by this method will be ignored if {@link #setBinding} is called.
-   * 
-   * <p>It is an error to call this method without also calling one of the {@code to}
-   * methods on the returned binding builder. 
-   */
-  public abstract LinkedBindingBuilder<T> setDefault();
-
-
-  /**
-   * Returns a binding builder used to set the actual value that will be injected.
-   * This overrides any binding set by {@link #setDefault}.
-   * 
-   * <p>It is an error to call this method without also calling one of the {@code to}
-   * methods on the returned binding builder. 
-   */
-  public abstract LinkedBindingBuilder<T> setBinding();
-  
-  enum Source { DEFAULT, ACTUAL }
-  
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface Default {
-    String value();
-  }
-
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface Actual {
-    String value();
-  }
-
-  /**
-   * The actual OptionalBinder plays several roles.  It implements Module to hide that
-   * fact from the public API, and installs the various bindings that are exposed to the user.
-   */
-  static final class RealOptionalBinder<T> extends OptionalBinder<T> implements Module {
-    private final Key<T> typeKey;
-    private final Key<Optional<T>> optionalKey;
-    private final Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey;
-    private final Key<Optional<Provider<T>>> optionalProviderKey;
-    private final Provider<Optional<Provider<T>>> optionalProviderT;
-    private final Key<T> defaultKey;
-    private final Key<T> actualKey;
-
-    private final Key javaOptionalKey;
-    private final Key javaOptionalJavaxProviderKey;
-    private final Key javaOptionalProviderKey;
-
-    /** the target injector's binder. non-null until initialization, null afterwards */
-    private Binder binder;
-    /** the default binding, for the SPI. */
-    private Binding<T> defaultBinding;
-    /** the actual binding, for the SPI */
-    private Binding<T> actualBinding;
-    
-    /** the dependencies -- initialized with defaults & overridden when tooled. */
-    private Set<Dependency<?>> dependencies;
-    /** the dependencies -- initialized with defaults & overridden when tooled. */
-    private Set<Dependency<?>> providerDependencies;
-
-    private RealOptionalBinder(Binder binder, Key<T> typeKey) {
-      this.binder = binder;
-      this.typeKey = checkNotNull(typeKey);
-      TypeLiteral<T> literal = typeKey.getTypeLiteral();
-      this.optionalKey = typeKey.ofType(optionalOf(literal));
-      this.optionalJavaxProviderKey = typeKey.ofType(optionalOfJavaxProvider(literal));
-      this.optionalProviderKey = typeKey.ofType(optionalOfProvider(literal));
-      this.optionalProviderT = binder.getProvider(optionalProviderKey);
-      String name = RealElement.nameOf(typeKey);
-      this.defaultKey = Key.get(typeKey.getTypeLiteral(), new DefaultImpl(name));
-      this.actualKey = Key.get(typeKey.getTypeLiteral(), new ActualImpl(name));
-      // Until the injector initializes us, we don't know what our dependencies are,
-      // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly).
-      this.dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
-      this.providerDependencies =
-          ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
-
-      if (JAVA_OPTIONAL_CLASS != null) {
-        this.javaOptionalKey = typeKey.ofType(javaOptionalOf(literal));
-        this.javaOptionalJavaxProviderKey = typeKey.ofType(javaOptionalOfJavaxProvider(literal));
-        this.javaOptionalProviderKey = typeKey.ofType(javaOptionalOfProvider(literal));
-      } else {
-        this.javaOptionalKey = null;
-        this.javaOptionalJavaxProviderKey = null;
-        this.javaOptionalProviderKey = null;
-      }
-    }
-
-    /**
-     * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
-     * bindings.
-     */
-    private void addDirectTypeBinding(Binder binder) {
-      binder.bind(typeKey).toProvider(new RealDirectTypeProvider());
-    }
-
-    Key<T> getKeyForDefaultBinding() {
-      checkConfiguration(!isInitialized(), "already initialized");      
-      addDirectTypeBinding(binder);
-      return defaultKey;
-    }
-
-    @Override public LinkedBindingBuilder<T> setDefault() {
-      return binder.bind(getKeyForDefaultBinding());
-    }
-    
-    Key<T> getKeyForActualBinding() {
-      checkConfiguration(!isInitialized(), "already initialized");      
-      addDirectTypeBinding(binder);
-      return actualKey;
-    }
-
-    @Override public LinkedBindingBuilder<T> setBinding() {
-      return binder.bind(getKeyForActualBinding());
-    }
-
-    @Override public void configure(Binder binder) {
-      checkConfiguration(!isInitialized(), "OptionalBinder was already initialized");
-
-      binder.bind(optionalProviderKey).toProvider(new RealOptionalProviderProvider());
-
-      // Optional is immutable, so it's safe to expose Optional<Provider<T>> as
-      // Optional<javax.inject.Provider<T>> (since Guice provider implements javax Provider).
-      @SuppressWarnings({"unchecked", "cast"})
-      Key massagedOptionalProviderKey = (Key) optionalProviderKey;
-      binder.bind(optionalJavaxProviderKey).to(massagedOptionalProviderKey);
-
-      binder.bind(optionalKey).toProvider(new RealOptionalKeyProvider());
-
-      // Bind the java-8 types if we know them.
-      bindJava8Optional(binder);
-    }
-
-    @SuppressWarnings("unchecked")
-    private void bindJava8Optional(Binder binder) {
-      if (JAVA_OPTIONAL_CLASS != null) {
-        binder.bind(javaOptionalKey).toProvider(new JavaOptionalProvider());
-        binder.bind(javaOptionalProviderKey).toProvider(new JavaOptionalProviderProvider());
-        // for the javax version we reuse the guice version since they're type-compatible.
-        binder.bind(javaOptionalJavaxProviderKey).to(javaOptionalProviderKey);
-      }
-    }
-
-    @SuppressWarnings("rawtypes")
-    final class JavaOptionalProvider extends RealOptionalBinderProviderWithDependencies 
-        implements ProviderWithExtensionVisitor, OptionalBinderBinding {
-      private JavaOptionalProvider() {
-        super(typeKey);
-      }
-
-      @Override public Object get() {
-        Optional<Provider<T>> optional = optionalProviderT.get();
-        try {
-          if (optional.isPresent()) {
-            return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get().get());
-          } else {
-            return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
-          }
-        } catch (IllegalAccessException e) {
-          throw new SecurityException(e);
-        } catch (IllegalArgumentException e) {
-          throw new IllegalStateException(e);
-        } catch (InvocationTargetException e) {
-          throw Throwables.propagate(e.getCause());
-        }
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return dependencies;
-      }
-
-      @SuppressWarnings("unchecked")
-      @Override public Object acceptExtensionVisitor(BindingTargetVisitor visitor,
-          ProviderInstanceBinding binding) {
-        if (visitor instanceof MultibindingsTargetVisitor) {
-          return ((MultibindingsTargetVisitor) visitor).visit(this);
-        } else {
-          return visitor.visit(binding);
-        }
-      }
-
-      @Override public boolean containsElement(Element element) {
-        return RealOptionalBinder.this.containsElement(element);
-      }
-
-      @Override public Binding getActualBinding() {
-        return RealOptionalBinder.this.getActualBinding();
-      }
-
-      @Override public Binding getDefaultBinding() {
-        return RealOptionalBinder.this.getDefaultBinding();
-      }
-
-      @Override public Key getKey() {
-        return javaOptionalKey;
-      }
-    }
-
-    @SuppressWarnings("rawtypes")
-    final class JavaOptionalProviderProvider extends RealOptionalBinderProviderWithDependencies {
-      private JavaOptionalProviderProvider() {
-        super(typeKey);
-      }
-
-      @Override public Object get() {
-        Optional<Provider<T>> optional = optionalProviderT.get();
-        try {
-          if (optional.isPresent()) {
-            return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get());
-          } else {
-            return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
-          }
-        } catch (IllegalAccessException e) {
-          throw new SecurityException(e);
-        } catch (IllegalArgumentException e) {
-          throw new IllegalStateException(e);
-        } catch (InvocationTargetException e) {
-          throw Throwables.propagate(e.getCause());
-        }
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return providerDependencies;
-      }
-    }
-
-    final class RealDirectTypeProvider extends RealOptionalBinderProviderWithDependencies<T> {
-      private RealDirectTypeProvider() {
-        super(typeKey);
-      }
-
-      @Override public T get() {
-        Optional<Provider<T>> optional = optionalProviderT.get();
-        if (optional.isPresent()) {
-          return optional.get().get();
-        }
-        // Let Guice handle blowing up if the injection point doesn't have @Nullable
-        // (If it does have @Nullable, that's fine.  This would only happen if
-        //  setBinding/setDefault themselves were bound to 'null').
-        return null;
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return dependencies;
-      }
-    }
-
-    final class RealOptionalProviderProvider
-        extends RealOptionalBinderProviderWithDependencies<Optional<Provider<T>>> {
-      private Optional<Provider<T>> optional;
-
-      private RealOptionalProviderProvider() {
-        super(typeKey);
-      }
-
-      @Toolable @Inject void initialize(Injector injector) {
-        RealOptionalBinder.this.binder = null;
-        actualBinding = injector.getExistingBinding(actualKey);
-        defaultBinding = injector.getExistingBinding(defaultKey);
-        Binding<T> userBinding = injector.getExistingBinding(typeKey);
-        Binding<T> binding = null;
-        if (actualBinding != null) {
-          // TODO(sameb): Consider exposing an option that will allow
-          // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null.
-          // Right now, an ACTUAL binding can convert from present -> absent
-          // if it's bound to a provider that returns null.
-          binding = actualBinding;
-        } else if (defaultBinding != null) {
-          binding = defaultBinding;
-        } else if (userBinding != null) {
-          // If neither the actual or default is set, then we fallback
-          // to the value bound to the type itself and consider that the
-          // "actual binding" for the SPI.
-          binding = userBinding;
-          actualBinding = userBinding;
-        }
-          
-        if (binding != null) {
-          optional = Optional.of(binding.getProvider());
-          RealOptionalBinder.this.dependencies =
-              ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey()));
-          RealOptionalBinder.this.providerDependencies =
-              ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey())));
-        } else {
-          optional = Optional.absent();
-          RealOptionalBinder.this.dependencies = ImmutableSet.of();
-          RealOptionalBinder.this.providerDependencies = ImmutableSet.of();
-        }
-      }
-        
-      @Override public Optional<Provider<T>> get() {
-        return optional;
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return providerDependencies;
-      }
-    }
-
-    final class RealOptionalKeyProvider
-        extends RealOptionalBinderProviderWithDependencies<Optional<T>>
-        implements ProviderWithExtensionVisitor<Optional<T>>,
-            OptionalBinderBinding<Optional<T>>,
-            Provider<Optional<T>> {
-      private RealOptionalKeyProvider() {
-        super(typeKey);
-      }
-      
-      @Override public Optional<T> get() {
-        Optional<Provider<T>> optional = optionalProviderT.get();
-        if (optional.isPresent()) {
-          return Optional.fromNullable(optional.get().get());
-        } else {
-          return Optional.absent();
-        }
-      }
-
-      @Override public Set<Dependency<?>> getDependencies() {
-        return dependencies;
-      }
-
-      @SuppressWarnings("unchecked")
-      @Override
-      public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
-          ProviderInstanceBinding<? extends B> binding) {
-        if (visitor instanceof MultibindingsTargetVisitor) {
-          return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this);
-        } else {
-          return visitor.visit(binding);
-        }
-      }
-
-      @Override public Key<Optional<T>> getKey() {
-        return optionalKey;
-      }
-
-      @Override public Binding<?> getActualBinding() {
-        return RealOptionalBinder.this.getActualBinding();
-      }
-
-      @Override public Binding<?> getDefaultBinding() {
-        return RealOptionalBinder.this.getDefaultBinding();
-      }
-
-      @Override public boolean containsElement(Element element) {
-        return RealOptionalBinder.this.containsElement(element);
-      }
-    }
-
-    private Binding<?> getActualBinding() {
-      if (isInitialized()) {
-        return actualBinding;
-      } else {
-        throw new UnsupportedOperationException(
-            "getActualBinding() not supported from Elements.getElements, requires an Injector.");
-      }
-    }
-
-    private Binding<?> getDefaultBinding() {
-      if (isInitialized()) {
-        return defaultBinding;
-      } else {
-        throw new UnsupportedOperationException(
-            "getDefaultBinding() not supported from Elements.getElements, requires an Injector.");
-      }
-    }
-
-    private boolean containsElement(Element element) {
-      Key<?> elementKey;
-      if (element instanceof Binding) {
-        elementKey = ((Binding<?>) element).getKey();
-      } else if (element instanceof ProviderLookup) {
-        elementKey = ((ProviderLookup<?>) element).getKey();
-      } else {
-        return false; // cannot match;
-      }
-
-      return elementKey.equals(optionalKey)
-          || elementKey.equals(optionalProviderKey)
-          || elementKey.equals(optionalJavaxProviderKey)
-          || elementKey.equals(defaultKey)
-          || elementKey.equals(actualKey)
-          || matchesJ8Keys(elementKey)
-          || matchesTypeKey(element, elementKey);
-    }
-
-    private boolean matchesJ8Keys(Key<?> elementKey) {
-      if (JAVA_OPTIONAL_CLASS != null) {
-        return elementKey.equals(javaOptionalKey)
-            || elementKey.equals(javaOptionalProviderKey)
-            || elementKey.equals(javaOptionalJavaxProviderKey);
-      }
-      return false;
-    }
-    
-    /** Returns true if the key & element indicate they were bound by this OptionalBinder. */
-    private boolean matchesTypeKey(Element element, Key<?> elementKey) {
-      // Just doing .equals(typeKey) isn't enough, because the user can bind that themselves.
-      return elementKey.equals(typeKey)
-          && element instanceof ProviderInstanceBinding
-          && (((ProviderInstanceBinding) element)
-              .getUserSuppliedProvider() instanceof RealOptionalBinderProviderWithDependencies);
-    }
-
-    private boolean isInitialized() {
-      return binder == null;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o instanceof RealOptionalBinder
-          && ((RealOptionalBinder<?>) o).typeKey.equals(typeKey);
-    }
-
-    @Override public int hashCode() {
-      return typeKey.hashCode();
-    }
-
-    /**
-     * A base class for ProviderWithDependencies that need equality based on a specific object.
-     */
-    private abstract static class RealOptionalBinderProviderWithDependencies<T> implements
-        ProviderWithDependencies<T> {
-      private final Object equality;
-
-      public RealOptionalBinderProviderWithDependencies(Object equality) {
-        this.equality = equality;
-      }
-
-      @Override public boolean equals(Object obj) {
-        return this.getClass() == obj.getClass()
-            && equality.equals(((RealOptionalBinderProviderWithDependencies<?>) obj).equality);
-      }
-
-      @Override public int hashCode() {
-        return equality.hashCode();
-      }
-    }
-  }
-  
-  static class DefaultImpl extends BaseAnnotation implements Default {
-    public DefaultImpl(String value) {
-      super(Default.class, value);
-    }
-  }
-  
-  static class ActualImpl extends BaseAnnotation implements Actual {
-    public ActualImpl(String value) {
-      super(Actual.class, value);
-    }
-  }
-  
-  abstract static class BaseAnnotation implements Serializable, Annotation {
-
-    private final String value;
-    private final Class<? extends Annotation> clazz;
-
-    BaseAnnotation(Class<? extends Annotation> clazz, String value) {
-      this.clazz = checkNotNull(clazz, "clazz");
-      this.value = checkNotNull(value, "value");
-    }
-
-    public String value() {
-      return this.value;
-    }
-
-    @Override public int hashCode() {
-      // This is specified in java.lang.Annotation.
-      return (127 * "value".hashCode()) ^ value.hashCode();
-    }
-
-    @Override public boolean equals(Object o) {
-      // We check against each annotation type instead of BaseAnnotation
-      // so that we can compare against generated annotation implementations. 
-      if (o instanceof Actual && clazz == Actual.class) {
-        Actual other = (Actual) o;
-        return value.equals(other.value());
-      } else if (o instanceof Default && clazz == Default.class) {
-        Default other = (Default) o;
-        return value.equals(other.value());
-      }
-      return false;
-    }
-
-    @Override public String toString() {
-      return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")");
-    }
-
-    @Override public Class<? extends Annotation> annotationType() {
-      return clazz;
-    }
-
-    private static final long serialVersionUID = 0;
-  }
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinderBinding.java b/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinderBinding.java
deleted file mode 100644
index fbbbc36..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/OptionalBinderBinding.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.google.inject.multibindings;
-
-import com.google.inject.Binding;
-import com.google.inject.Key;
-import com.google.inject.spi.Element;
-import com.google.inject.spi.Elements;
-
-/**
- * A binding for a OptionalBinder.
- * 
- * <p>Although OptionalBinders may be injected through a variety of types
- * {@code T}, {@code Optional<T>}, {@code Optional<Provider<T>>}, etc..), an
- * OptionalBinderBinding exists only on the Binding associated with the
- * {@code Optional<T>} key.  Other bindings can be validated to be derived from this
- * OptionalBinderBinding using {@link #containsElement}.
- * 
- * @param <T> The fully qualified type of the optional binding, including Optional.
- *        For example: {@code Optional<String>}.
- * 
- * @since 4.0
- * @author sameb@google.com (Sam Berlin)
- */
-public interface OptionalBinderBinding<T> {
-
-  /** Returns the {@link Key} for this binding. */
-  Key<T> getKey();
-  
-  /**
-   * Returns the default binding (set by {@link OptionalBinder#setDefault}) if one exists or null
-   * if no default binding is set. This will throw {@link UnsupportedOperationException} if it is
-   * called on an element retrieved from {@link Elements#getElements}.
-   * <p>
-   * The Binding's type will always match the type Optional's generic type. For example, if getKey
-   * returns a key of <code>Optional&lt;String></code>, then this will always return a
-   * <code>Binding&lt;String></code>.
-   */
-  Binding<?> getDefaultBinding();
-  
-  /**
-   * Returns the actual binding (set by {@link OptionalBinder#setBinding}) or null if not set.
-   * This will throw {@link UnsupportedOperationException} if it is called on an element retrieved
-   * from {@link Elements#getElements}.
-   * <p>
-   * The Binding's type will always match the type Optional's generic type. For example, if getKey
-   * returns a key of <code>Optional&lt;String></code>, then this will always return a
-   * <code>Binding&lt;String></code>.
-   */
-  Binding<?> getActualBinding();
-
-  /**
-   * Returns true if this OptionalBinder contains the given Element in order to build the optional
-   * binding or uses the given Element in order to support building and injecting its data. This
-   * will work for OptionalBinderBinding retrieved from an injector and
-   * {@link Elements#getElements}. Usually this is only necessary if you are working with elements
-   * retrieved from modules (without an Injector), otherwise {@link #getDefaultBinding} and
-   * {@link #getActualBinding} are better options.
-   */
-  boolean containsElement(Element element);
-}
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java b/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java
deleted file mode 100644
index e018f49..0000000
--- a/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import com.google.inject.Key;
-import com.google.inject.internal.Annotations;
-
-import java.lang.annotation.Annotation;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/** An implementation of Element. */
-// TODO(cgruber): Use AutoAnnotation when available, here & wherever else is makes sense.
-class RealElement implements Element {
-  private static final AtomicInteger nextUniqueId = new AtomicInteger(1);
-  
-  private final int uniqueId;
-  private final String setName;
-  private final Element.Type type;
-  private final String keyType;
-
-  RealElement(String setName, Element.Type type, String keyType) {
-    this(setName, type, keyType, nextUniqueId.incrementAndGet());
-  }
-  
-  RealElement(String setName, Element.Type type, String keyType, int uniqueId) {
-    this.uniqueId = uniqueId;
-    this.setName = setName;
-    this.type = type;
-    this.keyType = keyType;
-  }
-  
-  @Override public String setName() {
-    return setName;
-  }
-  
-  @Override public int uniqueId() {
-    return uniqueId;
-  }
-  
-  @Override public Element.Type type() {
-    return type;
-  }
-  
-  @Override public String keyType() {
-    return keyType;
-  }
-
-  @Override public Class<? extends Annotation> annotationType() {
-    return Element.class;
-  }
-  
-  @Override public String toString() {
-    return "@" + Element.class.getName() + "(setName=" + setName
-        + ",uniqueId=" + uniqueId + ", type=" + type + ", keyType=" + keyType + ")";
-  }
-
-  @Override public boolean equals(Object o) {
-    return o instanceof Element
-        && ((Element) o).setName().equals(setName())
-        && ((Element) o).uniqueId() == uniqueId()
-        && ((Element) o).type() == type()
-        && ((Element) o).keyType().equals(keyType());
-  }
-
-  @Override public int hashCode() {
-    return ((127 * "setName".hashCode()) ^ setName.hashCode())
-        + ((127 * "uniqueId".hashCode()) ^ uniqueId)
-        + ((127 * "type".hashCode()) ^ type.hashCode())
-        + ((127 * "keyType".hashCode()) ^ keyType.hashCode());
-  }
-
-  /**
-   * Returns the name the binding should use.  This is based on the annotation.
-   * If the annotation has an instance and is not a marker annotation,
-   * we ask the annotation for its toString.  If it was a marker annotation
-   * or just an annotation type, we use the annotation's name. Otherwise,
-   * the name is the empty string.
-   */
-  static String nameOf(Key<?> key) {
-    Annotation annotation = key.getAnnotation();
-    Class<? extends Annotation> annotationType = key.getAnnotationType();
-    if (annotation != null && !Annotations.isMarker(annotationType)) {
-      return key.getAnnotation().toString();
-    } else if (key.getAnnotationType() != null) {
-      return "@" + key.getAnnotationType().getName();
-    } else {
-      return "";
-    }
-  }
-}
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/AllTests.java b/extensions/multibindings/test/com/google/inject/multibindings/AllTests.java
deleted file mode 100644
index 6806edd..0000000
--- a/extensions/multibindings/test/com/google/inject/multibindings/AllTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
-public class AllTests {
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTestSuite(MapBinderTest.class);
-    suite.addTestSuite(MultibinderTest.class);
-    suite.addTestSuite(OptionalBinderTest.class);
-    suite.addTestSuite(RealElementTest.class);
-    suite.addTestSuite(ProvidesIntoTest.class);
-    return suite;
-  }
-}
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
deleted file mode 100644
index 4206521..0000000
--- a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
+++ /dev/null
@@ -1,1032 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import static com.google.inject.Asserts.asModuleChain;
-import static com.google.inject.Asserts.assertContains;
-import static com.google.inject.multibindings.SpiUtils.VisitType.BOTH;
-import static com.google.inject.multibindings.SpiUtils.VisitType.MODULE;
-import static com.google.inject.multibindings.SpiUtils.assertMapVisitor;
-import static com.google.inject.multibindings.SpiUtils.instance;
-import static com.google.inject.multibindings.SpiUtils.providerInstance;
-import static com.google.inject.name.Names.named;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.base.Function;
-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.inject.AbstractModule;
-import com.google.inject.Asserts;
-import com.google.inject.Binding;
-import com.google.inject.BindingAnnotation;
-import com.google.inject.ConfigurationException;
-import com.google.inject.CreationException;
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
-import com.google.inject.ProvisionException;
-import com.google.inject.Stage;
-import com.google.inject.TypeLiteral;
-import com.google.inject.internal.WeakKeySetUtils;
-import com.google.inject.name.Names;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.InstanceBinding;
-import com.google.inject.util.Modules;
-import com.google.inject.util.Providers;
-import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * @author dpb@google.com (David P. Baker)
- */
-public class MapBinderTest extends TestCase {
-
-  private static final Set<Key<?>> FRAMEWORK_KEYS = ImmutableSet.of(
-      Key.get(java.util.logging.Logger.class),
-      Key.get(Stage.class),
-      Key.get(Injector.class)
-  );
-
-  final TypeLiteral<Map<String, javax.inject.Provider<String>>> mapOfStringJavaxProvider =
-      new TypeLiteral<Map<String, javax.inject.Provider<String>>>() {};
-  final TypeLiteral<Map<String, Provider<String>>> mapOfStringProvider =
-      new TypeLiteral<Map<String, Provider<String>>>() {}; 
-  final TypeLiteral<Map<String, String>> mapOfString = new TypeLiteral<Map<String, String>>() {};
-  final TypeLiteral<Map<Integer, String>> mapOfIntString =
-      new TypeLiteral<Map<Integer, String>>() {};
-  final TypeLiteral<Map<String, Integer>> mapOfInteger = new TypeLiteral<Map<String, Integer>>() {};
-  final TypeLiteral<Map<String, Set<String>>> mapOfSetOfString =
-      new TypeLiteral<Map<String, Set<String>>>() {};
-      
-  private final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
-  private final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
-
-  private Type javaxProviderOf(Type type) {
-    return Types.newParameterizedType(javax.inject.Provider.class, type);
-  }
-
-  private Type mapEntryOf(Type keyType, Type valueType) {
-    return Types.newParameterizedTypeWithOwner(Map.class, Map.Entry.class, keyType, valueType);
-  }
-
-  private Type collectionOf(Type type) {
-    return Types.newParameterizedType(Collection.class, type);
-  }
-
-  public void testAllBindings() {
-    Module module = new AbstractModule() {
-      @Override
-      protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, String.class).permitDuplicates();
-      }
-    };
-
-    Injector injector = Guice.createInjector(module);
-
-    Map<Key<?>, Binding<?>> bindings = injector.getBindings();
-
-    ImmutableSet<Key<?>> expectedBindings = ImmutableSet.<Key<?>>builder()
-        .add(
-            // Map<K, V>
-            Key.get(Types.mapOf(String.class, String.class)),
-            // Map<K, Provider<V>>
-            Key.get(Types.mapOf(String.class, Types.providerOf(String.class))),
-            // Map<K, javax.inject.Provider<V>>
-            Key.get(Types.mapOf(String.class, javaxProviderOf(String.class))),
-            // Map<K, Set<V>>
-            Key.get(Types.mapOf(String.class, Types.setOf(String.class))),
-            // Map<K, Set<Provider<V>>
-            Key.get(Types.mapOf(String.class, Types.setOf(Types.providerOf(String.class)))),
-            // Set<Map.Entry<K, Provider<V>>>
-            Key.get(Types.setOf(mapEntryOf(String.class, Types.providerOf(String.class)))),
-            // Collection<Provider<Map.Entry<K, Provider<V>>>>
-            Key.get(collectionOf(Types.providerOf(
-                mapEntryOf(String.class, Types.providerOf(String.class))))),
-            // Collection<javax.inject.Provider<Map.Entry<K, Provider<V>>>>
-            Key.get(collectionOf(javaxProviderOf(
-                mapEntryOf(String.class, Types.providerOf(String.class))))),
-            // @Named(...) Boolean
-            Key.get(Boolean.class,
-                named("Multibinder<java.util.Map$Entry<java.lang.String, "
-                    + "com.google.inject.Provider<java.lang.String>>> permits duplicates"))
-        )
-        .addAll(FRAMEWORK_KEYS).build();
-
-    Set<Key<?>> missingBindings = Sets.difference(expectedBindings, bindings.keySet());
-    Set<Key<?>> extraBindings = Sets.difference(bindings.keySet(), expectedBindings);
-
-    assertTrue("There should be no missing bindings. Missing: " + missingBindings,
-        missingBindings.isEmpty());
-    assertTrue("There should be no extra bindings. Extra: " + extraBindings,
-        extraBindings.isEmpty());
-  }
-
-  public void testMapBinderAggregatesMultipleModules() {
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    Module de = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("d").toInstance("D");
-        multibinder.addBinding("e").toInstance("E");
-      }
-    };
-
-    Injector injector = Guice.createInjector(abc, de);
-    Map<String, String> abcde = injector.getInstance(Key.get(mapOfString));
-
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E"), abcde);
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(abc, de), BOTH, false, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"), instance("d", "D"), instance("e", "E"));
-
-    // just make sure these succeed
-    injector.getInstance(Key.get(mapOfStringProvider));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider));
-  }
-
-  public void testMapBinderAggregationForAnnotationInstance() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Names.named("abc"));
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-
-        multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Names.named("abc"));
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Map<String, String>> key = Key.get(mapOfString, Names.named("abc"));
-    Map<String, String> abc = injector.getInstance(key);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
-    assertMapVisitor(key, stringType, stringType, setOf(module), BOTH, false, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"));
-    
-    // just make sure these succeed
-    injector.getInstance(Key.get(mapOfStringProvider, Names.named("abc")));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, Names.named("abc")));
-  }
-
-  public void testMapBinderAggregationForAnnotationType() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Abc.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-
-        multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Abc.class);
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Map<String, String>> key = Key.get(mapOfString, Abc.class);
-    Map<String, String> abc = injector.getInstance(key);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
-    assertMapVisitor(key, stringType, stringType, setOf(module), BOTH, false, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"));
-    
-    // just make sure these succeed
-    injector.getInstance(Key.get(mapOfStringProvider, Abc.class));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, Abc.class));
-  }
-
-  public void testMapBinderWithMultipleAnnotationValueSets() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> abcMapBinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, named("abc"));
-        abcMapBinder.addBinding("a").toInstance("A");
-        abcMapBinder.addBinding("b").toInstance("B");
-        abcMapBinder.addBinding("c").toInstance("C");
-
-        MapBinder<String, String> deMapBinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, named("de"));
-        deMapBinder.addBinding("d").toInstance("D");
-        deMapBinder.addBinding("e").toInstance("E");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Map<String, String>> abcKey = Key.get(mapOfString, named("abc"));
-    Map<String, String> abc = injector.getInstance(abcKey);
-    Key<Map<String, String>> deKey = Key.get(mapOfString, named("de"));
-    Map<String, String> de = injector.getInstance(deKey);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
-    assertEquals(mapOf("d", "D", "e", "E"), de);
-    assertMapVisitor(abcKey, stringType, stringType, setOf(module), BOTH, false, 1,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"));
-    assertMapVisitor(deKey, stringType, stringType, setOf(module), BOTH, false, 1,
-        instance("d", "D"), instance("e", "E"));     
-    
-    // just make sure these succeed
-    injector.getInstance(Key.get(mapOfStringProvider, named("abc")));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, named("abc")));
-    injector.getInstance(Key.get(mapOfStringProvider, named("de")));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, named("de")));
-  }
-
-  public void testMapBinderWithMultipleAnnotationTypeSets() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> abcMapBinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Abc.class);
-        abcMapBinder.addBinding("a").toInstance("A");
-        abcMapBinder.addBinding("b").toInstance("B");
-        abcMapBinder.addBinding("c").toInstance("C");
-
-        MapBinder<String, String> deMapBinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, De.class);
-        deMapBinder.addBinding("d").toInstance("D");
-        deMapBinder.addBinding("e").toInstance("E");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Map<String, String>> abcKey = Key.get(mapOfString, Abc.class);
-    Map<String, String> abc = injector.getInstance(abcKey);
-    Key<Map<String, String>> deKey = Key.get(mapOfString, De.class);
-    Map<String, String> de = injector.getInstance(deKey);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), abc);
-    assertEquals(mapOf("d", "D", "e", "E"), de);
-    assertMapVisitor(abcKey, stringType, stringType, setOf(module), BOTH, false, 1,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"));
-    assertMapVisitor(deKey, stringType, stringType, setOf(module), BOTH, false, 1,
-        instance("d", "D"), instance("e", "E"));
-    
-    // just make sure these succeed
-    injector.getInstance(Key.get(mapOfStringProvider, Abc.class));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, Abc.class));
-    injector.getInstance(Key.get(mapOfStringProvider, De.class));
-    injector.getInstance(Key.get(mapOfStringJavaxProvider, De.class));
-  }
-
-  public void testMapBinderWithMultipleTypes() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("a").toInstance("A");
-        MapBinder.newMapBinder(binder(), String.class, Integer.class)
-            .addBinding("1").toInstance(1);
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    assertEquals(mapOf("a", "A"), injector.getInstance(Key.get(mapOfString)));
-    assertEquals(mapOf("1", 1), injector.getInstance(Key.get(mapOfInteger)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(module), BOTH, false, 1,
-        instance("a", "A"));
-    assertMapVisitor(Key.get(mapOfInteger), stringType, intType, setOf(module), BOTH, false, 1,
-        instance("1", 1));
-  }
-
-  public void testMapBinderWithEmptyMap() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, String.class);
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Map<String, String> map = injector.getInstance(Key.get(mapOfString));
-    assertEquals(Collections.emptyMap(), map);
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(module), BOTH, false, 0);
-  }
-
-  public void testMapBinderMapIsUnmodifiable() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("a").toInstance("A");
-      }
-    });
-
-    Map<String, String> map = injector.getInstance(Key.get(mapOfString));
-    try {
-      map.clear();
-      fail();
-    } catch(UnsupportedOperationException expected) {
-    }
-  }
-
-  public void testMapBinderMapIsLazy() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, Integer.class)
-            .addBinding("num").toProvider(new Provider<Integer>() {
-          int nextValue = 1;
-          @Override public Integer get() {
-            return nextValue++;
-          }
-        });
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    assertEquals(mapOf("num", 1), injector.getInstance(Key.get(mapOfInteger)));
-    assertEquals(mapOf("num", 2), injector.getInstance(Key.get(mapOfInteger)));
-    assertEquals(mapOf("num", 3), injector.getInstance(Key.get(mapOfInteger)));
-    assertMapVisitor(Key.get(mapOfInteger), stringType, intType, setOf(module), BOTH, false, 0,
-        providerInstance("num", 1));
-  }
-
-  public void testMapBinderMapForbidsDuplicateKeys() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("a").toInstance("B");
-      }
-    };
-    try {
-      Guice.createInjector(module);
-      fail();
-    } catch(CreationException expected) {
-      assertContains(expected.getMessage(),
-          "Map injection failed due to duplicated key \"a\"");
-    }
-    
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(module), MODULE, false, 0,
-        instance("a", "A"), instance("a", "B"));
-  }
-
-  public void testExhaustiveDuplicateErrorMessage() throws Exception {
-    class Module1 extends AbstractModule {
-      @Override protected void configure() {
-        MapBinder<String, Object> mapbinder =
-            MapBinder.newMapBinder(binder(), String.class, Object.class);
-        mapbinder.addBinding("a").to(String.class);
-      }
-    }
-    class Module2 extends AbstractModule {
-      @Override protected void configure() {
-        MapBinder<String, Object> mapbinder =
-            MapBinder.newMapBinder(binder(), String.class, Object.class);
-        mapbinder.addBinding("a").to(Integer.class);
-        mapbinder.addBinding("b").to(String.class);
-      }
-    }
-    class Module3 extends AbstractModule {
-      @Override protected void configure() {
-        MapBinder<String, Object> mapbinder =
-            MapBinder.newMapBinder(binder(), String.class, Object.class);
-        mapbinder.addBinding("b").to(Integer.class);
-      }
-    }
-    class Main extends AbstractModule {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, Object.class);
-        install(new Module1());
-        install(new Module2());
-        install(new Module3());
-      }
-      @Provides String provideString() { return "foo"; }
-      @Provides Integer provideInt() { return 42; }
-    }
-    try {
-      Guice.createInjector(new Main());
-      fail();
-    } catch(CreationException ce) {
-      assertContains(ce.getMessage(),
-          "Map injection failed due to duplicated key \"a\", from bindings:",
-          asModuleChain(Main.class, Module1.class),
-          asModuleChain(Main.class, Module2.class),
-          "and key: \"b\", from bindings:",
-          asModuleChain(Main.class, Module2.class),
-          asModuleChain(Main.class, Module3.class),
-          "at " + Main.class.getName() + ".configure(",
-          asModuleChain(Main.class, MapBinder.RealMapBinder.class));
-      assertEquals(1, ce.getErrorMessages().size());
-    }
-  }
-
-  public void testMapBinderMapPermitDuplicateElements() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.permitDuplicates();
-      }
-    };
-    Module bc = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.permitDuplicates();
-      }
-    };
-    Injector injector = Guice.createInjector(ab, bc);
-
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), injector.getInstance(Key.get(mapOfString)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(ab, bc), BOTH, true, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"));
-  }
-
-  public void testMapBinderMapDoesNotDedupeDuplicateValues() {
-    class ValueType {
-      int keyPart;
-      int dataPart;
-      private ValueType(int keyPart, int dataPart) {
-        this.keyPart = keyPart;
-        this.dataPart = dataPart;
-      }
-      @Override
-      public boolean equals(Object obj) {
-        return (obj instanceof ValueType) && (keyPart == ((ValueType) obj).keyPart);
-      }
-      @Override
-      public int hashCode() {
-        return keyPart;
-      }
-    }
-    Module m1 = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, ValueType> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, ValueType.class);
-        multibinder.addBinding("a").toInstance(new ValueType(1, 2));
-      }
-    };
-    Module m2 = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, ValueType> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, ValueType.class);
-        multibinder.addBinding("b").toInstance(new ValueType(1, 3));
-      }
-    };
-    
-    Injector injector = Guice.createInjector(m1, m2);
-    Map<String, ValueType> map = injector.getInstance(new Key<Map<String, ValueType>>() {});
-    assertEquals(2, map.get("a").dataPart);
-    assertEquals(3, map.get("b").dataPart);
-  }
-
-  public void testMapBinderMultimap() {
-    AbstractModule ab1c = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B1");
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    AbstractModule b2c = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        multibinder.addBinding("b").toInstance("B2");
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.permitDuplicates();
-      }
-    };
-    Injector injector = Guice.createInjector(ab1c, b2c);
-
-    assertEquals(mapOf("a", setOf("A"), "b", setOf("B1", "B2"), "c", setOf("C")),
-        injector.getInstance(Key.get(mapOfSetOfString)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(ab1c, b2c), BOTH, true, 0,
-        instance("a", "A"), instance("b", "B1"), instance("b", "B2"), instance("c", "C"));
-  }
-
-  public void testMapBinderMultimapWithAnotation() {
-    AbstractModule ab1 = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Abc.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B1");
-      }
-    };
-    AbstractModule b2c = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class, Abc.class);
-        multibinder.addBinding("b").toInstance("B2");
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.permitDuplicates();
-      }
-    };
-    Injector injector = Guice.createInjector(ab1, b2c);
-
-    assertEquals(mapOf("a", setOf("A"), "b", setOf("B1", "B2"), "c", setOf("C")),
-        injector.getInstance(Key.get(mapOfSetOfString, Abc.class)));
-    try {
-      injector.getInstance(Key.get(mapOfSetOfString));
-      fail();
-    } catch (ConfigurationException expected) {}
-    
-    assertMapVisitor(Key.get(mapOfString, Abc.class), stringType, stringType, setOf(ab1, b2c), BOTH, true, 0,
-        instance("a", "A"), instance("b", "B1"), instance("b", "B2"), instance("c", "C"));
-  }
-
-  public void testMapBinderMultimapIsUnmodifiable() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> mapBinder = MapBinder.newMapBinder(
-            binder(), String.class, String.class);
-        mapBinder.addBinding("a").toInstance("A");
-        mapBinder.permitDuplicates();
-      }
-    });
-
-    Map<String, Set<String>> map = injector.getInstance(Key.get(mapOfSetOfString));
-    try {
-      map.clear();
-      fail();
-    } catch(UnsupportedOperationException expected) {
-    }
-    try {
-      map.get("a").clear();
-      fail();
-    } catch(UnsupportedOperationException expected) {
-    }
-  }
-
-  public void testMapBinderMapForbidsNullKeys() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          MapBinder.newMapBinder(binder(), String.class, String.class).addBinding(null);
-        }
-      });
-      fail();
-    } catch (CreationException expected) {}
-  }
-
-  public void testMapBinderMapForbidsNullValues() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("null").toProvider(Providers.<String>of(null));
-      }
-    };
-    Injector injector = Guice.createInjector(m);
-
-    try {
-      injector.getInstance(Key.get(mapOfString));
-      fail();
-    } catch(ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "1) Map injection failed due to null value for key \"null\", bound at: "
-          + m.getClass().getName() + ".configure(");
-    }
-  }
-
-  public void testMapBinderProviderIsScoped() {
-    final Provider<Integer> counter = new Provider<Integer>() {
-      int next = 1;
-      @Override public Integer get() {
-        return next++;
-      }
-    };
-
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder.newMapBinder(binder(), String.class, Integer.class)
-            .addBinding("one").toProvider(counter).asEagerSingleton();
-      }
-    });
-
-    assertEquals(1, (int) injector.getInstance(Key.get(mapOfInteger)).get("one"));
-    assertEquals(1, (int) injector.getInstance(Key.get(mapOfInteger)).get("one"));
-  }
-
-  public void testSourceLinesInMapBindings() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          MapBinder.newMapBinder(binder(), String.class, Integer.class)
-              .addBinding("one");
-        }
-      });
-      fail();
-    } catch (CreationException expected) {
-      assertContains(expected.getMessage(),
-          "1) No implementation for java.lang.Integer",
-          "at " + getClass().getName());
-    }
-  }
-
-  /** We just want to make sure that mapbinder's binding depends on the underlying multibinder. */
-  public void testMultibinderDependencies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<Integer, String> mapBinder
-            = MapBinder.newMapBinder(binder(), Integer.class, String.class);
-        mapBinder.addBinding(1).toInstance("A");
-        mapBinder.addBinding(2).to(Key.get(String.class, Names.named("b")));
-
-        bindConstant().annotatedWith(Names.named("b")).to("B");
-      }
-    });
-
-    Binding<Map<Integer, String>> binding = injector.getBinding(new Key<Map<Integer, String>>() {});
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Key<?> setKey = new Key<Set<Map.Entry<Integer, Provider<String>>>>() {};
-    assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(setKey)),
-        withDependencies.getDependencies());
-    Set<String> elements = Sets.newHashSet();
-    elements.addAll(recurseForDependencies(injector, withDependencies));
-    assertEquals(ImmutableSet.of("A", "B"), elements);
-  }
-
-  private Set<String> recurseForDependencies(Injector injector, HasDependencies hasDependencies) {
-    Set<String> elements = Sets.newHashSet();
-    for (Dependency<?> dependency : hasDependencies.getDependencies()) {
-      Binding<?> binding = injector.getBinding(dependency.getKey());
-      HasDependencies deps = (HasDependencies) binding;
-      if (binding instanceof InstanceBinding) {
-        elements.add((String) ((InstanceBinding<?>) binding).getInstance());
-      } else {
-        elements.addAll(recurseForDependencies(injector, deps));
-      }
-    }    
-    return elements;
-  }
-
-  /** We just want to make sure that mapbinder's binding depends on the underlying multibinder. */
-  public void testMultibinderDependenciesInToolStage() {
-    Injector injector = Guice.createInjector(Stage.TOOL, new AbstractModule() {
-      @Override protected void configure() {
-          MapBinder<Integer, String> mapBinder
-              = MapBinder.newMapBinder(binder(), Integer.class, String.class);
-          mapBinder.addBinding(1).toInstance("A");
-          mapBinder.addBinding(2).to(Key.get(String.class, Names.named("b")));
-  
-          bindConstant().annotatedWith(Names.named("b")).to("B");
-        }});
-
-    Binding<Map<Integer, String>> binding = injector.getBinding(new Key<Map<Integer, String>>() {});
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Key<?> setKey = new Key<Set<Map.Entry<Integer, Provider<String>>>>() {};
-    assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(setKey)),
-        withDependencies.getDependencies());
-  }
-  
-
-  /**
-   * Our implementation maintains order, but doesn't guarantee it in the API spec.
-   * TODO: specify the iteration order?
-   */
-  public void testBindOrderEqualsIterationOrder() {
-    Injector injector = Guice.createInjector(
-        new AbstractModule() {
-          @Override protected void configure() {
-            MapBinder<String, String> mapBinder
-                = MapBinder.newMapBinder(binder(), String.class, String.class);
-            mapBinder.addBinding("leonardo").toInstance("blue");
-            mapBinder.addBinding("donatello").toInstance("purple");
-            install(new AbstractModule() {
-              @Override protected void configure() {
-                MapBinder.newMapBinder(binder(), String.class, String.class)
-                    .addBinding("michaelangelo").toInstance("orange");
-              }
-            });
-          }
-        },
-        new AbstractModule() {
-          @Override protected void configure() {
-            MapBinder.newMapBinder(binder(), String.class, String.class)
-                .addBinding("raphael").toInstance("red");
-          }
-        });
-
-    Map<String, String> map = injector.getInstance(new Key<Map<String, String>>() {});
-    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
-    assertEquals(Maps.immutableEntry("leonardo", "blue"), iterator.next());
-    assertEquals(Maps.immutableEntry("donatello", "purple"), iterator.next());
-    assertEquals(Maps.immutableEntry("michaelangelo", "orange"), iterator.next());
-    assertEquals(Maps.immutableEntry("raphael", "red"), iterator.next());
-  }
-  
-  /**
-   * With overrides, we should get the union of all map bindings.
-   */
-  public void testModuleOverrideAndMapBindings() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-      }
-    };
-    Module cd = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.addBinding("d").toInstance("D");
-      }
-    };
-    Module ef = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("e").toInstance("E");
-        multibinder.addBinding("f").toInstance("F");
-      }
-    };
-
-    Module abcd = Modules.override(ab).with(cd);
-    Injector injector = Guice.createInjector(abcd, ef);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F"),
-        injector.getInstance(Key.get(mapOfString)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(abcd, ef), BOTH, false, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"), instance("d", "D"), instance(
-            "e", "E"), instance("f", "F"));
-  }
-  
-  public void testDeduplicateMapBindings() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> mapbinder =
-            MapBinder.newMapBinder(binder(), String.class, String.class);
-        mapbinder.addBinding("a").toInstance("A");
-        mapbinder.addBinding("a").toInstance("A");
-        mapbinder.addBinding("b").toInstance("B");
-        mapbinder.addBinding("b").toInstance("B");
-        
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals(mapOf("a", "A", "b", "B"),
-        injector.getInstance(Key.get(mapOfString)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(module), BOTH, false, 0,
-        instance("a", "A"), instance("b", "B"));
-  }
-  
-  /**
-   * With overrides, we should get the union of all map bindings.
-   */
-  public void testModuleOverrideAndMapBindingsWithPermitDuplicates() {
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.permitDuplicates();
-      }
-    };
-    Module cd = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("c").toInstance("C");
-        multibinder.addBinding("d").toInstance("D");
-        multibinder.permitDuplicates();
-      }
-    };
-    Module ef = new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> multibinder = MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("e").toInstance("E");
-        multibinder.addBinding("f").toInstance("F");
-        multibinder.permitDuplicates();
-      }
-    };
-
-    Module abcd = Modules.override(abc).with(cd);
-    Injector injector = Guice.createInjector(abcd, ef);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F"),
-        injector.getInstance(Key.get(mapOfString)));
-    assertMapVisitor(Key.get(mapOfString), stringType, stringType, setOf(abcd, ef), BOTH, true, 0,
-        instance("a", "A"), instance("b", "B"), instance("c", "C"), instance(
-            "d", "D"), instance("e", "E"), instance("f", "F"));
-
-  }  
-
-  /** Ensure there are no initialization race conditions in basic map injection. */
-  public void testBasicMapDependencyInjection() {
-    final AtomicReference<Map<String, String>> injectedMap =
-        new AtomicReference<Map<String, String>>();
-    final Object anObject = new Object() {
-      @Inject void initialize(Map<String, String> map) {
-        injectedMap.set(map);
-      }
-    };
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        requestInjection(anObject);
-        MapBinder<String, String> multibinder =
-            MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    Guice.createInjector(abc);
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), injectedMap.get());
-  } 
-
-  /** Ensure there are no initialization race conditions in provider multimap injection. */
-  public void testProviderMultimapDependencyInjection() {
-    final AtomicReference<Map<String, Set<Provider<String>>>> injectedMultimap =
-        new AtomicReference<Map<String, Set<Provider<String>>>>();
-    final Object anObject = new Object() {
-      @Inject void initialize(Map<String, Set<Provider<String>>> multimap) {
-        injectedMultimap.set(multimap);
-      }
-    };
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        requestInjection(anObject);
-        MapBinder<String, String> multibinder =
-            MapBinder.newMapBinder(binder(), String.class, String.class);
-        multibinder.permitDuplicates();
-        multibinder.addBinding("a").toInstance("A");
-        multibinder.addBinding("b").toInstance("B");
-        multibinder.addBinding("c").toInstance("C");
-      }
-    };
-    Guice.createInjector(abc);
-    Map<String, String> map = Maps.transformValues(injectedMultimap.get(),
-        new Function<Set<Provider<String>>, String>() {
-          @Override public String apply(Set<Provider<String>> stringProvidersSet) {
-            return Iterables.getOnlyElement(stringProvidersSet).get();
-          }
-        });
-    assertEquals(mapOf("a", "A", "b", "B", "c", "C"), map);
-  }
-  
-  @Retention(RUNTIME) @BindingAnnotation
-  @interface Abc {}
-
-  @Retention(RUNTIME) @BindingAnnotation
-  @interface De {}
-
-  @SuppressWarnings("unchecked")
-  private <K, V> Map<K, V> mapOf(Object... elements) {
-    Map<K, V> result = new HashMap<K, V>();
-    for (int i = 0; i < elements.length; i += 2) {
-      result.put((K)elements[i], (V)elements[i+1]);
-    }
-    return result;
-  }
-
-  @SuppressWarnings("unchecked")
-  private <V> Set<V> setOf(V... elements) {
-    return new HashSet<V>(Arrays.asList(elements));
-  }
-
-  @BindingAnnotation
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
-  private static @interface Marker {}
-
-  @Marker
-  public void testMapBinderMatching() throws Exception {
-    Method m = MapBinderTest.class.getDeclaredMethod("testMapBinderMatching");
-    assertNotNull(m);
-    final Annotation marker = m.getAnnotation(Marker.class);
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override public void configure() {
-        MapBinder<Integer, Integer> mb1 =
-          MapBinder.newMapBinder(binder(), Integer.class, Integer.class, Marker.class);
-        MapBinder<Integer, Integer> mb2 = 
-          MapBinder.newMapBinder(binder(), Integer.class, Integer.class, marker);
-        mb1.addBinding(1).toInstance(1);
-        mb2.addBinding(2).toInstance(2);
-
-        // This assures us that the two binders are equivalent, so we expect the instance added to
-        // each to have been added to one set.
-        assertEquals(mb1, mb2);
-      }
-    });
-    TypeLiteral<Map<Integer, Integer>> t = new TypeLiteral<Map<Integer, Integer>>() {};
-    Map<Integer, Integer> s1 = injector.getInstance(Key.get(t, Marker.class));
-    Map<Integer, Integer> s2 = injector.getInstance(Key.get(t, marker));
-
-    // This assures us that the two sets are in fact equal.  They may not be same set (as in Java
-    // object identical), but we shouldn't expect that, since probably Guice creates the set each
-    // time in case the elements are dependent on scope.
-    assertEquals(s1, s2);
-
-    // This ensures that MultiBinder is internally using the correct set name --
-    // making sure that instances of marker annotations have the same set name as
-    // MarkerAnnotation.class.
-    Map<Integer, Integer> expected = new HashMap<Integer, Integer>();
-    expected.put(1, 1);
-    expected.put(2, 2);
-    assertEquals(expected, s1);
-  }
-
-  public void testTwoMapBindersAreDistinct() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {  
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("A").toInstance("a");
-        
-        MapBinder.newMapBinder(binder(), Integer.class, String.class)
-            .addBinding(1).toInstance("b");
-      }
-    });
-    Collector collector = new Collector();
-    Binding<Map<String, String>> map1 = injector.getBinding(Key.get(mapOfString));
-    map1.acceptTargetVisitor(collector);
-    assertNotNull(collector.mapbinding);
-    MapBinderBinding<?> map1Binding = collector.mapbinding;
-  
-    Binding<Map<Integer, String>> map2 = injector.getBinding(Key.get(mapOfIntString));
-    map2.acceptTargetVisitor(collector);
-    assertNotNull(collector.mapbinding);
-    MapBinderBinding<?> map2Binding = collector.mapbinding;
-  
-    List<Binding<String>> bindings = injector.findBindingsByType(stringType);
-    assertEquals("should have two elements: " + bindings, 2, bindings.size());
-    Binding<String> a = bindings.get(0);
-    Binding<String> b = bindings.get(1);
-    assertEquals("a", ((InstanceBinding<String>) a).getInstance());
-    assertEquals("b", ((InstanceBinding<String>) b).getInstance());
-    
-    // Make sure the correct elements belong to their own sets.
-    assertTrue(map1Binding.containsElement(a));
-    assertFalse(map1Binding.containsElement(b));
-  
-    assertFalse(map2Binding.containsElement(a));
-    assertTrue(map2Binding.containsElement(b));
-  }
-
-  // Tests for com.google.inject.internal.WeakKeySet not leaking memory.
-  public void testWeakKeySet_integration_mapbinder() {
-    Key<Map<String, String>> mapKey = Key.get(new TypeLiteral<Map<String, String>>() {});
-    
-    Injector parentInjector = Guice.createInjector(new AbstractModule() {
-          @Override protected void configure() {
-            bind(String.class).toInstance("hi");
-          }
-        });
-    WeakKeySetUtils.assertNotBlacklisted(parentInjector, mapKey);
-
-    Injector childInjector = parentInjector.createChildInjector(new AbstractModule() {
-      @Override protected void configure() {
-        MapBinder<String, String> binder =
-            MapBinder.newMapBinder(binder(), String.class, String.class);
-        binder.addBinding("bar").toInstance("foo");
-      }
-    });
-    WeakReference<Injector> weakRef = new WeakReference<Injector>(childInjector);
-    WeakKeySetUtils.assertBlacklisted(parentInjector, mapKey);
-    
-    // Clear the ref, GC, and ensure that we are no longer blacklisting.
-    childInjector = null;
-    
-    Asserts.awaitClear(weakRef);
-    WeakKeySetUtils.assertNotBlacklisted(parentInjector, mapKey);
-  }
-}
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
deleted file mode 100644
index 154779d..0000000
--- a/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
+++ /dev/null
@@ -1,1221 +0,0 @@
-/**
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.google.inject.multibindings;
-
-import static com.google.inject.Asserts.assertContains;
-import static com.google.inject.multibindings.Multibinder.collectionOfJavaxProvidersOf;
-import static com.google.inject.multibindings.SpiUtils.VisitType.BOTH;
-import static com.google.inject.multibindings.SpiUtils.VisitType.MODULE;
-import static com.google.inject.multibindings.SpiUtils.assertSetVisitor;
-import static com.google.inject.multibindings.SpiUtils.instance;
-import static com.google.inject.multibindings.SpiUtils.providerInstance;
-import static com.google.inject.name.Names.named;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
-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.Sets;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binding;
-import com.google.inject.BindingAnnotation;
-import com.google.inject.CreationException;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
-import com.google.inject.ProvisionException;
-import com.google.inject.Scopes;
-import com.google.inject.Stage;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Named;
-import com.google.inject.name.Names;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.Element;
-import com.google.inject.spi.Elements;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.InstanceBinding;
-import com.google.inject.spi.LinkedKeyBinding;
-import com.google.inject.util.Modules;
-import com.google.inject.util.Providers;
-import com.google.inject.util.Types;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
-public class MultibinderTest extends TestCase {
-
-  final TypeLiteral<Optional<String>> optionalOfString =
-      new TypeLiteral<Optional<String>>() {};
-  final TypeLiteral<Map<String, String>> mapOfStringString =
-      new TypeLiteral<Map<String, String>>() {};
-  final TypeLiteral<Set<String>> setOfString = new TypeLiteral<Set<String>>() {};
-  final TypeLiteral<Set<Integer>> setOfInteger = new TypeLiteral<Set<Integer>>() {};
-  final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
-  final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
-  final TypeLiteral<List<String>> listOfStrings = new TypeLiteral<List<String>>() {};
-  final TypeLiteral<Set<List<String>>> setOfListOfStrings = new TypeLiteral<Set<List<String>>>() {};
-  final TypeLiteral<Collection<Provider<String>>> collectionOfProvidersOfStrings =
-      new TypeLiteral<Collection<Provider<String>>>() {};
-
-  public void testMultibinderAggregatesMultipleModules() {
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Module de = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("D");
-        multibinder.addBinding().toInstance("E");
-      }
-    };
-
-    Injector injector = Guice.createInjector(abc, de);
-    Key<Set<String>> setKey = Key.get(setOfString);
-    Set<String> abcde = injector.getInstance(setKey);
-    Set<String> results = setOf("A", "B", "C", "D", "E");
-
-    assertEquals(results, abcde);
-    assertSetVisitor(setKey, stringType, setOf(abc, de), BOTH, false, 0,
-        instance("A"), instance("B"), instance("C"), instance("D"), instance("E"));
-  }
-
-  public void testMultibinderAggregationForAnnotationInstance() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder
-            = Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-
-        multibinder = Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Set<String>> setKey = Key.get(setOfString, Names.named("abc"));
-    Set<String> abc = injector.getInstance(setKey);
-    Set<String> results = setOf("A", "B", "C");
-    assertEquals(results, abc);
-    assertSetVisitor(setKey, stringType, setOf(module), BOTH, false, 0,
-        instance("A"), instance("B"), instance("C"));
-  }
-
-  public void testMultibinderAggregationForAnnotationType() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder
-            = Multibinder.newSetBinder(binder(), String.class, Abc.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-
-        multibinder = Multibinder.newSetBinder(binder(), String.class, Abc.class);
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Set<String>> setKey = Key.get(setOfString, Abc.class);
-    Set<String> abcde = injector.getInstance(setKey);
-    Set<String> results = setOf("A", "B", "C");
-    assertEquals(results, abcde);
-    assertSetVisitor(setKey, stringType, setOf(module), BOTH, false, 0,
-        instance("A"), instance("B"), instance("C"));
-  }
-
-  public void testMultibinderWithMultipleAnnotationValueSets() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> abcMultibinder
-            = Multibinder.newSetBinder(binder(), String.class, named("abc"));
-        abcMultibinder.addBinding().toInstance("A");
-        abcMultibinder.addBinding().toInstance("B");
-        abcMultibinder.addBinding().toInstance("C");
-
-        Multibinder<String> deMultibinder
-            = Multibinder.newSetBinder(binder(), String.class, named("de"));
-        deMultibinder.addBinding().toInstance("D");
-        deMultibinder.addBinding().toInstance("E");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Set<String>> abcSetKey = Key.get(setOfString, named("abc"));
-    Set<String> abc = injector.getInstance(abcSetKey);
-    Key<Set<String>> deSetKey = Key.get(setOfString, named("de"));
-    Set<String> de = injector.getInstance(deSetKey);
-    Set<String> abcResults = setOf("A", "B", "C");
-    assertEquals(abcResults, abc);
-    Set<String> deResults = setOf("D", "E");
-    assertEquals(deResults, de);
-    assertSetVisitor(abcSetKey, stringType, setOf(module), BOTH, false, 1,
-        instance("A"), instance("B"), instance("C"));
-    assertSetVisitor(deSetKey, stringType, setOf(module), BOTH, false, 1,
-        instance("D"), instance("E"));
-  }
-
-  public void testMultibinderWithMultipleAnnotationTypeSets() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> abcMultibinder
-            = Multibinder.newSetBinder(binder(), String.class, Abc.class);
-        abcMultibinder.addBinding().toInstance("A");
-        abcMultibinder.addBinding().toInstance("B");
-        abcMultibinder.addBinding().toInstance("C");
-
-        Multibinder<String> deMultibinder
-            = Multibinder.newSetBinder(binder(), String.class, De.class);
-        deMultibinder.addBinding().toInstance("D");
-        deMultibinder.addBinding().toInstance("E");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Key<Set<String>> abcSetKey = Key.get(setOfString, Abc.class);
-    Set<String> abc = injector.getInstance(abcSetKey);
-    Key<Set<String>> deSetKey = Key.get(setOfString, De.class);
-    Set<String> de = injector.getInstance(deSetKey);
-    Set<String> abcResults = setOf("A", "B", "C");
-    assertEquals(abcResults, abc);
-    Set<String> deResults = setOf("D", "E");
-    assertEquals(deResults, de);
-    assertSetVisitor(abcSetKey, stringType, setOf(module), BOTH, false, 1,
-        instance("A"), instance("B"), instance("C"));
-    assertSetVisitor(deSetKey, stringType, setOf(module), BOTH, false, 1,
-        instance("D"), instance("E"));
-  }
-
-  public void testMultibinderWithMultipleSetTypes() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toInstance("A");
-        Multibinder.newSetBinder(binder(), Integer.class)
-            .addBinding().toInstance(1);
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    assertEquals(setOf("A"), injector.getInstance(Key.get(setOfString)));
-    assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(module), BOTH, false, 1,
-        instance("A"));
-    assertSetVisitor(Key.get(setOfInteger), intType, setOf(module), BOTH, false, 1,
-        instance(1));
-  }
-
-  public void testMultibinderWithEmptySet() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class);
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Set<String> set = injector.getInstance(Key.get(setOfString));
-    assertEquals(Collections.emptySet(), set);
-    assertSetVisitor(Key.get(setOfString), stringType,
-        setOf(module), BOTH, false, 0);
-  }
-
-  public void testMultibinderSetIsUnmodifiable() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toInstance("A");
-      }
-    });
-
-    Set<String> set = injector.getInstance(Key.get(setOfString));
-    try {
-      set.clear();
-      fail();
-    } catch(UnsupportedOperationException expected) {
-    }
-  }
-
-  public void testMultibinderSetIsSerializable() throws IOException, ClassNotFoundException {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toInstance("A");
-      }
-    });
-
-    Set<String> set = injector.getInstance(Key.get(setOfString));
-    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-    ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
-    try {
-      objectOutputStream.writeObject(set);
-    } finally {
-      objectOutputStream.close();
-    }
-    ObjectInputStream objectInputStream = new ObjectInputStream(
-        new ByteArrayInputStream(byteStream.toByteArray()));
-    try {
-      Object setCopy = objectInputStream.readObject();
-      assertEquals(set, setCopy);
-    } finally {
-      objectInputStream.close();
-    }
-  }
-
-  public void testMultibinderSetIsLazy() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), Integer.class)
-            .addBinding().toProvider(new Provider<Integer>() {
-          int nextValue = 1;
-          public Integer get() {
-            return nextValue++;
-          }
-        });
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
-    assertEquals(setOf(2), injector.getInstance(Key.get(setOfInteger)));
-    assertEquals(setOf(3), injector.getInstance(Key.get(setOfInteger)));
-    assertSetVisitor(Key.get(setOfInteger), intType, setOf(module), BOTH, false, 0,
-        providerInstance(1));
-  }
-
-  public void testMultibinderSetForbidsDuplicateElements() {
-    Module module1 = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toProvider(Providers.of("A"));
-      }
-    };
-    Module module2 = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-      }
-    };
-    Injector injector = Guice.createInjector(module1, module2);
-
-    try {
-      injector.getInstance(Key.get(setOfString));
-      fail();
-    } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "1) Set injection failed due to duplicated element \"A\"",
-          "Bound at " + module1.getClass().getName(),
-          "Bound at " + module2.getClass().getName());
-    }
-
-    // But we can still visit the module!
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(module1, module2), MODULE, false, 0,
-        instance("A"), instance("A"));
-  }
-
-  public void testMultibinderSetShowsBothElementsIfToStringDifferent() {
-    // A simple example of a type whose toString returns more information than its equals method
-    // considers.
-    class ValueType {
-      int a;
-      int b;
-      ValueType(int a, int b) {
-        this.a = a;
-        this.b = b;
-      }
-      @Override
-      public boolean equals(Object obj) {
-        return (obj instanceof ValueType) && (((ValueType) obj).a == a);
-      }
-      @Override
-      public int hashCode() {
-        return a;
-      }
-      @Override
-      public String toString() {
-        return String.format("ValueType(%d,%d)", a, b);
-      }
-    }
-
-    Module module1 = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<ValueType> multibinder =
-            Multibinder.newSetBinder(binder(), ValueType.class);
-        multibinder.addBinding().toProvider(Providers.of(new ValueType(1, 2)));
-      }
-    };
-    Module module2 = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<ValueType> multibinder =
-            Multibinder.newSetBinder(binder(), ValueType.class);
-        multibinder.addBinding().toInstance(new ValueType(1, 3));
-      }
-    };
-    Injector injector = Guice.createInjector(module1, module2);
-
-    TypeLiteral<ValueType> valueType = TypeLiteral.get(ValueType.class);
-    TypeLiteral<Set<ValueType>> setOfValueType = new TypeLiteral<Set<ValueType>>() {};
-    try {
-      injector.getInstance(Key.get(setOfValueType));
-      fail();
-    } catch (ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "1) Set injection failed due to multiple elements comparing equal:",
-          "\"ValueType(1,2)\"",
-          "bound at " + module1.getClass().getName(),
-          "\"ValueType(1,3)\"",
-          "bound at " + module2.getClass().getName());
-    }
-
-    // But we can still visit the module!
-    assertSetVisitor(Key.get(setOfValueType), valueType, setOf(module1, module2), MODULE, false, 0,
-        instance(new ValueType(1, 2)), instance(new ValueType(1, 3)));
-  }
-
-  public void testMultibinderSetPermitDuplicateElements() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-      }
-    };
-    Module bc = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.permitDuplicates();
-        multibinder.addBinding().toInstance("B");
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(ab, bc);
-
-    assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(ab, bc), BOTH, true, 0,
-        instance("A"), instance("B"), instance("C"));
-  }
-
-  public void testMultibinderSetPermitDuplicateCallsToPermitDuplicates() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.permitDuplicates();
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-      }
-    };
-    Module bc = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.permitDuplicates();
-        multibinder.addBinding().toInstance("B");
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Injector injector = Guice.createInjector(ab, bc);
-
-    assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(ab, bc), BOTH, true, 0,
-        instance("A"), instance("B"), instance("C"));
-  }
-
-  public void testMultibinderSetForbidsNullElements() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toProvider(Providers.<String>of(null));
-      }
-    };
-    Injector injector = Guice.createInjector(m);
-
-    try {
-      injector.getInstance(Key.get(setOfString));
-      fail();
-    } catch(ProvisionException expected) {
-      assertContains(expected.getMessage(),
-          "1) Set injection failed due to null element bound at: "
-          + m.getClass().getName() + ".configure(");
-    }
-  }
-
-  public void testSourceLinesInMultibindings() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          Multibinder.newSetBinder(binder(), Integer.class).addBinding();
-        }
-      });
-      fail();
-    } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "No implementation for java.lang.Integer",
-          "at " + getClass().getName());
-    }
-  }
-
-  /**
-   * We just want to make sure that multibinder's binding depends on each of its values. We don't
-   * really care about the underlying structure of those bindings, which are implementation details.
-   */
-  public void testMultibinderDependencies() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
-
-        bindConstant().annotatedWith(Names.named("b")).to("B");
-      }
-    });
-
-    Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Set<String> elements = Sets.newHashSet();
-    for (Dependency<?> dependency : withDependencies.getDependencies()) {
-      elements.add((String) injector.getInstance(dependency.getKey()));
-    }
-    assertEquals(ImmutableSet.of("A", "B"), elements);
-  }
-
-  /**
-   * We just want to make sure that multibinder's binding depends on each of its values. We don't
-   * really care about the underlying structure of those bindings, which are implementation details.
-   */
-  public void testMultibinderDependenciesInToolStage() {
-    Injector injector = Guice.createInjector(Stage.TOOL, new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
-
-        bindConstant().annotatedWith(Names.named("b")).to("B");
-      }
-    });
-
-    Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
-    HasDependencies withDependencies = (HasDependencies) binding;
-    InstanceBinding<?> instanceBinding = null;
-    LinkedKeyBinding<?> linkedBinding = null;
-    // The non-tool stage test can test this by calling injector.getInstance to ensure
-    // the right values are returned -- in tool stage we can't do that.  It's also a
-    // little difficult to validate the dependencies & bindings, because they're
-    // bindings created internally within Multibinder.
-    // To workaround this, we just validate that the dependencies lookup to a single
-    // InstanceBinding whose value is "A" and another LinkedBinding whose target is
-    // the Key of @Named("b") String=B
-    for (Dependency<?> dependency : withDependencies.getDependencies()) {
-      Binding<?> b = injector.getBinding(dependency.getKey());
-      if(b instanceof InstanceBinding) {
-        if(instanceBinding != null) {
-          fail("Already have an instance binding of: " + instanceBinding + ", and now want to add: " + b);
-        } else {
-          instanceBinding = (InstanceBinding)b;
-        }
-      } else if(b instanceof LinkedKeyBinding) {
-        if(linkedBinding != null) {
-          fail("Already have a linked binding of: " + linkedBinding + ", and now want to add: " + b);
-        } else {
-          linkedBinding = (LinkedKeyBinding)b;
-        }
-      } else {
-        fail("Unexpected dependency of: " + dependency);
-      }
-    }
-
-    assertNotNull(instanceBinding);
-    assertNotNull(linkedBinding);
-
-    assertEquals("A", instanceBinding.getInstance());
-    assertEquals(Key.get(String.class, Names.named("b")), linkedBinding.getLinkedKey());
-  }
-
-  /**
-   * Our implementation maintains order, but doesn't guarantee it in the API spec.
-   * TODO: specify the iteration order?
-   */
-  public void testBindOrderEqualsIterationOrder() {
-    Injector injector = Guice.createInjector(
-        new AbstractModule() {
-          @Override protected void configure() {
-            Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-            multibinder.addBinding().toInstance("leonardo");
-            multibinder.addBinding().toInstance("donatello");
-            install(new AbstractModule() {
-              @Override protected void configure() {
-                Multibinder.newSetBinder(binder(), String.class)
-                    .addBinding().toInstance("michaelangelo");
-              }
-            });
-          }
-        },
-        new AbstractModule() {
-          @Override protected void configure() {
-            Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("raphael");
-          }
-        });
-
-    List<String> inOrder = ImmutableList.copyOf(injector.getInstance(Key.get(setOfString)));
-    assertEquals(ImmutableList.of("leonardo", "donatello", "michaelangelo", "raphael"), inOrder);
-  }
-
-  @Retention(RUNTIME) @BindingAnnotation
-  @interface Abc {}
-
-  @Retention(RUNTIME) @BindingAnnotation
-  @interface De {}
-
-  private <T> Set<T> setOf(T... elements) {
-    Set<T> result = Sets.newHashSet();
-    Collections.addAll(result, elements);
-    return result;
-  }
-
-  /**
-   * With overrides, we should get the union of all multibindings.
-   */
-  public void testModuleOverrideAndMultibindings() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-      }
-    };
-    Module cd = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("C");
-        multibinder.addBinding().toInstance("D");
-      }
-    };
-    Module ef = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("E");
-        multibinder.addBinding().toInstance("F");
-      }
-    };
-
-    Module abcd = Modules.override(ab).with(cd);
-    Injector injector = Guice.createInjector(abcd, ef);
-    assertEquals(ImmutableSet.of("A", "B", "C", "D", "E", "F"),
-        injector.getInstance(Key.get(setOfString)));
-
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(abcd, ef), BOTH, false, 0,
-        instance("A"), instance("B"), instance("C"), instance("D"), instance("E"), instance("F"));
-  }
-
-  /**
-   * With overrides, we should get the union of all multibindings.
-   */
-  public void testModuleOverrideAndMultibindingsWithPermitDuplicates() {
-    Module abc = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-        multibinder.addBinding().toInstance("C");
-        multibinder.permitDuplicates();
-      }
-    };
-    Module cd = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("C");
-        multibinder.addBinding().toInstance("D");
-        multibinder.permitDuplicates();
-      }
-    };
-    Module ef = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("E");
-        multibinder.addBinding().toInstance("F");
-        multibinder.permitDuplicates();
-      }
-    };
-
-    Module abcd = Modules.override(abc).with(cd);
-    Injector injector = Guice.createInjector(abcd, ef);
-    assertEquals(ImmutableSet.of("A", "B", "C", "D", "E", "F"),
-        injector.getInstance(Key.get(setOfString)));
-
-    assertSetVisitor(Key.get(setOfString), stringType, setOf(abcd, ef), BOTH, true, 0,
-        instance("A"), instance("B"), instance("C"), instance("D"), instance("E"), instance("F"));
-  }
-
-  /**
-   * Doubly-installed modules should not conflict, even when one is overridden.
-   */
-  public void testModuleOverrideRepeatedInstallsAndMultibindings_toInstance() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toInstance("A");
-        multibinder.addBinding().toInstance("B");
-      }
-    };
-
-    // Guice guarantees this assertion, as the same module cannot be installed twice.
-    assertEquals(ImmutableSet.of("A", "B"),
-        Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
-
-    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
-    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
-    assertEquals(ImmutableSet.of("A", "B"),
-        injector.getInstance(Key.get(setOfString)));
-  }
-
-  public void testModuleOverrideRepeatedInstallsAndMultibindings_toKey() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Key<String> aKey = Key.get(String.class, Names.named("A_string"));
-        Key<String> bKey = Key.get(String.class, Names.named("B_string"));
-        bind(aKey).toInstance("A");
-        bind(bKey).toInstance("B");
-
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().to(aKey);
-        multibinder.addBinding().to(bKey);
-      }
-    };
-
-    // Guice guarantees this assertion, as the same module cannot be installed twice.
-    assertEquals(ImmutableSet.of("A", "B"),
-        Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
-
-    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
-    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
-    assertEquals(ImmutableSet.of("A", "B"),
-        injector.getInstance(Key.get(setOfString)));
-  }
-
-  public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderInstance() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toProvider(Providers.of("A"));
-        multibinder.addBinding().toProvider(Providers.of("B"));
-      }
-    };
-
-    // Guice guarantees this assertion, as the same module cannot be installed twice.
-    assertEquals(ImmutableSet.of("A", "B"),
-        Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
-
-    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
-    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
-    assertEquals(ImmutableSet.of("A", "B"),
-        injector.getInstance(Key.get(setOfString)));
-  }
-
-  private static class AStringProvider implements Provider<String> {
-    public String get() {
-      return "A";
-    }
-  }
-
-  private static class BStringProvider implements Provider<String> {
-    public String get() {
-      return "B";
-    }
-  }
-
-  public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderKey() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toProvider(Key.get(AStringProvider.class));
-        multibinder.addBinding().toProvider(Key.get(BStringProvider.class));
-      }
-    };
-
-    // Guice guarantees this assertion, as the same module cannot be installed twice.
-    assertEquals(ImmutableSet.of("A", "B"),
-        Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
-
-    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
-    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
-    assertEquals(ImmutableSet.of("A", "B"),
-        injector.getInstance(Key.get(setOfString)));
-  }
-
-  private static class StringGrabber {
-    private final String string;
-
-    @SuppressWarnings("unused")  // Found by reflection
-    public StringGrabber(@Named("A_string") String string) {
-      this.string = string;
-    }
-
-    @SuppressWarnings("unused")  // Found by reflection
-    public StringGrabber(@Named("B_string") String string, int unused) {
-      this.string = string;
-    }
-
-    @Override
-    public int hashCode() {
-      return string.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      return (obj instanceof StringGrabber) && ((StringGrabber) obj).string.equals(string);
-    }
-
-    @Override
-    public String toString() {
-      return "StringGrabber(" + string + ")";
-    }
-
-    static Set<String> values(Iterable<StringGrabber> grabbers) {
-      Set<String> result = new HashSet<String>();
-      for (StringGrabber grabber : grabbers) {
-        result.add(grabber.string);
-      }
-      return result;
-    }
-  }
-
-  public void testModuleOverrideRepeatedInstallsAndMultibindings_toConstructor() {
-    TypeLiteral<Set<StringGrabber>> setOfStringGrabber = new TypeLiteral<Set<StringGrabber>>() {};
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Key<String> aKey = Key.get(String.class, Names.named("A_string"));
-        Key<String> bKey = Key.get(String.class, Names.named("B_string"));
-        bind(aKey).toInstance("A");
-        bind(bKey).toInstance("B");
-        bind(Integer.class).toInstance(0);  // used to disambiguate constructors
-
-        Multibinder<StringGrabber> multibinder =
-            Multibinder.newSetBinder(binder(), StringGrabber.class);
-        try {
-          multibinder.addBinding().toConstructor(
-              StringGrabber.class.getConstructor(String.class));
-          multibinder.addBinding().toConstructor(
-              StringGrabber.class.getConstructor(String.class, int.class));
-        } catch (NoSuchMethodException e) {
-          fail("No such method: " + e.getMessage());
-        }
-      }
-    };
-
-    // Guice guarantees this assertion, as the same module cannot be installed twice.
-    assertEquals(ImmutableSet.of("A", "B"),
-        StringGrabber.values(
-            Guice.createInjector(ab, ab).getInstance(Key.get(setOfStringGrabber))));
-
-    // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
-    Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
-    assertEquals(ImmutableSet.of("A", "B"),
-        StringGrabber.values(injector.getInstance(Key.get(setOfStringGrabber))));
-  }
-
-  /**
-   * Unscoped bindings should not conflict, whether they were bound with no explicit scope, or
-   * explicitly bound in {@link Scopes#NO_SCOPE}.
-   */
-  public void testDuplicateUnscopedBindings() {
-    Module singleBinding = new AbstractModule() {
-      @Override protected void configure() {
-        bind(Integer.class).to(Key.get(Integer.class, named("A")));
-        bind(Integer.class).to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
-      }
-
-      @Provides @Named("A")
-      int provideInteger() {
-        return 5;
-      }
-    };
-    Module multibinding = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<Integer> multibinder = Multibinder.newSetBinder(binder(), Integer.class);
-        multibinder.addBinding().to(Key.get(Integer.class, named("A")));
-        multibinder.addBinding().to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
-      }
-    };
-
-    assertEquals(5,
-        (int) Guice.createInjector(singleBinding).getInstance(Integer.class));
-    assertEquals(ImmutableSet.of(5),
-        Guice.createInjector(singleBinding, multibinding).getInstance(Key.get(setOfInteger)));
-  }
-
-  /**
-   * Ensure key hash codes are fixed at injection time, not binding time.
-   */
-  public void testKeyHashCodesFixedAtInjectionTime() {
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
-        List<String> list = Lists.newArrayList();
-        multibinder.addBinding().toInstance(list);
-        list.add("A");
-        list.add("B");
-      }
-    };
-
-    Injector injector = Guice.createInjector(ab);
-    for (Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
-      Key<?> bindingKey = entry.getKey();
-      Key<?> clonedKey;
-      if (bindingKey.getAnnotation() != null) {
-        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotation());
-      } else if (bindingKey.getAnnotationType() != null) {
-        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotationType());
-      } else {
-        clonedKey = Key.get(bindingKey.getTypeLiteral());
-      }
-      assertEquals(bindingKey, clonedKey);
-      assertEquals("Incorrect hashcode for " + bindingKey + " -> " + entry.getValue(),
-          bindingKey.hashCode(), clonedKey.hashCode());
-    }
-  }
-
-  /**
-   * Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}.
-   */
-  public void testBindingKeysFixedOnReturnFromGetElements() {
-    final List<String> list = Lists.newArrayList();
-    Module ab = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
-        multibinder.addBinding().toInstance(list);
-        list.add("A");
-        list.add("B");
-      }
-    };
-
-    InstanceBinding<?> binding = Iterables.getOnlyElement(
-        Iterables.filter(Elements.getElements(ab), InstanceBinding.class));
-    Key<?> keyBefore = binding.getKey();
-    assertEquals(listOfStrings, keyBefore.getTypeLiteral());
-
-    list.add("C");
-    Key<?> keyAfter = binding.getKey();
-    assertSame(keyBefore, keyAfter);
-  }
-
-  /*
-   * Verify through gratuitous mutation that key hashCode snapshots and whatnot happens at the right
-   * times, by binding two lists that are different at injector creation, but compare equal when the
-   * module is configured *and* when the set is instantiated.
-   */
-  public void testConcurrentMutation_bindingsDiffentAtInjectorCreation() {
-    // We initially bind two equal lists
-    final List<String> list1 = Lists.newArrayList();
-    final List<String> list2 = Lists.newArrayList();
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
-        multibinder.addBinding().toInstance(list1);
-        multibinder.addBinding().toInstance(list2);
-      }
-    };
-    List<Element> elements = Elements.getElements(module);
-
-    // Now we change the lists so they no longer match, and create the injector.
-    list1.add("A");
-    list2.add("B");
-    Injector injector = Guice.createInjector(Elements.getModule(elements));
-
-    // Now we change the lists so they compare equal again, and create the set.
-    list1.add(1, "B");
-    list2.add(0, "A");
-    try {
-      injector.getInstance(Key.get(setOfListOfStrings));
-      fail();
-    } catch (ProvisionException e) {
-      assertEquals(1, e.getErrorMessages().size());
-      assertContains(
-          Iterables.getOnlyElement(e.getErrorMessages()).getMessage().toString(),
-          "Set injection failed due to duplicated element \"[A, B]\"");
-    }
-
-    // Finally, we change the lists again so they are once more different, and ensure the set
-    // contains both.
-    list1.remove("A");
-    list2.remove("B");
-    Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
-    assertEquals(ImmutableSet.of(ImmutableList.of("A"), ImmutableList.of("B")), set);
-  }
-
-  /*
-   * Verify through gratuitous mutation that key hashCode snapshots and whatnot happen at the right
-   * times, by binding two lists that compare equal at injector creation, but are different when the
-   * module is configured *and* when the set is instantiated.
-   */
-  public void testConcurrentMutation_bindingsSameAtInjectorCreation() {
-    // We initially bind two distinct lists
-    final List<String> list1 = Lists.newArrayList("A");
-    final List<String> list2 = Lists.newArrayList("B");
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
-        multibinder.addBinding().toInstance(list1);
-        multibinder.addBinding().toInstance(list2);
-      }
-    };
-    List<Element> elements = Elements.getElements(module);
-
-    // Now we change the lists so they compare equal, and create the injector.
-    list1.add(1, "B");
-    list2.add(0, "A");
-    Injector injector = Guice.createInjector(Elements.getModule(elements));
-
-    // Now we change the lists again so they are once more different, and create the set.
-    list1.remove("A");
-    list2.remove("B");
-    Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
-
-    // The set will contain just one of the two lists.
-    // (In fact, it will be the first one we bound, but we don't promise that, so we won't test it.)
-    assertTrue(ImmutableSet.of(ImmutableList.of("A")).equals(set)
-        || ImmutableSet.of(ImmutableList.of("B")).equals(set));
-  }
-
-  @BindingAnnotation
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
-  private static @interface Marker {}
-
-  @Marker
-  public void testMultibinderMatching() throws Exception {
-    Method m = MultibinderTest.class.getDeclaredMethod("testMultibinderMatching");
-    assertNotNull(m);
-    final Annotation marker = m.getAnnotation(Marker.class);
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override public void configure() {
-        Multibinder<Integer> mb1 = Multibinder.newSetBinder(binder(), Integer.class, Marker.class);
-        Multibinder<Integer> mb2 = Multibinder.newSetBinder(binder(), Integer.class, marker);
-        mb1.addBinding().toInstance(1);
-        mb2.addBinding().toInstance(2);
-
-        // This assures us that the two binders are equivalent, so we expect the instance added to
-        // each to have been added to one set.
-        assertEquals(mb1, mb2);
-      }
-    });
-    TypeLiteral<Set<Integer>> t = new TypeLiteral<Set<Integer>>() {};
-    Set<Integer> s1 = injector.getInstance(Key.get(t, Marker.class));
-    Set<Integer> s2 = injector.getInstance(Key.get(t, marker));
-
-    // This assures us that the two sets are in fact equal.  They may not be same set (as in Java
-    // object identical), but we shouldn't expect that, since probably Guice creates the set each
-    // time in case the elements are dependent on scope.
-    assertEquals(s1, s2);
-
-    // This ensures that MultiBinder is internally using the correct set name --
-    // making sure that instances of marker annotations have the same set name as
-    // MarkerAnnotation.class.
-    Set<Integer> expected = new HashSet<Integer>();
-    expected.add(1);
-    expected.add(2);
-    assertEquals(expected, s1);
-  }
-
-  // See issue 670
-  public void testSetAndMapValueAreDistinct() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toInstance("A");
-
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("B").toInstance("b");
-
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setDefault().toInstance("C");
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setBinding().toInstance("D");
-      }
-    });
-
-    assertEquals(ImmutableSet.of("A"), injector.getInstance(Key.get(setOfString)));
-    assertEquals(ImmutableMap.of("B", "b"), injector.getInstance(Key.get(mapOfStringString)));
-    assertEquals(Optional.of("D"), injector.getInstance(Key.get(optionalOfString)));
-  }
-
-  // See issue 670
-  public void testSetAndMapValueAreDistinctInSpi() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        Multibinder.newSetBinder(binder(), String.class)
-            .addBinding().toInstance("A");
-
-        MapBinder.newMapBinder(binder(), String.class, String.class)
-            .addBinding("B").toInstance("b");
-        
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setDefault().toInstance("C");
-      }
-    });
-    Collector collector = new Collector();
-    Binding<Map<String, String>> mapbinding = injector.getBinding(Key.get(mapOfStringString));
-    mapbinding.acceptTargetVisitor(collector);
-    assertNotNull(collector.mapbinding);
-
-    Binding<Set<String>> setbinding = injector.getBinding(Key.get(setOfString));
-    setbinding.acceptTargetVisitor(collector);
-    assertNotNull(collector.setbinding);
-
-    Binding<Optional<String>> optionalbinding = injector.getBinding(Key.get(optionalOfString));
-    optionalbinding.acceptTargetVisitor(collector);
-    assertNotNull(collector.optionalbinding);
-
-    // There should only be three instance bindings for string types
-    // (but because of the OptionalBinder, there's 2 ProviderInstanceBindings also).
-    // We also know the InstanceBindings will be in the order: A, b, C because that's
-    // how we bound them, and binding order is preserved.
-    List<Binding<String>> bindings = FluentIterable.from(injector.findBindingsByType(stringType))
-        .filter(Predicates.instanceOf(InstanceBinding.class))
-        .toList();
-    assertEquals(bindings.toString(), 3, bindings.size());
-    Binding<String> a = bindings.get(0);
-    Binding<String> b = bindings.get(1);
-    Binding<String> c = bindings.get(2);
-    assertEquals("A", ((InstanceBinding<String>) a).getInstance());
-    assertEquals("b", ((InstanceBinding<String>) b).getInstance());
-    assertEquals("C", ((InstanceBinding<String>) c).getInstance());
-
-    // Make sure the correct elements belong to their own sets.
-    assertFalse(collector.mapbinding.containsElement(a));
-    assertTrue(collector.mapbinding.containsElement(b));
-    assertFalse(collector.mapbinding.containsElement(c));
-
-    assertTrue(collector.setbinding.containsElement(a));
-    assertFalse(collector.setbinding.containsElement(b));
-    assertFalse(collector.setbinding.containsElement(c));
-
-    assertFalse(collector.optionalbinding.containsElement(a));
-    assertFalse(collector.optionalbinding.containsElement(b));
-    assertTrue(collector.optionalbinding.containsElement(c));
-  }
-
-  public void testMultibinderCanInjectCollectionOfProviders() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
-        multibinder.addBinding().toProvider(Providers.of("A"));
-        multibinder.addBinding().toProvider(Providers.of("B"));
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
-
-    Injector injector = Guice.createInjector(module);
-
-    Collection<Provider<String>> providers =
-        injector.getInstance(Key.get(collectionOfProvidersOfStrings));
-    assertEquals(expectedValues, collectValues(providers));
-
-    Collection<javax.inject.Provider<String>> javaxProviders =
-        injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType)));
-    assertEquals(expectedValues, collectValues(javaxProviders));
-  }
-
-  public void testMultibinderCanInjectCollectionOfProvidersWithAnnotation() {
-    final Annotation ann = Names.named("foo");
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        final Multibinder<String> multibinder =
-            Multibinder.newSetBinder(binder(), String.class, ann);
-        multibinder.addBinding().toProvider(Providers.of("A"));
-        multibinder.addBinding().toProvider(Providers.of("B"));
-        multibinder.addBinding().toInstance("C");
-      }
-    };
-    Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
-
-    Injector injector = Guice.createInjector(module);
-
-    Collection<Provider<String>> providers =
-        injector.getInstance(Key.get(collectionOfProvidersOfStrings, ann));
-    Collection<String> values = collectValues(providers);
-    assertEquals(expectedValues, values);
-
-    Collection<javax.inject.Provider<String>> javaxProviders =
-        injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType), ann));
-    assertEquals(expectedValues, collectValues(javaxProviders));
-  }
-
-  public void testMultibindingProviderDependencies() {
-    final Annotation setAnn = Names.named("foo");
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          Multibinder<String> multibinder =
-              Multibinder.newSetBinder(binder(), String.class, setAnn);
-          multibinder.addBinding().toInstance("a");
-          multibinder.addBinding().toInstance("b");
-        }
-      });
-    HasDependencies providerBinding =
-      (HasDependencies) injector.getBinding(new Key<Collection<Provider<String>>>(setAnn) {});
-    HasDependencies setBinding =
-      (HasDependencies) injector.getBinding(new Key<Set<String>>(setAnn) {});
-    // sanity check the size
-    assertEquals(setBinding.getDependencies().toString(), 2, setBinding.getDependencies().size());
-    Set<Dependency<?>> expected = Sets.newHashSet();
-    for (Dependency<?> dep : setBinding.getDependencies()) {
-      Key key = dep.getKey();
-      Dependency<?> providerDependency =
-          Dependency.get(key.ofType(Types.providerOf(key.getTypeLiteral().getType())));
-      expected.add(providerDependency);
-    }
-    assertEquals(expected, providerBinding.getDependencies());
-  }
-
-  private <T> Collection<T> collectValues(
-      Collection<? extends javax.inject.Provider<T>> providers) {
-    Collection<T> values = Lists.newArrayList();
-    for (javax.inject.Provider<T> provider : providers) {
-      values.add(provider.get());
-    }
-    return values;
-  }
-}
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/OptionalBinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/OptionalBinderTest.java
deleted file mode 100644
index f3c9f63..0000000
--- a/extensions/multibindings/test/com/google/inject/multibindings/OptionalBinderTest.java
+++ /dev/null
@@ -1,1241 +0,0 @@
-/**
- * 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.google.inject.multibindings;
-
-import static com.google.inject.Asserts.assertContains;
-import static com.google.inject.multibindings.SpiUtils.assertOptionalVisitor;
-import static com.google.inject.multibindings.SpiUtils.instance;
-import static com.google.inject.multibindings.SpiUtils.linked;
-import static com.google.inject.multibindings.SpiUtils.providerInstance;
-import static com.google.inject.multibindings.SpiUtils.providerKey;
-import static com.google.inject.name.Names.named;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.inject.AbstractModule;
-import com.google.inject.Asserts;
-import com.google.inject.Binding;
-import com.google.inject.BindingAnnotation;
-import com.google.inject.CreationException;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
-import com.google.inject.Scopes;
-import com.google.inject.TypeLiteral;
-import com.google.inject.internal.WeakKeySetUtils;
-import com.google.inject.multibindings.OptionalBinder.Actual;
-import com.google.inject.multibindings.OptionalBinder.Default;
-import com.google.inject.multibindings.SpiUtils.VisitType;
-import com.google.inject.name.Named;
-import com.google.inject.name.Names;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.Elements;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.InstanceBinding;
-import com.google.inject.util.Modules;
-import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * @author sameb@google.com (Sam Berlin)
- */
-public class OptionalBinderTest extends TestCase {
-
-  private static final boolean HAS_JAVA_OPTIONAL;
-  private static final Class<?> JAVA_OPTIONAL_CLASS;
-  private static final Method JAVA_OPTIONAL_OR_ELSE;
-  static {
-    Class<?> optional = null;
-    Method orElse = null;
-    try {
-      optional = Class.forName("java.util.Optional");
-      orElse = optional.getDeclaredMethod("orElse", Object.class);
-    } catch (ClassNotFoundException ignored) {
-    } catch (NoSuchMethodException ignored) {
-    } catch (SecurityException ignored) {
-    }
-    HAS_JAVA_OPTIONAL = optional != null;
-    JAVA_OPTIONAL_CLASS = optional;
-    JAVA_OPTIONAL_OR_ELSE = orElse;
-  }
-
-  final Key<String> stringKey = Key.get(String.class);
-  final TypeLiteral<Optional<String>> optionalOfString = new TypeLiteral<Optional<String>>() {};
-  final TypeLiteral<?> javaOptionalOfString =  HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOf(stringKey.getTypeLiteral()) : null;
-  final TypeLiteral<Optional<Provider<String>>> optionalOfProviderString =
-      new TypeLiteral<Optional<Provider<String>>>() {};
-  final TypeLiteral<?> javaOptionalOfProviderString = HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOfProvider(stringKey.getTypeLiteral()) : null;
-  final TypeLiteral<Optional<javax.inject.Provider<String>>> optionalOfJavaxProviderString =
-      new TypeLiteral<Optional<javax.inject.Provider<String>>>() {};
-  final TypeLiteral<?> javaOptionalOfJavaxProviderString = HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOfJavaxProvider(stringKey.getTypeLiteral()) : null;
-
-  final Key<Integer> intKey = Key.get(Integer.class);
-  final TypeLiteral<Optional<Integer>> optionalOfInteger = new TypeLiteral<Optional<Integer>>() {};
-  final TypeLiteral<?> javaOptionalOfInteger =  HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOf(intKey.getTypeLiteral()) : null;
-  final TypeLiteral<Optional<Provider<Integer>>> optionalOfProviderInteger =
-      new TypeLiteral<Optional<Provider<Integer>>>() {};
-  final TypeLiteral<?> javaOptionalOfProviderInteger = HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOfProvider(intKey.getTypeLiteral()) : null;
-  final TypeLiteral<Optional<javax.inject.Provider<Integer>>> optionalOfJavaxProviderInteger =
-      new TypeLiteral<Optional<javax.inject.Provider<Integer>>>() {};
-  final TypeLiteral<?> javaOptionalOfJavaxProviderInteger = HAS_JAVA_OPTIONAL ?
-      OptionalBinder.javaOptionalOfJavaxProvider(intKey.getTypeLiteral()) : null;
-
-  final TypeLiteral<List<String>> listOfStrings = new TypeLiteral<List<String>>() {};
-
-  public void testTypeNotBoundByDefault() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class);
-        requireBinding(new Key<Optional<String>>() {}); // the above specifies this.
-        requireBinding(String.class); // but it doesn't specify this.
-        binder().requireExplicitBindings(); // need to do this, otherwise String will JIT
-
-        if (HAS_JAVA_OPTIONAL) {
-          requireBinding(Key.get(javaOptionalOfString));
-        }
-      }
-    };
-
-    try {
-      Guice.createInjector(module);
-      fail();
-    } catch (CreationException ce) {
-      assertContains(ce.getMessage(),
-          "1) Explicit bindings are required and java.lang.String is not explicitly bound.");
-      assertEquals(1, ce.getErrorMessages().size());
-    }
-  } 
-  
-  public void testOptionalIsAbsentByDefault() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class);
-      }
-    };
-
-    Injector injector = Guice.createInjector(module);
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertFalse(optional.isPresent());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertFalse(optionalP.isPresent());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertFalse(optionalJxP.isPresent());
-    
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, null, null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertFalse(optional.isPresent());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertFalse(optionalP.isPresent());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertFalse(optionalJxP.isPresent());
-    }
-  }
-  
-  public void testUsesUserBoundValue() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class);
-      }
-      @Provides String provideString() { return "foo"; }
-    };
-
-    Injector injector = Guice.createInjector(module);
-    assertEquals("foo", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertEquals("foo", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertEquals("foo", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertEquals("foo", optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module),
-        VisitType.BOTH,
-        0,
-        null,
-        null,
-        providerInstance("foo"));
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertEquals("foo", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertEquals("foo", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertEquals("foo", optionalJxP.get().get());
-    }
-  }
-  
-  public void testSetDefault() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("a", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("a", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("a", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("a", optionalJxP.get().get());
-
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, instance("a"), null, null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("a", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("a", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("a", optionalJxP.get().get());
-    }
-  }
-  
-  public void testSetBinding() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("a");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("a", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("a", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("a", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("a", optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, instance("a"), null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("a", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("a", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("a", optionalJxP.get().get());
-    }
-  }
-  
-  public void testSetBindingOverridesDefault() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> optionalBinder =
-            OptionalBinder.newOptionalBinder(binder(), String.class);
-        optionalBinder.setDefault().toInstance("a");
-        optionalBinder.setBinding().toInstance("b");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("b", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("b", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("b", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("b", optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module),
-        VisitType.BOTH,
-        0,
-        instance("a"),
-        instance("b"),
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("b", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("b", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("b", optionalJxP.get().get());
-    }
-  }
-  
-  public void testSpreadAcrossModules() throws Exception {
-    Module module1 = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class);
-      }
-    };
-    Module module2 = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-      }
-    };
-    Module module3 = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
-      }
-    };
-
-    Injector injector = Guice.createInjector(module1, module2, module3);
-    assertEquals("b", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("b", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("b", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("b", optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module1, module2, module3),
-        VisitType.BOTH,
-        0,
-        instance("a"),
-        instance("b"),
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("b", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("b", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("b", optionalJxP.get().get());
-    }
-  }
-  
-  public void testExactSameBindingCollapses_defaults() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault()
-            .toInstance(new String("a")); // using new String to ensure .equals is checked.
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault()
-            .toInstance(new String("a"));
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("a", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("a", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("a", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("a", optionalJxP.get().get());
-
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, instance("a"), null, null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("a", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("a", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("a", optionalJxP.get().get());
-    }
-  }
-  
-  public void testExactSameBindingCollapses_actual() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding()
-            .toInstance(new String("a")); // using new String to ensure .equals is checked.
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding()
-            .toInstance(new String("a"));
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("a", injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertTrue(optional.isPresent());
-    assertEquals("a", optional.get());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertEquals("a", optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("a", optionalJxP.get().get());
-
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 0, null, instance("a"), null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertTrue(optional.isPresent());
-      assertEquals("a", optional.get());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertEquals("a", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("a", optionalJxP.get().get());
-    }
-  }
-  
-  public void testDifferentBindingsFail_defaults() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("b");
-      }
-    };
-    try {
-      Guice.createInjector(module);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(ce.getMessage(), 1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(),
-          "1) A binding to java.lang.String annotated with @" 
-              + Default.class.getName() + " was already configured at "
-              + module.getClass().getName() + ".configure(",
-          "at " + module.getClass().getName() + ".configure(");
-    }
-  }  
-  
-  public void testDifferentBindingsFail_actual() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("a");
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
-      }
-    };
-    try {
-      Guice.createInjector(module);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(ce.getMessage(), 1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(),
-          "1) A binding to java.lang.String annotated with @" 
-              + Actual.class.getName() + " was already configured at "
-              + module.getClass().getName() + ".configure(",
-          "at " + module.getClass().getName() + ".configure(");
-    }
-  }  
-  
-  public void testDifferentBindingsFail_both() {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("b");
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("b");
-        OptionalBinder.newOptionalBinder(binder(), String.class).setBinding().toInstance("c");
-      }
-    };
-    try {
-      Guice.createInjector(module);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(ce.getMessage(), 2, ce.getErrorMessages().size());      
-      assertContains(ce.getMessage(),
-          "1) A binding to java.lang.String annotated with @"
-              + Default.class.getName() + " was already configured at "
-              + module.getClass().getName() + ".configure(",
-          "at " + module.getClass().getName() + ".configure(",
-          "2) A binding to java.lang.String annotated with @"
-              + Actual.class.getName() + " was already configured at "
-              + module.getClass().getName() + ".configure(",
-          "at " + module.getClass().getName() + ".configure(");
-    }
-  }
-  
-  public void testQualifiedAggregatesTogether() throws Exception {
-    Module module1 = new AbstractModule() {
-      @Override
-      protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")));
-      }
-    };
-    Module module2 = new AbstractModule() {
-      @Override
-      protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")))
-            .setDefault().toInstance("a");
-      }
-    };
-    Module module3 = new AbstractModule() {
-      @Override
-      protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("foo")))
-            .setBinding().toInstance("b");
-      }
-    };
-
-    Injector injector = Guice.createInjector(module1, module2, module3);
-    assertEquals("b", injector.getInstance(Key.get(String.class, Names.named("foo"))));
-
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString, Names.named("foo")));
-    assertTrue(optional.isPresent());
-    assertEquals("b", optional.get());
-
-    Optional<Provider<String>> optionalP =
-        injector.getInstance(Key.get(optionalOfProviderString, Names.named("foo")));
-    assertTrue(optionalP.isPresent());
-    assertEquals("b", optionalP.get().get());
-
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString, Names.named("foo")));
-    assertTrue(optionalJxP.isPresent());
-    assertEquals("b", optionalJxP.get().get());
-    
-    assertOptionalVisitor(Key.get(String.class, Names.named("foo")),
-        setOf(module1, module2, module3),
-        VisitType.BOTH,
-        0,
-        instance("a"),
-        instance("b"),
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString, Names.named("foo"))));
-      assertTrue(optional.isPresent());
-      assertEquals("b", optional.get());
-
-      optionalP = toOptional(injector.getInstance
-          (Key.get(javaOptionalOfProviderString, Names.named("foo"))));
-      assertTrue(optionalP.isPresent());
-      assertEquals("b", optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(
-          Key.get(javaOptionalOfJavaxProviderString, Names.named("foo"))));
-      assertTrue(optionalJxP.isPresent());
-      assertEquals("b", optionalJxP.get().get());
-    }
-  }
-  
-  public void testMultipleDifferentOptionals() {
-    final Key<String> bKey = Key.get(String.class, named("b"));
-    final Key<String> cKey = Key.get(String.class, named("c"));
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-        OptionalBinder.newOptionalBinder(binder(), Integer.class).setDefault().toInstance(1);
-        
-        OptionalBinder.newOptionalBinder(binder(), bKey).setDefault().toInstance("b");
-        OptionalBinder.newOptionalBinder(binder(), cKey).setDefault().toInstance("c");
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertEquals("a", injector.getInstance(String.class));
-    assertEquals(1, injector.getInstance(Integer.class).intValue());
-    assertEquals("b", injector.getInstance(bKey));
-    assertEquals("c", injector.getInstance(cKey));
-    
-    assertOptionalVisitor(stringKey, setOf(module), VisitType.BOTH, 3, instance("a"), null, null);
-    assertOptionalVisitor(intKey, setOf(module), VisitType.BOTH, 3, instance(1), null, null);
-    assertOptionalVisitor(bKey, setOf(module), VisitType.BOTH, 3, instance("b"), null, null);
-    assertOptionalVisitor(cKey, setOf(module), VisitType.BOTH, 3, instance("c"), null, null);
-  }
-  
-  public void testOptionalIsAppropriatelyLazy() throws Exception {
-    Module module = new AbstractModule() {
-      int nextValue = 1;
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), Integer.class)
-            .setDefault().to(Key.get(Integer.class, Names.named("foo")));
-      }
-      @Provides @Named("foo") int provideInt() {
-        return nextValue++;
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-
-    Optional<Provider<Integer>> optionalP =
-        injector.getInstance(Key.get(optionalOfProviderInteger));
-    Optional<javax.inject.Provider<Integer>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderInteger));
-    
-    assertEquals(1, injector.getInstance(Integer.class).intValue());
-    assertEquals(2, injector.getInstance(Integer.class).intValue());
-    
-    // Calling .get() on an Optional<Integer> multiple times will keep giving the same thing
-    Optional<Integer> optional = injector.getInstance(Key.get(optionalOfInteger));
-    assertEquals(3, optional.get().intValue());
-    assertEquals(3, optional.get().intValue());
-    // But getting another Optional<Integer> will give a new one.
-    assertEquals(4, injector.getInstance(Key.get(optionalOfInteger)).get().intValue());
-    
-    // And the Optional<Provider> will return a provider that gives a new value each time.
-    assertEquals(5, optionalP.get().get().intValue());
-    assertEquals(6, optionalP.get().get().intValue());
-    
-    assertEquals(7, optionalJxP.get().get().intValue());
-    assertEquals(8, optionalJxP.get().get().intValue());
-
-    // and same rules with java.util.Optional
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfInteger)));
-      assertEquals(9, optional.get().intValue());
-      assertEquals(9, optional.get().intValue());
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfInteger)));
-      assertEquals(10, optional.get().intValue());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderInteger)));
-      assertEquals(11, optionalP.get().get().intValue());
-      assertEquals(12, optionalP.get().get().intValue());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderInteger)));
-      assertEquals(13, optionalJxP.get().get().intValue());
-      assertEquals(14, optionalJxP.get().get().intValue());
-    }
-  }
-  
-  public void testLinkedToNullProvidersMakeAbsentValuesAndPresentProviders_default()
-      throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setDefault().toProvider(Providers.<String>of(null));
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertNull(injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertFalse(optional.isPresent());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertNull(optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertNull(optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module),
-        VisitType.BOTH,
-        0,
-        SpiUtils.<String>providerInstance(null),
-        null,
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertFalse(optional.isPresent());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertNull(optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertNull(optionalJxP.get().get());
-    }
-  }
-  
-  public void testLinkedToNullProvidersMakeAbsentValuesAndPresentProviders_actual()
-      throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setBinding().toProvider(Providers.<String>of(null));
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertNull(injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertFalse(optional.isPresent());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertNull(optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertNull(optionalJxP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module),
-        VisitType.BOTH,
-        0,
-        null,
-        SpiUtils.<String>providerInstance(null),
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertFalse(optional.isPresent());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertNull(optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertNull(optionalJxP.get().get());
-    }
-  }
-  
-  // TODO(sameb): Maybe change this?
-  public void testLinkedToNullActualDoesntFallbackToDefault() throws Exception {
-    Module module = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder.newOptionalBinder(binder(), String.class).setDefault().toInstance("a");
-        OptionalBinder.newOptionalBinder(binder(), String.class)
-            .setBinding().toProvider(Providers.<String>of(null));
-      }
-    };
-    Injector injector = Guice.createInjector(module);
-    assertNull(injector.getInstance(String.class));
-    
-    Optional<String> optional = injector.getInstance(Key.get(optionalOfString));
-    assertFalse(optional.isPresent());
-    
-    Optional<Provider<String>> optionalP = injector.getInstance(Key.get(optionalOfProviderString));
-    assertTrue(optionalP.isPresent());
-    assertNull(optionalP.get().get());
-    
-    Optional<javax.inject.Provider<String>> optionalJxP =
-        injector.getInstance(Key.get(optionalOfJavaxProviderString));
-    assertTrue(optionalJxP.isPresent());
-    assertNull(optionalP.get().get());
-    
-    assertOptionalVisitor(stringKey,
-        setOf(module),
-        VisitType.BOTH,
-        0,
-        instance("a"),
-        SpiUtils.<String>providerInstance(null),
-        null);
-
-    if (HAS_JAVA_OPTIONAL) {
-      optional = toOptional(injector.getInstance(Key.get(javaOptionalOfString)));
-      assertFalse(optional.isPresent());
-
-      optionalP = toOptional(injector.getInstance(Key.get(javaOptionalOfProviderString)));
-      assertTrue(optionalP.isPresent());
-      assertNull(optionalP.get().get());
-
-      optionalJxP = toOptional(injector.getInstance(Key.get(javaOptionalOfJavaxProviderString)));
-      assertTrue(optionalJxP.isPresent());
-      assertNull(optionalJxP.get().get());
-    }
-  }
-
-  public void testSourceLinesInException() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override protected void configure() {
-          OptionalBinder.newOptionalBinder(binder(),  Integer.class).setDefault();
-        }
-      });
-      fail();
-    } catch (CreationException expected) {
-      assertContains(expected.getMessage(), "No implementation for java.lang.Integer",
-          "at " + getClass().getName());
-    }
-  }
-
-  public void testDependencies_both() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> optionalbinder =
-            OptionalBinder.newOptionalBinder(binder(), String.class);
-        optionalbinder.setDefault().toInstance("A");
-        optionalbinder.setBinding().to(Key.get(String.class, Names.named("b")));
-        bindConstant().annotatedWith(Names.named("b")).to("B");
-      }
-    });
-
-    Binding<String> binding = injector.getBinding(Key.get(String.class));
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Set<String> elements = Sets.newHashSet();
-    elements.addAll(recurseForDependencies(injector, withDependencies));
-    assertEquals(ImmutableSet.of("B"), elements);
-  }
-
-  public void testDependencies_actual() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> optionalbinder =
-            OptionalBinder.newOptionalBinder(binder(), String.class);
-        optionalbinder.setBinding().to(Key.get(String.class, Names.named("b")));
-        bindConstant().annotatedWith(Names.named("b")).to("B");
-      }
-    });
-
-    Binding<String> binding = injector.getBinding(Key.get(String.class));
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Set<String> elements = Sets.newHashSet();
-    elements.addAll(recurseForDependencies(injector, withDependencies));
-    assertEquals(ImmutableSet.of("B"), elements);
-  }
-
-  public void testDependencies_default() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> optionalbinder =
-            OptionalBinder.newOptionalBinder(binder(), String.class);
-        optionalbinder.setDefault().toInstance("A");
-      }
-    });
-
-    Binding<String> binding = injector.getBinding(Key.get(String.class));
-    HasDependencies withDependencies = (HasDependencies) binding;
-    Set<String> elements = Sets.newHashSet();
-    elements.addAll(recurseForDependencies(injector, withDependencies));
-    assertEquals(ImmutableSet.of("A"), elements);
-  }
-  
-  @SuppressWarnings("rawtypes")
-  private Set<String> recurseForDependencies(Injector injector, HasDependencies hasDependencies) {
-    Set<String> elements = Sets.newHashSet();
-    for (Dependency<?> dependency : hasDependencies.getDependencies()) {
-      Binding<?> binding = injector.getBinding(dependency.getKey());
-      HasDependencies deps = (HasDependencies) binding;
-      if (binding instanceof InstanceBinding) {
-        elements.add((String) ((InstanceBinding) binding).getInstance());
-      } else {
-        elements.addAll(recurseForDependencies(injector, deps));
-      }
-    }    
-    return elements;
-  }
-
-  /**
-   * Doubly-installed modules should not conflict, even when one is overridden.
-   */
-  public void testModuleOverrideRepeatedInstalls_toInstance() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
-        b.setDefault().toInstance("A");
-        b.setBinding().toInstance("B");
-      }
-    };
-
-    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
-
-    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
-    assertEquals("B", injector.getInstance(Key.get(String.class)));
-
-    assertOptionalVisitor(stringKey,
-        setOf(m, Modules.override(m).with(m)),
-        VisitType.BOTH,
-        0,
-        instance("A"),
-        instance("B"),
-        null);
-  }
-
-  public void testModuleOverrideRepeatedInstalls_toKey() {
-    final Key<String> aKey = Key.get(String.class, Names.named("A_string"));
-    final Key<String> bKey = Key.get(String.class, Names.named("B_string"));
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        bind(aKey).toInstance("A");
-        bind(bKey).toInstance("B");
-
-        OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
-        b.setDefault().to(aKey);
-        b.setBinding().to(bKey);
-      }
-    };
-
-    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
-
-    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
-    assertEquals("B", injector.getInstance(Key.get(String.class)));
-
-    assertOptionalVisitor(stringKey,
-        setOf(m, Modules.override(m).with(m)),
-        VisitType.BOTH,
-        0,
-        linked(aKey),
-        linked(bKey),
-        null);
-  }
-
-  public void testModuleOverrideRepeatedInstalls_toProviderInstance() {
-    // Providers#of() does not redefine equals/hashCode, so use the same one both times.
-    final Provider<String> aProvider = Providers.of("A");
-    final Provider<String> bProvider = Providers.of("B");
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
-        b.setDefault().toProvider(aProvider);
-        b.setBinding().toProvider(bProvider);
-      }
-    };
-
-    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
-
-    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
-    assertEquals("B", injector.getInstance(Key.get(String.class)));
-
-    assertOptionalVisitor(stringKey,
-        setOf(m, Modules.override(m).with(m)),
-        VisitType.BOTH,
-        0,
-        providerInstance("A"),
-        providerInstance("B"),
-        null);
-  }
-
-  private static class AStringProvider implements Provider<String> {
-    public String get() {
-      return "A";
-    }
-  }
-
-  private static class BStringProvider implements Provider<String> {
-    public String get() {
-      return "B";
-    }
-  }
-
-  public void testModuleOverrideRepeatedInstalls_toProviderKey() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<String> b = OptionalBinder.newOptionalBinder(binder(), String.class);
-        b.setDefault().toProvider(Key.get(AStringProvider.class));
-        b.setBinding().toProvider(Key.get(BStringProvider.class));
-      }
-    };
-
-    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(String.class)));
-
-    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
-    assertEquals("B", injector.getInstance(Key.get(String.class)));
-
-    assertOptionalVisitor(stringKey,
-        setOf(m, Modules.override(m).with(m)),
-        VisitType.BOTH,
-        0,
-        providerKey(Key.get(AStringProvider.class)),
-        providerKey(Key.get(BStringProvider.class)),
-        null);
-  }
-
-  private static class StringGrabber {
-    private final String string;
-
-    @SuppressWarnings("unused")  // Found by reflection
-    public StringGrabber(@Named("A_string") String string) {
-      this.string = string;
-    }
-
-    @SuppressWarnings("unused")  // Found by reflection
-    public StringGrabber(@Named("B_string") String string, int unused) {
-      this.string = string;
-    }
-
-    @Override
-    public int hashCode() {
-      return string.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      return (obj instanceof StringGrabber) && ((StringGrabber) obj).string.equals(string);
-    }
-
-    @Override
-    public String toString() {
-      return "StringGrabber(" + string + ")";
-    }
-  }
-
-  public void testModuleOverrideRepeatedInstalls_toConstructor() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        Key<String> aKey = Key.get(String.class, Names.named("A_string"));
-        Key<String> bKey = Key.get(String.class, Names.named("B_string"));
-        bind(aKey).toInstance("A");
-        bind(bKey).toInstance("B");
-        bind(Integer.class).toInstance(0);  // used to disambiguate constructors
-
-
-        OptionalBinder<StringGrabber> b =
-            OptionalBinder.newOptionalBinder(binder(), StringGrabber.class);
-        try {
-          b.setDefault().toConstructor(
-              StringGrabber.class.getConstructor(String.class));
-          b.setBinding().toConstructor(
-              StringGrabber.class.getConstructor(String.class, int.class));
-        } catch (NoSuchMethodException e) {
-          fail("No such method: " + e.getMessage());
-        }
-      }
-    };
-
-    assertEquals("B", Guice.createInjector(m, m).getInstance(Key.get(StringGrabber.class)).string);
-
-    Injector injector = Guice.createInjector(m, Modules.override(m).with(m));
-    assertEquals("B", injector.getInstance(Key.get(StringGrabber.class)).string);
-  }
-
-  /**
-   * Unscoped bindings should not conflict, whether they were bound with no explicit scope, or
-   * explicitly bound in {@link Scopes#NO_SCOPE}.
-   */
-  public void testDuplicateUnscopedBindings() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<Integer> b = OptionalBinder.newOptionalBinder(binder(), Integer.class);
-        b.setDefault().to(Key.get(Integer.class, named("foo")));
-        b.setDefault().to(Key.get(Integer.class, named("foo"))).in(Scopes.NO_SCOPE);
-        b.setBinding().to(Key.get(Integer.class, named("foo")));
-        b.setBinding().to(Key.get(Integer.class, named("foo"))).in(Scopes.NO_SCOPE);
-      }
-      @Provides @Named("foo") int provideInt() { return 5; }
-    };
-    assertEquals(5, Guice.createInjector(m).getInstance(Integer.class).intValue());
-  }
-
-  /**
-   * Ensure key hash codes are fixed at injection time, not binding time.
-   */
-  public void testKeyHashCodesFixedAtInjectionTime() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<List<String>> b = OptionalBinder.newOptionalBinder(binder(), listOfStrings);
-        List<String> list = Lists.newArrayList();
-        b.setDefault().toInstance(list);
-        b.setBinding().toInstance(list);
-        list.add("A");
-        list.add("B");
-      }
-    };
-
-    Injector injector = Guice.createInjector(m);
-    for (Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
-      Key<?> bindingKey = entry.getKey();
-      Key<?> clonedKey;
-      if (bindingKey.getAnnotation() != null) {
-        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotation());
-      } else if (bindingKey.getAnnotationType() != null) {
-        clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotationType());
-      } else {
-        clonedKey = Key.get(bindingKey.getTypeLiteral());
-      }
-      assertEquals(bindingKey, clonedKey);
-      assertEquals("Incorrect hashcode for " + bindingKey + " -> " + entry.getValue(),
-          bindingKey.hashCode(), clonedKey.hashCode());
-    }
-  }
-
-  /**
-   * Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}.
-   */
-  public void testBindingKeysFixedOnReturnFromGetElements() {
-    final List<String> list = Lists.newArrayList();
-    Module m = new AbstractModule() {
-      @Override protected void configure() {
-        OptionalBinder<List<String>> b = OptionalBinder.newOptionalBinder(binder(), listOfStrings);
-        b.setDefault().toInstance(list);
-        list.add("A");
-        list.add("B");
-      }
-    };
-
-    InstanceBinding<?> binding = Iterables.getOnlyElement(
-        Iterables.filter(Elements.getElements(m), InstanceBinding.class));
-    Key<?> keyBefore = binding.getKey();
-    assertEquals(listOfStrings, keyBefore.getTypeLiteral());
-
-    list.add("C");
-    Key<?> keyAfter = binding.getKey();
-    assertSame(keyBefore, keyAfter);
-  }
-
-  @BindingAnnotation
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
-  private static @interface Marker {}
-
-  @Marker
-  public void testMatchingMarkerAnnotations() throws Exception {
-    Method m = OptionalBinderTest.class.getDeclaredMethod("testMatchingMarkerAnnotations");
-    assertNotNull(m);
-    final Annotation marker = m.getAnnotation(Marker.class);
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override public void configure() {
-        OptionalBinder<Integer> mb1 =
-            OptionalBinder.newOptionalBinder(binder(), Key.get(Integer.class, Marker.class));
-        OptionalBinder<Integer> mb2 =
-            OptionalBinder.newOptionalBinder(binder(), Key.get(Integer.class, marker));
-        mb1.setDefault().toInstance(1);
-        mb2.setBinding().toInstance(2);
-
-        // This assures us that the two binders are equivalent, so we expect the instance added to
-        // each to have been added to one set.
-        assertEquals(mb1, mb2);
-      }
-    });
-    Integer i1 = injector.getInstance(Key.get(Integer.class, Marker.class));
-    Integer i2 = injector.getInstance(Key.get(Integer.class, marker));
-
-    // These must be identical, because the marker annotations collapsed to the same thing.
-    assertSame(i1, i2);
-    assertEquals(2, i2.intValue());
-  }
-  
- // Tests for com.google.inject.internal.WeakKeySet not leaking memory.
- public void testWeakKeySet_integration() {   
-   Injector parentInjector = Guice.createInjector(new AbstractModule() {
-         @Override protected void configure() {
-           bind(String.class).toInstance("hi");
-         }
-       });
-   WeakKeySetUtils.assertNotBlacklisted(parentInjector, Key.get(Integer.class));
-
-   Injector childInjector = parentInjector.createChildInjector(new AbstractModule() {
-     @Override protected void configure() {
-       OptionalBinder.newOptionalBinder(binder(), Integer.class).setDefault().toInstance(4);
-     }
-   });
-   WeakReference<Injector> weakRef = new WeakReference<Injector>(childInjector);
-   WeakKeySetUtils.assertBlacklisted(parentInjector, Key.get(Integer.class));
-   
-   // Clear the ref, GC, and ensure that we are no longer blacklisting.
-   childInjector = null;
-   
-   Asserts.awaitClear(weakRef);
-   WeakKeySetUtils.assertNotBlacklisted(parentInjector, Key.get(Integer.class));
- }
-
- public void testCompareEqualsAgainstOtherAnnotation() {
-   OptionalBinder.Actual impl1 = new OptionalBinder.ActualImpl("foo");
-   OptionalBinder.Actual other1 = Dummy.class.getAnnotation(OptionalBinder.Actual.class);
-   assertEquals(impl1, other1);
-
-   OptionalBinder.Default impl2 = new OptionalBinder.DefaultImpl("foo");
-   OptionalBinder.Default other2 = Dummy.class.getAnnotation(OptionalBinder.Default.class);
-   assertEquals(impl2, other2);
-
-   assertFalse(impl1.equals(impl2));
-   assertFalse(impl1.equals(other2));
-   assertFalse(impl2.equals(other1));
-   assertFalse(other1.equals(other2));
- }
-
-  @OptionalBinder.Actual("foo")
-  @OptionalBinder.Default("foo")
-  static class Dummy {}
-  
-  @SuppressWarnings("unchecked") 
-  private <V> Set<V> setOf(V... elements) {
-    return ImmutableSet.copyOf(elements);
-  }
-
-  @SuppressWarnings("unchecked")
-  private <T> Optional<T> toOptional(Object object) throws Exception {
-    assertTrue("not a java.util.Optional: " + object.getClass(),
-        JAVA_OPTIONAL_CLASS.isInstance(object));
-    return Optional.fromNullable((T) JAVA_OPTIONAL_OR_ELSE.invoke(object, (Void) null));
-  }
-}
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/ProvidesIntoTest.java b/extensions/multibindings/test/com/google/inject/multibindings/ProvidesIntoTest.java
deleted file mode 100644
index 62c7a58..0000000
--- a/extensions/multibindings/test/com/google/inject/multibindings/ProvidesIntoTest.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/**
- * 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 com.google.inject.multibindings;
-
-import static com.google.inject.Asserts.assertContains;
-import static com.google.inject.name.Names.named;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.AbstractModule;
-import com.google.inject.CreationException;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.multibindings.ProvidesIntoOptional.Type;
-import com.google.inject.name.Named;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Retention;
-import java.lang.reflect.Field;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tests the various @ProvidesInto annotations.
- *
- * @author sameb@google.com (Sam Berlin)
- */
-public class ProvidesIntoTest extends TestCase {
-
-  public void testAnnotation() throws Exception {
-    Injector injector = Guice.createInjector(MultibindingsScanner.asModule(), new AbstractModule() {
-      @Override protected void configure() {}
-
-      @ProvidesIntoSet
-      @Named("foo")
-      String setFoo() { return "foo"; }
-
-      @ProvidesIntoSet
-      @Named("foo")
-      String setFoo2() { return "foo2"; }
-
-      @ProvidesIntoSet
-      @Named("bar")
-      String setBar() { return "bar"; }
-
-      @ProvidesIntoSet
-      @Named("bar")
-      String setBar2() { return "bar2"; }
-
-      @ProvidesIntoSet
-      String setNoAnnotation() { return "na"; }
-
-      @ProvidesIntoSet
-      String setNoAnnotation2() { return "na2"; }
-
-      @ProvidesIntoMap
-      @StringMapKey("fooKey")
-      @Named("foo")
-      String mapFoo() { return "foo"; }
-
-      @ProvidesIntoMap
-      @StringMapKey("foo2Key")
-      @Named("foo")
-      String mapFoo2() { return "foo2"; }
-
-      @ProvidesIntoMap
-      @ClassMapKey(String.class)
-      @Named("bar")
-      String mapBar() { return "bar"; }
-
-      @ProvidesIntoMap
-      @ClassMapKey(Number.class)
-      @Named("bar")
-      String mapBar2() { return "bar2"; }
-
-      @ProvidesIntoMap
-      @TestEnumKey(TestEnum.A)
-      String mapNoAnnotation() { return "na"; }
-
-      @ProvidesIntoMap
-      @TestEnumKey(TestEnum.B)
-      String mapNoAnnotation2() { return "na2"; }
-
-      @ProvidesIntoMap
-      @WrappedKey(number = 1)
-      Number wrapped1() { return 11; }
-
-      @ProvidesIntoMap
-      @WrappedKey(number = 2)
-      Number wrapped2() { return 22; }
-
-      @ProvidesIntoOptional(ProvidesIntoOptional.Type.DEFAULT)
-      @Named("foo")
-      String optionalDefaultFoo() { return "foo"; }
-
-      @ProvidesIntoOptional(ProvidesIntoOptional.Type.ACTUAL)
-      @Named("foo")
-      String optionalActualFoo() { return "foo2"; }
-
-      @ProvidesIntoOptional(ProvidesIntoOptional.Type.DEFAULT)
-      @Named("bar")
-      String optionalDefaultBar() { return "bar"; }
-
-      @ProvidesIntoOptional(ProvidesIntoOptional.Type.ACTUAL)
-      String optionalActualBar() { return "na2"; }
-    });
-
-    Set<String> fooSet = injector.getInstance(new Key<Set<String>>(named("foo")) {});
-    assertEquals(ImmutableSet.of("foo", "foo2"), fooSet);
-
-    Set<String> barSet = injector.getInstance(new Key<Set<String>>(named("bar")) {});
-    assertEquals(ImmutableSet.of("bar", "bar2"), barSet);
-
-    Set<String> noAnnotationSet = injector.getInstance(new Key<Set<String>>() {});
-    assertEquals(ImmutableSet.of("na", "na2"), noAnnotationSet);
-
-    Map<String, String> fooMap =
-        injector.getInstance(new Key<Map<String, String>>(named("foo")) {});
-    assertEquals(ImmutableMap.of("fooKey", "foo", "foo2Key", "foo2"), fooMap);
-
-    Map<Class<?>, String> barMap =
-        injector.getInstance(new Key<Map<Class<?>, String>>(named("bar")) {});
-    assertEquals(ImmutableMap.of(String.class, "bar", Number.class, "bar2"), barMap);
-
-    Map<TestEnum, String> noAnnotationMap =
-        injector.getInstance(new Key<Map<TestEnum, String>>() {});
-    assertEquals(ImmutableMap.of(TestEnum.A, "na", TestEnum.B, "na2"), noAnnotationMap);
-
-    Map<WrappedKey, Number> wrappedMap =
-        injector.getInstance(new Key<Map<WrappedKey, Number>>() {});
-    assertEquals(ImmutableMap.of(wrappedKeyFor(1), 11, wrappedKeyFor(2), 22), wrappedMap);
-
-    Optional<String> fooOptional =
-        injector.getInstance(new Key<Optional<String>>(named("foo")) {});
-    assertEquals("foo2", fooOptional.get());
-
-    Optional<String> barOptional =
-        injector.getInstance(new Key<Optional<String>>(named("bar")) {});
-    assertEquals("bar", barOptional.get());
-
-    Optional<String> noAnnotationOptional =
-        injector.getInstance(new Key<Optional<String>>() {});
-    assertEquals("na2", noAnnotationOptional.get());
-  }
-
-  enum TestEnum {
-    A, B
-  }
-
-  @MapKey(unwrapValue = true)
-  @Retention(RUNTIME)
-  @interface TestEnumKey {
-    TestEnum value();
-  }
-
-  @MapKey(unwrapValue = false)
-  @Retention(RUNTIME)
-  @interface WrappedKey {
-    int number();
-  }
-  
-  @SuppressWarnings("unused") @WrappedKey(number=1) private static Object wrappedKey1Holder;
-  @SuppressWarnings("unused") @WrappedKey(number=2) private static Object wrappedKey2Holder;
-  WrappedKey wrappedKeyFor(int number) throws Exception {
-    Field field;
-    switch (number) {
-      case 1:
-        field = ProvidesIntoTest.class.getDeclaredField("wrappedKey1Holder");
-        break;
-      case 2:
-        field = ProvidesIntoTest.class.getDeclaredField("wrappedKey2Holder");
-        break;
-      default:
-        throw new IllegalArgumentException("only 1 or 2 supported");
-    }
-    return field.getAnnotation(WrappedKey.class);
-  }
-  
-  public void testDoubleScannerIsIgnored() {
-    Injector injector = Guice.createInjector(
-        MultibindingsScanner.asModule(),
-        MultibindingsScanner.asModule(),
-        new AbstractModule() {
-          @Override protected void configure() {}
-          @ProvidesIntoSet String provideFoo() { return "foo"; }
-        }
-    );
-    assertEquals(ImmutableSet.of("foo"), injector.getInstance(new Key<Set<String>>() {}));
-  }
-  
-  @MapKey(unwrapValue = true)
-  @Retention(RUNTIME)
-  @interface ArrayUnwrappedKey {
-    int[] value();
-  }
-  
-  public void testArrayKeys_unwrapValuesTrue() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-      @ProvidesIntoMap @ArrayUnwrappedKey({1, 2}) String provideFoo() { return "foo"; }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(),
-          "Array types are not allowed in a MapKey with unwrapValue=true: "
-              + ArrayUnwrappedKey.class.getName(),
-          "at " + m.getClass().getName() + ".provideFoo(");
-    }    
-  }
-
-  @MapKey(unwrapValue = false)
-  @Retention(RUNTIME)
-  @interface ArrayWrappedKey {
-    int[] number();
-  }
-  
-  @SuppressWarnings("unused") @ArrayWrappedKey(number={1, 2}) private static Object arrayWrappedKeyHolder12;
-  @SuppressWarnings("unused") @ArrayWrappedKey(number={3, 4}) private static Object arrayWrappedKeyHolder34;
-  ArrayWrappedKey arrayWrappedKeyFor(int number) throws Exception {
-    Field field;
-    switch (number) {
-      case 12:
-        field = ProvidesIntoTest.class.getDeclaredField("arrayWrappedKeyHolder12");
-        break;
-      case 34:
-        field = ProvidesIntoTest.class.getDeclaredField("arrayWrappedKeyHolder34");
-        break;
-      default:
-        throw new IllegalArgumentException("only 1 or 2 supported");
-    }
-    return field.getAnnotation(ArrayWrappedKey.class);
-  }
-  
-  public void testArrayKeys_unwrapValuesFalse() throws Exception {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-      @ProvidesIntoMap @ArrayWrappedKey(number = {1, 2}) String provideFoo() { return "foo"; }
-      @ProvidesIntoMap @ArrayWrappedKey(number = {3, 4}) String provideBar() { return "bar"; }
-    };
-    Injector injector = Guice.createInjector(MultibindingsScanner.asModule(), m);
-    Map<ArrayWrappedKey, String> map =
-        injector.getInstance(new Key<Map<ArrayWrappedKey, String>>() {});
-    ArrayWrappedKey key12 = arrayWrappedKeyFor(12);
-    ArrayWrappedKey key34 = arrayWrappedKeyFor(34);
-    assertEquals("foo", map.get(key12));
-    assertEquals("bar", map.get(key34));
-    assertEquals(2, map.size());
-  }
-  
-  public void testProvidesIntoSetWithMapKey() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-      @ProvidesIntoSet @TestEnumKey(TestEnum.A) String provideFoo() { return "foo"; }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(), "Found a MapKey annotation on non map binding at "
-          + m.getClass().getName() + ".provideFoo");
-    }
-  }
-  
-  public void testProvidesIntoOptionalWithMapKey() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-
-      @ProvidesIntoOptional(Type.ACTUAL)
-      @TestEnumKey(TestEnum.A)
-      String provideFoo() {
-        return "foo";
-      }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(), "Found a MapKey annotation on non map binding at "
-          + m.getClass().getName() + ".provideFoo");
-    }
-  }
-  
-  public void testProvidesIntoMapWithoutMapKey() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-      @ProvidesIntoMap String provideFoo() { return "foo"; }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(), "No MapKey found for map binding at "
-          + m.getClass().getName() + ".provideFoo");
-    }
-  }
-  
-  @MapKey(unwrapValue = true)
-  @Retention(RUNTIME)
-  @interface TestEnumKey2 {
-    TestEnum value();
-  }
-  
-  public void testMoreThanOneMapKeyAnnotation() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-
-      @ProvidesIntoMap
-      @TestEnumKey(TestEnum.A)
-      @TestEnumKey2(TestEnum.B)
-      String provideFoo() {
-        return "foo";
-      }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(), "Found more than one MapKey annotations on "
-          + m.getClass().getName() + ".provideFoo");
-    }    
-  }
-  
-  @MapKey(unwrapValue = true)
-  @Retention(RUNTIME)
-  @interface MissingValueMethod {
-  }
-  
-  public void testMapKeyMissingValueMethod() {
-    Module m = new AbstractModule() {
-      @Override protected void configure() {}
-
-      @ProvidesIntoMap
-      @MissingValueMethod
-      String provideFoo() {
-        return "foo";
-      }
-    };
-    try {
-      Guice.createInjector(MultibindingsScanner.asModule(), m);
-      fail();
-    } catch (CreationException ce) {
-      assertEquals(1, ce.getErrorMessages().size());
-      assertContains(ce.getMessage(), "No 'value' method in MapKey with unwrapValue=true: "
-          + MissingValueMethod.class.getName());
-    }    
-  }
-}
diff --git a/extensions/persist/lib/cglib-nodep-3.0.jar b/extensions/persist/lib/cglib-nodep-3.0.jar
deleted file mode 100644
index 1f761af..0000000
--- a/extensions/persist/lib/cglib-nodep-3.0.jar
+++ /dev/null
Binary files differ
diff --git a/extensions/persist/lib/cglib-nodep-3.2.6.jar b/extensions/persist/lib/cglib-nodep-3.2.6.jar
new file mode 100644
index 0000000..0e333b0
--- /dev/null
+++ b/extensions/persist/lib/cglib-nodep-3.2.6.jar
Binary files differ
diff --git a/extensions/persist/pom.xml b/extensions/persist/pom.xml
index 1eb12db..7e27377 100644
--- a/extensions/persist/pom.xml
+++ b/extensions/persist/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-persist</artifactId>
@@ -63,4 +63,19 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.persist</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/persist/src/com/google/inject/persist/PersistFilter.java b/extensions/persist/src/com/google/inject/persist/PersistFilter.java
index 1aba144..4a41dcc 100644
--- a/extensions/persist/src/com/google/inject/persist/PersistFilter.java
+++ b/extensions/persist/src/com/google/inject/persist/PersistFilter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,7 @@
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -29,38 +27,37 @@
 import javax.servlet.ServletResponse;
 
 /**
- * Apply this filter to enable the HTTP Request unit of work and to have
- * guice-persist manage the lifecycle of active units of work.
- * The filter automatically starts and stops the relevant {@link PersistService}
- * upon {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and
- * {@link javax.servlet.Filter#destroy()} respectively.
+ * Apply this filter to enable the HTTP Request unit of work and to have guice-persist manage the
+ * lifecycle of active units of work. The filter automatically starts and stops the relevant {@link
+ * PersistService} upon {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and {@link
+ * javax.servlet.Filter#destroy()} respectively.
  *
- * <p> To be able to use the open session-in-view pattern (i.e. work per request),
- * register this filter <b>once</b> in your Guice {@code ServletModule}. It is
- * important that you register this filter before any other filter.
+ * <p>To be able to use the open session-in-view pattern (i.e. work per request), register this
+ * filter <b>once</b> in your Guice {@code ServletModule}. It is important that you register this
+ * filter before any other filter.
  *
- * For multiple providers, you should register this filter once per provider, inside
- * a private module for each persist module installed (this must be the same private
- * module where the specific persist module is itself installed).
+ * <p>For multiple providers, you should register this filter once per provider, inside a private
+ * module for each persist module installed (this must be the same private module where the specific
+ * persist module is itself installed).
  *
- * <p>
- * Example configuration:
+ * <p>Example configuration:
+ *
  * <pre>{@code
- *  public class MyModule extends ServletModule {
- *    public void configureServlets() {
- *      filter("/*").through(PersistFilter.class);
+ * public class MyModule extends ServletModule {
+ *   public void configureServlets() {
+ *     filter("/*").through(PersistFilter.class);
  *
- *      serve("/index.html").with(MyHtmlServlet.class);
- *      // Etc.
- *    }
- *  }
+ *     serve("/index.html").with(MyHtmlServlet.class);
+ *     // Etc.
+ *   }
+ * }
  * }</pre>
- * <p>
- * This filter is thread safe and allows you to create injectors concurrently
- * and deploy multiple guice-persist modules within the same injector, or even
- * multiple injectors with persist modules withing the same JVM or web app.
- * <p>
- * This filter requires the Guice Servlet extension.
+ *
+ * <p>This filter is thread safe and allows you to create injectors concurrently and deploy multiple
+ * guice-persist modules within the same injector, or even multiple injectors with persist modules
+ * withing the same JVM or web app.
+ *
+ * <p>This filter requires the Guice Servlet extension.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
@@ -75,16 +72,22 @@
     this.persistService = persistService;
   }
 
+  @Override
   public void init(FilterConfig filterConfig) throws ServletException {
     persistService.start();
   }
 
+  @Override
   public void destroy() {
     persistService.stop();
   }
 
-  public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
-      final FilterChain filterChain) throws IOException, ServletException {
+  @Override
+  public void doFilter(
+      final ServletRequest servletRequest,
+      final ServletResponse servletResponse,
+      final FilterChain filterChain)
+      throws IOException, ServletException {
 
     unitOfWork.begin();
     try {
diff --git a/extensions/persist/src/com/google/inject/persist/PersistModule.java b/extensions/persist/src/com/google/inject/persist/PersistModule.java
index 8efe895..e20c7ef 100644
--- a/extensions/persist/src/com/google/inject/persist/PersistModule.java
+++ b/extensions/persist/src/com/google/inject/persist/PersistModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,12 +20,10 @@
 import static com.google.inject.matcher.Matchers.any;
 
 import com.google.inject.AbstractModule;
-
 import org.aopalliance.intercept.MethodInterceptor;
 
 /**
- * Install this module to add guice-persist library support for JPA persistence
- * providers.
+ * Install this module to add guice-persist library support for JPA persistence providers.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
@@ -39,7 +37,7 @@
     requireBinding(UnitOfWork.class);
     /*if[AOP]*/
     // wrapping in an if[AOP] just to allow this to compile in NO_AOP -- it won't be used
-    
+
     // class-level @Transacational
     bindInterceptor(annotatedWith(Transactional.class), any(), getTransactionInterceptor());
     // method-level @Transacational
diff --git a/extensions/persist/src/com/google/inject/persist/PersistService.java b/extensions/persist/src/com/google/inject/persist/PersistService.java
index 85d4b35..6965177 100644
--- a/extensions/persist/src/com/google/inject/persist/PersistService.java
+++ b/extensions/persist/src/com/google/inject/persist/PersistService.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,29 +16,27 @@
 package com.google.inject.persist;
 
 /**
- * Persistence provider service. Use this to manage the overall
- * startup and stop of the persistence module(s).
+ * Persistence provider service. Use this to manage the overall startup and stop of the persistence
+ * module(s).
  *
- * TODO(dhanji): Integrate with Service API when appropriate.
+ * <p>TODO(dhanji): Integrate with Service API when appropriate.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public interface PersistService {
 
   /**
-   * Starts the underlying persistence engine and makes guice-persist ready for
-   * use. For instance, with JPA, it creates an EntityManagerFactory and may
-   * open connection pools. This method must be called by your code prior to
-   * using any guice-persist or JPA artifacts. If already started,
-   * calling this method does nothing, if already stopped, it also does
-   * nothing.
+   * Starts the underlying persistence engine and makes guice-persist ready for use. For instance,
+   * with JPA, it creates an EntityManagerFactory and may open connection pools. This method must be
+   * called by your code prior to using any guice-persist or JPA artifacts. If already started,
+   * calling this method does nothing, if already stopped, it also does nothing.
    */
   void start();
 
   /**
-   * Stops the underlying persistence engine. For instance, with JPA, it
-   * closes the {@code EntityManagerFactory}. If already stopped, calling this
-   * method does nothing. If not yet started, it also does nothing.
+   * Stops the underlying persistence engine. For instance, with JPA, it closes the {@code
+   * EntityManagerFactory}. If already stopped, calling this method does nothing. If not yet
+   * started, it also does nothing.
    */
   void stop();
 }
diff --git a/extensions/persist/src/com/google/inject/persist/Transactional.java b/extensions/persist/src/com/google/inject/persist/Transactional.java
index 9a8bbfb..b860e5b 100644
--- a/extensions/persist/src/com/google/inject/persist/Transactional.java
+++ b/extensions/persist/src/com/google/inject/persist/Transactional.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,40 +23,36 @@
 import java.lang.annotation.Target;
 
 /**
- * <p> Any method or class marked with this annotation will be considered for transactionality.
- * Consult the documentation on https://github.com/google/guice/wiki/GuicePersist for detailed
- * semantics.
- * Marking a method {@code @Transactional} will start a new transaction before the method
- * executes and commit it after the method returns.
- * <p>
- * If the method throws an exception, the transaction will be rolled back <em>unless</em>
- * you have specifically requested not to in the {@link #ignore()} clause.
- * <p>
- * Similarly, the set of exceptions that will trigger a rollback can be defined in
- * the {@link #rollbackOn()} clause. By default, only unchecked exceptions trigger a
- * rollback.
+ * Any method or class marked with this annotation will be considered for transactionality. Consult
+ * the documentation on https://github.com/google/guice/wiki/GuicePersist for detailed semantics.
+ * Marking a method {@code @Transactional} will start a new transaction before the method executes
+ * and commit it after the method returns.
+ *
+ * <p>If the method throws an exception, the transaction will be rolled back <em>unless</em> you
+ * have specifically requested not to in the {@link #ignore()} clause.
+ *
+ * <p>Similarly, the set of exceptions that will trigger a rollback can be defined in the {@link
+ * #rollbackOn()} clause. By default, only unchecked exceptions trigger a rollback.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
-@Target({ ElementType.METHOD, ElementType.TYPE })
+@Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Inherited
 public @interface Transactional {
 
   /**
-   * A list of exceptions to rollback on, if thrown by the transactional method.
-   * These exceptions are propagated correctly after a rollback.
+   * A list of exceptions to rollback on, if thrown by the transactional method. These exceptions
+   * are propagated correctly after a rollback.
    */
   Class<? extends Exception>[] rollbackOn() default RuntimeException.class;
 
   /**
-   * A list of exceptions to <b>not<b> rollback on. A caveat to the rollbackOn clause.
-   * The disjunction of rollbackOn and ignore represents the list of exceptions
-   * that will trigger a rollback.
-   * The complement of rollbackOn and the universal set plus any exceptions in the
-   * ignore set represents the list of exceptions that will trigger a commit.
-   * Note that ignore exceptions take precedence over rollbackOn, but with subtype
-   * granularity.
+   * A list of exceptions to <b>not<b> rollback on. A caveat to the rollbackOn clause. The
+   * disjunction of rollbackOn and ignore represents the list of exceptions that will trigger a
+   * rollback. The complement of rollbackOn and the universal set plus any exceptions in the ignore
+   * set represents the list of exceptions that will trigger a commit. Note that ignore exceptions
+   * take precedence over rollbackOn, but with subtype granularity.
    */
-  Class<? extends Exception>[] ignore() default { };
+  Class<? extends Exception>[] ignore() default {};
 }
diff --git a/extensions/persist/src/com/google/inject/persist/UnitOfWork.java b/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
index 061a6ab..86ef678 100644
--- a/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
+++ b/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,32 +17,32 @@
 package com.google.inject.persist;
 
 /**
- * This interface is used to gain manual control over the unit of work. This is mostly to do
- * work in non-request, non-transactional threads. Or where more fine-grained control over the unit
- * of work is required. Starting and ending a unit of work directly corresponds to opening and
- * closing a {@code Session}, {@code EntityManager} or {@code ObjectContainer} respectively.
- * <p> The
- * Unit of Work referred to by UnitOfWork will always be local to the calling thread. Be careful to
- * end() in a finally block. Neither JPA, nor Hibernate supports threadsafe sessions (reasoning
- * behind thread-locality of Unit of Work semantics).
+ * This interface is used to gain manual control over the unit of work. This is mostly to do work in
+ * non-request, non-transactional threads. Or where more fine-grained control over the unit of work
+ * is required. Starting and ending a unit of work directly corresponds to opening and closing a
+ * {@code Session}, {@code EntityManager} or {@code ObjectContainer} respectively.
+ *
+ * <p>The Unit of Work referred to by UnitOfWork will always be local to the calling thread. Be
+ * careful to end() in a finally block. Neither JPA, nor Hibernate supports threadsafe sessions
+ * (reasoning behind thread-locality of Unit of Work semantics).
  *
  * <ul>
- *   <li>Using UnitOfWork with the PersistFilter inside a request is not recommended.</li>
- *   <li>Using UnitOfWork with session-per-txn strategy is not terribly clever either.</li>
- *   <li>Using UnitOfWork with session-per-request strategy but *outside* a request (i.e. in a
- *       background or bootstrap thread) is probably a good use case.</li>
- *  </ul>
+ * <li>Using UnitOfWork with the PersistFilter inside a request is not recommended.
+ * <li>Using UnitOfWork with session-per-txn strategy is not terribly clever either.
+ * <li>Using UnitOfWork with session-per-request strategy but *outside* a request (i.e. in a
+ *     background or bootstrap thread) is probably a good use case.
+ * </ul>
  *
  * @author Dhanji R. Prasanna (dhanji@gmail com)
  */
 public interface UnitOfWork {
 
   /**
-   * Starts a Unit Of Work. Underneath, causes a session to the data layer to be opened. If there
-   * is already one open, the invocation will do nothing. In this way, you can define arbitrary
+   * Starts a Unit Of Work. Underneath, causes a session to the data layer to be opened. If there is
+   * already one open, the invocation will do nothing. In this way, you can define arbitrary
    * units-of-work that nest within one another safely.
    *
-   * Transaction semantics are not affected.
+   * <p>Transaction semantics are not affected.
    */
   void begin();
 
@@ -50,8 +50,8 @@
    * Declares an end to the current Unit of Work. Underneath, causes any open session to the data
    * layer to close. If there is no Unit of work open, then the call returns silently. You can
    * safely invoke end() repeatedly.
-   * <p>
-   * Transaction semantics are not affected.
+   *
+   * <p>Transaction semantics are not affected.
    */
   void end();
 }
diff --git a/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java b/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
index 3bcd931..6be2c11 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/persist/src/com/google/inject/persist/finder/Finder.java b/extensions/persist/src/com/google/inject/persist/finder/Finder.java
index 7bfbc92..d0c669e 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/Finder.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/Finder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,20 +32,18 @@
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Finder {
   /**
-   * Returns the configured named query's name. Specify a named query's name
-   * here. This name is typically specified in your JPA configuration.
+   * Returns the configured named query's name. Specify a named query's name here. This name is
+   * typically specified in your JPA configuration.
    */
   String namedQuery() default "";
 
-  /**
-   * Returns the configured query string. Directly specify a JPAQL query here.
-   */
+  /** Returns the configured query string. Directly specify a JPAQL query here. */
   String query() default "";
 
   /**
-   * Returns the configured autoboxing collection class.
-   * Use this clause to specify a collection impl to autobox result lists into. The impl must
-   * have a default no-arg constructor and be a subclass of {@code java.util.Collection}.
+   * Returns the configured autoboxing collection class. Use this clause to specify a collection
+   * impl to autobox result lists into. The impl must have a default no-arg constructor and be a
+   * subclass of {@code java.util.Collection}.
    */
   Class<? extends Collection> returnAs() default Collection.class;
-}
\ No newline at end of file
+}
diff --git a/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java b/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
index 0feed7e..7d9a214 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,13 +22,12 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotate any dynamic finder method's integer argument with this to pass in
- * the index of the first result in the result set you are interested in.
- * Useful for paging result sets. Complemented by {@link MaxResults}.
+ * Annotate any dynamic finder method's integer argument with this to pass in the index of the first
+ * result in the result set you are interested in. Useful for paging result sets. Complemented by
+ * {@link MaxResults}.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
 @Target(ElementType.PARAMETER)
 @Retention(RetentionPolicy.RUNTIME)
-public @interface FirstResult {
-}
+public @interface FirstResult {}
diff --git a/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java b/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
index 69223d0..3f9dd43 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,13 +22,11 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotate any dynamic finder method's integer argument with this to pass in
- * the maximum size of returned result window. Usefule for paging result sets.
- * Complement of {@link FirstResult}.
+ * Annotate any dynamic finder method's integer argument with this to pass in the maximum size of
+ * returned result window. Usefule for paging result sets. Complement of {@link FirstResult}.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
 @Target(ElementType.PARAMETER)
 @Retention(RetentionPolicy.RUNTIME)
-public @interface MaxResults {
-}
+public @interface MaxResults {}
diff --git a/extensions/persist/src/com/google/inject/persist/finder/package-info.java b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
index 279929c..bc4eb6e 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Dynamic Finder API for Guice Persist.
- */
+/** Dynamic Finder API for Guice Persist. */
 package com.google.inject.persist.finder;
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java b/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
index 0e7ac27..72b8694 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.persist.jpa;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -27,4 +26,5 @@
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 @Retention(RetentionPolicy.RUNTIME)
-@BindingAnnotation @interface Jpa {}
+@BindingAnnotation
+@interface Jpa {}
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
index 774fa9f..42de106 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,10 +24,6 @@
 import com.google.inject.persist.finder.Finder;
 import com.google.inject.persist.finder.FirstResult;
 import com.google.inject.persist.finder.MaxResults;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -35,9 +31,10 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
 /**
  * TODO(dhanji): Make this work!!
@@ -54,6 +51,7 @@
     this.emProvider = emProvider;
   }
 
+  @Override
   public Object invoke(MethodInvocation methodInvocation) throws Throwable {
     EntityManager em = emProvider.get();
 
@@ -82,31 +80,33 @@
     return result;
   }
 
-  private Object getAsCollection(JpaFinderProxy.FinderDescriptor finderDescriptor,
-      List results) {
+  private Object getAsCollection(JpaFinderProxy.FinderDescriptor finderDescriptor, List results) {
     Collection<?> collection;
     try {
       collection = (Collection) finderDescriptor.returnCollectionTypeConstructor.newInstance();
     } catch (InstantiationException e) {
       throw new RuntimeException(
           "Specified collection class of Finder's returnAs could not be instantated: "
-              + finderDescriptor.returnCollectionType, e);
+              + finderDescriptor.returnCollectionType,
+          e);
     } catch (IllegalAccessException e) {
       throw new RuntimeException(
           "Specified collection class of Finder's returnAs could not be instantated (do not have access privileges): "
-              + finderDescriptor.returnCollectionType, e);
+              + finderDescriptor.returnCollectionType,
+          e);
     } catch (InvocationTargetException e) {
       throw new RuntimeException(
           "Specified collection class of Finder's returnAs could not be instantated (it threw an exception): "
-              + finderDescriptor.returnCollectionType, e);
+              + finderDescriptor.returnCollectionType,
+          e);
     }
 
     collection.addAll(results);
     return collection;
   }
 
-  private void bindQueryNamedParameters(Query jpaQuery,
-      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
+  private void bindQueryNamedParameters(
+      Query jpaQuery, JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
     for (int i = 0; i < arguments.length; i++) {
       Object argument = arguments[i];
       Object annotation = descriptor.parameterAnnotations[i];
@@ -114,7 +114,7 @@
       if (null == annotation)
       //noinspection UnnecessaryContinue
       {
-        continue;   //skip param as it's not bindable
+        continue; //skip param as it's not bindable
       } else if (annotation instanceof Named) {
         Named named = (Named) annotation;
         jpaQuery.setParameter(named.value(), argument);
@@ -129,8 +129,8 @@
     }
   }
 
-  private void bindQueryRawParameters(Query jpaQuery,
-      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
+  private void bindQueryRawParameters(
+      Query jpaQuery, JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
     for (int i = 0, index = 1; i < arguments.length; i++) {
       Object argument = arguments[i];
       Object annotation = descriptor.parameterAnnotations[i];
@@ -189,7 +189,7 @@
         } else if (MaxResults.class.equals(annotationType)) {
           discoveredAnnotations[i] = annotation;
           break;
-        }   //leave as null for no binding
+        } //leave as null for no binding
       }
     }
 
@@ -201,13 +201,14 @@
         && finderDescriptor.returnClass != Collection.class) {
       finderDescriptor.returnCollectionType = finder.returnAs();
       try {
-        finderDescriptor.returnCollectionTypeConstructor = finderDescriptor.returnCollectionType
-            .getConstructor();
-        finderDescriptor.returnCollectionTypeConstructor.setAccessible(true);   //UGH!
+        finderDescriptor.returnCollectionTypeConstructor =
+            finderDescriptor.returnCollectionType.getConstructor();
+        finderDescriptor.returnCollectionTypeConstructor.setAccessible(true); //UGH!
       } catch (NoSuchMethodException e) {
         throw new RuntimeException(
             "Finder's collection return type specified has no default constructor! returnAs: "
-                + finderDescriptor.returnCollectionType, e);
+                + finderDescriptor.returnCollectionType,
+            e);
       }
     }
 
@@ -238,19 +239,17 @@
     return JpaFinderProxy.ReturnType.PLAIN;
   }
 
-  /**
-   * A wrapper data class that caches information about a finder method.
-   */
+  /** A wrapper data class that caches information about a finder method. */
   private static class FinderDescriptor {
     private volatile boolean isKeyedQuery = false;
     volatile boolean isBindAsRawParameters = true;
-        //should we treat the query as having ? instead of :named params
+    //should we treat the query as having ? instead of :named params
     volatile JpaFinderProxy.ReturnType returnType;
     volatile Class<?> returnClass;
     volatile Class<? extends Collection> returnCollectionType;
     volatile Constructor returnCollectionTypeConstructor;
     volatile Object[] parameterAnnotations;
-        //contract is: null = no bind, @Named = param, @FirstResult/@MaxResults for paging
+    //contract is: null = no bind, @Named = param, @FirstResult/@MaxResults for paging
 
     private String query;
     private String name;
@@ -274,6 +273,8 @@
   }
 
   private static enum ReturnType {
-    PLAIN, COLLECTION, ARRAY
+    PLAIN,
+    COLLECTION,
+    ARRAY
   }
 }
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
index 1f59a6d..7fe6982 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,33 +19,27 @@
 import com.google.inject.Inject;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
+import java.lang.reflect.Method;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 
-import java.lang.reflect.Method;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 class JpaLocalTxnInterceptor implements MethodInterceptor {
 
   // TODO(gak): Move these args to the cxtor & make these final.
-  @Inject
-  private JpaPersistService emProvider = null;
+  @Inject private JpaPersistService emProvider = null;
 
-  @Inject
-  private UnitOfWork unitOfWork = null;
+  @Inject private UnitOfWork unitOfWork = null;
 
   @Transactional
   private static class Internal {}
 
   // Tracks if the unit of work was begun implicitly by this transaction.
-  private final ThreadLocal<Boolean> didWeStartWork = new ThreadLocal<Boolean>();
+  private final ThreadLocal<Boolean> didWeStartWork = new ThreadLocal<>();
 
+  @Override
   public Object invoke(MethodInvocation methodInvocation) throws Throwable {
 
     // Should we start a unit of work?
@@ -91,7 +85,7 @@
       txn.commit();
     } finally {
       //close the em if necessary
-      if (null != didWeStartWork.get() ) {
+      if (null != didWeStartWork.get()) {
         didWeStartWork.remove();
         unitOfWork.end();
       }
@@ -127,8 +121,8 @@
    * @param e The exception to test for rollback
    * @param txn A JPA Transaction to issue rollbacks on
    */
-  private boolean rollbackIfNecessary(Transactional transactional, Exception e,
-      EntityTransaction txn) {
+  private boolean rollbackIfNecessary(
+      Transactional transactional, Exception e, EntityTransaction txn) {
     boolean commit = true;
 
     //check rollback clauses
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
index e9996c0..1b4bc16 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,26 +21,21 @@
 import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
 import com.google.inject.persist.PersistModule;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
 import com.google.inject.persist.finder.DynamicFinder;
 import com.google.inject.persist.finder.Finder;
-import com.google.inject.util.Providers;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.List;
 import java.util.Map;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
 
 /**
  * JPA provider for guice persist.
@@ -51,15 +46,16 @@
   private final String jpaUnit;
 
   public JpaPersistModule(String jpaUnit) {
-    Preconditions.checkArgument(null != jpaUnit && jpaUnit.length() > 0,
-        "JPA unit name must be a non-empty string.");
+    Preconditions.checkArgument(
+        null != jpaUnit && jpaUnit.length() > 0, "JPA unit name must be a non-empty string.");
     this.jpaUnit = jpaUnit;
   }
 
-  private Map<?,?> properties;
+  private Map<?, ?> properties;
   private MethodInterceptor transactionInterceptor;
 
-  @Override protected void configurePersistence() {
+  @Override
+  protected void configurePersistence() {
     bindConstant().annotatedWith(Jpa.class).to(jpaUnit);
 
     bind(JpaPersistService.class).in(Singleton.class);
@@ -79,22 +75,25 @@
     }
   }
 
-  @Override protected MethodInterceptor getTransactionInterceptor() {
+  @Override
+  protected MethodInterceptor getTransactionInterceptor() {
     return transactionInterceptor;
   }
 
-  @Provides @Jpa Map<?, ?> provideProperties() {
+  @Provides
+  @Jpa
+  Map<?, ?> provideProperties() {
     return properties;
   }
 
   /**
    * Configures the JPA persistence provider with a set of properties.
-   * 
-   * @param properties A set of name value pairs that configure a JPA persistence
-   *     provider as per the specification.
+   *
+   * @param properties A set of name value pairs that configure a JPA persistence provider as per
+   *     the specification.
    * @since 4.0 (since 3.0 with a parameter type of {@code java.util.Properties})
    */
-  public JpaPersistModule properties(Map<?,?> properties) {
+  public JpaPersistModule properties(Map<?, ?> properties) {
     this.properties = properties;
     return this;
   }
@@ -116,48 +115,60 @@
       return;
     }
 
-    InvocationHandler finderInvoker = new InvocationHandler() {
-      @Inject JpaFinderProxy finderProxy;
+    InvocationHandler finderInvoker =
+        new InvocationHandler() {
+          @Inject JpaFinderProxy finderProxy;
 
-      public Object invoke(final Object thisObject, final Method method, final Object[] args)
-          throws Throwable {
+          @Override
+          public Object invoke(final Object thisObject, final Method method, final Object[] args)
+              throws Throwable {
 
-        // Don't intercept non-finder methods like equals and hashcode.
-        if (!method.isAnnotationPresent(Finder.class)) {
-          // NOTE(dhanji): This is not ideal, we are using the invocation handler's equals
-          // and hashcode as a proxy (!) for the proxy's equals and hashcode. 
-          return method.invoke(this, args);
-        }
+            // Don't intercept non-finder methods like equals and hashcode.
+            if (!method.isAnnotationPresent(Finder.class)) {
+              // NOTE(dhanji): This is not ideal, we are using the invocation handler's equals
+              // and hashcode as a proxy (!) for the proxy's equals and hashcode.
+              return method.invoke(this, args);
+            }
 
-        return finderProxy.invoke(new MethodInvocation() {
-          public Method getMethod() {
-            return method;
+            return finderProxy.invoke(
+                new MethodInvocation() {
+                  @Override
+                  public Method getMethod() {
+                    return method;
+                  }
+
+                  @Override
+                  public Object[] getArguments() {
+                    return null == args ? new Object[0] : args;
+                  }
+
+                  @Override
+                  public Object proceed() throws Throwable {
+                    return method.invoke(thisObject, args);
+                  }
+
+                  @Override
+                  public Object getThis() {
+                    throw new UnsupportedOperationException(
+                        "Bottomless proxies don't expose a this.");
+                  }
+
+                  @Override
+                  public AccessibleObject getStaticPart() {
+                    throw new UnsupportedOperationException();
+                  }
+                });
           }
-
-          public Object[] getArguments() {
-            return null == args ? new Object[0] : args; 
-          }
-
-          public Object proceed() throws Throwable {
-            return method.invoke(thisObject, args);
-          }
-
-          public Object getThis() {
-            throw new UnsupportedOperationException("Bottomless proxies don't expose a this.");
-          }
-
-          public AccessibleObject getStaticPart() {
-            throw new UnsupportedOperationException();
-          }
-        });
-      }
-    };
+        };
     requestInjection(finderInvoker);
 
     @SuppressWarnings("unchecked") // Proxy must produce instance of type given.
-    T proxy = (T) Proxy
-        .newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { iface },
-            finderInvoker);
+    T proxy =
+        (T)
+            Proxy.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(),
+                new Class<?>[] {iface},
+                finderInvoker);
 
     bind(iface).toInstance(proxy);
   }
@@ -172,8 +183,12 @@
     for (Method method : iface.getMethods()) {
       DynamicFinder finder = DynamicFinder.from(method);
       if (null == finder) {
-        addError("Dynamic Finder methods must be annotated with @Finder, but " + iface
-            + "." + method.getName() + " was not");
+        addError(
+            "Dynamic Finder methods must be annotated with @Finder, but "
+                + iface
+                + "."
+                + method.getName()
+                + " was not");
         valid = false;
       }
     }
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
index 190506c..5396f95 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,44 +23,43 @@
 import com.google.inject.Singleton;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
-
 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;
 import java.util.Map;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Persistence;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 @Singleton
 class JpaPersistService implements Provider<EntityManager>, UnitOfWork, PersistService {
-  private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();
+  private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<>();
 
   private final String persistenceUnitName;
-  private final Map<?,?> persistenceProperties;
+  private final Map<?, ?> persistenceProperties;
 
   @Inject
-  public JpaPersistService(@Jpa String persistenceUnitName,
-      @Nullable @Jpa Map<?,?> persistenceProperties) {
+  public JpaPersistService(
+      @Jpa String persistenceUnitName, @Nullable @Jpa Map<?, ?> persistenceProperties) {
     this.persistenceUnitName = persistenceUnitName;
     this.persistenceProperties = persistenceProperties;
   }
 
+  @Override
   public EntityManager get() {
     if (!isWorking()) {
       begin();
     }
 
     EntityManager em = entityManager.get();
-    Preconditions.checkState(null != em, "Requested EntityManager outside work unit. "
-        + "Try calling UnitOfWork.begin() first, or use a PersistFilter if you "
-        + "are inside a servlet environment.");
+    Preconditions.checkState(
+        null != em,
+        "Requested EntityManager outside work unit. "
+            + "Try calling UnitOfWork.begin() first, or use a PersistFilter if you "
+            + "are inside a servlet environment.");
 
     return em;
   }
@@ -69,14 +68,17 @@
     return entityManager.get() != null;
   }
 
+  @Override
   public void begin() {
-    Preconditions.checkState(null == entityManager.get(),
+    Preconditions.checkState(
+        null == entityManager.get(),
         "Work already begun on this thread. Looks like you have called UnitOfWork.begin() twice"
-         + " without a balancing call to end() in between.");
+            + " without a balancing call to end() in between.");
 
     entityManager.set(emFactory.createEntityManager());
   }
 
+  @Override
   public void end() {
     EntityManager em = entityManager.get();
 
@@ -87,8 +89,7 @@
 
     try {
       em.close();
-    }
-    finally {
+    } finally {
       entityManager.remove();
     }
   }
@@ -100,17 +101,19 @@
     this.emFactory = emFactory;
   }
 
+  @Override
   public synchronized void start() {
     Preconditions.checkState(null == emFactory, "Persistence service was already initialized.");
 
     if (null != persistenceProperties) {
-      this.emFactory = Persistence
-          .createEntityManagerFactory(persistenceUnitName, persistenceProperties);
+      this.emFactory =
+          Persistence.createEntityManagerFactory(persistenceUnitName, persistenceProperties);
     } else {
       this.emFactory = Persistence.createEntityManagerFactory(persistenceUnitName);
     }
   }
 
+  @Override
   public synchronized void stop() {
     Preconditions.checkState(emFactory.isOpen(), "Persistence service was already shut down.");
     emFactory.close();
@@ -125,15 +128,15 @@
       this.emProvider = emProvider;
     }
 
+    @Override
     public EntityManagerFactory get() {
       assert null != emProvider.emFactory;
       return emProvider.emFactory;
     }
   }
-  
+
   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.PARAMETER)
-  private @interface Nullable { }
-
+  private @interface Nullable {}
 }
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
index f9e46da..88ea26d 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * guice-persist's Java Persistence API (JPA) support.
- */
+/** guice-persist's Java Persistence API (JPA) support. */
 package com.google.inject.persist.jpa;
diff --git a/extensions/persist/test/com/google/inject/persist/AllTests.java b/extensions/persist/test/com/google/inject/persist/AllTests.java
index 8651fc6..d55cf37 100644
--- a/extensions/persist/test/com/google/inject/persist/AllTests.java
+++ b/extensions/persist/test/com/google/inject/persist/AllTests.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,13 +27,10 @@
 import com.google.inject.persist.jpa.ManagedLocalTransactionsTest;
 import com.google.inject.persist.jpa.ManualLocalTransactionsTest;
 import com.google.inject.persist.jpa.ManualLocalTransactionsWithCustomMatcherTest;
-
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
-/**
- * @author dhanji@gmail.com (Dhanji R. Prasanna)
- */
+/** @author dhanji@gmail.com (Dhanji R. Prasanna) */
 public class AllTests {
 
   public static Test suite() {
@@ -54,4 +51,4 @@
 
     return suite;
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/persist/test/com/google/inject/persist/EdslTest.java b/extensions/persist/test/com/google/inject/persist/EdslTest.java
index 81e0b6b..55e1ef3 100644
--- a/extensions/persist/test/com/google/inject/persist/EdslTest.java
+++ b/extensions/persist/test/com/google/inject/persist/EdslTest.java
@@ -7,20 +7,20 @@
 import java.util.logging.Logger;
 import junit.framework.TestCase;
 
-/**
- * @author dhanji@google.com (Dhanji R. Prasanna)
- */
+/** @author dhanji@google.com (Dhanji R. Prasanna) */
 public class EdslTest extends TestCase {
 
   public void testModuleConfigUsingJpa() throws Exception {
     Logger.getLogger(getClass().getName()).info("Starting EDSL test.");
-    Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new JpaPersistModule("myunit"));
-        binder().requireExplicitBindings();
-      }
-    });
+    Guice.createInjector(
+        Stage.PRODUCTION,
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            install(new JpaPersistModule("myunit"));
+            binder().requireExplicitBindings();
+          }
+        });
     Logger.getLogger(getClass().getName()).info("Completed EDSL test.");
   }
 }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
index 36fcb31..103d0bb 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,21 +21,18 @@
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
-
-import junit.framework.TestCase;
-
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
-
 import javax.persistence.EntityManager;
+import junit.framework.TestCase;
 
 /**
  * This test asserts class level @Transactional annotation behavior.
  *
- * Class-level @Transactional is a shortcut if all non-private methods in the class are meant to be
- * transactional.
+ * <p>Class-level @Transactional is a shortcut if all non-private methods in the class are meant to
+ * be transactional.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
@@ -44,9 +41,10 @@
   private Injector injector;
   private static final String UNIQUE_TEXT = "JPAsome unique text88888" + new Date();
   private static final String UNIQUE_TEXT_2 = "JPAsome asda unique teasdalsdplasdxt" + new Date();
-  private static final String TRANSIENT_UNIQUE_TEXT = "JPAsome other unique texaksoksojadasdt"
-      + new Date();
+  private static final String TRANSIENT_UNIQUE_TEXT =
+      "JPAsome other unique texaksoksojadasdt" + new Date();
 
+  @Override
   public void setUp() {
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
 
@@ -54,6 +52,7 @@
     injector.getInstance(PersistService.class).start();
   }
 
+  @Override
   public void tearDown() {
     injector.getInstance(PersistService.class).stop();
     injector = null;
@@ -63,20 +62,26 @@
     injector.getInstance(TransactionalObject.class).runOperationInTxn();
 
     EntityManager session = injector.getInstance(EntityManager.class);
-    assertFalse("EntityManager was not closed by transactional service",
+    assertFalse(
+        "EntityManager was not closed by transactional service",
         session.getTransaction().isActive());
 
     //test that the data has been stored
     session.getTransaction().begin();
-    Object result = session.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult();
+    Object result =
+        session
+            .createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult();
 
     session.getTransaction().commit();
 
     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT, (((JpaTestEntity) result).getText()));
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT,
+        (((JpaTestEntity) result).getText()));
   }
 
   public void testSimpleTransactionRollbackOnChecked() {
@@ -87,13 +92,17 @@
     }
 
     EntityManager session = injector.getInstance(EntityManager.class);
-    assertFalse("EntityManager was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "EntityManager was not closed by transactional service (rollback didnt happen?)",
         session.getTransaction().isActive());
 
     //test that the data has been stored
     session.getTransaction().begin();
-    List<?> result = session.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", TRANSIENT_UNIQUE_TEXT).getResultList();
+    List<?> result =
+        session
+            .createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+            .getResultList();
 
     session.getTransaction().commit();
 
@@ -110,18 +119,21 @@
     }
 
     EntityManager session = injector.getInstance(EntityManager.class);
-    assertFalse("Txn was not closed by transactional service (commit didnt happen?)",
+    assertFalse(
+        "Txn was not closed by transactional service (commit didnt happen?)",
         session.getTransaction().isActive());
 
     //test that the data has been stored
     session.getTransaction().begin();
-    Object result = session.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT_2).getSingleResult();
+    Object result =
+        session
+            .createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT_2)
+            .getSingleResult();
 
     session.getTransaction().commit();
 
-    assertNotNull("a result was not returned! rollback happened anyway (ignore failed)!!!",
-        result);
+    assertNotNull("a result was not returned! rollback happened anyway (ignore failed)!!!", result);
   }
 
   public void testSimpleTransactionRollbackOnUnchecked() {
@@ -132,18 +144,21 @@
     }
 
     EntityManager session = injector.getInstance(EntityManager.class);
-    assertFalse("EntityManager was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "EntityManager was not closed by transactional service (rollback didnt happen?)",
         session.getTransaction().isActive());
 
     //test that the data has been stored
     session.getTransaction().begin();
-    List<?> result = session.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", TRANSIENT_UNIQUE_TEXT).getResultList();
+    List<?> result =
+        session
+            .createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+            .getResultList();
 
     session.getTransaction().commit();
 
-    assertTrue("a result was returned! rollback sure didnt happen!!!",
-        result.isEmpty());
+    assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty());
   }
 
   @Transactional
@@ -156,7 +171,6 @@
       entity.setText(UNIQUE_TEXT);
       session.persist(entity);
     }
-
   }
 
   @Transactional
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
index 288b277..7f1cd71 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,17 +20,12 @@
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import java.util.Properties;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class CustomPropsEntityManagerFactoryProvisionTest extends TestCase {
   private Injector injector;
@@ -51,7 +46,8 @@
 
   public void testSessionCreateOnInjection() {
 
-    assertEquals("SINGLETON VIOLATION " + UnitOfWork.class.getName(),
+    assertEquals(
+        "SINGLETON VIOLATION " + UnitOfWork.class.getName(),
         injector.getInstance(UnitOfWork.class),
         injector.getInstance(UnitOfWork.class));
 
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/DynamicFinderTest.java b/extensions/persist/test/com/google/inject/persist/jpa/DynamicFinderTest.java
index 825d244..f6fe254 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/DynamicFinderTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/DynamicFinderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,15 +23,12 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.finder.Finder;
-
-import junit.framework.TestCase;
-
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
-
 import javax.persistence.EntityManager;
+import junit.framework.TestCase;
 
 /**
  * A test around providing sessions (starting, closing etc.)
@@ -42,6 +39,7 @@
 public class DynamicFinderTest extends TestCase {
   private Injector injector;
 
+  @Override
   public void setUp() {
     injector = Guice.createInjector(new JpaPersistModule("testUnit").addFinder(JpaFinder.class));
 
@@ -49,6 +47,7 @@
     injector.getInstance(PersistService.class).start();
   }
 
+  @Override
   public final void tearDown() {
     injector.getInstance(PersistService.class).stop();
   }
@@ -64,7 +63,8 @@
     dao.persist(te);
 
     //im not sure this hack works...
-    assertFalse("Duplicate entity managers crossing-scope",
+    assertFalse(
+        "Duplicate entity managers crossing-scope",
         dao.lastEm.equals(injector.getInstance(EntityManager.class)));
 
     List<JpaTestEntity> list = injector.getInstance(JpaFinder.class).listAll();
@@ -85,7 +85,7 @@
 
     @Inject
     public JpaDao(Provider<EntityManager> em) {
-     this.em = em;
+      this.em = em;
     }
 
     @Transactional
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EnsureJpaCanTakeObjectsInPropertiesTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EnsureJpaCanTakeObjectsInPropertiesTest.java
index 6dcd6bd..6fe127c 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EnsureJpaCanTakeObjectsInPropertiesTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EnsureJpaCanTakeObjectsInPropertiesTest.java
@@ -49,7 +49,7 @@
 
     @Override
     protected void configure() {
-      Map<String, Object> p = new HashMap<String, Object>();
+      Map<String, Object> p = new HashMap<>();
 
       p.put(Environment.CONNECTION_PROVIDER, InjectedDataSourceConnectionProvider.class.getName());
       if (passDataSource) {
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
index 1a61e41..73bc7c9 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,23 +20,21 @@
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class EntityManagerFactoryProvisionTest extends TestCase {
   private Injector injector;
 
+  @Override
   public void setUp() {
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
   }
 
+  @Override
   public final void tearDown() {
     injector.getInstance(UnitOfWork.class).end();
     injector.getInstance(EntityManagerFactory.class).close();
@@ -44,8 +42,10 @@
 
   public void testSessionCreateOnInjection() {
 
-    assertEquals("SINGLETON VIOLATION " + UnitOfWork.class.getName(),
-        injector.getInstance(UnitOfWork.class), injector.getInstance(UnitOfWork.class));
+    assertEquals(
+        "SINGLETON VIOLATION " + UnitOfWork.class.getName(),
+        injector.getInstance(UnitOfWork.class),
+        injector.getInstance(UnitOfWork.class));
 
     //startup persistence
     injector.getInstance(PersistService.class).start();
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
index 733884f..8d6582d 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,11 +22,9 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
 /**
  * A test around providing sessions (starting, closing etc.)
@@ -63,14 +61,18 @@
     dao.persist(te);
 
     //im not sure this hack works...
-    assertEquals("Entity managers closed inside same thread-scope",
-        injector.getInstance(EntityManager.class), JpaDao.em);
+    assertEquals(
+        "Entity managers closed inside same thread-scope",
+        injector.getInstance(EntityManager.class),
+        JpaDao.em);
 
     //try to start a new em in a new txn
     dao = injector.getInstance(JpaDao.class);
 
-    assertTrue("EntityManager was closed and reopened around txn"
-        + " (persistent object does not persist)", dao.contains(te));
+    assertTrue(
+        "EntityManager was closed and reopened around txn"
+            + " (persistent object does not persist)",
+        dao.contains(te));
   }
 
   public void testEntityManagerLifecyclePerTxn2() {
@@ -83,16 +85,21 @@
     dao.persist(te);
 
     //im not sure this hack works...
-    assertEquals("Duplicate entity managers crossing-scope",
-        injector.getInstance(EntityManager.class), JpaDao.em);
-    assertEquals("Duplicate entity managers crossing-scope",
-        injector.getInstance(EntityManager.class), JpaDao.em);
+    assertEquals(
+        "Duplicate entity managers crossing-scope",
+        injector.getInstance(EntityManager.class),
+        JpaDao.em);
+    assertEquals(
+        "Duplicate entity managers crossing-scope",
+        injector.getInstance(EntityManager.class),
+        JpaDao.em);
 
     //try to start a new em in a new txn
     dao = injector.getInstance(JpaDao.class);
 
-    assertTrue("EntityManager was closed and reopened around txn"
-        + " (persistent object doesnt persist)", dao.contains(te));
+    assertTrue(
+        "EntityManager was closed and reopened around txn" + " (persistent object doesnt persist)",
+        dao.contains(te));
   }
 
   public static class JpaDao {
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
index fbde101..b432d4b 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,11 +22,9 @@
 import com.google.inject.Provider;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
-
-import junit.framework.TestCase;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
 /**
  * A test around providing sessions (starting, closing etc.)
@@ -37,6 +35,7 @@
 public class EntityManagerProvisionTest extends TestCase {
   private Injector injector;
 
+  @Override
   public void setUp() {
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
 
@@ -44,6 +43,7 @@
     injector.getInstance(PersistService.class).start();
   }
 
+  @Override
   public final void tearDown() {
     injector.getInstance(EntityManagerFactory.class).close();
   }
@@ -58,14 +58,17 @@
     dao.persist(te);
 
     //im not sure this hack works...
-    assertFalse("Duplicate entity managers crossing-scope",
+    assertFalse(
+        "Duplicate entity managers crossing-scope",
         dao.lastEm.equals(injector.getInstance(EntityManager.class)));
 
     //try to start a new em in a new txn
     dao = injector.getInstance(JpaDao.class);
 
-    assertFalse("EntityManager wasnt closed and reopened properly around txn"
-        + " (persistent object persists)", dao.contains(te));
+    assertFalse(
+        "EntityManager wasnt closed and reopened properly around txn"
+            + " (persistent object persists)",
+        dao.contains(te));
   }
 
   public void testEntityManagerLifecyclePerTxn2() {
@@ -78,14 +81,17 @@
     dao.persist(te);
 
     //im not sure this hack works...
-    assertFalse("Duplicate entity managers crossing-scope",
+    assertFalse(
+        "Duplicate entity managers crossing-scope",
         dao.lastEm.equals(injector.getInstance(EntityManager.class)));
 
     //try to start a new em in a new txn
     dao = injector.getInstance(JpaDao.class);
 
-    assertFalse("EntityManager wasnt closed and reopened properly around txn"
-        + " (persistent object persists)", dao.contains(te));
+    assertFalse(
+        "EntityManager wasnt closed and reopened properly around txn"
+            + " (persistent object persists)",
+        dao.contains(te));
   }
 
   public static class JpaDao {
@@ -94,7 +100,7 @@
 
     @Inject
     public JpaDao(Provider<EntityManager> em) {
-     this.em = em;
+      this.em = em;
     }
 
     @Transactional
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
index a1e4e80..ecd48ba 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,26 +22,21 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.NoResultException;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class JoiningLocalTransactionsTest extends TestCase {
   private Injector injector;
-  private static final String UNIQUE_TEXT = JoiningLocalTransactionsTest.class + "some unique text"
-      + new Date();
-  private static final String TRANSIENT_UNIQUE_TEXT = JoiningLocalTransactionsTest.class
-      + "some other unique text" + new Date();
+  private static final String UNIQUE_TEXT =
+      JoiningLocalTransactionsTest.class + "some unique text" + new Date();
+  private static final String TRANSIENT_UNIQUE_TEXT =
+      JoiningLocalTransactionsTest.class + "some other unique text" + new Date();
 
   @Override
   public void setUp() {
@@ -59,27 +54,32 @@
   }
 
   public void testSimpleTransaction() {
-    injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
+    injector
+        .getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
         .runOperationInTxn();
 
     EntityManager em = injector.getInstance(EntityManager.class);
-    assertFalse("txn was not closed by transactional service",
-        em.getTransaction().isActive());
+    assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
 
     //test that the data has been stored
-    Object result = em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult();
+    Object result =
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult();
     injector.getInstance(UnitOfWork.class).end();
 
     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?", UNIQUE_TEXT,
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT,
         ((JpaTestEntity) result).getText());
   }
 
   public void testSimpleTransactionRollbackOnChecked() {
     try {
-      injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
+      injector
+          .getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
           .runOperationInTxnThrowingChecked();
     } catch (IOException e) {
       //ignore
@@ -88,21 +88,26 @@
 
     EntityManager em = injector.getInstance(EntityManager.class);
 
-    assertFalse("EM was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "EM was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     //test that the data has been stored
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail("a result was returned! rollback sure didnt happen!!!");
-    } catch (NoResultException e) { }
+    } catch (NoResultException e) {
+    }
   }
 
   public void testSimpleTransactionRollbackOnUnchecked() {
     try {
-      injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
+      injector
+          .getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
           .runOperationInTxnThrowingUnchecked();
     } catch (RuntimeException re) {
       //ignore
@@ -110,15 +115,19 @@
     }
 
     EntityManager em = injector.getInstance(EntityManager.class);
-    assertFalse("Session was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "Session was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail("a result was returned! rollback sure didnt happen!!!");
-    } catch (NoResultException e) {}
+    } catch (NoResultException e) {
+    }
   }
 
   public static class TransactionalObject {
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JpaParentTestEntity.java b/extensions/persist/test/com/google/inject/persist/jpa/JpaParentTestEntity.java
index 600e088..c100883 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JpaParentTestEntity.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JpaParentTestEntity.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,40 +18,38 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.OneToMany;
 
 /**
- * Created with IntelliJ IDEA.
- * On: 2/06/2007
+ * Created with IntelliJ IDEA. On: 2/06/2007
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  * @since 1.0
  */
 @Entity
 public class JpaParentTestEntity {
-    private Long id;
-    private List<JpaTestEntity> children = new ArrayList<JpaTestEntity>();
+  private Long id;
+  private List<JpaTestEntity> children = new ArrayList<>();
 
-    @Id
-    @GeneratedValue
-    public Long getId() {
-        return id;
-    }
+  @Id
+  @GeneratedValue
+  public Long getId() {
+    return id;
+  }
 
-    public void setId(Long id) {
-        this.id = id;
-    }
+  public void setId(Long id) {
+    this.id = id;
+  }
 
-    @OneToMany
-    public List<JpaTestEntity> getChildren() {
-        return children;
-    }
+  @OneToMany
+  public List<JpaTestEntity> getChildren() {
+    return children;
+  }
 
-    public void setChildren(List<JpaTestEntity> children) {
-        this.children = children;
-    }
+  public void setChildren(List<JpaTestEntity> children) {
+    this.children = children;
+  }
 }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JpaPersistServiceTest.java b/extensions/persist/test/com/google/inject/persist/jpa/JpaPersistServiceTest.java
index e099a5e..67b9288 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JpaPersistServiceTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JpaPersistServiceTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,6 @@
 
 package com.google.inject.persist.jpa;
 
-import junit.framework.TestCase;
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.doThrow;
@@ -24,24 +23,26 @@
 import static org.mockito.Mockito.when;
 
 import java.util.Properties;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.spi.PersistenceProvider;
+import junit.framework.TestCase;
 
 public class JpaPersistServiceTest extends TestCase {
 
   private static final String PERSISTENCE_UNIT_NAME = "test_persistence_unit_name";
   private static final Properties PERSISTENCE_PROPERTIES = new Properties();
 
-  private final JpaPersistService sut = new JpaPersistService(PERSISTENCE_UNIT_NAME, PERSISTENCE_PROPERTIES);
+  private final JpaPersistService sut =
+      new JpaPersistService(PERSISTENCE_UNIT_NAME, PERSISTENCE_PROPERTIES);
   private final PersistenceProvider provider = mock(PersistenceProvider.class);
   private final EntityManagerFactory factory = mock(EntityManagerFactory.class);
   private final EntityManager entityManager = mock(EntityManager.class);
 
   @Override
   public void setUp() throws Exception {
-    when(provider.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, PERSISTENCE_PROPERTIES)).thenReturn(factory);
+    when(provider.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, PERSISTENCE_PROPERTIES))
+        .thenReturn(factory);
     when(factory.createEntityManager()).thenReturn(entityManager);
   }
 
@@ -54,12 +55,10 @@
     try {
       sut.end();
       fail("Exception expected");
-    }
-    catch (SimulatedException expected) {
+    } catch (SimulatedException expected) {
       assertThat(sut.isWorking(), is(false));
     }
   }
 
-  private class SimulatedException extends RuntimeException {
-  }
+  private static class SimulatedException extends RuntimeException {}
 }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JpaTestEntity.java b/extensions/persist/test/com/google/inject/persist/jpa/JpaTestEntity.java
index 8fa6fd1..4d8993a 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JpaTestEntity.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JpaTestEntity.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,7 +26,8 @@
   private Long id;
   private String text;
 
-  @Id @GeneratedValue
+  @Id
+  @GeneratedValue
   public Long getId() {
     return id;
   }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java b/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
index 84dff07..c9b6fe9 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,24 +22,21 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-import org.hibernate.HibernateException;
-
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Query;
+import junit.framework.TestCase;
+import org.hibernate.HibernateException;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class JpaWorkManagerTest extends TestCase {
   private Injector injector;
-  private static final String UNIQUE_TEXT_3 = JpaWorkManagerTest.class.getSimpleName()
-      + "CONSTRAINT_VIOLATING some other unique text" + new Date();
+  private static final String UNIQUE_TEXT_3 =
+      JpaWorkManagerTest.class.getSimpleName()
+          + "CONSTRAINT_VIOLATING some other unique text"
+          + new Date();
 
   @Override
   public void setUp() {
@@ -53,8 +50,8 @@
   public void tearDown() {
     try {
       injector.getInstance(EntityManagerFactory.class).close();
-    } catch(HibernateException ex) {
-        // Expected if the persist service has already been stopped.
+    } catch (HibernateException ex) {
+      // Expected if the persist service has already been stopped.
     }
   }
 
@@ -64,14 +61,15 @@
       injector.getInstance(TransactionalObject.class).runOperationInTxn();
     } finally {
       injector.getInstance(UnitOfWork.class).end();
-
     }
 
     injector.getInstance(UnitOfWork.class).begin();
     injector.getInstance(EntityManager.class).getTransaction().begin();
     try {
-      final Query query = injector.getInstance(EntityManager.class)
-          .createQuery("select e from JpaTestEntity as e where text = :text");
+      final Query query =
+          injector
+              .getInstance(EntityManager.class)
+              .createQuery("select e from JpaTestEntity as e where text = :text");
 
       query.setParameter("text", UNIQUE_TEXT_3);
       final Object o = query.getSingleResult();
@@ -80,8 +78,10 @@
       assertTrue("Unknown type returned " + o.getClass(), o instanceof JpaTestEntity);
       JpaTestEntity ent = (JpaTestEntity) o;
 
-      assertEquals("Incorrect result returned or not persisted properly" + ent.getText(),
-          UNIQUE_TEXT_3, ent.getText());
+      assertEquals(
+          "Incorrect result returned or not persisted properly" + ent.getText(),
+          UNIQUE_TEXT_3,
+          ent.getText());
 
     } finally {
       injector.getInstance(EntityManager.class).getTransaction().commit();
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
index 76e3f7f..1c31fe4 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,26 +24,21 @@
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
 import com.google.inject.persist.finder.Finder;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.NoResultException;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class ManagedLocalTransactionsAcrossRequestTest extends TestCase {
   private Injector injector;
   private static final String UNIQUE_TEXT = "some unique text" + new Date();
   private static final String UNIQUE_TEXT_MERGE = "meRG_Esome unique text" + new Date();
-  private static final String UNIQUE_TEXT_MERGE_FORDF = "aSdoaksdoaksdmeRG_Esome unique text"
-      + new Date();
+  private static final String UNIQUE_TEXT_MERGE_FORDF =
+      "aSdoaksdoaksdmeRG_Esome unique text" + new Date();
   private static final String TRANSIENT_UNIQUE_TEXT = "some other unique text" + new Date();
 
   @Override
@@ -66,22 +61,25 @@
     assertFalse(em.getTransaction().isActive());
 
     //test that the data has been stored
-    Object result = em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult();
+    Object result =
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult();
     injector.getInstance(UnitOfWork.class).end();
 
     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT, ((JpaTestEntity) result).getText());
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT,
+        ((JpaTestEntity) result).getText());
     injector.getInstance(UnitOfWork.class).end();
-
   }
 
   public void testSimpleTransactionWithMerge() {
     EntityManager emOrig = injector.getInstance(EntityManager.class);
-    JpaTestEntity entity = injector.getInstance(TransactionalObject.class)
-        .runOperationInTxnWithMerge();
+    JpaTestEntity entity =
+        injector.getInstance(TransactionalObject.class).runOperationInTxnWithMerge();
 
     assertNotNull("Entity was not given an id (was not persisted correctly?)", entity.getId());
 
@@ -93,22 +91,25 @@
     assertEquals("Em was not kept open across txns", emOrig, em);
     assertTrue("Merge did not store state or did not return persistent copy", em.contains(entity));
 
-    Object result = em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult();
+    Object result =
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT_MERGE)
+            .getSingleResult();
     injector.getInstance(UnitOfWork.class).end();
 
     assertTrue(result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT_MERGE, ((JpaTestEntity) result).getText());
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT_MERGE,
+        ((JpaTestEntity) result).getText());
     injector.getInstance(UnitOfWork.class).end();
-
   }
 
   public void disabled_testSimpleTransactionWithMergeAndDF() {
     EntityManager emOrig = injector.getInstance(EntityManager.class);
-    JpaTestEntity entity = injector.getInstance(TransactionalObject.class)
-        .runOperationInTxnWithMergeForDf();
+    JpaTestEntity entity =
+        injector.getInstance(TransactionalObject.class).runOperationInTxnWithMergeForDf();
 
     EntityManager em = injector.getInstance(EntityManager.class);
     assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
@@ -124,10 +125,11 @@
     assertNotNull(result);
     assertTrue(result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT_MERGE_FORDF, ((JpaTestEntity) result).getText());
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT_MERGE_FORDF,
+        ((JpaTestEntity) result).getText());
     injector.getInstance(UnitOfWork.class).end();
-
   }
 
   public void testSimpleTransactionRollbackOnChecked() {
@@ -140,16 +142,20 @@
 
     EntityManager em = injector.getInstance(EntityManager.class);
 
-    assertFalse("Previous EM was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "Previous EM was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     //test that the data has been stored
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail();
-    } catch (NoResultException e) {}
+    } catch (NoResultException e) {
+    }
 
     injector.getInstance(UnitOfWork.class).end();
   }
@@ -163,15 +169,19 @@
     }
 
     EntityManager em = injector.getInstance(EntityManager.class);
-    assertFalse("Session was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "Session was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail();
-    } catch (NoResultException e) {}
+    } catch (NoResultException e) {
+    }
 
     injector.getInstance(UnitOfWork.class).end();
   }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
index 2ba9195..167d6a4 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,19 +22,14 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.NoResultException;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class ManagedLocalTransactionsTest extends TestCase {
   private Injector injector;
@@ -63,19 +58,23 @@
     assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
 
     //test that the data has been stored
-    Object result = em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult();
+    Object result =
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult();
     injector.getInstance(UnitOfWork.class).end();
 
     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT, ((JpaTestEntity) result).getText());
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT,
+        ((JpaTestEntity) result).getText());
   }
 
   public void testSimpleTransactionWithMerge() {
-    JpaTestEntity entity = injector.getInstance(TransactionalObject.class)
-        .runOperationInTxnWithMerge();
+    JpaTestEntity entity =
+        injector.getInstance(TransactionalObject.class).runOperationInTxnWithMerge();
 
     EntityManager em = injector.getInstance(EntityManager.class);
     assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
@@ -83,14 +82,18 @@
     //test that the data has been stored
     assertTrue("Em was closed after txn!", em.isOpen());
 
-    Object result = em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult();
+    Object result =
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT_MERGE)
+            .getSingleResult();
     injector.getInstance(UnitOfWork.class).end();
 
     assertTrue(result instanceof JpaTestEntity);
 
-    assertEquals("queried entity did not match--did automatic txn fail?",
-        UNIQUE_TEXT_MERGE, ((JpaTestEntity) result).getText());
+    assertEquals(
+        "queried entity did not match--did automatic txn fail?",
+        UNIQUE_TEXT_MERGE,
+        ((JpaTestEntity) result).getText());
   }
 
   public void testSimpleTransactionRollbackOnChecked() {
@@ -103,16 +106,20 @@
 
     EntityManager em = injector.getInstance(EntityManager.class);
 
-    assertFalse("Previous EM was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "Previous EM was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     //test that the data has been stored
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail("a result was returned! rollback sure didnt happen!!!");
-    } catch (NoResultException e) {}
+    } catch (NoResultException e) {
+    }
   }
 
   public void testSimpleTransactionRollbackOnUnchecked() {
@@ -124,15 +131,19 @@
     }
 
     EntityManager em = injector.getInstance(EntityManager.class);
-    assertFalse("Session was not closed by transactional service (rollback didnt happen?)",
+    assertFalse(
+        "Session was not closed by transactional service (rollback didnt happen?)",
         em.getTransaction().isActive());
 
     try {
-      Object result = em.createQuery("from JpaTestEntity where text = :text")
-          .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
+      Object result =
+          em.createQuery("from JpaTestEntity where text = :text")
+              .setParameter("text", TRANSIENT_UNIQUE_TEXT)
+              .getSingleResult();
       injector.getInstance(UnitOfWork.class).end();
       fail("a result was returned! rollback sure didnt happen!!!");
-    } catch (NoResultException e) {}
+    } catch (NoResultException e) {
+    }
   }
 
   public static class TransactionalObject {
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
index ecd2999..cad8734 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,23 +21,19 @@
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
-
-import junit.framework.TestCase;
-
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceException;
+import junit.framework.TestCase;
 
-/**
- * @author Dhanji R. Prasanna (dhanji@gmail.com)
- */
+/** @author Dhanji R. Prasanna (dhanji@gmail.com) */
 
 public class ManualLocalTransactionsConfidenceTest extends TestCase {
   private Injector injector;
   private static final String UNIQUE_TEXT_3 =
       ManualLocalTransactionsConfidenceTest.class.getSimpleName()
-          + "CONSTRAINT_VIOLATING some other unique text" + new Date();
+          + "CONSTRAINT_VIOLATING some other unique text"
+          + new Date();
 
   @Override
   public void setUp() {
@@ -69,7 +65,8 @@
     }
 
     assertNotNull("No exception was thrown!", e);
-    assertTrue("Exception thrown was not what was expected (i.e. commit-time)",
+    assertTrue(
+        "Exception thrown was not what was expected (i.e. commit-time)",
         e instanceof PersistenceException);
   }
 
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
index 2baa345..2d04be7 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,13 +22,10 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
 /**
  * For instance, a session-per-request strategy will control the opening and closing of the EM at
@@ -42,6 +39,7 @@
   private static final String UNIQUE_TEXT = "some unique text" + new Date();
   private static final String UNIQUE_TEXT_2 = "some other unique text" + new Date();
 
+  @Override
   public void setUp() {
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
 
@@ -49,6 +47,7 @@
     injector.getInstance(PersistService.class).start();
   }
 
+  @Override
   public void tearDown() {
     injector.getInstance(EntityManagerFactory.class).close();
   }
@@ -63,7 +62,8 @@
     injector.getInstance(TransactionalObject.class).runOperationInTxn2();
 
     //persisted entity should remain in the same em (which should still be open)
-    assertTrue("EntityManager  appears to have been closed across txns!",
+    assertTrue(
+        "EntityManager  appears to have been closed across txns!",
         injector.getInstance(EntityManager.class).contains(entity));
     assertTrue("EntityManager  appears to have been closed across txns!", em.contains(entity));
     assertTrue("EntityManager appears to have been closed across txns!", em.isOpen());
@@ -73,10 +73,14 @@
 
     //try to query them back out
     em = injector.getInstance(EntityManager.class);
-    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult());
-    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT_2).getSingleResult());
+    assertNotNull(
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult());
+    assertNotNull(
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT_2)
+            .getSingleResult());
     em.close();
 
     assertFalse(em.isOpen());
@@ -100,6 +104,5 @@
       entity.setText(UNIQUE_TEXT_2);
       em.persist(entity);
     }
-
   }
 }
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
index 4290d1d..41991f5 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,18 +22,15 @@
 import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
 import com.google.inject.persist.UnitOfWork;
-
-import junit.framework.TestCase;
-
 import java.util.Date;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import junit.framework.TestCase;
 
 /**
  * Created with IntelliJ IDEA. On: 2/06/2007
  *
- * For instance, a session-per-request strategy will control the opening and closing of the EM at
+ * <p>For instance, a session-per-request strategy will control the opening and closing of the EM at
  * its own (manual) discretion. As opposed to a transactional unit of work.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
@@ -62,14 +59,17 @@
     //pretend that the request was started here
     EntityManager em = injector.getInstance(EntityManager.class);
 
-    JpaTestEntity entity = injector
+    JpaTestEntity entity =
+        injector
+            .getInstance(ManualLocalTransactionsWithCustomMatcherTest.TransactionalObject.class)
+            .runOperationInTxn();
+    injector
         .getInstance(ManualLocalTransactionsWithCustomMatcherTest.TransactionalObject.class)
-        .runOperationInTxn();
-    injector.getInstance(ManualLocalTransactionsWithCustomMatcherTest.TransactionalObject.class)
         .runOperationInTxn2();
 
     //persisted entity should remain in the same em (which should still be open)
-    assertTrue("EntityManager  appears to have been closed across txns!",
+    assertTrue(
+        "EntityManager  appears to have been closed across txns!",
         injector.getInstance(EntityManager.class).contains(entity));
     assertTrue("EntityManager  appears to have been closed across txns!", em.contains(entity));
     assertTrue("EntityManager appears to have been closed across txns!", em.isOpen());
@@ -78,10 +78,14 @@
 
     //try to query them back out
     em = injector.getInstance(EntityManager.class);
-    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT).getSingleResult());
-    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
-        .setParameter("text", UNIQUE_TEXT_2).getSingleResult());
+    assertNotNull(
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT)
+            .getSingleResult());
+    assertNotNull(
+        em.createQuery("from JpaTestEntity where text = :text")
+            .setParameter("text", UNIQUE_TEXT_2)
+            .getSingleResult());
     em.close();
   }
 
@@ -103,6 +107,5 @@
       entity.setText(UNIQUE_TEXT_2);
       em.persist(entity);
     }
-
   }
 }
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 283baa2..538b894 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject</groupId>
     <artifactId>guice-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <packaging>pom</packaging>
@@ -18,7 +18,6 @@
 
   <modules>
     <module>assistedinject</module>
-    <!-- TODO(cgruber): Comment out dagger-adapter module if guice releases before dagger 2.x -->
     <module>dagger-adapter</module>
     <module>grapher</module>
     <module>jmx</module>
diff --git a/extensions/service/pom.xml b/extensions/service/pom.xml
index 2d96e0d..b23beb0 100644
--- a/extensions/service/pom.xml
+++ b/extensions/service/pom.xml
@@ -13,4 +13,18 @@
 
   <name>Google Guice - Extensions - Service</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.service</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/service/src/com/google/inject/service/AsyncService.java b/extensions/service/src/com/google/inject/service/AsyncService.java
index fe0c3a5..34687b1 100644
--- a/extensions/service/src/com/google/inject/service/AsyncService.java
+++ b/extensions/service/src/com/google/inject/service/AsyncService.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,22 +17,23 @@
 package com.google.inject.service;
 
 import com.google.common.base.Preconditions;
-
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
 
 /**
- * An asynchronous implementation of {@link com.google.inject.service.Service}
- * that provides convenience callbacks to create your own services.
+ * An asynchronous implementation of {@link com.google.inject.service.Service} that provides
+ * convenience callbacks to create your own services.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public abstract class AsyncService implements Service {
-  private static final Runnable DO_NOTHING = new Runnable() {
-    @Override public void run() {}
-  };
+  private static final Runnable DO_NOTHING =
+      new Runnable() {
+        @Override
+        public void run() {}
+      };
 
   private final ExecutorService executor;
 
@@ -42,33 +43,35 @@
     this.executor = executor;
   }
 
-  public synchronized final Future<State> start() {
-    Preconditions.checkState(state != State.STOPPED,
-        "Cannot restart a service that has been stopped");
+  @Override
+  public final synchronized Future<State> start() {
+    Preconditions.checkState(
+        state != State.STOPPED, "Cannot restart a service that has been stopped");
 
     // Starts are idempotent.
     if (state == State.STARTED) {
       return new FutureTask<State>(DO_NOTHING, State.STARTED);
     }
 
-    return executor.submit(new Callable<State>() {
-      public State call() {
-        onStart();
-        return state = State.STARTED;
-      }
-    });
+    return executor.submit(
+        new Callable<State>() {
+          @Override
+          public State call() {
+            onStart();
+            return state = State.STARTED;
+          }
+        });
   }
 
   /**
-   * Called back when this service must do its start work. Typically occurs
-   * in a background thread. The result of this method is returned to the
-   * original caller of {@link Service#start()} and can thus be used to
-   * return a status message after start completes (or fails as the case
-   * may be).
+   * Called back when this service must do its start work. Typically occurs in a background thread.
+   * The result of this method is returned to the original caller of {@link Service#start()} and can
+   * thus be used to return a status message after start completes (or fails as the case may be).
    */
   protected abstract void onStart();
 
-  public synchronized final Future<State> stop() {
+  @Override
+  public final synchronized Future<State> stop() {
     Preconditions.checkState(state != null, "Must start this service before you stop it!");
 
     // Likewise, stops are idempotent.
@@ -76,23 +79,24 @@
       return new FutureTask<State>(DO_NOTHING, State.STOPPED);
     }
 
-    return executor.submit(new Callable<State>() {
-      public State call() {
-        onStop();
-        return state = State.STOPPED;
-      }
-    });
+    return executor.submit(
+        new Callable<State>() {
+          @Override
+          public State call() {
+            onStop();
+            return state = State.STOPPED;
+          }
+        });
   }
 
   /**
-   * Called back when this service must shutdown. Typically occurs
-   * in a background thread. The result of this method is returned to the
-   * original caller of {@link Service#stop()} and can thus be used to
-   * return a status message after stop completes (or fails as the case
-   * may be).
+   * Called back when this service must shutdown. Typically occurs in a background thread. The
+   * result of this method is returned to the original caller of {@link Service#stop()} and can thus
+   * be used to return a status message after stop completes (or fails as the case may be).
    */
   protected abstract void onStop();
 
+  @Override
   public final State state() {
     return state;
   }
diff --git a/extensions/service/src/com/google/inject/service/CompositeService.java b/extensions/service/src/com/google/inject/service/CompositeService.java
index 13e8b3d..1bcd54a 100644
--- a/extensions/service/src/com/google/inject/service/CompositeService.java
+++ b/extensions/service/src/com/google/inject/service/CompositeService.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Key;
-
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Callable;
@@ -41,12 +40,12 @@
   private final Set<Key<? extends Service>> services = Sets.newLinkedHashSet();
 
   /**
-   * Represents the state of this composite service. Will equal FAILED
-   * even if only one component service fails to start or stop. In other
-   * words, all component services must start successfully for this
-   * service to be considered started and similarly for stopped.
+   * Represents the state of this composite service. Will equal FAILED even if only one component
+   * service fails to start or stop. In other words, all component services must start successfully
+   * for this service to be considered started and similarly for stopped.
    */
   private volatile Service.State compositeState;
+
   private boolean composed;
 
   @Inject
@@ -59,7 +58,8 @@
   }
 
   public CompositeService add(Key<? extends Service> service) {
-    Preconditions.checkState(!composed,
+    Preconditions.checkState(
+        !composed,
         "Cannot reuse a CompositeService after it has been compose()d. Please create a new one.");
     // Verify that the binding exists. Throws an exception if not.
     injector.getBinding(service);
@@ -69,7 +69,8 @@
   }
 
   public Service compose() {
-    Preconditions.checkState(!composed,
+    Preconditions.checkState(
+        !composed,
         "Cannot reuse a CompositeService after it has been compose()d. Please create a new one.");
     composed = true;
 
@@ -77,6 +78,7 @@
     final List<Key<? extends Service>> services = ImmutableList.copyOf(this.services);
 
     return new Service() {
+      @Override
       public Future<State> start() {
         final List<Future<State>> tasks = Lists.newArrayList();
         for (Key<? extends Service> service : services) {
@@ -86,6 +88,7 @@
         return futureGet(tasks, State.STARTED);
       }
 
+      @Override
       public Future<State> stop() {
         final List<Future<State>> tasks = Lists.newArrayList();
         for (Key<? extends Service> service : services) {
@@ -95,29 +98,32 @@
         return futureGet(tasks, State.STOPPED);
       }
 
+      @Override
       public State state() {
         return compositeState;
       }
     };
   }
 
-  private FutureTask<Service.State> futureGet(final List<Future<Service.State>> tasks,
-      final Service.State state) {
-    return new FutureTask<Service.State>(new Callable<Service.State>() {
-      public Service.State call() {
-        boolean ok = true;
-        for (Future<Service.State> task : tasks) {
-          try {
-            ok = state == task.get();
-          } catch (InterruptedException e) {
-            return compositeState = Service.State.FAILED;
-          } catch (ExecutionException e) {
-            return compositeState = Service.State.FAILED;
-          }
-        }
+  private FutureTask<Service.State> futureGet(
+      final List<Future<Service.State>> tasks, final Service.State state) {
+    return new FutureTask<Service.State>(
+        new Callable<Service.State>() {
+          @Override
+          public Service.State call() {
+            boolean ok = true;
+            for (Future<Service.State> task : tasks) {
+              try {
+                ok = state == task.get();
+              } catch (InterruptedException e) {
+                return compositeState = Service.State.FAILED;
+              } catch (ExecutionException e) {
+                return compositeState = Service.State.FAILED;
+              }
+            }
 
-        return compositeState = ok ? state : Service.State.FAILED;
-      }
-    });
+            return compositeState = ok ? state : Service.State.FAILED;
+          }
+        });
   }
 }
diff --git a/extensions/service/src/com/google/inject/service/Service.java b/extensions/service/src/com/google/inject/service/Service.java
index fb7dc0d..e85c760 100644
--- a/extensions/service/src/com/google/inject/service/Service.java
+++ b/extensions/service/src/com/google/inject/service/Service.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,48 +20,46 @@
 import java.util.concurrent.Future;
 
 /**
- * An object with an operational state, asynchronous {@link #start()} and
- * {@link #stop()} lifecycle methods to transition in and out of this state.
- * Example services include http servers, RPC systems and timer tasks.
+ * An object with an operational state, asynchronous {@link #start()} and {@link #stop()} lifecycle
+ * methods to transition in and out of this state. Example services include http servers, RPC
+ * systems and timer tasks.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public interface Service {
   /**
-   * If the service has already been started, this method returns
-   * immediately without taking action. A stopped service may not be restarted.
+   * If the service has already been started, this method returns immediately without taking action.
+   * A stopped service may not be restarted.
    *
-   * @return a future for the startup result, regardless of whether this call
-   *     initiated startup. Calling {@link Future#get} will block until the
-   *     service has finished starting, and returns the resultant state. If
-   *     the service fails to start, {@link Future#get} will throw an {@link
-   *     ExecutionException}. If it has already finished starting,
-   *     {@link Future#get} returns immediately.
+   * @return a future for the startup result, regardless of whether this call initiated startup.
+   *     Calling {@link Future#get} will block until the service has finished starting, and returns
+   *     the resultant state. If the service fails to start, {@link Future#get} will throw an {@link
+   *     ExecutionException}. If it has already finished starting, {@link Future#get} returns
+   *     immediately.
    */
   Future<State> start();
 
   /**
-   * If the service is {@link State#STARTED} initiates service shutdown and
-   * returns immediately. If the service has already been stopped, this
-   * method returns immediately without taking action.
+   * If the service is {@link State#STARTED} initiates service shutdown and returns immediately. If
+   * the service has already been stopped, this method returns immediately without taking action.
    *
-   * @return a future for the shutdown result, regardless of whether this call
-   *     initiated shutdown. Calling {@link Future#get} will block until the
-   *     service has finished shutting down, and either returns {@link
-   *     State#STOPPED} or throws an {@link ExecutionException}. If it has
+   * @return a future for the shutdown result, regardless of whether this call initiated shutdown.
+   *     Calling {@link Future#get} will block until the service has finished shutting down, and
+   *     either returns {@link State#STOPPED} or throws an {@link ExecutionException}. If it has
    *     already finished stopping, {@link Future#get} returns immediately.
    */
   Future<State> stop();
 
   /**
-   * Returns the current state of this service. One of {@link State} possible
-   * values, or null if this is a brand new object, i.e., has not been put into
-   * any state yet.
+   * Returns the current state of this service. One of {@link State} possible values, or null if
+   * this is a brand new object, i.e., has not been put into any state yet.
    */
   State state();
 
-  /**
-   * The lifecycle states of a service.
-   */
-  enum State { STARTED, STOPPED, FAILED }
+  /** The lifecycle states of a service. */
+  enum State {
+    STARTED,
+    STOPPED,
+    FAILED
+  }
 }
diff --git a/extensions/service/test/com/google/inject/service/SingleServiceIntegrationTest.java b/extensions/service/test/com/google/inject/service/SingleServiceIntegrationTest.java
index 9463b16..c7c92f9 100644
--- a/extensions/service/test/com/google/inject/service/SingleServiceIntegrationTest.java
+++ b/extensions/service/test/com/google/inject/service/SingleServiceIntegrationTest.java
@@ -1,8 +1,5 @@
 package com.google.inject.service;
 
-
-import junit.framework.TestCase;
-
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -11,10 +8,9 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import junit.framework.TestCase;
 
-/**
- * Tests using Async Service.
- */
+/** Tests using Async Service. */
 
 public class SingleServiceIntegrationTest extends TestCase {
 
@@ -23,21 +19,24 @@
 
     final CountDownLatch startLatch = new CountDownLatch(1);
     final CountDownLatch stopLatch = new CountDownLatch(1);
-    AsyncService service = new AsyncService(executor) {
-      @Override protected void onStart() {
-        assertEquals(1, startLatch.getCount());
-        assertEquals(1, stopLatch.getCount());
+    AsyncService service =
+        new AsyncService(executor) {
+          @Override
+          protected void onStart() {
+            assertEquals(1, startLatch.getCount());
+            assertEquals(1, stopLatch.getCount());
 
-        startLatch.countDown();
-      }
+            startLatch.countDown();
+          }
 
-      @Override protected void onStop() {
-        assertEquals(0, startLatch.getCount());
-        assertEquals(1, stopLatch.getCount());
+          @Override
+          protected void onStop() {
+            assertEquals(0, startLatch.getCount());
+            assertEquals(1, stopLatch.getCount());
 
-        stopLatch.countDown();
-      }
-    };
+            stopLatch.countDown();
+          }
+        };
 
     Future<?> future = service.start();
     // This should not pass!  TODO(sameb): Why?  Looks like it should to me
@@ -61,15 +60,18 @@
     ExecutorService executor = Executors.newSingleThreadExecutor();
 
     final AtomicInteger integer = new AtomicInteger(2);
-    AsyncService service = new AsyncService(executor) {
-      @Override protected void onStart() {
-        assertEquals(2, integer.getAndDecrement());
-      }
+    AsyncService service =
+        new AsyncService(executor) {
+          @Override
+          protected void onStart() {
+            assertEquals(2, integer.getAndDecrement());
+          }
 
-      @Override protected void onStop() {
-        assertEquals(1, integer.getAndDecrement());
-      }
-    };
+          @Override
+          protected void onStop() {
+            assertEquals(1, integer.getAndDecrement());
+          }
+        };
 
     service.start().get(2, TimeUnit.SECONDS);
     service.stop().get(2, TimeUnit.SECONDS);
diff --git a/extensions/servlet/pom.xml b/extensions/servlet/pom.xml
index 76805c8..bf700cf 100644
--- a/extensions/servlet/pom.xml
+++ b/extensions/servlet/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-servlet</artifactId>
@@ -28,4 +28,18 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.servlet</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/servlet/src/com/google/inject/servlet/AbstractServletModuleBinding.java b/extensions/servlet/src/com/google/inject/servlet/AbstractServletModuleBinding.java
index 3566dc1..e6c463b 100644
--- a/extensions/servlet/src/com/google/inject/servlet/AbstractServletModuleBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/AbstractServletModuleBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,42 +20,43 @@
 
 /**
  * Abstract implementation for all servlet module bindings
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 class AbstractServletModuleBinding<T> implements ServletModuleBinding {
-  
+
   private final Map<String, String> initParams;
-  private final String pattern;
   private final T target;
   private final UriPatternMatcher patternMatcher;
 
-  AbstractServletModuleBinding(Map<String, String> initParams, String pattern, T target,
-      UriPatternMatcher patternMatcher) {
+  AbstractServletModuleBinding(
+      Map<String, String> initParams, T target, UriPatternMatcher patternMatcher) {
     this.initParams = initParams;
-    this.pattern = pattern;
     this.target = target;
     this.patternMatcher = patternMatcher;
   }
 
+  @Override
   public Map<String, String> getInitParams() {
     return initParams;
   }
 
+  @Override
   public String getPattern() {
-    return pattern;
+    return patternMatcher.getOriginalPattern();
   }
 
   protected T getTarget() {
     return target;
   }
 
+  @Override
   public UriPatternType getUriPatternType() {
     return patternMatcher.getPatternType();
   }
-  
+
+  @Override
   public boolean matchesUri(String uri) {
     return patternMatcher.matches(uri);
   }
-
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java b/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java
index 9c473bb..3872d62 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,8 @@
 
 import com.google.common.collect.Maps;
 import com.google.inject.OutOfScopeException;
-
 import java.io.IOException;
 import java.util.Map;
-
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
@@ -29,8 +27,7 @@
 import javax.servlet.http.HttpSession;
 
 /**
- * A wrapper for requests that makes requests immutable, taking a snapshot
- * of the original request.
+ * A wrapper for requests that makes requests immutable, taking a snapshot of the original request.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
@@ -63,31 +60,38 @@
     }
   }
 
-  @Override public HttpSession getSession() {
+  @Override
+  public HttpSession getSession() {
     throw new OutOfScopeException("Cannot access the session in a continued request");
   }
 
-  @Override public HttpSession getSession(boolean create) {
+  @Override
+  public HttpSession getSession(boolean create) {
     throw new UnsupportedOperationException("Cannot access the session in a continued request");
   }
 
-  @Override public ServletInputStream getInputStream() throws IOException {
+  @Override
+  public ServletInputStream getInputStream() throws IOException {
     throw new UnsupportedOperationException("Cannot access raw request on a continued request");
   }
 
-  @Override public void setAttribute(String name, Object o) {
+  @Override
+  public void setAttribute(String name, Object o) {
     attributes.put(name, o);
   }
 
-  @Override public void removeAttribute(String name) {
+  @Override
+  public void removeAttribute(String name) {
     attributes.remove(name);
   }
 
-  @Override public Object getAttribute(String name) {
+  @Override
+  public Object getAttribute(String name) {
     return attributes.get(name);
   }
 
-  @Override public Cookie[] getCookies() {
+  @Override
+  public Cookie[] getCookies() {
     // NOTE(dhanji): Cookies themselves are mutable. However a ContinuingHttpServletRequest
     // snapshots the original set of cookies it received and imprisons them in immutable
     // form. Unfortunately, the cookie array itself is mutable and there is no way for us
@@ -112,31 +116,38 @@
       }
     }
 
-    @Override public void setComment(String purpose) {
+    @Override
+    public void setComment(String purpose) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setDomain(String pattern) {
+    @Override
+    public void setDomain(String pattern) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setMaxAge(int expiry) {
+    @Override
+    public void setMaxAge(int expiry) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setPath(String uri) {
+    @Override
+    public void setPath(String uri) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setSecure(boolean flag) {
+    @Override
+    public void setSecure(boolean flag) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setValue(String newValue) {
+    @Override
+    public void setValue(String newValue) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
 
-    @Override public void setVersion(int v) {
+    @Override
+    public void setVersion(int v) {
       throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
     }
   }
diff --git a/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
index db32948..343f232 100644
--- a/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,6 @@
 package com.google.inject.servlet;
 
 import java.io.IOException;
-
 import javax.inject.Inject;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletContext;
@@ -31,17 +30,19 @@
  * @see com.google.inject.servlet.ManagedFilterPipeline See Also ManagedFilterPipeline.
  */
 class DefaultFilterPipeline implements FilterPipeline {
-  @Inject DefaultFilterPipeline() {
-  }
+  @Inject
+  DefaultFilterPipeline() {}
 
-  public void initPipeline(ServletContext context) {
-  }
+  @Override
+  public void initPipeline(ServletContext context) {}
 
-  public void destroyPipeline() {
-  }
+  @Override
+  public void destroyPipeline() {}
 
-  public void dispatch(ServletRequest request, ServletResponse response,
-      FilterChain proceedingFilterChain) throws IOException, ServletException {
+  @Override
+  public void dispatch(
+      ServletRequest request, ServletResponse response, FilterChain proceedingFilterChain)
+      throws IOException, ServletException {
 
     proceedingFilterChain.doFilter(request, response);
   }
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
index b4112cf..c3c27a5 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,11 +18,8 @@
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
-
 import java.io.IOException;
 import java.util.List;
-import java.util.Set;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -35,19 +32,19 @@
  * A Filter chain impl which basically passes itself to the "current" filter and iterates the chain
  * on {@code doFilter()}. Modeled on something similar in Apache Tomcat.
  *
- * Following this, it attempts to dispatch to guice-servlet's registered servlets using the
+ * <p>Following this, it attempts to dispatch to guice-servlet's registered servlets using the
  * ManagedServletPipeline.
  *
- * And the end, it proceeds to the web.xml (default) servlet filter chain, if needed.
+ * <p>And the end, it proceeds to the web.xml (default) servlet filter chain, if needed.
  *
  * @author Dhanji R. Prasanna
  * @since 1.0
  */
 class FilterChainInvocation implements FilterChain {
-  
-  private static final Set<String> SERVLET_INTERNAL_METHODS = ImmutableSet.of(
-      FilterChainInvocation.class.getName() + ".doFilter");
-  
+
+  private static final ImmutableSet<String> SERVLET_INTERNAL_METHODS =
+      ImmutableSet.of(FilterChainInvocation.class.getName() + ".doFilter");
+
   private final FilterDefinition[] filterDefinitions;
   private final FilterChain proceedingChain;
   private final ManagedServletPipeline servletPipeline;
@@ -57,21 +54,24 @@
   // whether or not we've caught an exception & cleaned up stack traces
   private boolean cleanedStacks = false;
 
-  public FilterChainInvocation(FilterDefinition[] filterDefinitions,
-      ManagedServletPipeline servletPipeline, FilterChain proceedingChain) {
+  public FilterChainInvocation(
+      FilterDefinition[] filterDefinitions,
+      ManagedServletPipeline servletPipeline,
+      FilterChain proceedingChain) {
 
     this.filterDefinitions = filterDefinitions;
     this.servletPipeline = servletPipeline;
     this.proceedingChain = proceedingChain;
   }
 
+  @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
       throws IOException, ServletException {
     GuiceFilter.Context previous = GuiceFilter.localContext.get();
     HttpServletRequest request = (HttpServletRequest) servletRequest;
     HttpServletResponse response = (HttpServletResponse) servletResponse;
-    HttpServletRequest originalRequest
-        = (previous != null) ? previous.getOriginalRequest() : request;
+    HttpServletRequest originalRequest =
+        (previous != null) ? previous.getOriginalRequest() : request;
     GuiceFilter.localContext.set(new GuiceFilter.Context(originalRequest, request, response));
     try {
       Filter filter = findNextFilter(request);
@@ -106,8 +106,8 @@
   }
 
   /**
-   * Iterates over the remaining filter definitions.
-   * Returns the first applicable filter, or null if none apply.
+   * Iterates over the remaining filter definitions. Returns the first applicable filter, or null if
+   * none apply.
    */
   private Filter findNextFilter(HttpServletRequest request) {
     while (++index < filterDefinitions.length) {
@@ -118,10 +118,10 @@
     }
     return null;
   }
-  
+
   /**
-   * Removes stacktrace elements related to AOP internal mechanics from the
-   * throwable's stack trace and any causes it may have.
+   * Removes stacktrace elements related to AOP internal mechanics from the throwable's stack trace
+   * and any causes it may have.
    */
   private void pruneStacktrace(Throwable throwable) {
     for (Throwable t = throwable; t != null; t = t.getCause()) {
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
index ff1e5b6..c50313d 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,14 +22,12 @@
 import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderWithExtensionVisitor;
-
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
@@ -42,7 +40,6 @@
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition> {
-  private final String pattern;
   private final Key<? extends Filter> filterKey;
   private final UriPatternMatcher patternMatcher;
   private final Map<String, String> initParams;
@@ -50,36 +47,34 @@
   private final Filter filterInstance;
 
   // always set after init is called.
-  private final AtomicReference<Filter> filter = new AtomicReference<Filter>();
+  private final AtomicReference<Filter> filter = new AtomicReference<>();
 
-  public FilterDefinition(String pattern, Key<? extends Filter> filterKey,
-      UriPatternMatcher patternMatcher, Map<String, String> initParams, Filter filterInstance) {
-    this.pattern = pattern;
+  public FilterDefinition(
+      Key<? extends Filter> filterKey,
+      UriPatternMatcher patternMatcher,
+      Map<String, String> initParams,
+      Filter filterInstance) {
     this.filterKey = filterKey;
     this.patternMatcher = patternMatcher;
     this.initParams = Collections.unmodifiableMap(new HashMap<String, String>(initParams));
     this.filterInstance = filterInstance;
   }
 
+  @Override
   public FilterDefinition get() {
     return this;
   }
 
-  public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
-      ProviderInstanceBinding<? extends B> binding) {
-    if(visitor instanceof ServletModuleTargetVisitor) {
-      if(filterInstance != null) {
-        return ((ServletModuleTargetVisitor<B, V>)visitor).visit(
-            new InstanceFilterBindingImpl(initParams,
-                pattern,
-                filterInstance,
-                patternMatcher));
+  @Override
+  public <B, V> V acceptExtensionVisitor(
+      BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding) {
+    if (visitor instanceof ServletModuleTargetVisitor) {
+      if (filterInstance != null) {
+        return ((ServletModuleTargetVisitor<B, V>) visitor)
+            .visit(new InstanceFilterBindingImpl(initParams, filterInstance, patternMatcher));
       } else {
-        return ((ServletModuleTargetVisitor<B, V>)visitor).visit(
-            new LinkedFilterBindingImpl(initParams,
-                pattern,
-                filterKey,
-                patternMatcher));
+        return ((ServletModuleTargetVisitor<B, V>) visitor)
+            .visit(new LinkedFilterBindingImpl(initParams, filterKey, patternMatcher));
       }
     } else {
       return visitor.visit(binding);
@@ -90,13 +85,16 @@
     return uri != null && patternMatcher.matches(uri);
   }
 
-  public void init(final ServletContext servletContext, Injector injector,
-      Set<Filter> initializedSoFar) throws ServletException {
+  public void init(
+      final ServletContext servletContext, Injector injector, Set<Filter> initializedSoFar)
+      throws ServletException {
 
     // This absolutely must be a singleton, and so is only initialized once.
     if (!Scopes.isSingleton(injector.getBinding(filterKey))) {
-      throw new ServletException("Filters must be bound as singletons. "
-        + filterKey + " was not bound in singleton scope.");
+      throw new ServletException(
+          "Filters must be bound as singletons. "
+              + filterKey
+              + " was not bound in singleton scope.");
     }
 
     Filter filter = injector.getInstance(filterKey);
@@ -109,23 +107,28 @@
     }
 
     //initialize our filter with the configured context params and servlet context
-    filter.init(new FilterConfig() {
-      public String getFilterName() {
-        return filterKey.toString();
-      }
+    filter.init(
+        new FilterConfig() {
+          @Override
+          public String getFilterName() {
+            return filterKey.toString();
+          }
 
-      public ServletContext getServletContext() {
-        return servletContext;
-      }
+          @Override
+          public ServletContext getServletContext() {
+            return servletContext;
+          }
 
-      public String getInitParameter(String s) {
-        return initParams.get(s);
-      }
+          @Override
+          public String getInitParameter(String s) {
+            return initParams.get(s);
+          }
 
-      public Enumeration getInitParameterNames() {
-        return Iterators.asEnumeration(initParams.keySet().iterator());
-      }
-    });
+          @Override
+          public Enumeration getInitParameterNames() {
+            return Iterators.asEnumeration(initParams.keySet().iterator());
+          }
+        });
 
     initializedSoFar.add(filter);
   }
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/FilterPipeline.java
index 985064b..702b4a3 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FilterPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterPipeline.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +16,7 @@
 package com.google.inject.servlet;
 
 import com.google.inject.ImplementedBy;
-
 import java.io.IOException;
-
 import javax.servlet.FilterChain;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -26,23 +24,22 @@
 import javax.servlet.ServletResponse;
 
 /**
- * An internal dispatcher for guice-servlet registered servlets and filters.
- * By default, we assume a Guice 1.0 style servlet module is in play. In other
- * words, we dispatch directly to the web.xml pipeline after setting up scopes.
+ * An internal dispatcher for guice-servlet registered servlets and filters. By default, we assume a
+ * Guice 1.0 style servlet module is in play. In other words, we dispatch directly to the web.xml
+ * pipeline after setting up scopes.
  *
- * <p>
- * If on the other hand, {@link ServletModule} is used to register managed
- * servlets and/or filters, then a different pipeline is bound instead. Which,
- * after dispatching to Guice-injected filters and servlets continues to the web.xml
- * pipeline (if necessary).
+ * <p>If on the other hand, {@link ServletModule} is used to register managed servlets and/or
+ * filters, then a different pipeline is bound instead. Which, after dispatching to Guice-injected
+ * filters and servlets continues to the web.xml pipeline (if necessary).
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 @ImplementedBy(DefaultFilterPipeline.class)
 interface FilterPipeline {
   void initPipeline(ServletContext context) throws ServletException;
+
   void destroyPipeline();
 
-  void dispatch(ServletRequest request, ServletResponse response,
-      FilterChain defaultFilterChain) throws IOException, ServletException;
+  void dispatch(ServletRequest request, ServletResponse response, FilterChain defaultFilterChain)
+      throws IOException, ServletException;
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java b/extensions/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
index 4c301ad..7395a2d 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,82 +18,99 @@
 import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.internal.UniqueAnnotations;
-
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import javax.servlet.Filter;
 
 /**
- * Builds the guice module that binds configured filters, with their
- * wrapper FilterDefinitions. Is part of the binding EDSL. All Filters
- * and Servlets are always bound as singletons.
+ * Builds the guice module that binds configured filters, with their wrapper FilterDefinitions. Is
+ * part of the binding EDSL. All Filters and Servlets are always bound as singletons.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 class FiltersModuleBuilder {
-  
+
   private final Binder binder;
-  
+
   public FiltersModuleBuilder(Binder binder) {
     this.binder = binder;
   }
 
   public ServletModule.FilterKeyBindingBuilder filter(List<String> patterns) {
-    return new FilterKeyBindingBuilderImpl(patterns, UriPatternType.SERVLET);
+    return new FilterKeyBindingBuilderImpl(parsePatterns(UriPatternType.SERVLET, patterns));
   }
 
   public ServletModule.FilterKeyBindingBuilder filterRegex(List<String> regexes) {
-    return new FilterKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
+    return new FilterKeyBindingBuilderImpl(parsePatterns(UriPatternType.REGEX, regexes));
+  }
+
+  private List<UriPatternMatcher> parsePatterns(UriPatternType type, List<String> patterns) {
+    List<UriPatternMatcher> patternMatchers = new ArrayList<>();
+    for (String pattern : patterns) {
+      UriPatternMatcher matcher = null;
+      try {
+        matcher = UriPatternType.get(type, pattern);
+      } catch (IllegalArgumentException iae) {
+        binder
+            .skipSources(ServletModule.class, FiltersModuleBuilder.class)
+            .addError("%s", iae.getMessage());
+      }
+      if (matcher != null) {
+        patternMatchers.add(matcher);
+      }
+    }
+    return patternMatchers;
   }
 
   //non-static inner class so it can access state of enclosing module class
   class FilterKeyBindingBuilderImpl implements ServletModule.FilterKeyBindingBuilder {
-    private final List<String> uriPatterns;
-    private final UriPatternType uriPatternType;
+    private final List<UriPatternMatcher> uriPatterns;
 
-    private FilterKeyBindingBuilderImpl(List<String> uriPatterns, UriPatternType uriPatternType) {
+    private FilterKeyBindingBuilderImpl(List<UriPatternMatcher> uriPatterns) {
       this.uriPatterns = uriPatterns;
-      this.uriPatternType = uriPatternType;
     }
 
+    @Override
     public void through(Class<? extends Filter> filterKey) {
       through(Key.get(filterKey));
     }
 
+    @Override
     public void through(Key<? extends Filter> filterKey) {
       through(filterKey, new HashMap<String, String>());
     }
 
+    @Override
     public void through(Filter filter) {
       through(filter, new HashMap<String, String>());
     }
 
-    public void through(Class<? extends Filter> filterKey,
-        Map<String, String> initParams) {
-      
+    @Override
+    public void through(Class<? extends Filter> filterKey, Map<String, String> initParams) {
+
       // Careful you don't accidentally make this method recursive, thank you IntelliJ IDEA!
       through(Key.get(filterKey), initParams);
     }
 
-    public void through(Key<? extends Filter> filterKey,
-        Map<String, String> initParams) {
+    @Override
+    public void through(Key<? extends Filter> filterKey, Map<String, String> initParams) {
       through(filterKey, initParams, null);
     }
-    
-    private void through(Key<? extends Filter> filterKey,
-        Map<String, String> initParams,
-        Filter filterInstance) {
-      for (String pattern : uriPatterns) {
-        binder.bind(FilterDefinition.class).annotatedWith(UniqueAnnotations.create()).toProvider(
-            new FilterDefinition(pattern, filterKey, UriPatternType.get(uriPatternType, pattern),
-                initParams, filterInstance));
+
+    private void through(
+        Key<? extends Filter> filterKey, Map<String, String> initParams, Filter filterInstance) {
+      for (UriPatternMatcher pattern : uriPatterns) {
+        binder
+            .bind(FilterDefinition.class)
+            .annotatedWith(UniqueAnnotations.create())
+            .toProvider(new FilterDefinition(filterKey, pattern, initParams, filterInstance));
       }
     }
 
-    public void through(Filter filter,
-        Map<String, String> initParams) {
+    @Override
+    public void through(Filter filter, Map<String, String> initParams) {
       Key<Filter> filterKey = Key.get(Filter.class, UniqueAnnotations.create());
       binder.bind(filterKey).toInstance(filter);
       through(filterKey, initParams, filter);
diff --git a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
index ba7a5af..ad4d69a 100644
--- a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
+++ b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,12 +21,11 @@
 import com.google.inject.Key;
 import com.google.inject.OutOfScopeException;
 import com.google.inject.internal.Errors;
-
 import java.io.IOException;
 import java.lang.ref.WeakReference;
-import java.util.concurrent.Callable;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Logger;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -38,11 +37,11 @@
 import javax.servlet.http.HttpServletResponse;
 
 /**
- * <p>
  * Apply this filter in web.xml above all other filters (typically), to all requests where you plan
- *  to use servlet scopes. This is also needed in order to dispatch requests to injectable filters
- *  and servlets:
- *  <pre>
+ * to use servlet scopes. This is also needed in order to dispatch requests to injectable filters
+ * and servlets:
+ *
+ * <pre>
  *  &lt;filter&gt;
  *    &lt;filter-name&gt;guiceFilter&lt;/filter-name&gt;
  *    &lt;filter-class&gt;<b>com.google.inject.servlet.GuiceFilter</b>&lt;/filter-class&gt;
@@ -54,20 +53,18 @@
  *  &lt;/filter-mapping&gt;
  *  </pre>
  *
- * This filter must appear before every filter that makes use of Guice injection or servlet
- * scopes functionality. Typically, you will only register this filter in web.xml and register
- * any other filters (and servlets) using a {@link ServletModule}.
+ * This filter must appear before every filter that makes use of Guice injection or servlet scopes
+ * functionality. Typically, you will only register this filter in web.xml and register any other
+ * filters (and servlets) using a {@link ServletModule}.
  *
  * @author crazybob@google.com (Bob Lee)
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public class GuiceFilter implements Filter {
-  static final ThreadLocal<Context> localContext = new ThreadLocal<Context>();
+  static final ThreadLocal<Context> localContext = new ThreadLocal<>();
   static volatile FilterPipeline pipeline = new DefaultFilterPipeline();
 
-  /**
-   * We allow both the static and dynamic versions of the pipeline to exist.
-   */
+  /** We allow both the static and dynamic versions of the pipeline to exist. */
   private final FilterPipeline injectedPipeline;
 
   /** Used to inject the servlets configured via {@link ServletModule} */
@@ -76,12 +73,13 @@
 
   private static final String MULTIPLE_INJECTORS_WARNING =
       "Multiple Servlet injectors detected. This is a warning "
-      + "indicating that you have more than one "
-      + GuiceFilter.class.getSimpleName() + " running "
-      + "in your web application. If this is deliberate, you may safely "
-      + "ignore this message. If this is NOT deliberate however, "
-      + "your application may not work as expected.";
-  
+          + "indicating that you have more than one "
+          + GuiceFilter.class.getSimpleName()
+          + " running "
+          + "in your web application. If this is deliberate, you may safely "
+          + "ignore this message. If this is NOT deliberate however, "
+          + "your application may not work as expected.";
+
   private static final Logger LOGGER = Logger.getLogger(GuiceFilter.class.getName());
 
   public GuiceFilter() {
@@ -89,7 +87,8 @@
     this(null);
   }
 
-  @Inject GuiceFilter(FilterPipeline filterPipeline) {
+  @Inject
+  GuiceFilter(FilterPipeline filterPipeline) {
     injectedPipeline = filterPipeline;
   }
 
@@ -113,6 +112,7 @@
     localContext.remove();
   }
 
+  @Override
   public void doFilter(
       final ServletRequest servletRequest,
       final ServletResponse servletResponse,
@@ -124,16 +124,16 @@
     Context previous = GuiceFilter.localContext.get();
     HttpServletRequest request = (HttpServletRequest) servletRequest;
     HttpServletResponse response = (HttpServletResponse) servletResponse;
-    HttpServletRequest originalRequest
-        = (previous != null) ? previous.getOriginalRequest() : request;
+    HttpServletRequest originalRequest =
+        (previous != null) ? previous.getOriginalRequest() : request;
     try {
-      new Context(originalRequest, request, response).call(new Callable<Void>() {
-        @Override public Void call() throws Exception {
-          //dispatch across the servlet pipeline, ensuring web.xml's filterchain is honored
-          filterPipeline.dispatch(servletRequest, servletResponse, filterChain);
-          return null;
-        }
-      });
+      RequestScoper.CloseableScope scope = new Context(originalRequest, request, response).open();
+      try {
+        //dispatch across the servlet pipeline, ensuring web.xml's filterchain is honored
+        filterPipeline.dispatch(servletRequest, servletResponse, filterChain);
+      } finally {
+        scope.close();
+      }
     } catch (IOException e) {
       throw e;
     } catch (ServletException e) {
@@ -162,20 +162,29 @@
   private static Context getContext(Key<?> key) {
     Context context = localContext.get();
     if (context == null) {
-      throw new OutOfScopeException("Cannot access scoped [" + Errors.convert(key) 
-          + "]. Either we are not currently inside an HTTP Servlet request, or you may"
-          + " have forgotten to apply " + GuiceFilter.class.getName()
-          + " as a servlet filter for this request.");
+      throw new OutOfScopeException(
+          "Cannot access scoped ["
+              + Errors.convert(key)
+              + "]. Either we are not currently inside an HTTP Servlet request, or you may"
+              + " have forgotten to apply "
+              + GuiceFilter.class.getName()
+              + " as a servlet filter for this request.");
     }
     return context;
   }
 
-  static class Context {
+  static class Context implements RequestScoper {
     final HttpServletRequest originalRequest;
     final HttpServletRequest request;
     final HttpServletResponse response;
 
-    Context(HttpServletRequest originalRequest, HttpServletRequest request,
+    // Synchronized to prevent two threads from using the same request
+    // scope concurrently.
+    final Lock lock = new ReentrantLock();
+
+    Context(
+        HttpServletRequest originalRequest,
+        HttpServletRequest request,
         HttpServletResponse response) {
       this.originalRequest = originalRequest;
       this.request = request;
@@ -194,24 +203,27 @@
       return response;
     }
 
-    // Synchronized to prevent two threads from using the same request
-    // scope concurrently.
-    synchronized <T> T call(Callable<T> callable) throws Exception {
-      Context previous = localContext.get();
+    @Override
+    public CloseableScope open() {
+      lock.lock();
+      final Context previous = localContext.get();
       localContext.set(this);
-      try {
-        return callable.call();
-      } finally {
-        localContext.set(previous);
-      }
+      return new CloseableScope() {
+        @Override
+        public void close() {
+          localContext.set(previous);
+          lock.unlock();
+        }
+      };
     }
   }
 
+  @Override
   public void init(FilterConfig filterConfig) throws ServletException {
     final ServletContext servletContext = filterConfig.getServletContext();
 
     // Store servlet context in a weakreference, for injection
-    GuiceFilter.servletContext = new WeakReference<ServletContext>(servletContext);
+    GuiceFilter.servletContext = new WeakReference<>(servletContext);
 
     // In the default pipeline, this is a noop. However, if replaced
     // by a managed pipeline, a lazy init will be triggered the first time
@@ -220,6 +232,7 @@
     filterPipeline.initPipeline(servletContext);
   }
 
+  @Override
   public void destroy() {
 
     try {
diff --git a/extensions/servlet/src/com/google/inject/servlet/GuiceServletContextListener.java b/extensions/servlet/src/com/google/inject/servlet/GuiceServletContextListener.java
index ffc189b..0ba11d1 100644
--- a/extensions/servlet/src/com/google/inject/servlet/GuiceServletContextListener.java
+++ b/extensions/servlet/src/com/google/inject/servlet/GuiceServletContextListener.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,47 +17,44 @@
 package com.google.inject.servlet;
 
 import com.google.inject.Injector;
-
 import java.lang.ref.WeakReference;
-
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 
 /**
- * As of Guice 2.0 you can still use (your subclasses of) {@code GuiceServletContextListener}
- * class as a logical place to create and configure your injector. This will ensure the injector
- * is created when the web application is deployed.
- * 
+ * As of Guice 2.0 you can still use (your subclasses of) {@code GuiceServletContextListener} class
+ * as a logical place to create and configure your injector. This will ensure the injector is
+ * created when the web application is deployed.
+ *
  * @author Kevin Bourrillion (kevinb@google.com)
  * @since 2.0
  */
-public abstract class GuiceServletContextListener
-    implements ServletContextListener {
+public abstract class GuiceServletContextListener implements ServletContextListener {
 
   static final String INJECTOR_NAME = Injector.class.getName();
 
+  @Override
   public void contextInitialized(ServletContextEvent servletContextEvent) {
     final ServletContext servletContext = servletContextEvent.getServletContext();
 
     // Set the Servletcontext early for those people who are using this class.
     // NOTE(dhanji): This use of the servletContext is deprecated.
-    GuiceFilter.servletContext = new WeakReference<ServletContext>(servletContext);
+    GuiceFilter.servletContext = new WeakReference<>(servletContext);
 
     Injector injector = getInjector();
-    injector.getInstance(InternalServletModule.BackwardsCompatibleServletContextProvider.class)
+    injector
+        .getInstance(InternalServletModule.BackwardsCompatibleServletContextProvider.class)
         .set(servletContext);
     servletContext.setAttribute(INJECTOR_NAME, injector);
   }
 
+  @Override
   public void contextDestroyed(ServletContextEvent servletContextEvent) {
     ServletContext servletContext = servletContextEvent.getServletContext();
     servletContext.removeAttribute(INJECTOR_NAME);
   }
 
-  /**
-   * Override this method to create (or otherwise obtain a reference to) your
-   * injector.
-   */
+  /** Override this method to create (or otherwise obtain a reference to) your injector. */
   protected abstract Injector getInjector();
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBinding.java b/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBinding.java
index e0cca0f..0260720 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,7 @@
 import javax.servlet.Filter;
 
 /**
- * A binding to a single instance of a filter. 
+ * A binding to a single instance of a filter.
  *
  * @author sameb@google.com
  * @since 3.0
@@ -28,5 +28,4 @@
 
   /** Returns the filter instance that will be used. */
   Filter getFilterInstance();
-
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBindingImpl.java b/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBindingImpl.java
index 57b5efb..bebcaa0 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBindingImpl.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InstanceFilterBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,35 +16,35 @@
 
 package com.google.inject.servlet;
 
-import com.google.common.base.Objects;
-
+import com.google.common.base.MoreObjects;
 import java.util.Map;
-
 import javax.servlet.Filter;
 
 /**
  * Default implementation of InstanceFilterBinding.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
-class InstanceFilterBindingImpl extends AbstractServletModuleBinding<Filter> implements
-    InstanceFilterBinding {
+class InstanceFilterBindingImpl extends AbstractServletModuleBinding<Filter>
+    implements InstanceFilterBinding {
 
-  InstanceFilterBindingImpl(Map<String, String> initParams, String pattern,
-      Filter target, UriPatternMatcher patternMatcher) {
-    super(initParams, pattern, target, patternMatcher);
+  InstanceFilterBindingImpl(
+      Map<String, String> initParams, Filter target, UriPatternMatcher patternMatcher) {
+    super(initParams, target, patternMatcher);
   }
 
+  @Override
   public Filter getFilterInstance() {
     return getTarget();
   }
-  
-  @Override public String toString() {
-    return Objects.toStringHelper(InstanceFilterBinding.class)
-      .add("pattern", getPattern())
-      .add("initParams", getInitParams())
-      .add("uriPatternType", getUriPatternType())
-      .add("filterInstance", getFilterInstance())
-      .toString();
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(InstanceFilterBinding.class)
+        .add("pattern", getPattern())
+        .add("initParams", getInitParams())
+        .add("uriPatternType", getUriPatternType())
+        .add("filterInstance", getFilterInstance())
+        .toString();
   }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InstanceServletBinding.java b/extensions/servlet/src/com/google/inject/servlet/InstanceServletBinding.java
index d466cfc..79528b6 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InstanceServletBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InstanceServletBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,7 @@
 import javax.servlet.http.HttpServlet;
 
 /**
- * A binding to a single instance of a servlet. 
+ * A binding to a single instance of a servlet.
  *
  * @author sameb@google.com
  * @since 3.0
@@ -28,5 +28,4 @@
 
   /** Returns the servlet instance that will be used. */
   HttpServlet getServletInstance();
-
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InstanceServletBindingImpl.java b/extensions/servlet/src/com/google/inject/servlet/InstanceServletBindingImpl.java
index 6e275cb..6ca79ad 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InstanceServletBindingImpl.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InstanceServletBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,36 +16,35 @@
 
 package com.google.inject.servlet;
 
-import com.google.common.base.Objects;
-
+import com.google.common.base.MoreObjects;
 import java.util.Map;
-
 import javax.servlet.http.HttpServlet;
 
 /**
  * Default implementation of InstanceServletBinding.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
-class InstanceServletBindingImpl extends AbstractServletModuleBinding<HttpServlet> implements
-    InstanceServletBinding {
+class InstanceServletBindingImpl extends AbstractServletModuleBinding<HttpServlet>
+    implements InstanceServletBinding {
 
-  InstanceServletBindingImpl(Map<String, String> initParams, String pattern,
-      HttpServlet target, UriPatternMatcher patternMatcher) {
-    super(initParams, pattern, target, patternMatcher);
+  InstanceServletBindingImpl(
+      Map<String, String> initParams, HttpServlet target, UriPatternMatcher patternMatcher) {
+    super(initParams, target, patternMatcher);
   }
 
+  @Override
   public HttpServlet getServletInstance() {
     return getTarget();
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(InstanceServletBinding.class)
-      .add("pattern", getPattern())
-      .add("initParams", getInitParams())
-      .add("uriPatternType", getUriPatternType())
-      .add("servletInstance", getServletInstance())
-      .toString();
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(InstanceServletBinding.class)
+        .add("pattern", getPattern())
+        .add("initParams", getInitParams())
+        .add("uriPatternType", getUriPatternType())
+        .add("servletInstance", getServletInstance())
+        .toString();
   }
-  
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
index 4b234ba..9b5115b 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,10 +24,8 @@
 import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
-
 import java.util.Map;
 import java.util.logging.Logger;
-
 import javax.servlet.ServletContext;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -36,44 +34,47 @@
 import javax.servlet.http.HttpSession;
 
 /**
- * This is a left-factoring of all ServletModules installed in the system.
- * In other words, this module contains the bindings common to all ServletModules,
- * and is bound exactly once per injector.
+ * This is a left-factoring of all ServletModules installed in the system. In other words, this
+ * module contains the bindings common to all ServletModules, and is bound exactly once per
+ * injector.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 final class InternalServletModule extends AbstractModule {
 
   /**
-   * Special Provider that tries to obtain an injected servlet context, specific
-   * to the current injector, failing which, it falls back to the static singleton
-   * instance that is available in the legacy Guice Servlet.
+   * Special Provider that tries to obtain an injected servlet context, specific to the current
+   * injector, failing which, it falls back to the static singleton instance that is available in
+   * the legacy Guice Servlet.
    */
   @Singleton
   static class BackwardsCompatibleServletContextProvider implements Provider<ServletContext> {
     private ServletContext injectedServletContext;
 
-    @Inject BackwardsCompatibleServletContextProvider() {}
+    @Inject
+    BackwardsCompatibleServletContextProvider() {}
 
     // This setter is called by the GuiceServletContextListener
     void set(ServletContext injectedServletContext) {
       this.injectedServletContext = injectedServletContext;
     }
 
+    @Override
     public ServletContext get() {
       if (null != injectedServletContext) {
         return injectedServletContext;
       }
 
       Logger.getLogger(InternalServletModule.class.getName())
-          .warning("You are attempting to use a deprecated API (specifically,"
-          + " attempting to @Inject ServletContext inside an eagerly created"
-          + " singleton. While we allow this for backwards compatibility, be"
-          + " warned that this MAY have unexpected behavior if you have more"
-          + " than one injector (with ServletModule) running in the same JVM."
-          + " Please consult the Guice documentation at"
-          + " https://github.com/google/guice/wiki/Servlets for more"
-          + " information.");
+          .warning(
+              "You are attempting to use a deprecated API (specifically,"
+                  + " attempting to @Inject ServletContext inside an eagerly created"
+                  + " singleton. While we allow this for backwards compatibility, be"
+                  + " warned that this MAY have unexpected behavior if you have more"
+                  + " than one injector (with ServletModule) running in the same JVM."
+                  + " Please consult the Guice documentation at"
+                  + " https://github.com/google/guice/wiki/Servlets for more"
+                  + " information.");
       return GuiceFilter.getServletContext();
     }
   }
@@ -98,25 +99,35 @@
     bind(BackwardsCompatibleServletContextProvider.class);
   }
 
-  @Provides @Singleton @ScopingOnly GuiceFilter provideScopingOnlyGuiceFilter() {
+  @Provides
+  @Singleton
+  @ScopingOnly
+  GuiceFilter provideScopingOnlyGuiceFilter() {
     return new GuiceFilter(new DefaultFilterPipeline());
   }
 
-  @Provides @RequestScoped HttpServletRequest provideHttpServletRequest() {
+  @Provides
+  @RequestScoped
+  HttpServletRequest provideHttpServletRequest() {
     return GuiceFilter.getRequest(Key.get(HttpServletRequest.class));
   }
 
-  @Provides @RequestScoped HttpServletResponse provideHttpServletResponse() {
+  @Provides
+  @RequestScoped
+  HttpServletResponse provideHttpServletResponse() {
     return GuiceFilter.getResponse(Key.get(HttpServletResponse.class));
   }
 
-  @Provides HttpSession provideHttpSession() {
+  @Provides
+  HttpSession provideHttpSession() {
     return GuiceFilter.getRequest(Key.get(HttpSession.class)).getSession();
   }
 
   @SuppressWarnings("unchecked") // defined by getParameterMap()
-  @Provides @RequestScoped @RequestParameters Map<String, String[]> provideRequestParameters(
-      ServletRequest req) {
+  @Provides
+  @RequestScoped
+  @RequestParameters
+  Map<String, String[]> provideRequestParameters(ServletRequest req) {
     return req.getParameterMap();
   }
 
diff --git a/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBinding.java b/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBinding.java
index a30bdc3..e395be8 100644
--- a/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +17,10 @@
 package com.google.inject.servlet;
 
 import com.google.inject.Key;
-
 import javax.servlet.Filter;
 
 /**
- * A linked binding to a filter. 
+ * A linked binding to a filter.
  *
  * @author sameb@google.com
  * @since 3.0
@@ -30,5 +29,4 @@
 
   /** Returns the key used to lookup the filter instance. */
   Key<? extends Filter> getLinkedKey();
-
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBindingImpl.java b/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBindingImpl.java
index 5b87ca9..4232553 100644
--- a/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBindingImpl.java
+++ b/extensions/servlet/src/com/google/inject/servlet/LinkedFilterBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,37 +16,38 @@
 
 package com.google.inject.servlet;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.Key;
-
 import java.util.Map;
-
 import javax.servlet.Filter;
 
 /**
  * Default implementation of LinkedFilterBinding.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 class LinkedFilterBindingImpl extends AbstractServletModuleBinding<Key<? extends Filter>>
     implements LinkedFilterBinding {
 
-  LinkedFilterBindingImpl(Map<String, String> initParams, String pattern,
-      Key<? extends Filter> target, UriPatternMatcher patternMatcher) {
-    super(initParams, pattern, target, patternMatcher);
+  LinkedFilterBindingImpl(
+      Map<String, String> initParams,
+      Key<? extends Filter> target,
+      UriPatternMatcher patternMatcher) {
+    super(initParams, target, patternMatcher);
   }
 
+  @Override
   public Key<? extends Filter> getLinkedKey() {
     return getTarget();
   }
-  
-  @Override public String toString() {
-    return Objects.toStringHelper(LinkedFilterBinding.class)
-      .add("pattern", getPattern())
-      .add("initParams", getInitParams())
-      .add("uriPatternType", getUriPatternType())
-      .add("linkedFilterKey", getLinkedKey())
-      .toString();
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(LinkedFilterBinding.class)
+        .add("pattern", getPattern())
+        .add("initParams", getInitParams())
+        .add("uriPatternType", getUriPatternType())
+        .add("linkedFilterKey", getLinkedKey())
+        .toString();
   }
-  
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/LinkedServletBinding.java b/extensions/servlet/src/com/google/inject/servlet/LinkedServletBinding.java
index 335dd1d..6000706 100644
--- a/extensions/servlet/src/com/google/inject/servlet/LinkedServletBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/LinkedServletBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +17,10 @@
 package com.google.inject.servlet;
 
 import com.google.inject.Key;
-
 import javax.servlet.http.HttpServlet;
 
 /**
- * A linked binding to a servlet. 
+ * A linked binding to a servlet.
  *
  * @author sameb@google.com
  * @since 3.0
@@ -30,5 +29,4 @@
 
   /** Returns the key used to lookup the servlet instance. */
   Key<? extends HttpServlet> getLinkedKey();
-
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/LinkedServletBindingImpl.java b/extensions/servlet/src/com/google/inject/servlet/LinkedServletBindingImpl.java
index 8e73735..57bc604 100644
--- a/extensions/servlet/src/com/google/inject/servlet/LinkedServletBindingImpl.java
+++ b/extensions/servlet/src/com/google/inject/servlet/LinkedServletBindingImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,37 +16,38 @@
 
 package com.google.inject.servlet;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.inject.Key;
-
 import java.util.Map;
-
 import javax.servlet.http.HttpServlet;
 
 /**
  * Default implementation of LinkedServletBinding.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 class LinkedServletBindingImpl extends AbstractServletModuleBinding<Key<? extends HttpServlet>>
     implements LinkedServletBinding {
 
-  LinkedServletBindingImpl(Map<String, String> initParams, String pattern,
-      Key<? extends HttpServlet> target, UriPatternMatcher patternMatcher) {
-    super(initParams, pattern, target, patternMatcher);
+  LinkedServletBindingImpl(
+      Map<String, String> initParams,
+      Key<? extends HttpServlet> target,
+      UriPatternMatcher patternMatcher) {
+    super(initParams, target, patternMatcher);
   }
 
+  @Override
   public Key<? extends HttpServlet> getLinkedKey() {
     return getTarget();
   }
 
-  @Override public String toString() {
-    return Objects.toStringHelper(LinkedServletBinding.class)
-      .add("pattern", getPattern())
-      .add("initParams", getInitParams())
-      .add("uriPatternType", getUriPatternType())
-      .add("linkedServletKey", getLinkedKey())
-      .toString();
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(LinkedServletBinding.class)
+        .add("pattern", getPattern())
+        .add("initParams", getInitParams())
+        .add("uriPatternType", getUriPatternType())
+        .add("linkedServletKey", getLinkedKey())
+        .toString();
   }
-  
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
index 538e10a..d8f9343 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,11 +23,9 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.TypeLiteral;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.Set;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.RequestDispatcher;
@@ -45,7 +43,7 @@
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 @Singleton
-class ManagedFilterPipeline implements FilterPipeline{
+class ManagedFilterPipeline implements FilterPipeline {
   private final FilterDefinition[] filterDefinitions;
   private final ManagedServletPipeline servletPipeline;
   private final Provider<ServletContext> servletContext;
@@ -59,7 +57,9 @@
       TypeLiteral.get(FilterDefinition.class);
 
   @Inject
-  public ManagedFilterPipeline(Injector injector, ManagedServletPipeline servletPipeline,
+  public ManagedFilterPipeline(
+      Injector injector,
+      ManagedServletPipeline servletPipeline,
       Provider<ServletContext> servletContext) {
     this.injector = injector;
     this.servletPipeline = servletPipeline;
@@ -71,26 +71,25 @@
   /**
    * Introspects the injector and collects all instances of bound {@code List<FilterDefinition>}
    * into a master list.
-   * 
-   * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
-   * that preserves insertion order in entry-set iterators.
+   *
+   * <p>We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map that
+   * preserves insertion order in entry-set iterators.
    */
   private FilterDefinition[] collectFilterDefinitions(Injector injector) {
     List<FilterDefinition> filterDefinitions = Lists.newArrayList();
     for (Binding<FilterDefinition> entry : injector.findBindingsByType(FILTER_DEFS)) {
       filterDefinitions.add(entry.getProvider().get());
     }
-    
+
     // Copy to a fixed-size array for speed of iteration.
     return filterDefinitions.toArray(new FilterDefinition[filterDefinitions.size()]);
   }
 
-  public synchronized void initPipeline(ServletContext servletContext)
-      throws ServletException {
+  @Override
+  public synchronized void initPipeline(ServletContext servletContext) throws ServletException {
 
     //double-checked lock, prevents duplicate initialization
-    if (initialized)
-      return;
+    if (initialized) return;
 
     // Used to prevent duplicate initialization.
     Set<Filter> initializedSoFar = Sets.newIdentityHashSet();
@@ -106,8 +105,10 @@
     initialized = true;
   }
 
-  public void dispatch(ServletRequest request, ServletResponse response,
-      FilterChain proceedingFilterChain) throws IOException, ServletException {
+  @Override
+  public void dispatch(
+      ServletRequest request, ServletResponse response, FilterChain proceedingFilterChain)
+      throws IOException, ServletException {
 
     //lazy init of filter pipeline (OK by the servlet specification). This is needed
     //in order for us not to force users to create a GuiceServletContextListener subclass.
@@ -118,23 +119,22 @@
     //obtain the servlet pipeline to dispatch against
     new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
         .doFilter(withDispatcher(request, servletPipeline), response);
-
   }
 
   /**
    * Used to create an proxy that dispatches either to the guice-servlet pipeline or the regular
    * pipeline based on uri-path match. This proxy also provides minimal forwarding support.
    *
-   * We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
+   * <p>We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
    * is not called again). However, we can wrap requests with our own dispatcher to forward the
    * *other* way. web.xml Servlets/JSPs can forward to themselves as per normal.
    *
-   * This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
+   * <p>This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
    * incrementally, but not the other way around (which, we should actively discourage).
    */
-  @SuppressWarnings({ "JavaDoc", "deprecation" })
-  private ServletRequest withDispatcher(ServletRequest servletRequest,
-      final ManagedServletPipeline servletPipeline) {
+  @SuppressWarnings({"JavaDoc", "deprecation"})
+  private ServletRequest withDispatcher(
+      ServletRequest servletRequest, final ManagedServletPipeline servletPipeline) {
 
     // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
     // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
@@ -156,6 +156,7 @@
     };
   }
 
+  @Override
   public void destroyPipeline() {
     //destroy servlets first
     servletPipeline.destroy();
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
index 455551a..7a378b1 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,11 +23,9 @@
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
 import com.google.inject.TypeLiteral;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.Set;
-
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -62,13 +60,13 @@
    * Introspects the injector and collects all instances of bound {@code List<ServletDefinition>}
    * into a master list.
    *
-   * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
-   * that preserves insertion order in entry-set iterators.
+   * <p>We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map that
+   * preserves insertion order in entry-set iterators.
    */
   private ServletDefinition[] collectServletDefinitions(Injector injector) {
     List<ServletDefinition> servletDefinitions = Lists.newArrayList();
     for (Binding<ServletDefinition> entry : injector.findBindingsByType(SERVLET_DEFS)) {
-        servletDefinitions.add(entry.getProvider().get());
+      servletDefinitions.add(entry.getProvider().get());
     }
 
     // Copy to a fixed size array for speed.
@@ -105,8 +103,8 @@
   }
 
   /**
-   * @return Returns a request dispatcher wrapped with a servlet mapped to
-   * the given path or null if no mapping was found.
+   * @return Returns a request dispatcher wrapped with a servlet mapped to the given path or null if
+   *     no mapping was found.
    */
   RequestDispatcher getRequestDispatcher(String path) {
     final String newRequestUri = path;
@@ -117,18 +115,20 @@
     for (final ServletDefinition servletDefinition : servletDefinitions) {
       if (servletDefinition.shouldServe(path)) {
         return new RequestDispatcher() {
+          @Override
           public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
               throws ServletException, IOException {
-            Preconditions.checkState(!servletResponse.isCommitted(),
+            Preconditions.checkState(
+                !servletResponse.isCommitted(),
                 "Response has been committed--you can only call forward before"
-                + " committing the response (hint: don't flush buffers)");
+                    + " committing the response (hint: don't flush buffers)");
 
             // clear buffer before forwarding
             servletResponse.resetBuffer();
 
             ServletRequest requestToProcess;
             if (servletRequest instanceof HttpServletRequest) {
-               requestToProcess = wrapRequest((HttpServletRequest)servletRequest, newRequestUri);
+              requestToProcess = wrapRequest((HttpServletRequest) servletRequest, newRequestUri);
             } else {
               // This should never happen, but instead of throwing an exception
               // we will allow a happy case pass thru for maximum tolerance to
@@ -140,14 +140,18 @@
             doServiceImpl(servletDefinition, requestToProcess, servletResponse);
           }
 
+          @Override
           public void include(ServletRequest servletRequest, ServletResponse servletResponse)
               throws ServletException, IOException {
             // route to the target servlet
             doServiceImpl(servletDefinition, servletRequest, servletResponse);
           }
 
-          private void doServiceImpl(ServletDefinition servletDefinition, ServletRequest servletRequest,
-              ServletResponse servletResponse) throws ServletException, IOException {
+          private void doServiceImpl(
+              ServletDefinition servletDefinition,
+              ServletRequest servletRequest,
+              ServletResponse servletResponse)
+              throws ServletException, IOException {
             servletRequest.setAttribute(REQUEST_DISPATCHER_REQUEST, Boolean.TRUE);
 
             try {
@@ -171,15 +175,16 @@
 
   /**
    * A Marker constant attribute that when present in the request indicates to Guice servlet that
-   * this request has been generated by a request dispatcher rather than the servlet pipeline.
-   * In accordance with section 8.4.2 of the Servlet 2.4 specification.
+   * this request has been generated by a request dispatcher rather than the servlet pipeline. In
+   * accordance with section 8.4.2 of the Servlet 2.4 specification.
    */
   public static final String REQUEST_DISPATCHER_REQUEST = "javax.servlet.forward.servlet_path";
 
   private static class RequestDispatcherRequestWrapper extends HttpServletRequestWrapper {
     private final String newRequestUri;
 
-    public RequestDispatcherRequestWrapper(HttpServletRequest servletRequest, String newRequestUri) {
+    public RequestDispatcherRequestWrapper(
+        HttpServletRequest servletRequest, String newRequestUri) {
       super(servletRequest);
       this.newRequestUri = newRequestUri;
     }
@@ -199,9 +204,9 @@
       url.append("://");
       url.append(getServerName());
       // port might be -1 in some cases (see java.net.URL.getPort)
-      if (port > 0 &&
-          (("http".equals(scheme) && (port != 80)) ||
-           ("https".equals(scheme) && (port != 443)))) {
+      if (port > 0
+          && (("http".equals(scheme) && (port != 80))
+              || ("https".equals(scheme) && (port != 443)))) {
         url.append(':');
         url.append(port);
       }
diff --git a/extensions/servlet/src/com/google/inject/servlet/RequestParameters.java b/extensions/servlet/src/com/google/inject/servlet/RequestParameters.java
index ca5bbc3..2315916 100644
--- a/extensions/servlet/src/com/google/inject/servlet/RequestParameters.java
+++ b/extensions/servlet/src/com/google/inject/servlet/RequestParameters.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,18 +19,17 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * Apply this to field or parameters of type {@code Map<String, String[]>}
- * when you want the HTTP request parameter map to be injected.
+ * Apply this to field or parameters of type {@code Map<String, String[]>} when you want the HTTP
+ * request parameter map to be injected.
  *
  * @author crazybob@google.com (Bob Lee)
  */
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
 public @interface RequestParameters {}
diff --git a/extensions/servlet/src/com/google/inject/servlet/RequestScoped.java b/extensions/servlet/src/com/google/inject/servlet/RequestScoped.java
index 38f9cff..00009a7 100644
--- a/extensions/servlet/src/com/google/inject/servlet/RequestScoped.java
+++ b/extensions/servlet/src/com/google/inject/servlet/RequestScoped.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.servlet;
 
 import com.google.inject.ScopeAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -28,7 +27,7 @@
  *
  * @author crazybob@google.com (Bob Lee)
  */
-@Target({ ElementType.TYPE, ElementType.METHOD })
+@Target({ElementType.TYPE, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 @ScopeAnnotation
 public @interface RequestScoped {}
diff --git a/extensions/servlet/src/com/google/inject/servlet/RequestScoper.java b/extensions/servlet/src/com/google/inject/servlet/RequestScoper.java
new file mode 100644
index 0000000..877ec44
--- /dev/null
+++ b/extensions/servlet/src/com/google/inject/servlet/RequestScoper.java
@@ -0,0 +1,20 @@
+package com.google.inject.servlet;
+
+import java.io.Closeable;
+
+/** Object that can be used to apply a request scope to a block of code. */
+public interface RequestScoper {
+  /**
+   * Opens up the request scope until the returned object is closed. Implementations should ensure
+   * (e.g. by blocking) that multiple threads cannot open the same request scope concurrently. It is
+   * allowable to open the same request scope on the same thread, as long as open/close calls are
+   * correctly nested.
+   */
+  CloseableScope open();
+
+  /** Closeable subclass that does not throw any exceptions from close. */
+  public interface CloseableScope extends Closeable {
+    @Override
+    void close();
+  }
+}
diff --git a/extensions/servlet/src/com/google/inject/servlet/ScopingException.java b/extensions/servlet/src/com/google/inject/servlet/ScopingException.java
index 1513959..742a019 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ScopingException.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ScopingException.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/extensions/servlet/src/com/google/inject/servlet/ScopingOnly.java b/extensions/servlet/src/com/google/inject/servlet/ScopingOnly.java
index d828d75..17e4c1e 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ScopingOnly.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ScopingOnly.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,19 +19,18 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.BindingAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * Annotates a {@link GuiceFilter} that provides scope functionality, but
- * doesn't dispatch to {@link ServletModule} bound servlets or filters.
+ * Annotates a {@link GuiceFilter} that provides scope functionality, but doesn't dispatch to {@link
+ * ServletModule} bound servlets or filters.
  *
  * @author iqshum@google.com (Isaac Shum)
  * @since 4.0
  */
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
 @BindingAnnotation
 public @interface ScopingOnly {}
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
index 11328ed..51e784c 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,6 @@
 import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderWithExtensionVisitor;
-
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -34,7 +33,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -52,7 +50,6 @@
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinition> {
-  private final String pattern;
   private final Key<? extends HttpServlet> servletKey;
   private final UriPatternMatcher patternMatcher;
   private final Map<String, String> initParams;
@@ -60,36 +57,34 @@
   private final HttpServlet servletInstance;
 
   //always set in init, our servlet is always presumed to be a singleton
-  private final AtomicReference<HttpServlet> httpServlet = new AtomicReference<HttpServlet>();
+  private final AtomicReference<HttpServlet> httpServlet = new AtomicReference<>();
 
-  public ServletDefinition(String pattern, Key<? extends HttpServlet> servletKey,
-      UriPatternMatcher patternMatcher, Map<String, String> initParams, HttpServlet servletInstance) {
-    this.pattern = pattern;
+  public ServletDefinition(
+      Key<? extends HttpServlet> servletKey,
+      UriPatternMatcher patternMatcher,
+      Map<String, String> initParams,
+      HttpServlet servletInstance) {
     this.servletKey = servletKey;
     this.patternMatcher = patternMatcher;
     this.initParams = Collections.unmodifiableMap(new HashMap<String, String>(initParams));
     this.servletInstance = servletInstance;
   }
 
+  @Override
   public ServletDefinition get() {
     return this;
   }
 
-  public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
-      ProviderInstanceBinding<? extends B> binding) {
-    if(visitor instanceof ServletModuleTargetVisitor) {
-      if(servletInstance != null) {
-        return ((ServletModuleTargetVisitor<B, V>)visitor).visit(
-            new InstanceServletBindingImpl(initParams,
-                pattern,
-                servletInstance,
-                patternMatcher));
+  @Override
+  public <B, V> V acceptExtensionVisitor(
+      BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding) {
+    if (visitor instanceof ServletModuleTargetVisitor) {
+      if (servletInstance != null) {
+        return ((ServletModuleTargetVisitor<B, V>) visitor)
+            .visit(new InstanceServletBindingImpl(initParams, servletInstance, patternMatcher));
       } else {
-        return ((ServletModuleTargetVisitor<B, V>)visitor).visit(
-            new LinkedServletBindingImpl(initParams,
-                pattern,
-                servletKey,
-                patternMatcher));
+        return ((ServletModuleTargetVisitor<B, V>) visitor)
+            .visit(new LinkedServletBindingImpl(initParams, servletKey, patternMatcher));
       }
     } else {
       return visitor.visit(binding);
@@ -100,13 +95,16 @@
     return uri != null && patternMatcher.matches(uri);
   }
 
-  public void init(final ServletContext servletContext, Injector injector,
-      Set<HttpServlet> initializedSoFar) throws ServletException {
+  public void init(
+      final ServletContext servletContext, Injector injector, Set<HttpServlet> initializedSoFar)
+      throws ServletException {
 
     // This absolutely must be a singleton, and so is only initialized once.
     if (!Scopes.isSingleton(injector.getBinding(servletKey))) {
-      throw new ServletException("Servlets must be bound as singletons. "
-        + servletKey + " was not bound in singleton scope.");
+      throw new ServletException(
+          "Servlets must be bound as singletons. "
+              + servletKey
+              + " was not bound in singleton scope.");
     }
 
     HttpServlet httpServlet = injector.getInstance(servletKey);
@@ -118,23 +116,28 @@
     }
 
     //initialize our servlet with the configured context params and servlet context
-    httpServlet.init(new ServletConfig() {
-      public String getServletName() {
-        return servletKey.toString();
-      }
+    httpServlet.init(
+        new ServletConfig() {
+          @Override
+          public String getServletName() {
+            return servletKey.toString();
+          }
 
-      public ServletContext getServletContext() {
-        return servletContext;
-      }
+          @Override
+          public ServletContext getServletContext() {
+            return servletContext;
+          }
 
-      public String getInitParameter(String s) {
-        return initParams.get(s);
-      }
+          @Override
+          public String getInitParameter(String s) {
+            return initParams.get(s);
+          }
 
-      public Enumeration getInitParameterNames() {
-        return Iterators.asEnumeration(initParams.keySet().iterator());
-      }
-    });
+          @Override
+          public Enumeration getInitParameterNames() {
+            return Iterators.asEnumeration(initParams.keySet().iterator());
+          }
+        });
 
     // Mark as initialized.
     initializedSoFar.add(httpServlet);
@@ -163,14 +166,13 @@
    * Wrapper around the service chain to ensure a servlet is servicing what it must and provides it
    * with a wrapped request.
    *
-   * @return Returns true if this servlet triggered for the given request. Or false if
-   *          guice-servlet should continue dispatching down the servlet pipeline.
-   *
+   * @return Returns true if this servlet triggered for the given request. Or false if guice-servlet
+   *     should continue dispatching down the servlet pipeline.
    * @throws IOException If thrown by underlying servlet
    * @throws ServletException If thrown by underlying servlet
    */
-  public boolean service(ServletRequest servletRequest,
-      ServletResponse servletResponse) throws IOException, ServletException {
+  public boolean service(ServletRequest servletRequest, ServletResponse servletResponse)
+      throws IOException, ServletException {
 
     final HttpServletRequest request = (HttpServletRequest) servletRequest;
     final String path = ServletUtils.getContextRelativePath(request);
@@ -190,89 +192,90 @@
    * Utility that delegates to the actual service method of the servlet wrapped with a contextual
    * request (i.e. with correctly computed path info).
    *
-   * We need to suppress deprecation coz we use HttpServletRequestWrapper, which implements
+   * <p>We need to suppress deprecation coz we use HttpServletRequestWrapper, which implements
    * deprecated API for backwards compatibility.
    */
   void doService(final ServletRequest servletRequest, ServletResponse servletResponse)
       throws ServletException, IOException {
 
-    HttpServletRequest request = new HttpServletRequestWrapper(
-        (HttpServletRequest) servletRequest) {
-      private boolean pathComputed;
-      private String path;
+    HttpServletRequest request =
+        new HttpServletRequestWrapper((HttpServletRequest) servletRequest) {
+          private boolean pathComputed;
+          private String path;
 
-      private boolean pathInfoComputed;
-      private String pathInfo;
+          private boolean pathInfoComputed;
+          private String pathInfo;
 
-      @Override
-      public String getPathInfo() {
-        if (!isPathInfoComputed()) {
-          String servletPath = getServletPath();
-          int servletPathLength = servletPath.length();
-          String requestUri = getRequestURI();
-          pathInfo = requestUri.substring(getContextPath().length()).replaceAll("[/]{2,}", "/");
-          // See: https://github.com/google/guice/issues/372
-          if (pathInfo.startsWith(servletPath)) {
-            pathInfo = pathInfo.substring(servletPathLength);
-            // Corner case: when servlet path & request path match exactly (without trailing '/'),
-            // then pathinfo is null.
-            if (pathInfo.isEmpty() && servletPathLength > 0) {
-              pathInfo = null;
-            } else {
-              try {
-                pathInfo = new URI(pathInfo).getPath();
-              } catch (URISyntaxException e) {
-                // ugh, just leave it alone then
+          @Override
+          public String getPathInfo() {
+            if (!isPathInfoComputed()) {
+              String servletPath = getServletPath();
+              int servletPathLength = servletPath.length();
+              String requestUri = getRequestURI();
+              pathInfo = requestUri.substring(getContextPath().length()).replaceAll("[/]{2,}", "/");
+              // See: https://github.com/google/guice/issues/372
+              if (pathInfo.startsWith(servletPath)) {
+                pathInfo = pathInfo.substring(servletPathLength);
+                // Corner case: when servlet path & request path match exactly (without trailing '/'),
+                // then pathinfo is null.
+                if (pathInfo.isEmpty() && servletPathLength > 0) {
+                  pathInfo = null;
+                } else {
+                  try {
+                    pathInfo = new URI(pathInfo).getPath();
+                  } catch (URISyntaxException e) {
+                    // ugh, just leave it alone then
+                  }
+                }
+              } else {
+                pathInfo = null; // we know nothing additional about the URI.
+              }
+              pathInfoComputed = true;
+            }
+
+            return pathInfo;
+          }
+
+          // NOTE(dhanji): These two are a bit of a hack to help ensure that request dispatcher-sent
+          // requests don't use the same path info that was memoized for the original request.
+          // NOTE(iqshum): I don't think this is possible, since the dispatcher-sent request would
+          // perform its own wrapping.
+          private boolean isPathInfoComputed() {
+            return pathInfoComputed
+                && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
+          }
+
+          private boolean isPathComputed() {
+            return pathComputed && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
+          }
+
+          @Override
+          public String getServletPath() {
+            return computePath();
+          }
+
+          @Override
+          public String getPathTranslated() {
+            final String info = getPathInfo();
+
+            return (null == info) ? null : getRealPath(info);
+          }
+
+          // Memoizer pattern.
+          private String computePath() {
+            if (!isPathComputed()) {
+              String servletPath = super.getServletPath();
+              path = patternMatcher.extractPath(servletPath);
+              pathComputed = true;
+
+              if (null == path) {
+                path = servletPath;
               }
             }
-          } else {
-            pathInfo = null; // we know nothing additional about the URI.
+
+            return path;
           }
-          pathInfoComputed = true;
-        }
-
-        return pathInfo;
-      }
-
-      // NOTE(dhanji): These two are a bit of a hack to help ensure that request dispatcher-sent
-      // requests don't use the same path info that was memoized for the original request.
-      // NOTE(iqshum): I don't think this is possible, since the dispatcher-sent request would
-      // perform its own wrapping.
-      private boolean isPathInfoComputed() {
-        return pathInfoComputed && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
-      }
-
-      private boolean isPathComputed() {
-        return pathComputed && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
-      }
-
-      @Override
-      public String getServletPath() {
-        return computePath();
-      }
-
-      @Override
-      public String getPathTranslated() {
-        final String info = getPathInfo();
-
-        return (null == info) ? null : getRealPath(info);
-      }
-
-      // Memoizer pattern.
-      private String computePath() {
-        if (!isPathComputed()) {
-          String servletPath = super.getServletPath();
-          path = patternMatcher.extractPath(servletPath);
-          pathComputed = true;
-
-          if (null == path) {
-            path = servletPath;
-          }
-        }
-
-        return path;
-      }
-    };
+        };
 
     doServiceImpl(request, (HttpServletResponse) servletResponse);
   }
@@ -280,8 +283,8 @@
   private void doServiceImpl(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
     GuiceFilter.Context previous = GuiceFilter.localContext.get();
-    HttpServletRequest originalRequest
-        = (previous != null) ? previous.getOriginalRequest() : request;
+    HttpServletRequest originalRequest =
+        (previous != null) ? previous.getOriginalRequest() : request;
     GuiceFilter.localContext.set(new GuiceFilter.Context(originalRequest, request, response));
     try {
       httpServlet.get().service(request, response);
@@ -293,8 +296,4 @@
   String getKey() {
     return servletKey.toString();
   }
-
-  String getPattern() {
-    return pattern;
-  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletModule.java b/extensions/servlet/src/com/google/inject/servlet/ServletModule.java
index c85e7ad..15e26df 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletModule.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,20 +21,17 @@
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Key;
-
 import java.util.Map;
-
 import javax.servlet.Filter;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServlet;
 
 /**
- * Configures the servlet scopes and creates bindings for the servlet API
- * objects so you can inject the request, response, session, etc.
+ * Configures the servlet scopes and creates bindings for the servlet API objects so you can inject
+ * the request, response, session, etc.
  *
- * <p>
- * You should subclass this module to register servlets and
- * filters in the {@link #configureServlets()} method.
+ * <p>You should subclass this module to register servlets and filters in the {@link
+ * #configureServlets()} method.
  *
  * @author crazybob@google.com (Bob Lee)
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
@@ -50,7 +47,7 @@
     try {
       // Install common bindings (skipped if already installed).
       install(new InternalServletModule());
-  
+
       // Install local filter and servlet bindings.
       configureServlets();
     } finally {
@@ -60,12 +57,14 @@
   }
 
   /**
+   *
+   *
    * <h3>Servlet Mapping EDSL</h3>
    *
-   * <p> Part of the EDSL builder language for configuring servlets
-   * and filters with guice-servlet. Think of this as an in-code replacement for web.xml.
-   * Filters and servlets are configured here using simple java method calls. Here is a typical
-   * example of registering a filter when creating your Guice injector:
+   * <p>Part of the EDSL builder language for configuring servlets and filters with guice-servlet.
+   * Think of this as an in-code replacement for web.xml. Filters and servlets are configured here
+   * using simple java method calls. Here is a typical example of registering a filter when creating
+   * your Guice injector:
    *
    * <pre>
    *   Guice.createInjector(..., new ServletModule() {
@@ -86,13 +85,15 @@
    * </pre>
    *
    * Every servlet (or filter) is required to be a singleton. If you cannot annotate the class
-   * directly, you should add a separate {@code bind(..).in(Singleton.class)} rule elsewhere in
-   * your module. Mapping a servlet that is bound under any other scope is an error.
+   * directly, you should add a separate {@code bind(..).in(Singleton.class)} rule elsewhere in your
+   * module. Mapping a servlet that is bound under any other scope is an error.
    *
    * <p>
+   *
    * <h4>Dispatch Order</h4>
-   * You are free to register as many servlets and filters as you like this way. They will
-   * be compared and dispatched in the order in which the filter methods are called:
+   *
+   * You are free to register as many servlets and filters as you like this way. They will be
+   * compared and dispatched in the order in which the filter methods are called:
    *
    * <pre>
    *
@@ -112,51 +113,56 @@
    *      }
    *    }
    * </pre>
-   * This will traverse down the list of rules in lexical order. For example, a url
-   *  "{@code /my/file.js}" (after it runs through the matching filters) will first
-   *  be compared against the servlet mapping:
-   * 
+   *
+   * This will traverse down the list of rules in lexical order. For example, a url "{@code
+   * /my/file.js}" (after it runs through the matching filters) will first be compared against the
+   * servlet mapping:
+   *
    * <pre>
    *       serve("*.html").with(MyServlet.class);
    * </pre>
+   *
    * And failing that, it will descend to the next servlet mapping:
    *
    * <pre>
    *       serve("/my/*").with(MyServlet.class);
    * </pre>
    *
-   * Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These
-   * two mapping rules can also be written in more compact form using varargs syntax:
+   * Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These two mapping
+   * rules can also be written in more compact form using varargs syntax:
    *
    * <pre>
    *       serve(<b>"*.html", "/my/*"</b>).with(MyServlet.class);
    * </pre>
-   * 
-   * This way you can map several URI patterns to the same servlet. A similar syntax is
-   * also available for filter mappings.
+   *
+   * This way you can map several URI patterns to the same servlet. A similar syntax is also
+   * available for filter mappings.
    *
    * <p>
+   *
    * <h4>Regular Expressions</h4>
+   *
    * You can also map servlets (or filters) to URIs using regular expressions:
+   *
    * <pre>
    *    <b>serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)</b>
    * </pre>
    *
    * This will map any URI containing the text "ajax" in it to {@code MyAjaxServlet}. Such as:
-   * <ul>
-   * <li>http://www.google.com/ajax.html</li>
-   * <li>http://www.google.com/content/ajax/index</li>
-   * <li>http://www.google.com/it/is_totally_ajaxian</li>
-   * </ul>
    *
+   * <ul>
+   * <li>http://www.google.com/ajax.html
+   * <li>http://www.google.com/content/ajax/index
+   * <li>http://www.google.com/it/is_totally_ajaxian
+   * </ul>
    *
    * <h3>Initialization Parameters</h3>
    *
-   * Servlets (and filters) allow you to pass in init params
-   * using the {@code <init-param>} tag in web.xml. You can similarly pass in parameters to
-   * Servlets and filters registered in Guice-servlet using a {@link java.util.Map} of parameter
-   * name/value pairs. For example, to initialize {@code MyServlet} with two parameters
-   * ({@code name="Dhanji", site="google.com"}) you could write:
+   * Servlets (and filters) allow you to pass in init params using the {@code <init-param>} tag in
+   * web.xml. You can similarly pass in parameters to Servlets and filters registered in
+   * Guice-servlet using a {@link java.util.Map} of parameter name/value pairs. For example, to
+   * initialize {@code MyServlet} with two parameters ({@code name="Dhanji", site="google.com"}) you
+   * could write:
    *
    * <pre>
    *  Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
@@ -168,11 +174,11 @@
    * </pre>
    *
    * <p>
+   *
    * <h3>Binding Keys</h3>
    *
-   * You can also bind keys rather than classes. This lets you hide
-   * implementations with package-local visbility and expose them using
-   * only a Guice module and an annotation:
+   * You can also bind keys rather than classes. This lets you hide implementations with
+   * package-local visbility and expose them using only a Guice module and an annotation:
    *
    * <pre>
    *  ...
@@ -180,8 +186,8 @@
    * </pre>
    *
    * Where {@code Filter.class} refers to the Servlet API interface and {@code Fave.class} is a
-   * custom binding annotation. Elsewhere (in one of your own modules) you can bind this
-   * filter's implementation:
+   * custom binding annotation. Elsewhere (in one of your own modules) you can bind this filter's
+   * implementation:
    *
    * <pre>
    *   bind(Filter.class)<b>.annotatedWith(Fave.class)</b>.to(MyFilterImpl.class);
@@ -190,32 +196,33 @@
    * See {@link com.google.inject.Binder} for more information on binding syntax.
    *
    * <p>
+   *
    * <h3>Multiple Modules</h3>
    *
-   * It is sometimes useful to capture servlet and filter mappings from multiple different
-   * modules. This is essential if you want to package and offer drop-in Guice plugins that
-   * provide servlet functionality.
+   * It is sometimes useful to capture servlet and filter mappings from multiple different modules.
+   * This is essential if you want to package and offer drop-in Guice plugins that provide servlet
+   * functionality.
    *
-   * <p>
-   * Guice Servlet allows you to register several instances of {@code ServletModule} to your
-   * injector. The order in which these modules are installed determines the dispatch order
-   * of filters and the precedence order of servlets. For example, if you had two servlet modules,
-   * {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped
-   * to the same URI pattern, {@code "/*"}:
+   * <p>Guice Servlet allows you to register several instances of {@code ServletModule} to your
+   * injector. The order in which these modules are installed determines the dispatch order of
+   * filters and the precedence order of servlets. For example, if you had two servlet modules,
+   * {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped to
+   * the same URI pattern, {@code "/*"}:
    *
-   * <p>
-   * In {@code RpcModule}:
+   * <p>In {@code RpcModule}:
+   *
    * <pre>
    *     filter("/*").through(RpcFilter.class);
    * </pre>
    *
    * In {@code WebServiceModule}:
+   *
    * <pre>
    *     filter("/*").through(WebServiceFilter.class);
    * </pre>
    *
-   * Then the order in which these filters are dispatched is determined by the order in which
-   * the modules are installed:
+   * Then the order in which these filters are dispatched is determined by the order in which the
+   * modules are installed:
    *
    * <pre>
    *   <b>install(new WebServiceModule());</b>
@@ -223,25 +230,23 @@
    * </pre>
    *
    * In the case shown above {@code WebServiceFilter} will run first.
-   * 
+   *
    * @since 2.0
    */
-  protected void configureServlets() {
-  }
-
+  protected void configureServlets() {}
 
   private FiltersModuleBuilder filtersModuleBuilder;
   private ServletsModuleBuilder servletsModuleBuilder;
 
   private FiltersModuleBuilder getFiltersModuleBuilder() {
-    checkState(filtersModuleBuilder != null,
-        "This method can only be used inside configureServlets()");
+    checkState(
+        filtersModuleBuilder != null, "This method can only be used inside configureServlets()");
     return filtersModuleBuilder;
   }
 
   private ServletsModuleBuilder getServletModuleBuilder() {
-    checkState(servletsModuleBuilder != null,
-        "This method can only be used inside configureServlets()");
+    checkState(
+        servletsModuleBuilder != null, "This method can only be used inside configureServlets()");
     return servletsModuleBuilder;
   }
 
@@ -255,6 +260,14 @@
   }
 
   /**
+   * @param urlPatterns Any Servlet-style patterns. examples: /*, /html/*, *.html, etc.
+   * @since 4.1
+   */
+  protected final FilterKeyBindingBuilder filter(Iterable<String> urlPatterns) {
+    return getFiltersModuleBuilder().filter(ImmutableList.copyOf(urlPatterns));
+  }
+
+  /**
    * @param regex Any Java-style regular expression.
    * @since 2.0
    */
@@ -264,6 +277,14 @@
   }
 
   /**
+   * @param regexes Any Java-style regular expressions.
+   * @since 4.1
+   */
+  protected final FilterKeyBindingBuilder filterRegex(Iterable<String> regexes) {
+    return getFiltersModuleBuilder().filterRegex(ImmutableList.copyOf(regexes));
+  }
+
+  /**
    * @param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
    * @since 2.0
    */
@@ -273,6 +294,14 @@
   }
 
   /**
+   * @param urlPatterns Any Servlet-style patterns. examples: /*, /html/*, *.html, etc.
+   * @since 4.1
+   */
+  protected final ServletKeyBindingBuilder serve(Iterable<String> urlPatterns) {
+    return getServletModuleBuilder().serve(ImmutableList.copyOf(urlPatterns));
+  }
+
+  /**
    * @param regex Any Java-style regular expression.
    * @since 2.0
    */
@@ -282,8 +311,17 @@
   }
 
   /**
-   * This method only works if you are using the {@linkplain GuiceServletContextListener} to
-   * create your injector. Otherwise, it returns null.
+   * @param regexes Any Java-style regular expressions.
+   * @since 4.1
+   */
+  protected final ServletKeyBindingBuilder serveRegex(Iterable<String> regexes) {
+    return getServletModuleBuilder().serveRegex(ImmutableList.copyOf(regexes));
+  }
+
+  /**
+   * This method only works if you are using the {@linkplain GuiceServletContextListener} to create
+   * your injector. Otherwise, it returns null.
+   *
    * @return The current servlet context.
    * @since 3.0
    */
@@ -298,10 +336,13 @@
    */
   public static interface FilterKeyBindingBuilder {
     void through(Class<? extends Filter> filterKey);
+
     void through(Key<? extends Filter> filterKey);
     /** @since 3.0 */
     void through(Filter filter);
+
     void through(Class<? extends Filter> filterKey, Map<String, String> initParams);
+
     void through(Key<? extends Filter> filterKey, Map<String, String> initParams);
     /** @since 3.0 */
     void through(Filter filter, Map<String, String> initParams);
@@ -314,10 +355,13 @@
    */
   public static interface ServletKeyBindingBuilder {
     void with(Class<? extends HttpServlet> servletKey);
+
     void with(Key<? extends HttpServlet> servletKey);
     /** @since 3.0 */
     void with(HttpServlet servlet);
+
     void with(Class<? extends HttpServlet> servletKey, Map<String, String> initParams);
+
     void with(Key<? extends HttpServlet> servletKey, Map<String, String> initParams);
     /** @since 3.0 */
     void with(HttpServlet servlet, Map<String, String> initParams);
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletModuleBinding.java b/extensions/servlet/src/com/google/inject/servlet/ServletModuleBinding.java
index 7895744..671eddd 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletModuleBinding.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletModuleBinding.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,7 @@
 
 /**
  * A binding created by {@link ServletModule}.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  * @since 3.0
  */
@@ -34,7 +34,7 @@
 
   /** Returns any context params supplied when creating the binding. */
   Map<String, String> getInitParams();
-  
+
   /** Returns true if the given URI will match this binding. */
   boolean matchesUri(String uri);
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletModuleTargetVisitor.java b/extensions/servlet/src/com/google/inject/servlet/ServletModuleTargetVisitor.java
index fade33d..7037f81 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletModuleTargetVisitor.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletModuleTargetVisitor.java
@@ -1,11 +1,11 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software distributed under the License
  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  * or implied. See the License for the specific language governing permissions and limitations under
@@ -17,50 +17,49 @@
 import com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder;
 import com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder;
 import com.google.inject.spi.BindingTargetVisitor;
-
 import javax.servlet.Filter;
 import javax.servlet.http.HttpServlet;
 
 /**
  * A visitor for the servlet extension.
- * 
- * If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ *
+ * <p>If your {@link BindingTargetVisitor} implements this interface, bindings created by using
  * {@link ServletModule} will be visited through this interface.
- * 
+ *
  * @since 3.0
  * @author sameb@google.com (Sam Berlin)
  */
 public interface ServletModuleTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
 
   /**
-   * Visits a filter binding created by {@link ServletModule#filter}, where
-   * {@link FilterKeyBindingBuilder#through} is called with a Class or Key.
-   * 
-   * If multiple patterns were specified, this will be called multiple times.
+   * Visits a filter binding created by {@link ServletModule#filter}, where {@link
+   * FilterKeyBindingBuilder#through} is called with a Class or Key.
+   *
+   * <p>If multiple patterns were specified, this will be called multiple times.
    */
   V visit(LinkedFilterBinding binding);
 
   /**
-   * Visits a filter binding created by {@link ServletModule#filter} where
-   * {@link FilterKeyBindingBuilder#through} is called with a {@link Filter}.
-   * 
-   * If multiple patterns were specified, this will be called multiple times. 
+   * Visits a filter binding created by {@link ServletModule#filter} where {@link
+   * FilterKeyBindingBuilder#through} is called with a {@link Filter}.
+   *
+   * <p>If multiple patterns were specified, this will be called multiple times.
    */
   V visit(InstanceFilterBinding binding);
 
   /**
-   * Visits a servlet binding created by {@link ServletModule#serve} where
-   * {@link ServletKeyBindingBuilder#with}, is called with a Class or Key.
-   * 
-   * If multiple patterns were specified, this will be called multiple times.
+   * Visits a servlet binding created by {@link ServletModule#serve} where {@link
+   * ServletKeyBindingBuilder#with}, is called with a Class or Key.
+   *
+   * <p>If multiple patterns were specified, this will be called multiple times.
    */
   V visit(LinkedServletBinding binding);
 
   /**
-   * Visits a servlet binding created by {@link ServletModule#serve} where 
-   * {@link ServletKeyBindingBuilder#with}, is called with an {@link HttpServlet}.
-   * 
-   * If multiple patterns were specified, this will be called multiple times.
+   * Visits a servlet binding created by {@link ServletModule#serve} where {@link
+   * ServletKeyBindingBuilder#with}, is called with an {@link HttpServlet}.
+   *
+   * <p>If multiple patterns were specified, this will be called multiple times.
    */
   V visit(InstanceServletBinding binding);
-}
\ No newline at end of file
+}
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
index 54c120e..3a8e8b7 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,10 +27,10 @@
 import com.google.inject.Provider;
 import com.google.inject.Scope;
 import com.google.inject.Scopes;
-
 import java.util.Map;
 import java.util.concurrent.Callable;
-
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -45,29 +45,33 @@
   private ServletScopes() {}
 
   /**
-   * A threadlocal scope map for non-http request scopes. The {@link #REQUEST}
-   * scope falls back to this scope map if no http request is available, and
-   * requires {@link #scopeRequest} to be called as an alternative.
+   * A threadlocal scope map for non-http request scopes. The {@link #REQUEST} scope falls back to
+   * this scope map if no http request is available, and requires {@link #scopeRequest} to be called
+   * as an alternative.
    */
-  private static final ThreadLocal<Context> requestScopeContext
-      = new ThreadLocal<Context>();
+  private static final ThreadLocal<Context> requestScopeContext = new ThreadLocal<>();
 
   /** A sentinel attribute value representing null. */
-  enum NullObject { INSTANCE }
+  enum NullObject {
+    INSTANCE
+  }
 
-  /**
-   * HTTP servlet request scope.
-   */
-  public static final Scope REQUEST = new Scope() {
+  /** HTTP servlet request scope. */
+  public static final Scope REQUEST = new RequestScope();
+
+  private static final class RequestScope implements Scope {
+    @Override
     public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
       return new Provider<T>() {
 
         /** Keys bound in request-scope which are handled directly by GuiceFilter. */
-        private final ImmutableSet<Key<?>> REQUEST_CONTEXT_KEYS = ImmutableSet.of(
+        private final ImmutableSet<Key<?>> REQUEST_CONTEXT_KEYS =
+            ImmutableSet.of(
                 Key.get(HttpServletRequest.class),
                 Key.get(HttpServletResponse.class),
                 new Key<Map<String, String[]>>(RequestParameters.class) {});
 
+        @Override
         public T get() {
           // Check if the alternate request scope should be used, if no HTTP
           // request is in progress.
@@ -96,7 +100,7 @@
 
               return t;
             } // else: fall into normal HTTP request scope and out of scope
-              // exception is thrown.
+            // exception is thrown.
           }
 
           // Always synchronize and get/set attributes on the underlying request
@@ -139,15 +143,17 @@
     public String toString() {
       return "ServletScopes.REQUEST";
     }
-  };
+  }
 
-  /**
-   * HTTP session scope.
-   */
-  public static final Scope SESSION = new Scope() {
+  /** HTTP session scope. */
+  public static final Scope SESSION = new SessionScope();
+
+  private static final class SessionScope implements Scope {
+    @Override
     public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
       final String name = key.toString();
       return new Provider<T>() {
+        @Override
         public T get() {
           HttpSession session = GuiceFilter.getRequest(key).getSession();
           synchronized (session) {
@@ -166,6 +172,7 @@
             return t;
           }
         }
+
         @Override
         public String toString() {
           return String.format("%s[%s]", creator, SESSION);
@@ -177,122 +184,135 @@
     public String toString() {
       return "ServletScopes.SESSION";
     }
-  };
+  }
 
   /**
-   * Wraps the given callable in a contextual callable that "continues" the
-   * HTTP request in another thread. This acts as a way of transporting
-   * request context data from the request processing thread to to worker
-   * threads.
-   * <p>
-   * There are some limitations:
+   * Wraps the given callable in a contextual callable that "continues" the HTTP request in another
+   * thread. This acts as a way of transporting request context data from the request processing
+   * thread to to worker threads.
+   *
+   * <p>There are some limitations:
+   *
    * <ul>
-   *   <li>Derived objects (i.e. anything marked @RequestScoped will not be
-   *      transported.</li>
-   *   <li>State changes to the HttpServletRequest after this method is called
-   *      will not be seen in the continued thread.</li>
-   *   <li>Only the HttpServletRequest, ServletContext and request parameter
-   *      map are available in the continued thread. The response and session
-   *      are not available.</li>
+   * <li>Derived objects (i.e. anything marked @RequestScoped will not be transported.
+   * <li>State changes to the HttpServletRequest after this method is called will not be seen in the
+   *     continued thread.
+   * <li>Only the HttpServletRequest, ServletContext and request parameter map are available in the
+   *     continued thread. The response and session are not available.
    * </ul>
    *
-   * <p>The returned callable will throw a {@link ScopingException} when called
-   * if the HTTP request scope is still active on the current thread.
+   * <p>The returned callable will throw a {@link ScopingException} when called if the HTTP request
+   * scope is still active on the current thread.
    *
-   * @param callable code to be executed in another thread, which depends on
-   *     the request scope.
-   * @param seedMap the initial set of scoped instances for Guice to seed the
-   *     request scope with.  To seed a key with null, use {@code null} as
-   *     the value.
-   * @return a callable that will invoke the given callable, making the request
-   *     context available to it.
-   * @throws OutOfScopeException if this method is called from a non-request
-   *     thread, or if the request has completed.
-   * 
+   * @param callable code to be executed in another thread, which depends on the request scope.
+   * @param seedMap the initial set of scoped instances for Guice to seed the request scope with. To
+   *     seed a key with null, use {@code null} as the value.
+   * @return a callable that will invoke the given callable, making the request context available to
+   *     it.
+   * @throws OutOfScopeException if this method is called from a non-request thread, or if the
+   *     request has completed.
    * @since 3.0
+   * @deprecated You probably want to use {@code transferRequest} instead
    */
-  public static <T> Callable<T> continueRequest(final Callable<T> callable,
-      final Map<Key<?>, Object> seedMap) {
-    Preconditions.checkArgument(null != seedMap,
-        "Seed map cannot be null, try passing in Collections.emptyMap() instead.");
+  @Deprecated
+  public static <T> Callable<T> continueRequest(Callable<T> callable, Map<Key<?>, Object> seedMap) {
+    return wrap(callable, continueRequest(seedMap));
+  }
+
+  private static RequestScoper continueRequest(Map<Key<?>, Object> seedMap) {
+    Preconditions.checkArgument(
+        null != seedMap, "Seed map cannot be null, try passing in Collections.emptyMap() instead.");
 
     // Snapshot the seed map and add all the instances to our continuing HTTP request.
     final ContinuingHttpServletRequest continuingRequest =
-        new ContinuingHttpServletRequest(
-            GuiceFilter.getRequest(Key.get(HttpServletRequest.class)));
+        new ContinuingHttpServletRequest(GuiceFilter.getRequest(Key.get(HttpServletRequest.class)));
     for (Map.Entry<Key<?>, Object> entry : seedMap.entrySet()) {
       Object value = validateAndCanonicalizeValue(entry.getKey(), entry.getValue());
       continuingRequest.setAttribute(entry.getKey().toString(), value);
     }
 
-    return new Callable<T>() {
-      public T call() throws Exception {
-        checkScopingState(null == GuiceFilter.localContext.get(),
+    return new RequestScoper() {
+      @Override
+      public CloseableScope open() {
+        checkScopingState(
+            null == GuiceFilter.localContext.get(),
             "Cannot continue request in the same thread as a HTTP request!");
-        return new GuiceFilter.Context(continuingRequest, continuingRequest, null)
-            .call(callable);
+        return new GuiceFilter.Context(continuingRequest, continuingRequest, null).open();
       }
     };
   }
 
   /**
-   * Wraps the given callable in a contextual callable that "transfers" the
-   * request to another thread. This acts as a way of transporting
-   * request context data from the current thread to a future thread.
+   * Wraps the given callable in a contextual callable that "transfers" the request to another
+   * thread. This acts as a way of transporting request context data from the current thread to a
+   * future thread.
    *
-   * <p>As opposed to {@link #continueRequest}, this method propagates all
-   * existing scoped objects. The primary use case is in server implementations
-   * where you can detach the request processing thread while waiting for data,
-   * and reattach to a different thread to finish processing at a later time.
+   * <p>As opposed to {@link #continueRequest}, this method propagates all existing scoped objects.
+   * The primary use case is in server implementations where you can detach the request processing
+   * thread while waiting for data, and reattach to a different thread to finish processing at a
+   * later time.
    *
-   * <p>Because request-scoped objects are not typically thread-safe, the
-   * callable returned by this method must not be run on a different thread
-   * until the current request scope has terminated. The returned callable will
-   * block until the current thread has released the request scope.
+   * <p>Because request-scoped objects are not typically thread-safe, the callable returned by this
+   * method must not be run on a different thread until the current request scope has terminated.
+   * The returned callable will block until the current thread has released the request scope.
    *
-   * @param callable code to be executed in another thread, which depends on
-   *     the request scope.
-   * @return a callable that will invoke the given callable, making the request
-   *     context available to it.
-   * @throws OutOfScopeException if this method is called from a non-request
-   *     thread, or if the request has completed.
+   * @param callable code to be executed in another thread, which depends on the request scope.
+   * @return a callable that will invoke the given callable, making the request context available to
+   *     it.
+   * @throws OutOfScopeException if this method is called from a non-request thread, or if the
+   *     request has completed.
    * @since 4.0
    */
   public static <T> Callable<T> transferRequest(Callable<T> callable) {
-    return (GuiceFilter.localContext.get() != null)
-        ? transferHttpRequest(callable)
-        : transferNonHttpRequest(callable);
+    return wrap(callable, transferRequest());
   }
 
-  private static <T> Callable<T> transferHttpRequest(final Callable<T> callable) {
+  /**
+   * Returns an object that "transfers" the request to another thread. This acts as a way of
+   * transporting request context data from the current thread to a future thread. The transferred
+   * scope is the one active for the thread that calls this method. A later call to {@code open()}
+   * activates the transferred the scope, including propagating any objects scoped at that time.
+   *
+   * <p>As opposed to {@link #continueRequest}, this method propagates all existing scoped objects.
+   * The primary use case is in server implementations where you can detach the request processing
+   * thread while waiting for data, and reattach to a different thread to finish processing at a
+   * later time.
+   *
+   * <p>Because request-scoped objects are not typically thread-safe, it is important to avoid
+   * applying the same request scope concurrently. The returned Scoper will block on open until the
+   * current thread has released the request scope.
+   *
+   * @return an object that when opened will initiate the request scope
+   * @throws OutOfScopeException if this method is called from a non-request thread, or if the
+   *     request has completed.
+   * @since 4.1
+   */
+  public static RequestScoper transferRequest() {
+    return (GuiceFilter.localContext.get() != null)
+        ? transferHttpRequest()
+        : transferNonHttpRequest();
+  }
+
+  private static RequestScoper transferHttpRequest() {
     final GuiceFilter.Context context = GuiceFilter.localContext.get();
     if (context == null) {
       throw new OutOfScopeException("Not in a request scope");
     }
-    return new Callable<T>() {
-      public T call() throws Exception {
-        return context.call(callable);
-      }
-    };
+    return context;
   }
 
-  private static <T> Callable<T> transferNonHttpRequest(final Callable<T> callable) {
+  private static RequestScoper transferNonHttpRequest() {
     final Context context = requestScopeContext.get();
     if (context == null) {
       throw new OutOfScopeException("Not in a request scope");
     }
-    return new Callable<T>() {
-      public T call() throws Exception {
-        return context.call(callable);
-      }
-    };
+    return context;
   }
 
   /**
-   * Returns true if {@code binding} is request-scoped. If the binding is a
-   * {@link com.google.inject.spi.LinkedKeyBinding linked key binding} and
-   * belongs to an injector (i. e. it was retrieved via
-   * {@link Injector#getBinding Injector.getBinding()}), then this method will
+   * Returns true if {@code binding} is request-scoped. If the binding is a {@link
+   * com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (i. e. it
+   * was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will
    * also return true if the target binding is request-scoped.
    *
    * @since 4.0
@@ -302,53 +322,73 @@
   }
 
   /**
-   * Scopes the given callable inside a request scope. This is not the same
-   * as the HTTP request scope, but is used if no HTTP request scope is in
-   * progress. In this way, keys can be scoped as @RequestScoped and exist
-   * in non-HTTP requests (for example: RPC requests) as well as in HTTP
+   * Scopes the given callable inside a request scope. This is not the same as the HTTP request
+   * scope, but is used if no HTTP request scope is in progress. In this way, keys can be scoped
+   * as @RequestScoped and exist in non-HTTP requests (for example: RPC requests) as well as in HTTP
    * request threads.
    *
-   * <p>The returned callable will throw a {@link ScopingException} when called
-   * if there is a request scope already active on the current thread.
+   * <p>The returned callable will throw a {@link ScopingException} when called if there is a
+   * request scope already active on the current thread.
    *
-   * @param callable code to be executed which depends on the request scope.
-   *     Typically in another thread, but not necessarily so.
-   * @param seedMap the initial set of scoped instances for Guice to seed the
-   *     request scope with.  To seed a key with null, use {@code null} as
-   *     the value.
-   * @return a callable that when called will run inside the a request scope
-   *     that exposes the instances in the {@code seedMap} as scoped keys.
+   * @param callable code to be executed which depends on the request scope. Typically in another
+   *     thread, but not necessarily so.
+   * @param seedMap the initial set of scoped instances for Guice to seed the request scope with. To
+   *     seed a key with null, use {@code null} as the value.
+   * @return a callable that when called will run inside the a request scope that exposes the
+   *     instances in the {@code seedMap} as scoped keys.
    * @since 3.0
    */
-  public static <T> Callable<T> scopeRequest(final Callable<T> callable,
-      Map<Key<?>, Object> seedMap) {
-    Preconditions.checkArgument(null != seedMap,
-        "Seed map cannot be null, try passing in Collections.emptyMap() instead.");
+  public static <T> Callable<T> scopeRequest(Callable<T> callable, Map<Key<?>, Object> seedMap) {
+    return wrap(callable, scopeRequest(seedMap));
+  }
+
+  /**
+   * Returns an object that will apply request scope to a block of code. This is not the same as the
+   * HTTP request scope, but is used if no HTTP request scope is in progress. In this way, keys can
+   * be scoped as @RequestScoped and exist in non-HTTP requests (for example: RPC requests) as well
+   * as in HTTP request threads.
+   *
+   * <p>The returned object will throw a {@link ScopingException} when opened if there is a request
+   * scope already active on the current thread.
+   *
+   * @param seedMap the initial set of scoped instances for Guice to seed the request scope with. To
+   *     seed a key with null, use {@code null} as the value.
+   * @return an object that when opened will initiate the request scope
+   * @since 4.1
+   */
+  public static RequestScoper scopeRequest(Map<Key<?>, Object> seedMap) {
+    Preconditions.checkArgument(
+        null != seedMap, "Seed map cannot be null, try passing in Collections.emptyMap() instead.");
 
     // Copy the seed values into our local scope map.
     final Context context = new Context();
     Map<Key<?>, Object> validatedAndCanonicalizedMap =
-        Maps.transformEntries(seedMap, new EntryTransformer<Key<?>, Object, Object>() {
-          @Override public Object transformEntry(Key<?> key, Object value) {
-            return validateAndCanonicalizeValue(key, value);
-          }
-        });
+        Maps.transformEntries(
+            seedMap,
+            new EntryTransformer<Key<?>, Object, Object>() {
+              @Override
+              public Object transformEntry(Key<?> key, Object value) {
+                return validateAndCanonicalizeValue(key, value);
+              }
+            });
     context.map.putAll(validatedAndCanonicalizedMap);
-
-    return new Callable<T>() {
-      public T call() throws Exception {
-        checkScopingState(null == GuiceFilter.localContext.get(),
+    return new RequestScoper() {
+      @Override
+      public CloseableScope open() {
+        checkScopingState(
+            null == GuiceFilter.localContext.get(),
             "An HTTP request is already in progress, cannot scope a new request in this thread.");
-        checkScopingState(null == requestScopeContext.get(),
+        checkScopingState(
+            null == requestScopeContext.get(),
             "A request scope is already in progress, cannot scope a new request in this thread.");
-        return context.call(callable);
+        return context.open();
       }
     };
   }
 
   /**
-   * Validates the key and object, ensuring the value matches the key type, and
-   * canonicalizing null objects to the null sentinel.
+   * Validates the key and object, ensuring the value matches the key type, and canonicalizing null
+   * objects to the null sentinel.
    */
   private static Object validateAndCanonicalizeValue(Key<?> key, Object object) {
     if (object == null || object == NullObject.INSTANCE) {
@@ -356,26 +396,38 @@
     }
 
     if (!key.getTypeLiteral().getRawType().isInstance(object)) {
-      throw new IllegalArgumentException("Value[" + object + "] of type["
-          + object.getClass().getName() + "] is not compatible with key[" + key + "]");
+      throw new IllegalArgumentException(
+          "Value["
+              + object
+              + "] of type["
+              + object.getClass().getName()
+              + "] is not compatible with key["
+              + key
+              + "]");
     }
 
     return object;
   }
 
-  private static class Context {
+  private static class Context implements RequestScoper {
     final Map<Key, Object> map = Maps.newHashMap();
 
     // Synchronized to prevent two threads from using the same request
     // scope concurrently.
-    synchronized <T> T call(Callable<T> callable) throws Exception {
-      Context previous = requestScopeContext.get();
+    final Lock lock = new ReentrantLock();
+
+    @Override
+    public CloseableScope open() {
+      lock.lock();
+      final Context previous = requestScopeContext.get();
       requestScopeContext.set(this);
-      try {
-        return callable.call();
-      } finally {
-        requestScopeContext.set(previous);
-      }
+      return new CloseableScope() {
+        @Override
+        public void close() {
+          requestScopeContext.set(previous);
+          lock.unlock();
+        }
+      };
     }
   }
 
@@ -384,4 +436,19 @@
       throw new ScopingException(msg);
     }
   }
+
+  private static final <T> Callable<T> wrap(
+      final Callable<T> delegate, final RequestScoper requestScoper) {
+    return new Callable<T>() {
+      @Override
+      public T call() throws Exception {
+        RequestScoper.CloseableScope scope = requestScoper.open();
+        try {
+          return delegate.call();
+        } finally {
+          scope.close();
+        }
+      }
+    };
+  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java b/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
index 88ecd31..ea1c353 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,16 @@
 
 package com.google.inject.servlet;
 
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.net.UrlEscapers;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 /**
@@ -24,29 +34,193 @@
  * @author ntang@google.com (Michael Tang)
  */
 final class ServletUtils {
+  private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+  private static final Joiner SLASH_JOINER = Joiner.on('/');
+
   private ServletUtils() {
     // private to prevent instantiation.
   }
 
   /**
-   * Gets the context path relative path of the URI. Returns the path of the
-   * resource relative to the context path for a request's URI, or null if no
-   * path can be extracted.
+   * Gets the context path relative path of the URI. Returns the path of the resource relative to
+   * the context path for a request's URI, or null if no path can be extracted.
+   *
+   * <p>Also performs url decoding and normalization of the path.
    */
   // @Nullable
-  public static String getContextRelativePath(
+  static String getContextRelativePath(
       // @Nullable
       final HttpServletRequest request) {
     if (request != null) {
       String contextPath = request.getContextPath();
       String requestURI = request.getRequestURI();
       if (contextPath.length() < requestURI.length()) {
-        return requestURI.substring(contextPath.length());
-      } else if (requestURI != null && requestURI.trim().length() > 0 &&
-          contextPath.length() == requestURI.length()) {
+        String suffix = requestURI.substring(contextPath.length());
+        return normalizePath(suffix);
+      } else if (requestURI.trim().length() > 0 && contextPath.length() == requestURI.length()) {
         return "/";
       }
     }
     return null;
   }
+
+  /** Normalizes a path by unescaping all safe, percent encoded characters. */
+  static String normalizePath(String path) {
+    StringBuilder sb = new StringBuilder(path.length());
+    int queryStart = path.indexOf('?');
+    String query = null;
+    if (queryStart != -1) {
+      query = path.substring(queryStart);
+      path = path.substring(0, queryStart);
+    }
+    // Normalize the path.  we need to decode path segments, normalize and rejoin in order to
+    // 1. decode and normalize safe percent escaped characters.  e.g. %70 -> 'p'
+    // 2. decode and interpret dangerous character sequences. e.g. /%2E/ -> '/./' -> '/'
+    // 3. preserve dangerous encoded characters. e.g. '/%2F/' -> '///' -> '/%2F'
+    List<String> segments = new ArrayList<>();
+    for (String segment : SLASH_SPLITTER.split(path)) {
+      // This decodes all non-special characters from the path segment.  so if someone passes
+      // /%2E/foo we will normalize it to /./foo and then /foo
+      String normalized =
+          UrlEscapers.urlPathSegmentEscaper().escape(lenientDecode(segment, UTF_8, false));
+      if (".".equals(normalized)) {
+        // skip
+      } else if ("..".equals(normalized)) {
+        if (segments.size() > 1) {
+          segments.remove(segments.size() - 1);
+        }
+      } else {
+        segments.add(normalized);
+      }
+    }
+    SLASH_JOINER.appendTo(sb, segments);
+    if (query != null) {
+      sb.append(query);
+    }
+    return sb.toString();
+  }
+
+
+  /**
+   * Percent-decodes a US-ASCII string into a Unicode string. The specified encoding is used to
+   * determine what characters are represented by any consecutive sequences of the form
+   * "%<i>XX</i>". This is the lenient kind of decoding that will simply ignore and copy as-is any
+   * "%XX" sequence that is invalid (for example, "%HH").
+   *
+   * @param string a percent-encoded US-ASCII string
+   * @param encoding a character encoding
+   * @param decodePlus boolean to indicate whether to decode '+' as ' '
+   * @return a Unicode string
+   */
+  private static String lenientDecode(String string, Charset encoding, boolean decodePlus) {
+
+    checkNotNull(string);
+    checkNotNull(encoding);
+
+    if (decodePlus) {
+      string = string.replace('+', ' ');
+    }
+
+    int firstPercentPos = string.indexOf('%');
+
+    if (firstPercentPos < 0) {
+      return string;
+    }
+
+    ByteAccumulator accumulator = new ByteAccumulator(string.length(), encoding);
+    StringBuilder builder = new StringBuilder(string.length());
+
+    if (firstPercentPos > 0) {
+      builder.append(string, 0, firstPercentPos);
+    }
+
+    for (int srcPos = firstPercentPos; srcPos < string.length(); srcPos++) {
+
+      char c = string.charAt(srcPos);
+
+      if (c < 0x80) { // ASCII
+        boolean processed = false;
+
+        if (c == '%' && string.length() >= srcPos + 3) {
+          String hex = string.substring(srcPos + 1, srcPos + 3);
+
+          try {
+            int encoded = Integer.parseInt(hex, 16);
+
+            if (encoded >= 0) {
+              accumulator.append((byte) encoded);
+              srcPos += 2;
+              processed = true;
+            }
+          } catch (NumberFormatException ignore) {
+            // Expected case (badly formatted % group)
+          }
+        }
+
+        if (!processed) {
+          if (accumulator.isEmpty()) {
+            // We're not accumulating elements of a multibyte encoded
+            // char, so just toss it right into the result string.
+
+            builder.append(c);
+          } else {
+            accumulator.append((byte) c);
+          }
+        }
+      } else { // Non-ASCII
+        // A non-ASCII char marks the end of a multi-char encoding sequence,
+        // if one is in progress.
+
+        accumulator.dumpTo(builder);
+        builder.append(c);
+      }
+    }
+
+    accumulator.dumpTo(builder);
+
+    return builder.toString();
+  }
+
+  /** Accumulates byte sequences while decoding strings, and encodes them into a StringBuilder. */
+  private static class ByteAccumulator {
+    private byte[] bytes;
+    private int length;
+    private final Charset encoding;
+
+    ByteAccumulator(int capacity, Charset encoding) {
+      this.bytes = new byte[Math.min(16, capacity)];
+      this.encoding = encoding;
+    }
+
+    void append(byte b) {
+      ensureCapacity(length + 1);
+      bytes[length++] = b;
+    }
+
+    void dumpTo(StringBuilder dest) {
+      if (length != 0) {
+        dest.append(new String(bytes, 0, length, encoding));
+        length = 0;
+      }
+    }
+
+    boolean isEmpty() {
+      return length == 0;
+    }
+
+    private void ensureCapacity(int minCapacity) {
+      int cap = bytes.length;
+      if (cap >= minCapacity) {
+        return;
+      }
+      int newCapacity = cap + (cap >> 1); // *1.5
+      if (newCapacity < minCapacity) {
+        // we are close to overflowing, grow by smaller steps
+        newCapacity = minCapacity;
+      }
+      // in other cases, we will naturally throw an OOM from here
+      bytes = Arrays.copyOf(bytes, newCapacity);
+    }
+  }
+
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java b/extensions/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
index 79f2d0b..dde2f25 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,87 +19,107 @@
 import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.internal.UniqueAnnotations;
-
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import javax.servlet.http.HttpServlet;
 
 /**
- * Builds the guice module that binds configured servlets, with their
- * wrapper ServletDefinitions. Is part of the binding EDSL. Very similar to
- * {@link com.google.inject.servlet.FiltersModuleBuilder}.
+ * Builds the guice module that binds configured servlets, with their wrapper ServletDefinitions. Is
+ * part of the binding EDSL. Very similar to {@link com.google.inject.servlet.FiltersModuleBuilder}.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
 class ServletsModuleBuilder {
-  
+
   private final Set<String> servletUris = Sets.newHashSet();
   private final Binder binder;
-  
+
   public ServletsModuleBuilder(Binder binder) {
     this.binder = binder;
   }
 
   //the first level of the EDSL--
   public ServletModule.ServletKeyBindingBuilder serve(List<String> urlPatterns) {
-    return new ServletKeyBindingBuilderImpl(urlPatterns, UriPatternType.SERVLET);
+    return new ServletKeyBindingBuilderImpl(parsePatterns(UriPatternType.SERVLET, urlPatterns));
   }
 
   public ServletModule.ServletKeyBindingBuilder serveRegex(List<String> regexes) {
-    return new ServletKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
+    return new ServletKeyBindingBuilderImpl(parsePatterns(UriPatternType.REGEX, regexes));
+  }
+
+  private List<UriPatternMatcher> parsePatterns(UriPatternType type, List<String> patterns) {
+    List<UriPatternMatcher> patternMatchers = new ArrayList<>();
+    for (String pattern : patterns) {
+      if (!servletUris.add(pattern)) {
+        binder
+            .skipSources(ServletModule.class, ServletsModuleBuilder.class)
+            .addError("More than one servlet was mapped to the same URI pattern: " + pattern);
+      } else {
+        UriPatternMatcher matcher = null;
+        try {
+          matcher = UriPatternType.get(type, pattern);
+        } catch (IllegalArgumentException iae) {
+          binder
+              .skipSources(ServletModule.class, ServletsModuleBuilder.class)
+              .addError("%s", iae.getMessage());
+        }
+        if (matcher != null) {
+          patternMatchers.add(matcher);
+        }
+      }
+    }
+    return patternMatchers;
   }
 
   //non-static inner class so it can access state of enclosing module class
   class ServletKeyBindingBuilderImpl implements ServletModule.ServletKeyBindingBuilder {
-    private final List<String> uriPatterns;
-    private final UriPatternType uriPatternType;
+    private final List<UriPatternMatcher> uriPatterns;
 
-    private ServletKeyBindingBuilderImpl(List<String> uriPatterns, UriPatternType uriPatternType) {
+    private ServletKeyBindingBuilderImpl(List<UriPatternMatcher> uriPatterns) {
       this.uriPatterns = uriPatterns;
-      this.uriPatternType = uriPatternType;
     }
 
+    @Override
     public void with(Class<? extends HttpServlet> servletKey) {
       with(Key.get(servletKey));
     }
 
+    @Override
     public void with(Key<? extends HttpServlet> servletKey) {
       with(servletKey, new HashMap<String, String>());
     }
 
+    @Override
     public void with(HttpServlet servlet) {
       with(servlet, new HashMap<String, String>());
     }
 
-    public void with(Class<? extends HttpServlet> servletKey,
-        Map<String, String> initParams) {
+    @Override
+    public void with(Class<? extends HttpServlet> servletKey, Map<String, String> initParams) {
       with(Key.get(servletKey), initParams);
     }
 
-    public void with(Key<? extends HttpServlet> servletKey,
-        Map<String, String> initParams) {
+    @Override
+    public void with(Key<? extends HttpServlet> servletKey, Map<String, String> initParams) {
       with(servletKey, initParams, null);
     }
 
-    private void with(Key<? extends HttpServlet> servletKey, Map<String, String> initParams,
+    private void with(
+        Key<? extends HttpServlet> servletKey,
+        Map<String, String> initParams,
         HttpServlet servletInstance) {
-      for (String pattern : uriPatterns) {
-        // Ensure two servlets aren't bound to the same pattern.
-        if (!servletUris.add(pattern)) {
-          binder.addError("More than one servlet was mapped to the same URI pattern: " + pattern);
-        } else {
-          binder.bind(Key.get(ServletDefinition.class, UniqueAnnotations.create())).toProvider(
-              new ServletDefinition(pattern, servletKey, UriPatternType
-                  .get(uriPatternType, pattern), initParams, servletInstance));
-        }
+      for (UriPatternMatcher pattern : uriPatterns) {
+        binder
+            .bind(Key.get(ServletDefinition.class, UniqueAnnotations.create()))
+            .toProvider(new ServletDefinition(servletKey, pattern, initParams, servletInstance));
       }
     }
 
-    public void with(HttpServlet servlet,
-        Map<String, String> initParams) {
+    @Override
+    public void with(HttpServlet servlet, Map<String, String> initParams) {
       Key<HttpServlet> servletKey = Key.get(HttpServlet.class, UniqueAnnotations.create());
       binder.bind(servletKey).toInstance(servlet);
       with(servletKey, initParams, servlet);
diff --git a/extensions/servlet/src/com/google/inject/servlet/SessionScoped.java b/extensions/servlet/src/com/google/inject/servlet/SessionScoped.java
index 5b61e26..b464f54 100644
--- a/extensions/servlet/src/com/google/inject/servlet/SessionScoped.java
+++ b/extensions/servlet/src/com/google/inject/servlet/SessionScoped.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.servlet;
 
 import com.google.inject.ScopeAnnotation;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -29,7 +28,7 @@
  * @see com.google.inject.Scopes#SINGLETON
  * @author crazybob@google.com (Bob Lee)
  */
-@Target({ ElementType.TYPE, ElementType.METHOD })
+@Target({ElementType.TYPE, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 @ScopeAnnotation
 public @interface SessionScoped {}
diff --git a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
index d8bac74..ec452ef 100644
--- a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
+++ b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,7 @@
  */
 interface UriPatternMatcher {
   /**
-   * @param uri A "contextual" (i.e. relative) Request URI, *not* a complete one.
+   * @param uri A "contextual" (i.e. relative) and "normalized" Request URI, *not* a complete one.
    * @return Returns true if the uri matches the pattern.
    */
   boolean matches(String uri);
@@ -32,13 +32,15 @@
   /**
    * @param pattern The Path that this service pattern can match against.
    * @return Returns a canonical servlet path from this pattern. For instance, if the pattern is
-   *         {@code /home/*} then the path extracted will be {@code /home}. Each pattern matcher
-   *         implementation must decide and publish what a canonical path represents.
-   *
-   *         NOTE(dhanji): This method returns null for the regex pattern matcher.
+   *     {@code /home/*} then the path extracted will be {@code /home}. Each pattern matcher
+   *     implementation must decide and publish what a canonical path represents.
+   *     <p>NOTE(dhanji): This method returns null for the regex pattern matcher.
    */
   String extractPath(String pattern);
-  
+
   /** Returns the type of pattern this is. */
   UriPatternType getPatternType();
+
+  /** Returns the original pattern that was registered. */
+  String getOriginalPattern();
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/UriPatternType.java b/extensions/servlet/src/com/google/inject/servlet/UriPatternType.java
index 80d6aea..404de7f 100644
--- a/extensions/servlet/src/com/google/inject/servlet/UriPatternType.java
+++ b/extensions/servlet/src/com/google/inject/servlet/UriPatternType.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,14 +17,16 @@
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 /**
  * An enumeration of the available URI-pattern matching styles
- * 
+ *
  * @since 3.0
  */
 public enum UriPatternType {
-  SERVLET, REGEX;
+  SERVLET,
+  REGEX;
 
   static UriPatternMatcher get(UriPatternType type, String pattern) {
     switch (type) {
@@ -52,24 +54,45 @@
    * @author dhanji@gmail.com (Dhanji R. Prasanna)
    */
   private static class ServletStyleUriPatternMatcher implements UriPatternMatcher {
-    private final String pattern;
+    private final String literal;
+    private final String originalPattern;
     private final Kind patternKind;
 
-    private static enum Kind { PREFIX, SUFFIX, LITERAL, }
+    private static enum Kind {
+      PREFIX,
+      SUFFIX,
+      LITERAL,
+    }
 
     public ServletStyleUriPatternMatcher(String pattern) {
+      this.originalPattern = pattern;
       if (pattern.startsWith("*")) {
-        this.pattern = pattern.substring(1);
+        this.literal = pattern.substring(1);
         this.patternKind = Kind.PREFIX;
       } else if (pattern.endsWith("*")) {
-        this.pattern = pattern.substring(0, pattern.length() - 1);
+        this.literal = pattern.substring(0, pattern.length() - 1);
         this.patternKind = Kind.SUFFIX;
       } else {
-        this.pattern = pattern;
+        this.literal = pattern;
         this.patternKind = Kind.LITERAL;
       }
+      String normalized = ServletUtils.normalizePath(literal);
+      if (patternKind == Kind.PREFIX) {
+        normalized = "*" + normalized;
+      } else if (patternKind == Kind.SUFFIX) {
+        normalized = normalized + "*";
+      }
+      if (!pattern.equals(normalized)) {
+        throw new IllegalArgumentException(
+            "Servlet patterns cannot contain escape patterns. Registered pattern: '"
+                + pattern
+                + "' normalizes to: '"
+                + normalized
+                + "'");
+      }
     }
 
+    @Override
     public boolean matches(String uri) {
       if (null == uri) {
         return false;
@@ -77,20 +100,21 @@
 
       uri = getUri(uri);
       if (patternKind == Kind.PREFIX) {
-        return uri.endsWith(pattern);
+        return uri.endsWith(literal);
       } else if (patternKind == Kind.SUFFIX) {
-        return uri.startsWith(pattern);
+        return uri.startsWith(literal);
       }
 
-      //else treat as a literal
-      return pattern.equals(uri);
+      //else we need a complete match
+      return literal.equals(uri);
     }
 
+    @Override
     public String extractPath(String path) {
       if (patternKind == Kind.PREFIX) {
         return null;
       } else if (patternKind == Kind.SUFFIX) {
-        String extract = pattern;
+        String extract = literal;
 
         //trim the trailing '/'
         if (extract.endsWith("/")) {
@@ -103,10 +127,16 @@
       //else treat as literal
       return path;
     }
-    
+
+    @Override
     public UriPatternType getPatternType() {
       return UriPatternType.SERVLET;
     }
+
+    @Override
+    public String getOriginalPattern() {
+      return originalPattern;
+    }
   }
 
   /**
@@ -116,15 +146,23 @@
    */
   private static class RegexUriPatternMatcher implements UriPatternMatcher {
     private final Pattern pattern;
+    private final String originalPattern;
 
     public RegexUriPatternMatcher(String pattern) {
-      this.pattern = Pattern.compile(pattern);
+      this.originalPattern = pattern;
+      try {
+        this.pattern = Pattern.compile(pattern);
+      } catch (PatternSyntaxException pse) {
+        throw new IllegalArgumentException("Invalid regex pattern: " + pse.getMessage());
+      }
     }
 
+    @Override
     public boolean matches(String uri) {
       return null != uri && this.pattern.matcher(getUri(uri)).matches();
     }
 
+    @Override
     public String extractPath(String path) {
       Matcher matcher = pattern.matcher(path);
       if (matcher.matches() && matcher.groupCount() >= 1) {
@@ -140,9 +178,15 @@
       }
       return null;
     }
-    
+
+    @Override
     public UriPatternType getPatternType() {
       return UriPatternType.REGEX;
     }
+
+    @Override
+    public String getOriginalPattern() {
+      return originalPattern;
+    }
   }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/package-info.java b/extensions/servlet/src/com/google/inject/servlet/package-info.java
index 53f2746..490b3f4 100644
--- a/extensions/servlet/src/com/google/inject/servlet/package-info.java
+++ b/extensions/servlet/src/com/google/inject/servlet/package-info.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +15,7 @@
  */
 
 /**
- * Servlet API scopes, bindings and registration; this extension requires {@code
- * guice-servlet.jar}.
+ * Servlet API scopes, bindings and registration; this extension requires {@code guice-servlet.jar}.
  *
  * <p>Apply {@link com.google.inject.servlet.GuiceFilter} to any servlets which will use the servlet
  * scopes. Install {@link com.google.inject.servlet.ServletModule} into your {@link
diff --git a/extensions/servlet/test/com/google/inject/servlet/AllTests.java b/extensions/servlet/test/com/google/inject/servlet/AllTests.java
index a80c398..bc8d9ec 100644
--- a/extensions/servlet/test/com/google/inject/servlet/AllTests.java
+++ b/extensions/servlet/test/com/google/inject/servlet/AllTests.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,9 +19,7 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
-/**
- * @author dhanji@gmail.com (Dhanji R. Prasanna)
- */
+/** @author dhanji@gmail.com (Dhanji R. Prasanna) */
 public class AllTests {
 
   public static Test suite() {
diff --git a/extensions/servlet/test/com/google/inject/servlet/ContextPathTest.java b/extensions/servlet/test/com/google/inject/servlet/ContextPathTest.java
index 36f6258..96b6954 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ContextPathTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ContextPathTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,13 +26,7 @@
 import com.google.inject.Scopes;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
-import org.easymock.IMocksControl;
-
 import java.io.IOException;
-
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
@@ -42,14 +36,18 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
+import org.easymock.IMocksControl;
 
 /** Tests to make sure that servlets with a context path are handled right. */
 public class ContextPathTest extends TestCase {
 
-  @Inject @Named("foo")
+  @Inject
+  @Named("foo")
   private TestServlet fooServlet;
 
-  @Inject @Named("bar") 
+  @Inject
+  @Named("bar")
   private TestServlet barServlet;
 
   private IMocksControl globalControl;
@@ -60,18 +58,24 @@
 
   @Override
   public final void setUp() throws Exception {
-    injector = Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        bind(TestServlet.class).annotatedWith(Names.named("foo"))
-            .to(TestServlet.class).in(Scopes.SINGLETON);
-        bind(TestServlet.class).annotatedWith(Names.named("bar"))
-            .to(TestServlet.class).in(Scopes.SINGLETON);
-        serve("/foo/*").with(Key.get(TestServlet.class, Names.named("foo")));
-        serve("/bar/*").with(Key.get(TestServlet.class, Names.named("bar")));
-        // TODO: add a filter(..) call and validate it is correct
-      }
-    });
+    injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                bind(TestServlet.class)
+                    .annotatedWith(Names.named("foo"))
+                    .to(TestServlet.class)
+                    .in(Scopes.SINGLETON);
+                bind(TestServlet.class)
+                    .annotatedWith(Names.named("bar"))
+                    .to(TestServlet.class)
+                    .in(Scopes.SINGLETON);
+                serve("/foo/*").with(Key.get(TestServlet.class, Names.named("foo")));
+                serve("/bar/*").with(Key.get(TestServlet.class, Names.named("bar")));
+                // TODO: add a filter(..) call and validate it is correct
+              }
+            });
     injector.injectMembers(this);
 
     assertNotNull(fooServlet);
@@ -83,7 +87,8 @@
     filterConfig = globalControl.createMock(FilterConfig.class);
 
     expect(servletContext.getAttribute(GuiceServletContextListener.INJECTOR_NAME))
-        .andReturn(injector).anyTimes();
+        .andReturn(injector)
+        .anyTimes();
     expect(filterConfig.getServletContext()).andReturn(servletContext).anyTimes();
 
     globalControl.replay();
@@ -229,8 +234,13 @@
     runTest("/webtest/xxx", "/xxx", "/webtest", true, false, false);
   }
 
-  private void runTest(final String requestURI, final String servletPath, final String contextPath,
-      final boolean filterResult, final boolean fooResult, final boolean barResult)
+  private void runTest(
+      final String requestURI,
+      final String servletPath,
+      final String contextPath,
+      final boolean filterResult,
+      final boolean fooResult,
+      final boolean barResult)
       throws Exception {
     IMocksControl testControl = createControl();
 
@@ -277,8 +287,9 @@
   public static class TestFilterChain implements FilterChain {
     private boolean triggered = false;
 
-    public void doFilter(ServletRequest request, ServletResponse response) throws IOException,
-        ServletException {
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response)
+        throws IOException, ServletException {
       triggered = true;
     }
 
diff --git a/extensions/servlet/test/com/google/inject/servlet/ContinuingHttpServletRequestTest.java b/extensions/servlet/test/com/google/inject/servlet/ContinuingHttpServletRequestTest.java
index 778c9ad..e9337fb 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ContinuingHttpServletRequestTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ContinuingHttpServletRequestTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2013 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,16 +15,15 @@
  */
 package com.google.inject.servlet;
 
-import junit.framework.AssertionFailedError;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
-import junit.framework.TestCase;
-
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
 
 public class ContinuingHttpServletRequestTest extends TestCase {
 
@@ -42,19 +41,16 @@
 
     verify(delegate);
   }
-  
+
   public void testReturnDelegateCookies() {
-    Cookie[] cookies = new Cookie[]{
-        new Cookie("testName1", TEST_VALUE_1),
-        new Cookie("testName2", "testValue2")
-    };
+    Cookie[] cookies =
+        new Cookie[] {new Cookie("testName1", TEST_VALUE_1), new Cookie("testName2", "testValue2")};
     HttpServletRequest delegate = createMock(HttpServletRequest.class);
     expect(delegate.getCookies()).andStubReturn(cookies);
 
     replay(delegate);
 
-    ContinuingHttpServletRequest continuingRequest = new ContinuingHttpServletRequest(
-        delegate);
+    ContinuingHttpServletRequest continuingRequest = new ContinuingHttpServletRequest(delegate);
 
     assertCookieArraysEqual(cookies, continuingRequest.getCookies());
 
@@ -65,7 +61,7 @@
 
     try {
       assertCookieArraysEqual(cookies, continuingRequest.getCookies());
-      fail();
+      throw new Error();
     } catch (AssertionFailedError e) {
       // Expected.
     }
@@ -76,8 +72,8 @@
     assertEquals(DEFAULT_MAX_AGE, continuingRequest.getCookies()[1].getMaxAge());
 
     // Perform a snapshot of the snapshot.
-    ContinuingHttpServletRequest furtherContinuingRequest = new ContinuingHttpServletRequest(
-        continuingRequest);
+    ContinuingHttpServletRequest furtherContinuingRequest =
+        new ContinuingHttpServletRequest(continuingRequest);
 
     // The cookies should be fixed.
     assertCookieArraysEqual(continuingRequest.getCookies(), furtherContinuingRequest.getCookies());
diff --git a/extensions/servlet/test/com/google/inject/servlet/ContinuingRequestIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/ContinuingRequestIntegrationTest.java
index 164369e..2dcd543 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ContinuingRequestIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ContinuingRequestIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,6 @@
 
 package com.google.inject.servlet;
 
-import javax.servlet.http.Cookie;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -30,9 +29,6 @@
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.AbstractExecutorService;
@@ -42,66 +38,73 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
 
-/**
- * Tests continuation of requests
- */
+/** Tests continuation of requests */
 
 public class ContinuingRequestIntegrationTest extends TestCase {
   private static final String PARAM_VALUE = "there";
   private static final String PARAM_NAME = "hi";
 
   private final AtomicBoolean failed = new AtomicBoolean(false);
-  private final AbstractExecutorService sameThreadExecutor = new AbstractExecutorService() {
-    public void shutdown() {
-    }
+  private final AbstractExecutorService sameThreadExecutor =
+      new AbstractExecutorService() {
+        @Override
+        public void shutdown() {}
 
-    public List<Runnable> shutdownNow() {
-      return ImmutableList.of();
-    }
+        @Override
+        public List<Runnable> shutdownNow() {
+          return ImmutableList.of();
+        }
 
-    public boolean isShutdown() {
-      return true;
-    }
+        @Override
+        public boolean isShutdown() {
+          return true;
+        }
 
-    public boolean isTerminated() {
-      return true;
-    }
+        @Override
+        public boolean isTerminated() {
+          return true;
+        }
 
-    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-      return true;
-    }
+        @Override
+        public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+          return true;
+        }
 
-    public void execute(Runnable command) {
-      command.run();
-    }
+        @Override
+        public void execute(Runnable command) {
+          command.run();
+        }
 
-    @Override public <T> Future<T> submit(Callable<T> task) {
-      try {
-        task.call();
-        fail();
-      } catch (Exception e) {
-        // Expected.
-        assertTrue(e instanceof IllegalStateException);
-        failed.set(true);
-      }
+        @Override
+        public <T> Future<T> submit(Callable<T> task) {
+          try {
+            task.call();
+            fail();
+          } catch (Exception e) {
+            // Expected.
+            assertTrue(e instanceof IllegalStateException);
+            failed.set(true);
+          }
 
-      return null;
-    }
-  };
+          return null;
+        }
+      };
 
   private ExecutorService executor;
   private Injector injector;
 
-  @Override protected void tearDown() throws Exception {
+  @Override
+  protected void tearDown() throws Exception {
     injector.getInstance(GuiceFilter.class).destroy();
   }
 
@@ -109,13 +112,16 @@
       throws ServletException, IOException, InterruptedException {
     executor = Executors.newSingleThreadExecutor();
 
-    injector = Guice.createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        serve("/*").with(ContinuingServlet.class);
+    injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                serve("/*").with(ContinuingServlet.class);
 
-        bind(ExecutorService.class).toInstance(executor);
-      }
-    });
+                bind(ExecutorService.class).toInstance(executor);
+              }
+            });
 
     FilterConfig filterConfig = createMock(FilterConfig.class);
     expect(filterConfig.getServletContext()).andReturn(createMock(ServletContext.class));
@@ -125,9 +131,7 @@
     HttpServletRequest request = createMock(HttpServletRequest.class);
 
     expect(request.getRequestURI()).andReturn("/");
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
     expect(request.getMethod()).andReturn("GET");
     expect(request.getCookies()).andReturn(new Cookie[0]);
 
@@ -150,15 +154,18 @@
   public final void testRequestContinuationDiesInHttpRequestThread()
       throws ServletException, IOException, InterruptedException {
     executor = sameThreadExecutor;
-    injector = Guice.createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        serve("/*").with(ContinuingServlet.class);
+    injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                serve("/*").with(ContinuingServlet.class);
 
-        bind(ExecutorService.class).toInstance(executor);
+                bind(ExecutorService.class).toInstance(executor);
 
-        bind(SomeObject.class);
-      }
-    });
+                bind(SomeObject.class);
+              }
+            });
 
     FilterConfig filterConfig = createMock(FilterConfig.class);
     expect(filterConfig.getServletContext()).andReturn(createMock(ServletContext.class));
@@ -168,9 +175,7 @@
     HttpServletRequest request = createMock(HttpServletRequest.class);
 
     expect(request.getRequestURI()).andReturn("/");
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     expect(request.getMethod()).andReturn("GET");
     expect(request.getCookies()).andReturn(new Cookie[0]);
@@ -192,8 +197,7 @@
   }
 
   @RequestScoped
-  public static class SomeObject {
-  }
+  public static class SomeObject {}
 
   @Singleton
   public static class ContinuingServlet extends HttpServlet {
@@ -202,14 +206,16 @@
 
     private SomeObject someObject;
 
-    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException {
       assertNull(someObject);
 
       // Seed with someobject.
       someObject = new SomeObject();
-      Callable<String> task = ServletScopes.continueRequest(callable,
-          ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject));
+      Callable<String> task =
+          ServletScopes.continueRequest(
+              callable, ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject));
 
       executorService.submit(task);
     }
@@ -223,6 +229,7 @@
 
     public String value;
 
+    @Override
     public String call() throws Exception {
       assertNull(response.get());
 
diff --git a/extensions/servlet/test/com/google/inject/servlet/DummyFilterImpl.java b/extensions/servlet/test/com/google/inject/servlet/DummyFilterImpl.java
index c931801..5f9e4a9 100644
--- a/extensions/servlet/test/com/google/inject/servlet/DummyFilterImpl.java
+++ b/extensions/servlet/test/com/google/inject/servlet/DummyFilterImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
 package com.google.inject.servlet;
 
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -33,20 +32,20 @@
 public class DummyFilterImpl implements Filter {
   int num;
 
-  public DummyFilterImpl() {
-  }
+  public DummyFilterImpl() {}
 
   public DummyFilterImpl(int num) {
     this.num = num;
   }
 
-  public void init(FilterConfig filterConfig) throws ServletException {
-  }
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {}
 
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-      FilterChain filterChain) throws IOException, ServletException {
-  }
+  @Override
+  public void doFilter(
+      ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+      throws IOException, ServletException {}
 
-  public void destroy() {
-  }
+  @Override
+  public void destroy() {}
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/DummyServlet.java b/extensions/servlet/test/com/google/inject/servlet/DummyServlet.java
index 861f8e0..4893ad1 100644
--- a/extensions/servlet/test/com/google/inject/servlet/DummyServlet.java
+++ b/extensions/servlet/test/com/google/inject/servlet/DummyServlet.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,6 @@
 package com.google.inject.servlet;
 
 import com.google.inject.Singleton;
-
 import javax.servlet.http.HttpServlet;
 
 /**
@@ -25,6 +24,4 @@
  * @author Dhanji R. Prasanna (dhanji@gmail com)
  */
 @Singleton
-public class DummyServlet extends HttpServlet {
-
-}
+public class DummyServlet extends HttpServlet {}
diff --git a/extensions/servlet/test/com/google/inject/servlet/EdslTest.java b/extensions/servlet/test/com/google/inject/servlet/EdslTest.java
index 5c62116..7a2d6a9 100644
--- a/extensions/servlet/test/com/google/inject/servlet/EdslTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/EdslTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,10 +22,8 @@
 import com.google.inject.Module;
 import com.google.inject.Singleton;
 import com.google.inject.Stage;
-
-import junit.framework.TestCase;
-
 import java.util.HashMap;
+import junit.framework.TestCase;
 
 /**
  * Sanity checks the EDSL and resultant bound module(s).
@@ -35,18 +33,21 @@
 public class EdslTest extends TestCase {
 
   public final void testExplicitBindingsWorksWithGuiceServlet() {
-    Injector injector = Guice.createInjector(
-        new AbstractModule() {
-          @Override
-          protected void configure() {
-            binder().requireExplicitBindings();
-          }
-        }, new ServletModule() {
-          @Override protected void configureServlets() {
-            bind(DummyServlet.class).in(Singleton.class);
-            serve("/*").with(DummyServlet.class);
-          }
-        });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                binder().requireExplicitBindings();
+              }
+            },
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                bind(DummyServlet.class).in(Singleton.class);
+                serve("/*").with(DummyServlet.class);
+              }
+            });
 
     assertNotNull(injector.getInstance(DummyServlet.class));
   }
@@ -54,53 +55,49 @@
   public final void testConfigureServlets() {
 
     //the various possible config calls--
-    Module webModule = new ServletModule() {
+    Module webModule =
+        new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(DummyFilterImpl.class);
-        filter("*.html").through(DummyFilterImpl.class);
-        filter("/*").through(Key.get(DummyFilterImpl.class));
-        filter("/*").through(new DummyFilterImpl());
+          @Override
+          protected void configureServlets() {
+            filter("/*").through(DummyFilterImpl.class);
+            filter("*.html").through(DummyFilterImpl.class);
+            filter("/*").through(Key.get(DummyFilterImpl.class));
+            filter("/*").through(new DummyFilterImpl());
 
-        filter("*.html").through(DummyFilterImpl.class,
-            new HashMap<String, String>());
+            filter("*.html").through(DummyFilterImpl.class, new HashMap<String, String>());
 
-        filterRegex("/person/[0-9]*").through(DummyFilterImpl.class);
-        filterRegex("/person/[0-9]*").through(DummyFilterImpl.class,
-            new HashMap<String, String>());
+            filterRegex("/person/[0-9]*").through(DummyFilterImpl.class);
+            filterRegex("/person/[0-9]*")
+                .through(DummyFilterImpl.class, new HashMap<String, String>());
 
-        filterRegex("/person/[0-9]*").through(Key.get(DummyFilterImpl.class));
-        filterRegex("/person/[0-9]*").through(Key.get(DummyFilterImpl.class),
-            new HashMap<String, String>());
+            filterRegex("/person/[0-9]*").through(Key.get(DummyFilterImpl.class));
+            filterRegex("/person/[0-9]*")
+                .through(Key.get(DummyFilterImpl.class), new HashMap<String, String>());
 
-        filterRegex("/person/[0-9]*").through(new DummyFilterImpl());
-        filterRegex("/person/[0-9]*").through(new DummyFilterImpl(),
-            new HashMap<String, String>());
+            filterRegex("/person/[0-9]*").through(new DummyFilterImpl());
+            filterRegex("/person/[0-9]*")
+                .through(new DummyFilterImpl(), new HashMap<String, String>());
 
+            serve("/1/*").with(DummyServlet.class);
+            serve("/2/*").with(Key.get(DummyServlet.class));
+            serve("/3/*").with(new DummyServlet());
+            serve("/4/*").with(DummyServlet.class, new HashMap<String, String>());
 
-        serve("/1/*").with(DummyServlet.class);
-        serve("/2/*").with(Key.get(DummyServlet.class));
-        serve("/3/*").with(new DummyServlet());
-        serve("/4/*").with(DummyServlet.class, new HashMap<String, String>());
+            serve("*.htm").with(Key.get(DummyServlet.class));
+            serve("*.html").with(Key.get(DummyServlet.class), new HashMap<String, String>());
 
-        serve("*.htm").with(Key.get(DummyServlet.class));
-        serve("*.html").with(Key.get(DummyServlet.class),
-            new HashMap<String, String>());
+            serveRegex("/person/[0-8]*").with(DummyServlet.class);
+            serveRegex("/person/[0-9]*").with(DummyServlet.class, new HashMap<String, String>());
 
-        serveRegex("/person/[0-8]*").with(DummyServlet.class);
-        serveRegex("/person/[0-9]*").with(DummyServlet.class,
-            new HashMap<String, String>());
+            serveRegex("/person/[0-6]*").with(Key.get(DummyServlet.class));
+            serveRegex("/person/[0-9]/2/*")
+                .with(Key.get(DummyServlet.class), new HashMap<String, String>());
 
-        serveRegex("/person/[0-6]*").with(Key.get(DummyServlet.class));
-        serveRegex("/person/[0-9]/2/*").with(Key.get(DummyServlet.class),
-            new HashMap<String, String>());
-
-        serveRegex("/person/[0-5]*").with(new DummyServlet());
-        serveRegex("/person/[0-9]/3/*").with(new DummyServlet(),
-            new HashMap<String, String>());
-      }
-    };
+            serveRegex("/person/[0-5]*").with(new DummyServlet());
+            serveRegex("/person/[0-9]/3/*").with(new DummyServlet(), new HashMap<String, String>());
+          }
+        };
 
     //verify that it doesn't blow up!
     Guice.createInjector(Stage.TOOL, webModule);
diff --git a/extensions/servlet/test/com/google/inject/servlet/ExtensionSpiTest.java b/extensions/servlet/test/com/google/inject/servlet/ExtensionSpiTest.java
index e6ca1cf..a04a083 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ExtensionSpiTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ExtensionSpiTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,11 +29,9 @@
 import com.google.inject.servlet.ServletSpiVisitor.Params;
 import com.google.inject.spi.Element;
 import com.google.inject.spi.Elements;
-
-import junit.framework.TestCase;
-
 import java.util.Iterator;
 import java.util.List;
+import junit.framework.TestCase;
 
 /**
  * A very basic test that servletmodule works with bindings.
@@ -55,9 +53,9 @@
   public final void testSpiOnElements() {
     ServletSpiVisitor visitor = new ServletSpiVisitor(false);
     int count = 0;
-    for(Element element : Elements.getElements(new Module())) {
-      if(element instanceof Binding) {
-        assertEquals(count++, ((Binding)element).acceptTargetVisitor(visitor));
+    for (Element element : Elements.getElements(new Module())) {
+      if (element instanceof Binding) {
+        assertEquals(count++, ((Binding) element).acceptTargetVisitor(visitor));
       }
     }
     validateVisitor(visitor);
@@ -67,7 +65,7 @@
     ServletSpiVisitor visitor = new ServletSpiVisitor(true);
     int count = 0;
     Injector injector = Guice.createInjector(new Module());
-    for(Binding binding : injector.getBindings().values()) {
+    for (Binding binding : injector.getBindings().values()) {
       assertEquals(count++, binding.acceptTargetVisitor(visitor));
     }
     validateVisitor(visitor);
@@ -77,64 +75,168 @@
     assertEquals(48, visitor.currentCount - visitor.otherCount);
 
     // This is the expected param list, in order..
-    List<Params> expected = ImmutableList.of(
-        new Params("/class", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
-        new Params("/class/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
-        new Params("/key", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
-        new Params("/key/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
-        new Params("/instance", dummyFilter1, ImmutableMap.of(), SERVLET),
-        new Params("/instance/2", dummyFilter1, ImmutableMap.of(), SERVLET),
-        new Params("/class/keyvalues", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/class/keyvalues/2", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/key/keyvalues", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/key/keyvalues/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/instance/keyvalues", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/instance/keyvalues/2", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
-
-        new Params("/class[0-9]", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
-        new Params("/class[0-9]/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
-        new Params("/key[0-9]", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), REGEX),
-        new Params("/key[0-9]/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), REGEX),
-        new Params("/instance[0-9]", dummyFilter3, ImmutableMap.of(), REGEX),
-        new Params("/instance[0-9]/2", dummyFilter3, ImmutableMap.of(), REGEX),
-        new Params("/class[0-9]/keyvalues", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/class[0-9]/keyvalues/2", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/key[0-9]/keyvalues", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/key[0-9]/keyvalues/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/instance[0-9]/keyvalues", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
-        new Params("/instance[0-9]/keyvalues/2", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
-
-        new Params("/class", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
-        new Params("/class/2", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
-        new Params("/key", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
-        new Params("/key/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
-        new Params("/instance", dummyServlet1, ImmutableMap.of(), SERVLET),
-        new Params("/instance/2", dummyServlet1, ImmutableMap.of(), SERVLET),
-        new Params("/class/keyvalues", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/class/keyvalues/2", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/key/keyvalues", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/key/keyvalues/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/instance/keyvalues", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
-        new Params("/instance/keyvalues/2", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
-
-        new Params("/class[0-9]", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
-        new Params("/class[0-9]/2", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
-        new Params("/key[0-9]", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), REGEX),
-        new Params("/key[0-9]/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), REGEX),
-        new Params("/instance[0-9]", dummyServlet3, ImmutableMap.of(), REGEX),
-        new Params("/instance[0-9]/2", dummyServlet3, ImmutableMap.of(), REGEX),
-        new Params("/class[0-9]/keyvalues", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/class[0-9]/keyvalues/2", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/key[0-9]/keyvalues", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/key[0-9]/keyvalues/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
-        new Params("/instance[0-9]/keyvalues", dummyServlet4, ImmutableMap.of("key", "value"), REGEX),
-        new Params("/instance[0-9]/keyvalues/2", dummyServlet4, ImmutableMap.of("key", "value"), REGEX)
-    );
+    List<Params> expected =
+        ImmutableList.of(
+            new Params("/class", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
+            new Params("/class/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
+            new Params(
+                "/key",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of(),
+                SERVLET),
+            new Params(
+                "/key/2",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of(),
+                SERVLET),
+            new Params("/instance", dummyFilter1, ImmutableMap.of(), SERVLET),
+            new Params("/instance/2", dummyFilter1, ImmutableMap.of(), SERVLET),
+            new Params(
+                "/class/keyvalues",
+                Key.get(DummyFilterImpl.class),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/class/keyvalues/2",
+                Key.get(DummyFilterImpl.class),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/key/keyvalues",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/key/keyvalues/2",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/instance/keyvalues", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
+            new Params(
+                "/instance/keyvalues/2", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
+            new Params("/class[0-9]", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
+            new Params("/class[0-9]/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
+            new Params(
+                "/key[0-9]",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of(),
+                REGEX),
+            new Params(
+                "/key[0-9]/2",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of(),
+                REGEX),
+            new Params("/instance[0-9]", dummyFilter3, ImmutableMap.of(), REGEX),
+            new Params("/instance[0-9]/2", dummyFilter3, ImmutableMap.of(), REGEX),
+            new Params(
+                "/class[0-9]/keyvalues",
+                Key.get(DummyFilterImpl.class),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/class[0-9]/keyvalues/2",
+                Key.get(DummyFilterImpl.class),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/key[0-9]/keyvalues",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/key[0-9]/keyvalues/2",
+                Key.get(DummyFilterImpl.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/instance[0-9]/keyvalues", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
+            new Params(
+                "/instance[0-9]/keyvalues/2", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
+            new Params("/class", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
+            new Params("/class/2", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
+            new Params(
+                "/key",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of(),
+                SERVLET),
+            new Params(
+                "/key/2",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of(),
+                SERVLET),
+            new Params("/instance", dummyServlet1, ImmutableMap.of(), SERVLET),
+            new Params("/instance/2", dummyServlet1, ImmutableMap.of(), SERVLET),
+            new Params(
+                "/class/keyvalues",
+                Key.get(DummyServlet.class),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/class/keyvalues/2",
+                Key.get(DummyServlet.class),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/key/keyvalues",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/key/keyvalues/2",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                SERVLET),
+            new Params(
+                "/instance/keyvalues", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
+            new Params(
+                "/instance/keyvalues/2", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
+            new Params("/class[0-9]", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
+            new Params("/class[0-9]/2", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
+            new Params(
+                "/key[0-9]",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of(),
+                REGEX),
+            new Params(
+                "/key[0-9]/2",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of(),
+                REGEX),
+            new Params("/instance[0-9]", dummyServlet3, ImmutableMap.of(), REGEX),
+            new Params("/instance[0-9]/2", dummyServlet3, ImmutableMap.of(), REGEX),
+            new Params(
+                "/class[0-9]/keyvalues",
+                Key.get(DummyServlet.class),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/class[0-9]/keyvalues/2",
+                Key.get(DummyServlet.class),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/key[0-9]/keyvalues",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/key[0-9]/keyvalues/2",
+                Key.get(DummyServlet.class, Names.named("foo")),
+                ImmutableMap.of("key", "value"),
+                REGEX),
+            new Params(
+                "/instance[0-9]/keyvalues", dummyServlet4, ImmutableMap.of("key", "value"), REGEX),
+            new Params(
+                "/instance[0-9]/keyvalues/2",
+                dummyServlet4,
+                ImmutableMap.of("key", "value"),
+                REGEX));
 
     assertEquals(expected.size(), visitor.actual.size());
     Iterator<Params> actualIterator = visitor.actual.iterator();
     int i = 0;
-    for(Params param : expected) {
+    for (Params param : expected) {
       assertEquals("wrong " + i++ + "th param", param, actualIterator.next());
     }
   }
@@ -145,48 +247,47 @@
       binder().requireExplicitBindings();
 
       filter("/class", "/class/2").through(DummyFilterImpl.class);
-      filter("/key", "/key/2").through(
-          Key.get(DummyFilterImpl.class, Names.named("foo")));
+      filter("/key", "/key/2").through(Key.get(DummyFilterImpl.class, Names.named("foo")));
       filter("/instance", "/instance/2").through(dummyFilter1);
-      filter("/class/keyvalues", "/class/keyvalues/2").through(
-          DummyFilterImpl.class, ImmutableMap.of("key", "value"));
-      filter("/key/keyvalues", "/key/keyvalues/2").through(
-          Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
-      filter("/instance/keyvalues", "/instance/keyvalues/2").through(
-          dummyFilter2, ImmutableMap.of("key", "value"));
+      filter("/class/keyvalues", "/class/keyvalues/2")
+          .through(DummyFilterImpl.class, ImmutableMap.of("key", "value"));
+      filter("/key/keyvalues", "/key/keyvalues/2")
+          .through(
+              Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
+      filter("/instance/keyvalues", "/instance/keyvalues/2")
+          .through(dummyFilter2, ImmutableMap.of("key", "value"));
 
       filterRegex("/class[0-9]", "/class[0-9]/2").through(DummyFilterImpl.class);
-      filterRegex("/key[0-9]", "/key[0-9]/2").through(
-          Key.get(DummyFilterImpl.class, Names.named("foo")));
+      filterRegex("/key[0-9]", "/key[0-9]/2")
+          .through(Key.get(DummyFilterImpl.class, Names.named("foo")));
       filterRegex("/instance[0-9]", "/instance[0-9]/2").through(dummyFilter3);
-      filterRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2").through(
-          DummyFilterImpl.class, ImmutableMap.of("key", "value"));
-      filterRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2").through(
-          Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
-      filterRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2").through(
-          dummyFilter4, ImmutableMap.of("key", "value"));
+      filterRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2")
+          .through(DummyFilterImpl.class, ImmutableMap.of("key", "value"));
+      filterRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2")
+          .through(
+              Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
+      filterRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2")
+          .through(dummyFilter4, ImmutableMap.of("key", "value"));
 
       serve("/class", "/class/2").with(DummyServlet.class);
-      serve("/key", "/key/2").with(
-          Key.get(DummyServlet.class, Names.named("foo")));
+      serve("/key", "/key/2").with(Key.get(DummyServlet.class, Names.named("foo")));
       serve("/instance", "/instance/2").with(dummyServlet1);
-      serve("/class/keyvalues", "/class/keyvalues/2").with(
-          DummyServlet.class, ImmutableMap.of("key", "value"));
-      serve("/key/keyvalues", "/key/keyvalues/2").with(
-          Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
-      serve("/instance/keyvalues", "/instance/keyvalues/2").with(
-          dummyServlet2, ImmutableMap.of("key", "value"));
+      serve("/class/keyvalues", "/class/keyvalues/2")
+          .with(DummyServlet.class, ImmutableMap.of("key", "value"));
+      serve("/key/keyvalues", "/key/keyvalues/2")
+          .with(Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
+      serve("/instance/keyvalues", "/instance/keyvalues/2")
+          .with(dummyServlet2, ImmutableMap.of("key", "value"));
 
       serveRegex("/class[0-9]", "/class[0-9]/2").with(DummyServlet.class);
-      serveRegex("/key[0-9]", "/key[0-9]/2").with(
-          Key.get(DummyServlet.class, Names.named("foo")));
+      serveRegex("/key[0-9]", "/key[0-9]/2").with(Key.get(DummyServlet.class, Names.named("foo")));
       serveRegex("/instance[0-9]", "/instance[0-9]/2").with(dummyServlet3);
-      serveRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2").with(
-          DummyServlet.class, ImmutableMap.of("key", "value"));
-      serveRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2").with(
-          Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
-      serveRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2").with(
-          dummyServlet4, ImmutableMap.of("key", "value"));
+      serveRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2")
+          .with(DummyServlet.class, ImmutableMap.of("key", "value"));
+      serveRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2")
+          .with(Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
+      serveRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2")
+          .with(dummyServlet4, ImmutableMap.of("key", "value"));
     }
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java b/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
index 136a3cd..aa019c5 100644
--- a/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
@@ -12,14 +12,10 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.spi.BindingScopingVisitor;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -28,6 +24,7 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
  * Tests the lifecycle of the encapsulated {@link FilterDefinition} class.
@@ -43,22 +40,20 @@
 
     final MockFilter mockFilter = new MockFilter();
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(Filter.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding);
 
-    expect(injector.getInstance(Key.get(Filter.class)))
-        .andReturn(mockFilter)
-        .anyTimes();
+    expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
 
     replay(binding, injector);
 
     //some init params
     //noinspection SSBasedInspection
-    final Map<String, String> initParams = new ImmutableMap.Builder<String, String>()
-      .put("ahsd", "asdas24dok")
-      .put("ahssd", "asdasd124ok").build();
+    final Map<String, String> initParams =
+        new ImmutableMap.Builder<String, String>()
+            .put("ahsd", "asdas24dok")
+            .put("ahssd", "asdasd124ok")
+            .build();
 
     ServletContext servletContext = createMock(ServletContext.class);
     final String contextName = "thing__!@@44";
@@ -67,14 +62,18 @@
     replay(servletContext);
 
     String pattern = "/*";
-    final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
-        UriPatternType.get(UriPatternType.SERVLET, pattern), initParams, null);
+    final FilterDefinition filterDef =
+        new FilterDefinition(
+            Key.get(Filter.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            initParams,
+            null);
     filterDef.init(servletContext, injector, Sets.<Filter>newIdentityHashSet());
 
     assertTrue(filterDef.getFilter() instanceof MockFilter);
     final FilterConfig filterConfig = mockFilter.getConfig();
     assertTrue(null != filterConfig);
-    assertEquals(filterConfig.getServletContext().getServletContextName(), contextName);
+    assertEquals(contextName, filterConfig.getServletContext().getServletContextName());
     assertEquals(filterConfig.getFilterName(), Key.get(Filter.class).toString());
 
     final Enumeration names = filterConfig.getInitParameterNames();
@@ -95,26 +94,23 @@
 
     final MockFilter mockFilter = new MockFilter();
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(Filter.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding);
 
-    expect(injector.getInstance(Key.get(Filter.class)))
-        .andReturn(mockFilter)
-        .anyTimes();
+    expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
 
     expect(request.getRequestURI()).andReturn("/index.html");
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     replay(injector, binding, request);
 
     String pattern = "/*";
-    final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
-        UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final FilterDefinition filterDef =
+        new FilterDefinition(
+            Key.get(Filter.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
     //should fire on mockfilter now
     filterDef.init(createMock(ServletContext.class), injector, Sets.<Filter>newIdentityHashSet());
     assertTrue(filterDef.getFilter() instanceof MockFilter);
@@ -125,12 +121,15 @@
     assertSame(mockFilter, matchingFilter);
 
     final boolean proceed[] = new boolean[1];
-    matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
-      @Override
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
-        proceed[0] = true;
-      }
-    });
+    matchingFilter.doFilter(
+        request,
+        null,
+        new FilterChainInvocation(null, null, null) {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            proceed[0] = true;
+          }
+        });
 
     assertTrue("Filter did not proceed down chain", proceed[0]);
 
@@ -138,7 +137,6 @@
     assertTrue("Destroy did not fire", mockFilter.isDestroy());
 
     verify(injector, request);
-
   }
 
   public final void testFilterCreateDispatchDestroySupressChain()
@@ -148,51 +146,53 @@
     Binding binding = createMock(Binding.class);
     HttpServletRequest request = createMock(HttpServletRequest.class);
 
-    final MockFilter mockFilter = new MockFilter() {
-      @Override
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-          FilterChain filterChain) {
-        //suppress rest of chain...
-      }
-    };
+    final MockFilter mockFilter =
+        new MockFilter() {
+          @Override
+          public void doFilter(
+              ServletRequest servletRequest,
+              ServletResponse servletResponse,
+              FilterChain filterChain) {
+            //suppress rest of chain...
+          }
+        };
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(Filter.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding);
 
-    expect(injector.getInstance(Key.get(Filter.class)))
-        .andReturn(mockFilter)
-        .anyTimes();
+    expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
 
     expect(request.getRequestURI()).andReturn("/index.html");
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     replay(injector, binding, request);
 
     String pattern = "/*";
-    final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
-        UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final FilterDefinition filterDef =
+        new FilterDefinition(
+            Key.get(Filter.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
     //should fire on mockfilter now
     filterDef.init(createMock(ServletContext.class), injector, Sets.<Filter>newIdentityHashSet());
     assertTrue(filterDef.getFilter() instanceof MockFilter);
 
-
     assertTrue("init did not fire", mockFilter.isInit());
 
     Filter matchingFilter = filterDef.getFilterIfMatching(request);
     assertSame(mockFilter, matchingFilter);
 
     final boolean proceed[] = new boolean[1];
-    matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
-      @Override
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
-        proceed[0] = true;
-      }
-    });
+    matchingFilter.doFilter(
+        request,
+        null,
+        new FilterChainInvocation(null, null, null) {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            proceed[0] = true;
+          }
+        });
 
     assertFalse("filter did not suppress chain", proceed[0]);
 
@@ -200,33 +200,34 @@
     assertTrue("destroy did not fire", mockFilter.isDestroy());
 
     verify(injector, request);
-
   }
 
   public void testGetFilterIfMatching() throws ServletException {
     String pattern = "/*";
-    final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
-        UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final FilterDefinition filterDef =
+        new FilterDefinition(
+            Key.get(Filter.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
     HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
     ServletContext servletContext = createMock(ServletContext.class);
     Injector injector = createMock(Injector.class);
     Binding binding = createMock(Binding.class);
 
-    final MockFilter mockFilter = new MockFilter() {
-      @Override
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-          FilterChain filterChain) {
-        //suppress rest of chain...
-      }
-    };
-    expect(injector.getBinding(Key.get(Filter.class)))
-        .andReturn(binding);
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getInstance(Key.get(Filter.class)))
-        .andReturn(mockFilter)
-        .anyTimes();
+    final MockFilter mockFilter =
+        new MockFilter() {
+          @Override
+          public void doFilter(
+              ServletRequest servletRequest,
+              ServletResponse servletResponse,
+              FilterChain filterChain) {
+            //suppress rest of chain...
+          }
+        };
+    expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
 
     expect(servletRequest.getContextPath()).andReturn("/a_context_path");
     expect(servletRequest.getRequestURI()).andReturn("/a_context_path/test.html");
@@ -240,28 +241,30 @@
 
   public void testGetFilterIfMatchingNotMatching() throws ServletException {
     String pattern = "/*";
-    final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
-        UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final FilterDefinition filterDef =
+        new FilterDefinition(
+            Key.get(Filter.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
     HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
     ServletContext servletContext = createMock(ServletContext.class);
     Injector injector = createMock(Injector.class);
     Binding binding = createMock(Binding.class);
 
-    final MockFilter mockFilter = new MockFilter() {
-      @Override
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-          FilterChain filterChain) {
-        //suppress rest of chain...
-      }
-    };
-    expect(injector.getBinding(Key.get(Filter.class)))
-        .andReturn(binding);
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getInstance(Key.get(Filter.class)))
-        .andReturn(mockFilter)
-        .anyTimes();
+    final MockFilter mockFilter =
+        new MockFilter() {
+          @Override
+          public void doFilter(
+              ServletRequest servletRequest,
+              ServletResponse servletResponse,
+              FilterChain filterChain) {
+            //suppress rest of chain...
+          }
+        };
+    expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
 
     expect(servletRequest.getContextPath()).andReturn("/a_context_path");
     expect(servletRequest.getRequestURI()).andReturn("/test.html");
@@ -278,18 +281,22 @@
     private boolean destroy;
     private FilterConfig config;
 
+    @Override
     public void init(FilterConfig filterConfig) {
       init = true;
 
       this.config = filterConfig;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       //proceed
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroy = true;
     }
diff --git a/extensions/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
index 1d55ec1..634a6d9 100644
--- a/extensions/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,17 +26,10 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-import org.easymock.IMocksControl;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -46,18 +39,19 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
 
 /**
+ * This tests that filter stage of the pipeline dispatches correctly to guice-managed filters.
  *
- * This tests that filter stage of the pipeline dispatches
- * correctly to guice-managed filters.
- *
- * WARNING(dhanji): Non-parallelizable test =(
+ * <p>WARNING(dhanji): Non-parallelizable test =(
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public class FilterDispatchIntegrationTest extends TestCase {
-    private static int inits, doFilters, destroys;
+  private static int inits, doFilters, destroys;
 
   private IMocksControl control;
 
@@ -70,24 +64,25 @@
     GuiceFilter.reset();
   }
 
-
   public final void testDispatchRequestToManagedPipeline() throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(TestFilter.class);
-        filter("*.html").through(TestFilter.class);
-        filter("/*").through(Key.get(TestFilter.class));
+              @Override
+              protected void configureServlets() {
+                filter("/*").through(TestFilter.class);
+                filter("*.html").through(TestFilter.class);
+                filter("/*").through(Key.get(TestFilter.class));
 
-        // These filters should never fire
-        filter("/index/*").through(Key.get(TestFilter.class));
-        filter("*.jsp").through(Key.get(TestFilter.class));
+                // These filters should never fire
+                filter("/index/*").through(Key.get(TestFilter.class));
+                filter("*.jsp").through(Key.get(TestFilter.class));
 
-        // Bind a servlet
-        serve("*.html").with(TestServlet.class);
-      }
-    });
+                // Bind a servlet
+                serve("*.html").with(TestServlet.class);
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -95,20 +90,14 @@
     // create ourselves a mock request with test URI
     HttpServletRequest requestMock = control.createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index.html")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true);
     requestMock.removeAttribute(REQUEST_DISPATCHER_REQUEST);
 
     HttpServletResponse responseMock = control.createMock(HttpServletResponse.class);
-    expect(responseMock.isCommitted())
-        .andReturn(false)
-        .anyTimes();
+    expect(responseMock.isCommitted()).andReturn(false).anyTimes();
     responseMock.resetBuffer();
     expectLastCall().anyTimes();
 
@@ -125,25 +114,33 @@
     assertTrue(servlet.processedUris.contains("/index.html"));
     assertTrue(servlet.processedUris.contains(TestServlet.FORWARD_TO));
 
-    assertTrue("lifecycle states did not"
-        + " fire correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys, inits == 1 && doFilters == 3 && destroys == 1);
+    assertTrue(
+        "lifecycle states did not"
+            + " fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
+        inits == 1 && doFilters == 3 && destroys == 1);
   }
 
   public final void testDispatchThatNoFiltersFire() throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/public/*").through(TestFilter.class);
-        filter("*.html").through(TestFilter.class);
-        filter("*.xml").through(Key.get(TestFilter.class));
+              @Override
+              protected void configureServlets() {
+                filter("/public/*").through(TestFilter.class);
+                filter("*.html").through(TestFilter.class);
+                filter("*.xml").through(Key.get(TestFilter.class));
 
-        // These filters should never fire
-        filter("/index/*").through(Key.get(TestFilter.class));
-        filter("*.jsp").through(Key.get(TestFilter.class));
-      }
-    });
+                // These filters should never fire
+                filter("/index/*").through(Key.get(TestFilter.class));
+                filter("*.jsp").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -151,12 +148,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = control.createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index.xhtml")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.xhtml").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     FilterChain filterChain = control.createMock(FilterChain.class);
@@ -166,25 +159,32 @@
     pipeline.destroyPipeline();
     control.verify();
 
-    assertTrue("lifecycle states did not "
-        + "fire correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not "
+            + "fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 0 && destroys == 1);
   }
 
-  public final void testDispatchFilterPipelineWithRegexMatching() throws ServletException,
-      IOException {
+  public final void testDispatchFilterPipelineWithRegexMatching()
+      throws ServletException, IOException {
 
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filterRegex("/[A-Za-z]*").through(TestFilter.class);
-        filterRegex("/index").through(TestFilter.class);
-        //these filters should never fire
-        filterRegex("\\w").through(Key.get(TestFilter.class));
-      }
-    });
+              @Override
+              protected void configureServlets() {
+                filterRegex("/[A-Za-z]*").through(TestFilter.class);
+                filterRegex("/index").through(TestFilter.class);
+                //these filters should never fire
+                filterRegex("\\w").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -192,12 +192,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = control.createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     // dispatch request
     FilterChain filterChain = control.createMock(FilterChain.class);
@@ -207,44 +203,101 @@
     pipeline.destroyPipeline();
     control.verify();
 
-    assertTrue("lifecycle states did not fire "
-        + "correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire "
+            + "correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 2 && destroys == 1);
   }
 
   @Singleton
   public static class TestFilter implements Filter {
+    @Override
     public void init(FilterConfig filterConfig) {
       inits++;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       doFilters++;
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
   }
 
+  public final void testFilterBypass() throws ServletException, IOException {
+
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("/protected/*").through(TestFilter.class);
+              }
+            });
+
+    final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
+    pipeline.initPipeline(null);
+    assertEquals(1, inits);
+
+    runRequestForPath(pipeline, "/./protected/resource", true);
+    runRequestForPath(pipeline, "/protected/../resource", false);
+    runRequestForPath(pipeline, "/protected/../protected/resource", true);
+
+    assertEquals(0, destroys);
+    pipeline.destroyPipeline();
+    assertEquals(1, destroys);
+  }
+
+  private void runRequestForPath(FilterPipeline pipeline, String value, boolean matches)
+      throws IOException, ServletException {
+    assertEquals(0, doFilters);
+    //create ourselves a mock request with test URI
+    HttpServletRequest requestMock = control.createMock(HttpServletRequest.class);
+    expect(requestMock.getRequestURI()).andReturn(value).anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
+    // dispatch request
+    FilterChain filterChain = control.createMock(FilterChain.class);
+    filterChain.doFilter(requestMock, null);
+    control.replay();
+    pipeline.dispatch(requestMock, null, filterChain);
+    control.verify();
+    control.reset();
+    if (matches) {
+      assertEquals("filter was not run", 1, doFilters);
+      doFilters = 0;
+    } else {
+      assertEquals("filter was run", 0, doFilters);
+    }
+  }
+
   @Singleton
   public static class TestServlet extends HttpServlet {
     public static final String FORWARD_FROM = "/index.html";
     public static final String FORWARD_TO = "/forwarded.html";
-    public List<String> processedUris = new ArrayList<String>();
+    public List<String> processedUris = new ArrayList<>();
 
     @Override
-    protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
+    protected void service(
+        HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
         throws ServletException, IOException {
       String requestUri = httpServletRequest.getRequestURI();
       processedUris.add(requestUri);
 
       // If the client is requesting /index.html then we forward to /forwarded.html
       if (FORWARD_FROM.equals(requestUri)) {
-        httpServletRequest.getRequestDispatcher(FORWARD_TO)
+        httpServletRequest
+            .getRequestDispatcher(FORWARD_TO)
             .forward(httpServletRequest, httpServletResponse);
       }
     }
@@ -255,33 +308,36 @@
       service((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
     }
   }
-  
+
   public void testFilterOrder() throws Exception {
     AtomicInteger counter = new AtomicInteger();
     final CountFilter f1 = new CountFilter(counter);
     final CountFilter f2 = new CountFilter(counter);
-    
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        filter("/").through(f1);
-        install(new ServletModule() {
-          @Override
-          protected void configureServlets() {
-            filter("/").through(f2);
-          }
-        });
-      }
-    });
-    
-    HttpServletRequest request = newFakeHttpServletRequest();    
+
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("/").through(f1);
+                install(
+                    new ServletModule() {
+                      @Override
+                      protected void configureServlets() {
+                        filter("/").through(f2);
+                      }
+                    });
+              }
+            });
+
+    HttpServletRequest request = newFakeHttpServletRequest();
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
-    pipeline.initPipeline(null);    
+    pipeline.initPipeline(null);
     pipeline.dispatch(request, null, newNoOpFilterChain());
     assertEquals(0, f1.calledAt);
     assertEquals(1, f2.calledAt);
   }
-  
+
   /** A filter that keeps count of when it was called by increment a counter. */
   private static class CountFilter implements Filter {
     private final AtomicInteger counter;
@@ -290,10 +346,11 @@
     public CountFilter(AtomicInteger counter) {
       this.counter = counter;
     }
-    
-    public void destroy() {
-    }
-    
+
+    @Override
+    public void destroy() {}
+
+    @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
         throws ServletException, IOException {
       if (calledAt != -1) {
@@ -302,62 +359,69 @@
       calledAt = counter.getAndIncrement();
       chain.doFilter(request, response);
     }
-    
+
+    @Override
     public void init(FilterConfig filterConfig) {}
   }
-  
+
   public final void testFilterExceptionPrunesStack() throws Exception {
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        filter("/").through(TestFilter.class);
-        filter("/nothing").through(TestFilter.class);
-        filter("/").through(ThrowingFilter.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("/").through(TestFilter.class);
+                filter("/nothing").through(TestFilter.class);
+                filter("/").through(ThrowingFilter.class);
+              }
+            });
 
-    HttpServletRequest request = newFakeHttpServletRequest();    
+    HttpServletRequest request = newFakeHttpServletRequest();
     FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
-    pipeline.initPipeline(null);    
+    pipeline.initPipeline(null);
     try {
       pipeline.dispatch(request, null, null);
       fail("expected exception");
-    } catch(ServletException ex) {
+    } catch (ServletException ex) {
       for (StackTraceElement element : ex.getStackTrace()) {
         String className = element.getClassName();
-        assertTrue("was: " + element,
+        assertTrue(
+            "was: " + element,
             !className.equals(FilterChainInvocation.class.getName())
-            && !className.equals(FilterDefinition.class.getName()));
+                && !className.equals(FilterDefinition.class.getName()));
       }
     }
   }
-  
+
   public final void testServletExceptionPrunesStack() throws Exception {
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        filter("/").through(TestFilter.class);
-        filter("/nothing").through(TestFilter.class);
-        serve("/").with(ThrowingServlet.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("/").through(TestFilter.class);
+                filter("/nothing").through(TestFilter.class);
+                serve("/").with(ThrowingServlet.class);
+              }
+            });
 
-    HttpServletRequest request = newFakeHttpServletRequest();    
+    HttpServletRequest request = newFakeHttpServletRequest();
     FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
-    pipeline.initPipeline(null);    
+    pipeline.initPipeline(null);
     try {
       pipeline.dispatch(request, null, null);
       fail("expected exception");
-    } catch(ServletException ex) {
+    } catch (ServletException ex) {
       for (StackTraceElement element : ex.getStackTrace()) {
         String className = element.getClassName();
-        assertTrue("was: " + element,
+        assertTrue(
+            "was: " + element,
             !className.equals(FilterChainInvocation.class.getName())
-            && !className.equals(FilterDefinition.class.getName()));
+                && !className.equals(FilterDefinition.class.getName()));
       }
     }
   }
-  
+
   @Singleton
   private static class ThrowingServlet extends HttpServlet {
 
@@ -366,26 +430,20 @@
         throws ServletException {
       throw new ServletException("failure!");
     }
-    
   }
 
-
   @Singleton
   private static class ThrowingFilter implements Filter {
     @Override
-    public void destroy() {
-    }
-    
+    public void destroy() {}
+
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
         throws ServletException {
       throw new ServletException("we failed!");
     }
-    
-    @Override
-    public void init(FilterConfig filterConfig) {
 
-    }
-    
+    @Override
+    public void init(FilterConfig filterConfig) {}
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/FilterPipelineTest.java b/extensions/servlet/test/com/google/inject/servlet/FilterPipelineTest.java
index 06e3990..9ada4e6 100644
--- a/extensions/servlet/test/com/google/inject/servlet/FilterPipelineTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/FilterPipelineTest.java
@@ -11,11 +11,7 @@
 import com.google.inject.Guice;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -24,11 +20,12 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
- * This is a basic whitebox test that verifies the glue between
- * GuiceFilter and ManagedFilterPipeline is working.
- * 
+ * This is a basic whitebox test that verifies the glue between GuiceFilter and
+ * ManagedFilterPipeline is working.
+ *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public class FilterPipelineTest extends TestCase {
@@ -36,21 +33,22 @@
   @Override
   public final void setUp() {
     GuiceFilter.reset();
-    
-    Guice.createInjector(new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-          filter("/*").through(TestFilter.class);
-          filter("*.html").through(TestFilter.class);
-          filter("/*").through(Key.get(TestFilter.class));
-          filter("*.jsp").through(Key.get(TestFilter.class));
+    Guice.createInjector(
+        new ServletModule() {
 
-          // These filters should never fire
-          filter("/index/*").through(Key.get(NeverFilter.class));
-          filter("/public/login/*").through(Key.get(NeverFilter.class));
-      }
-    });
+          @Override
+          protected void configureServlets() {
+            filter("/*").through(TestFilter.class);
+            filter("*.html").through(TestFilter.class);
+            filter("/*").through(Key.get(TestFilter.class));
+            filter("*.jsp").through(Key.get(TestFilter.class));
+
+            // These filters should never fire
+            filter("/index/*").through(Key.get(NeverFilter.class));
+            filter("/public/login/*").through(Key.get(NeverFilter.class));
+          }
+        });
   }
 
   @Override
@@ -68,16 +66,10 @@
 
     //begin mock script ***
 
-    expect(filterConfig.getServletContext())
-        .andReturn(servletContext)
-        .once();
+    expect(filterConfig.getServletContext()).andReturn(servletContext).once();
 
-    expect(request.getRequestURI())
-        .andReturn("/public/login.jsp")
-        .anyTimes();
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getRequestURI()).andReturn("/public/login.jsp").anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     //at the end, proceed down webapp's normal filter chain
     proceedingFilterChain.doFilter(isA(HttpServletRequest.class), (ServletResponse) isNull());
@@ -98,29 +90,32 @@
 
   @Singleton
   public static class TestFilter implements Filter {
-    public void init(FilterConfig filterConfig) {
-    }
+    @Override
+    public void init(FilterConfig filterConfig) {}
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
-    public void destroy() {
-    }
+    @Override
+    public void destroy() {}
   }
 
   @Singleton
   public static class NeverFilter implements Filter {
-    public void init(FilterConfig filterConfig) {
-    }
+    @Override
+    public void init(FilterConfig filterConfig) {}
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
       fail("This filter should never have fired");
     }
 
-    public void destroy() {
-    }
+    @Override
+    public void destroy() {}
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/InjectedFilterPipelineTest.java b/extensions/servlet/test/com/google/inject/servlet/InjectedFilterPipelineTest.java
index 020f277..bfeafc5 100644
--- a/extensions/servlet/test/com/google/inject/servlet/InjectedFilterPipelineTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/InjectedFilterPipelineTest.java
@@ -13,11 +13,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -26,10 +22,11 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
- * Exactly the same as {@linkplain com.google.inject.servlet.FilterPipelineTest} except
- * that we test that the static pipeline is not used.
+ * Exactly the same as {@linkplain com.google.inject.servlet.FilterPipelineTest} except that we test
+ * that the static pipeline is not used.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
@@ -39,40 +36,43 @@
 
   @Override
   public final void setUp() {
-    injector1 = Guice.createInjector(new ServletModule() {
+    injector1 =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-          filter("/*").through(TestFilter.class);
-          filter("*.html").through(TestFilter.class);
-          filter("/*").through(Key.get(TestFilter.class));
-          filter("*.jsp").through(Key.get(TestFilter.class));
+              @Override
+              protected void configureServlets() {
+                filter("/*").through(TestFilter.class);
+                filter("*.html").through(TestFilter.class);
+                filter("/*").through(Key.get(TestFilter.class));
+                filter("*.jsp").through(Key.get(TestFilter.class));
 
-          // These filters should never fire
-          filter("/index/*").through(Key.get(NeverFilter.class));
-          filter("/public/login/*").through(Key.get(NeverFilter.class));
-      }
-    });
+                // These filters should never fire
+                filter("/index/*").through(Key.get(NeverFilter.class));
+                filter("/public/login/*").through(Key.get(NeverFilter.class));
+              }
+            });
 
     // Test second injector with exactly opposite pipeline config
-    injector2 = Guice.createInjector(new ServletModule() {
+    injector2 =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-          // These filters should never fire
-          filter("*.html").through(NeverFilter.class);
-          filter("/non-jsp/*").through(Key.get(NeverFilter.class));
+              @Override
+              protected void configureServlets() {
+                // These filters should never fire
+                filter("*.html").through(NeverFilter.class);
+                filter("/non-jsp/*").through(Key.get(NeverFilter.class));
 
-          // only these filters fire.
-          filter("/index/*").through(Key.get(TestFilter.class));
-          filter("/public/login/*").through(Key.get(TestFilter.class));
-      }
-    });
+                // only these filters fire.
+                filter("/index/*").through(Key.get(TestFilter.class));
+                filter("/public/login/*").through(Key.get(TestFilter.class));
+              }
+            });
   }
 
   @Override
-  public final void tearDown() {
-  }
+  public final void tearDown() {}
 
   public final void testDispatchThruInjectedGuiceFilter() throws ServletException, IOException {
 
@@ -84,16 +84,12 @@
 
     //begin mock script ***
 
-    expect(filterConfig.getServletContext())
-        .andReturn(servletContext)
-        .once();
+    expect(filterConfig.getServletContext()).andReturn(servletContext).once();
 
     expect(request.getRequestURI())
         .andReturn("/non-jsp/login.html") // use a path that will fail in injector2
         .anyTimes();
-    expect(request.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     //at the end, proceed down webapp's normal filter chain
     proceedingFilterChain.doFilter(isA(HttpServletRequest.class), (ServletResponse) isNull());
@@ -111,11 +107,6 @@
     //assert expectations
     verify(filterConfig, servletContext, request, proceedingFilterChain);
 
-
-
-
-
-
     // reset mocks and run them against the other injector
     reset(filterConfig, servletContext, request, proceedingFilterChain);
 
@@ -124,15 +115,11 @@
 
     //begin mock script ***
 
-    expect(filterConfig.getServletContext())
-        .andReturn(servletContext)
-        .once();
+    expect(filterConfig.getServletContext()).andReturn(servletContext).once();
     expect(request.getRequestURI())
-            .andReturn("/public/login/login.jsp") // use a path that will fail in injector1
-            .anyTimes();
-    expect(request.getContextPath())
-        .andReturn("")
+        .andReturn("/public/login/login.jsp") // use a path that will fail in injector1
         .anyTimes();
+    expect(request.getContextPath()).andReturn("").anyTimes();
 
     //at the end, proceed down webapp's normal filter chain
     proceedingFilterChain2.doFilter(isA(HttpServletRequest.class), (ServletResponse) isNull());
@@ -153,29 +140,33 @@
 
   @Singleton
   public static class TestFilter implements Filter {
-    public void init(FilterConfig filterConfig) throws ServletException {
-    }
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {}
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
-    public void destroy() {
-    }
+    @Override
+    public void destroy() {}
   }
 
   @Singleton
   public static class NeverFilter implements Filter {
-    public void init(FilterConfig filterConfig) throws ServletException {
-    }
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {}
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       fail("This filter should never have fired");
     }
 
-    public void destroy() {
-    }
+    @Override
+    public void destroy() {}
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java b/extensions/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java
index 689e3e8..79342ce 100644
--- a/extensions/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java
@@ -5,16 +5,14 @@
 import com.google.inject.Guice;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
+import junit.framework.TestCase;
 
 /**
- * Ensures that an error is thrown if a Servlet or Filter is bound
- * under any scope other than singleton, explicitly.
+ * Ensures that an error is thrown if a Servlet or Filter is bound under any scope other than
+ * singleton, explicitly.
  *
  * @author dhanji@gmail.com
  */
@@ -25,15 +23,16 @@
     GuiceFilter.reset();
   }
 
-  public final void testServletInNonSingletonScopeThrowsServletException(){
+  public final void testServletInNonSingletonScopeThrowsServletException() {
     GuiceFilter guiceFilter = new GuiceFilter();
 
-    Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        serve("/*").with(MyNonSingletonServlet.class);
-      }
-    });
+    Guice.createInjector(
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            serve("/*").with(MyNonSingletonServlet.class);
+          }
+        });
 
     ServletException se = null;
     try {
@@ -45,15 +44,16 @@
     }
   }
 
-  public final void testFilterInNonSingletonScopeThrowsServletException(){
+  public final void testFilterInNonSingletonScopeThrowsServletException() {
     GuiceFilter guiceFilter = new GuiceFilter();
 
-    Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(MyNonSingletonFilter.class);
-      }
-    });
+    Guice.createInjector(
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            filter("/*").through(MyNonSingletonFilter.class);
+          }
+        });
 
     ServletException se = null;
     try {
@@ -65,20 +65,21 @@
     }
   }
 
-  public final void testHappyCaseFilter(){
+  public final void testHappyCaseFilter() {
     GuiceFilter guiceFilter = new GuiceFilter();
 
-    Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        // Annotated scoping variant.
-        filter("/*").through(MySingletonFilter.class);
+    Guice.createInjector(
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            // Annotated scoping variant.
+            filter("/*").through(MySingletonFilter.class);
 
-        // Explicit scoping variant.
-        bind(DummyFilterImpl.class).in(Scopes.SINGLETON);
-        filter("/*").through(DummyFilterImpl.class);
-      }
-    });
+            // Explicit scoping variant.
+            bind(DummyFilterImpl.class).in(Scopes.SINGLETON);
+            filter("/*").through(DummyFilterImpl.class);
+          }
+        });
 
     ServletException se = null;
     try {
@@ -91,11 +92,11 @@
   }
 
   @RequestScoped
-  public static class MyNonSingletonServlet extends HttpServlet { }
+  public static class MyNonSingletonServlet extends HttpServlet {}
 
   @SessionScoped
-  public static class MyNonSingletonFilter extends DummyFilterImpl { }
+  public static class MyNonSingletonFilter extends DummyFilterImpl {}
 
   @Singleton
-  public static class MySingletonFilter extends DummyFilterImpl { }
+  public static class MySingletonFilter extends DummyFilterImpl {}
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
index 5fc285b..f8db290 100644
--- a/extensions/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
@@ -9,11 +9,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -21,18 +17,18 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
+ * This tests that filter stage of the pipeline dispatches correctly to guice-managed filters with
+ * multiple modules.
  *
- * This tests that filter stage of the pipeline dispatches
- * correctly to guice-managed filters with multiple modules.
- *
- * WARNING(dhanji): Non-parallelizable test =(
+ * <p>WARNING(dhanji): Non-parallelizable test =(
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public class MultiModuleDispatchIntegrationTest extends TestCase {
-    private static int inits, doFilters, destroys;
+  private static int inits, doFilters, destroys;
 
   @Override
   public final void setUp() {
@@ -43,30 +39,30 @@
     GuiceFilter.reset();
   }
 
-
   public final void testDispatchRequestToManagedPipeline() throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filter("/*").through(TestFilter.class);
 
-        // These filters should never fire
-        filter("*.jsp").through(Key.get(TestFilter.class));
-      }
+                // These filters should never fire
+                filter("*.jsp").through(Key.get(TestFilter.class));
+              }
+            },
+            new ServletModule() {
 
-    }, new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("*.html").through(TestFilter.class);
+                filter("/*").through(Key.get(TestFilter.class));
 
-      @Override
-      protected void configureServlets() {
-        filter("*.html").through(TestFilter.class);
-        filter("/*").through(Key.get(TestFilter.class));
-
-        // These filters should never fire
-        filter("/index/*").through(Key.get(TestFilter.class));
-      }
-
-    });
+                // These filters should never fire
+                filter("/index/*").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -74,12 +70,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index.html")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -88,24 +80,33 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not"
-        + " fire correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not"
+            + " fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 3 && destroys == 1);
   }
 
   @Singleton
   public static class TestFilter implements Filter {
+    @Override
     public void init(FilterConfig filterConfig) throws ServletException {
       inits++;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       doFilters++;
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
diff --git a/extensions/servlet/test/com/google/inject/servlet/MultipleServletInjectorsTest.java b/extensions/servlet/test/com/google/inject/servlet/MultipleServletInjectorsTest.java
index 96dd51b..2e4c061 100644
--- a/extensions/servlet/test/com/google/inject/servlet/MultipleServletInjectorsTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/MultipleServletInjectorsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,16 +25,13 @@
 
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
-import junit.framework.TestCase;
-
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.http.HttpServlet;
+import junit.framework.TestCase;
 
 /**
- * This gorgeous test asserts that multiple servlet pipelines can
- * run in the SAME JVM. booya.
+ * This gorgeous test asserts that multiple servlet pipelines can run in the SAME JVM. booya.
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
@@ -61,14 +58,16 @@
       @Override
       protected Injector getInjector() {
         // Cache this injector in the test for later testing...
-        return injectorOne = Guice.createInjector(new ServletModule() {
+        return injectorOne =
+            Guice.createInjector(
+                new ServletModule() {
 
-          @Override
-          protected void configureServlets() {
-            // This creates a ManagedFilterPipeline internally...
-            serve("/*").with(DummyServlet.class);
-          }
-        });
+                  @Override
+                  protected void configureServlets() {
+                    // This creates a ManagedFilterPipeline internally...
+                    serve("/*").with(DummyServlet.class);
+                  }
+                });
       }
     }.contextInitialized(new ServletContextEvent(fakeContextOne));
 
@@ -81,16 +80,18 @@
 
       @Override
       protected Injector getInjector() {
-        return injectorTwo = Guice.createInjector(new ServletModule() {
+        return injectorTwo =
+            Guice.createInjector(
+                new ServletModule() {
 
-          @Override
-          protected void configureServlets() {
-            // This creates a ManagedFilterPipeline internally...
-            filter("/8").through(DummyFilterImpl.class);
+                  @Override
+                  protected void configureServlets() {
+                    // This creates a ManagedFilterPipeline internally...
+                    filter("/8").through(DummyFilterImpl.class);
 
-            serve("/*").with(HttpServlet.class);
-          }
-        });
+                    serve("/*").with(HttpServlet.class);
+                  }
+                });
       }
     }.contextInitialized(new ServletContextEvent(fakeContextTwo));
 
diff --git a/extensions/servlet/test/com/google/inject/servlet/ScopeRequestIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/ScopeRequestIntegrationTest.java
index 9a4d0d4..672f053 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ScopeRequestIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ScopeRequestIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,9 +28,6 @@
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -38,12 +35,10 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
-
 import javax.servlet.ServletException;
+import junit.framework.TestCase;
 
-/**
- * Tests continuation of requests
- */
+/** Tests continuation of requests */
 
 public class ScopeRequestIntegrationTest extends TestCase {
   private static final String A_VALUE = "thereaoskdao";
@@ -57,17 +52,24 @@
 
     // We use servlet module here because we want to test that @RequestScoped
     // behaves properly with the non-HTTP request scope logic.
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
-        bind(SomeObject.class).in(RequestScoped.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
+                bind(SomeObject.class).in(RequestScoped.class);
+              }
+            });
 
     SomeObject someObject = new SomeObject(A_VALUE);
     OffRequestCallable offRequestCallable = injector.getInstance(OffRequestCallable.class);
-    executor.submit(ServletScopes.scopeRequest(offRequestCallable,
-        ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject))).get();
+    executor
+        .submit(
+            ServletScopes.scopeRequest(
+                offRequestCallable,
+                ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject)))
+        .get();
 
     assertSame(injector.getInstance(OffRequestCallable.class), offRequestCallable);
 
@@ -77,8 +79,12 @@
 
     // Now create a new request and assert that the scopes don't cross.
     someObject = new SomeObject(A_DIFFERENT_VALUE);
-    executor.submit(ServletScopes.scopeRequest(offRequestCallable,
-        ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject))).get();
+    executor
+        .submit(
+            ServletScopes.scopeRequest(
+                offRequestCallable,
+                ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), someObject)))
+        .get();
 
     assertSame(injector.getInstance(OffRequestCallable.class), offRequestCallable);
 
@@ -90,36 +96,46 @@
   }
 
   public final void testWrongValueClasses() throws Exception {
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
-        bind(SomeObject.class).in(RequestScoped.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
+                bind(SomeObject.class).in(RequestScoped.class);
+              }
+            });
 
     OffRequestCallable offRequestCallable = injector.getInstance(OffRequestCallable.class);
     try {
-      ServletScopes.scopeRequest(offRequestCallable,
-        ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), "Boo!"));
+      ServletScopes.scopeRequest(
+          offRequestCallable, ImmutableMap.<Key<?>, Object>of(Key.get(SomeObject.class), "Boo!"));
       fail();
-    } catch(IllegalArgumentException iae) {
-      assertEquals("Value[Boo!] of type[java.lang.String] is not compatible with key[" + Key.get(SomeObject.class) + "]", iae.getMessage());
+    } catch (IllegalArgumentException iae) {
+      assertEquals(
+          "Value[Boo!] of type[java.lang.String] is not compatible with key["
+              + Key.get(SomeObject.class)
+              + "]",
+          iae.getMessage());
     }
   }
 
   public final void testNullReplacement() throws Exception {
-    Injector injector = Guice.createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
-        bind(SomeObject.class).in(RequestScoped.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                bindConstant().annotatedWith(Names.named(SomeObject.INVALID)).to(SHOULDNEVERBESEEN);
+                bind(SomeObject.class).in(RequestScoped.class);
+              }
+            });
 
     Callable<SomeObject> callable = injector.getInstance(Caller.class);
     try {
       assertNotNull(callable.call());
       fail();
-    } catch(ProvisionException pe) {
+    } catch (ProvisionException pe) {
       assertTrue(pe.getCause() instanceof OutOfScopeException);
     }
 
@@ -138,6 +154,7 @@
     public SomeObject(@Named(INVALID) String value) {
       this.value = value;
     }
+
     private final String value;
   }
 
@@ -147,6 +164,7 @@
 
     public String value;
 
+    @Override
     public String call() throws Exception {
       // Inside this request, we should always get the same instance.
       assertSame(someObject.get(), someObject.get());
@@ -161,6 +179,7 @@
   private static class Caller implements Callable<SomeObject> {
     @Inject Provider<SomeObject> someObject;
 
+    @Override
     public SomeObject call() throws Exception {
       return someObject.get();
     }
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
index c89834f..eef8c9f 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,20 +28,16 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.spi.BindingScopingVisitor;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.HashMap;
-
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
 
 /**
- * Ensures servlet spec compliance for CGI-style variables and general
- *  path/pattern matching.
+ * Ensures servlet spec compliance for CGI-style variables and general path/pattern matching.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail com)
  */
@@ -61,86 +57,8 @@
     servletPath("/thing/wing/index.html", "/thing/*", "/thing");
   }
 
-  private void servletPath(final String requestPath, String mapping,
-      final String expectedServletPath) throws IOException, ServletException {
-
-    Injector injector = createMock(Injector.class);
-    Binding binding = createMock(Binding.class);
-    HttpServletRequest request = createMock(HttpServletRequest.class);
-    HttpServletResponse response = createMock(HttpServletResponse.class);
-
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
-
-    final boolean[] run = new boolean[1];
-    //get an instance of this servlet
-    expect(injector.getInstance(Key.get(HttpServlet.class)))
-        .andReturn(new HttpServlet() {
-
-          @Override
-          protected void service(HttpServletRequest servletRequest,
-              HttpServletResponse httpServletResponse) throws ServletException, IOException {
-
-            final String path = servletRequest.getServletPath();
-            assertEquals(String.format("expected [%s] but was [%s]", expectedServletPath, path),
-                expectedServletPath, path);
-            run[0] = true;
-          }
-        });
-
-    expect(request.getServletPath())
-        .andReturn(requestPath);
-
-    replay(injector, binding, request);
-
-    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
-        UriPatternType.get(UriPatternType.SERVLET, mapping), new HashMap<String, String>(), null);
-
-    servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
-    servletDefinition.doService(request, response);
-
-    assertTrue("Servlet did not run!", run[0]);
-    
-    verify(injector, binding, request);
-
-  }
-
-  // Data-driven test.
-  public final void testPathInfoWithServletStyleMatching() throws IOException, ServletException {
-    pathInfoWithServletStyleMatching("/path/index.html", "/path", "/*", "/index.html", "");
-    pathInfoWithServletStyleMatching("/path//hulaboo///index.html", "/path", "/*",
-        "/hulaboo/index.html", "");
-    pathInfoWithServletStyleMatching("/path/", "/path", "/*", "/", "");
-    pathInfoWithServletStyleMatching("/path////////", "/path", "/*", "/", "");
-
-    // a servlet mapping of /thing/*
-    pathInfoWithServletStyleMatching("/path/thing////////", "/path", "/thing/*", "/", "/thing");
-    pathInfoWithServletStyleMatching("/path/thing/stuff", "/path", "/thing/*", "/stuff", "/thing");
-    pathInfoWithServletStyleMatching("/path/thing/stuff.html", "/path", "/thing/*", "/stuff.html",
-        "/thing");
-    pathInfoWithServletStyleMatching("/path/thing", "/path", "/thing/*", null, "/thing");
-
-    // see external issue 372
-    pathInfoWithServletStyleMatching("/path/some/path/of.jsp", "/path", "/thing/*",
-        null, "/some/path/of.jsp");
-
-    // *.xx style mapping
-    pathInfoWithServletStyleMatching("/path/thing.thing", "/path", "*.thing", null, "/thing.thing");
-    pathInfoWithServletStyleMatching("/path///h.thing", "/path", "*.thing", null, "/h.thing");
-    pathInfoWithServletStyleMatching("/path///...//h.thing", "/path", "*.thing", null,
-        "/.../h.thing");
-    pathInfoWithServletStyleMatching("/path/my/h.thing", "/path", "*.thing", null, "/my/h.thing");
-
-    // Encoded URLs
-    pathInfoWithServletStyleMatching("/path/index%2B.html", "/path", "/*", "/index+.html", "");
-    pathInfoWithServletStyleMatching("/path/a%20file%20with%20spaces%20in%20name.html", "/path", "/*", "/a file with spaces in name.html", "");
-    pathInfoWithServletStyleMatching("/path/Tam%C3%A1s%20nem%20m%C3%A1s.html", "/path", "/*", "/Tamás nem más.html", "");
-  }
-
-  private void pathInfoWithServletStyleMatching(final String requestUri, final String contextPath,
-      String mapping, final String expectedPathInfo, final String servletPath)
+  private void servletPath(
+      final String requestPath, String mapping, final String expectedServletPath)
       throws IOException, ServletException {
 
     Injector injector = createMock(Injector.class);
@@ -148,55 +66,146 @@
     HttpServletRequest request = createMock(HttpServletRequest.class);
     HttpServletResponse response = createMock(HttpServletResponse.class);
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
 
     final boolean[] run = new boolean[1];
     //get an instance of this servlet
     expect(injector.getInstance(Key.get(HttpServlet.class)))
-        .andReturn(new HttpServlet() {
+        .andReturn(
+            new HttpServlet() {
 
-          @Override
-          protected void service(HttpServletRequest servletRequest,
-              HttpServletResponse httpServletResponse) throws ServletException, IOException {
+              @Override
+              protected void service(
+                  HttpServletRequest servletRequest, HttpServletResponse httpServletResponse)
+                  throws ServletException, IOException {
 
-            final String path = servletRequest.getPathInfo();
+                final String path = servletRequest.getServletPath();
+                assertEquals(
+                    String.format("expected [%s] but was [%s]", expectedServletPath, path),
+                    expectedServletPath,
+                    path);
+                run[0] = true;
+              }
+            });
 
-            if (null == expectedPathInfo) {
-              assertNull(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
-                  path);
-            }
-            else {
-              assertEquals(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
-                  expectedPathInfo, path);
-            }
+    expect(request.getServletPath()).andReturn(requestPath);
 
-            //assert memoizer
-            //noinspection StringEquality
-            assertSame("memo field did not work", path, servletRequest.getPathInfo());
+    replay(injector, binding, request);
 
-            run[0] = true;
-          }
-        });
+    ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, mapping),
+            new HashMap<String, String>(),
+            null);
 
-    expect(request.getRequestURI())
-        .andReturn(requestUri);
+    servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
+    servletDefinition.doService(request, response);
 
-    expect(request.getServletPath())
-        .andReturn(servletPath)
-        .anyTimes();
+    assertTrue("Servlet did not run!", run[0]);
 
-    expect(request.getContextPath())
-        .andReturn(contextPath);
+    verify(injector, binding, request);
+  }
+
+  // Data-driven test.
+  public final void testPathInfoWithServletStyleMatching() throws IOException, ServletException {
+    pathInfoWithServletStyleMatching("/path/index.html", "/path", "/*", "/index.html", "");
+    pathInfoWithServletStyleMatching(
+        "/path//hulaboo///index.html", "/path", "/*", "/hulaboo/index.html", "");
+    pathInfoWithServletStyleMatching("/path/", "/path", "/*", "/", "");
+    pathInfoWithServletStyleMatching("/path////////", "/path", "/*", "/", "");
+
+    // a servlet mapping of /thing/*
+    pathInfoWithServletStyleMatching("/path/thing////////", "/path", "/thing/*", "/", "/thing");
+    pathInfoWithServletStyleMatching("/path/thing/stuff", "/path", "/thing/*", "/stuff", "/thing");
+    pathInfoWithServletStyleMatching(
+        "/path/thing/stuff.html", "/path", "/thing/*", "/stuff.html", "/thing");
+    pathInfoWithServletStyleMatching("/path/thing", "/path", "/thing/*", null, "/thing");
+
+    // see external issue 372
+    pathInfoWithServletStyleMatching(
+        "/path/some/path/of.jsp", "/path", "/thing/*", null, "/some/path/of.jsp");
+
+    // *.xx style mapping
+    pathInfoWithServletStyleMatching("/path/thing.thing", "/path", "*.thing", null, "/thing.thing");
+    pathInfoWithServletStyleMatching("/path///h.thing", "/path", "*.thing", null, "/h.thing");
+    pathInfoWithServletStyleMatching(
+        "/path///...//h.thing", "/path", "*.thing", null, "/.../h.thing");
+    pathInfoWithServletStyleMatching("/path/my/h.thing", "/path", "*.thing", null, "/my/h.thing");
+
+    // Encoded URLs
+    pathInfoWithServletStyleMatching("/path/index%2B.html", "/path", "/*", "/index+.html", "");
+    pathInfoWithServletStyleMatching(
+        "/path/a%20file%20with%20spaces%20in%20name.html",
+        "/path", "/*", "/a file with spaces in name.html", "");
+    pathInfoWithServletStyleMatching(
+        "/path/Tam%C3%A1s%20nem%20m%C3%A1s.html", "/path", "/*", "/Tamás nem más.html", "");
+  }
+
+  private void pathInfoWithServletStyleMatching(
+      final String requestUri,
+      final String contextPath,
+      String mapping,
+      final String expectedPathInfo,
+      final String servletPath)
+      throws IOException, ServletException {
+
+    Injector injector = createMock(Injector.class);
+    Binding binding = createMock(Binding.class);
+    HttpServletRequest request = createMock(HttpServletRequest.class);
+    HttpServletResponse response = createMock(HttpServletResponse.class);
+
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
+
+    final boolean[] run = new boolean[1];
+    //get an instance of this servlet
+    expect(injector.getInstance(Key.get(HttpServlet.class)))
+        .andReturn(
+            new HttpServlet() {
+
+              @Override
+              protected void service(
+                  HttpServletRequest servletRequest, HttpServletResponse httpServletResponse)
+                  throws ServletException, IOException {
+
+                final String path = servletRequest.getPathInfo();
+
+                if (null == expectedPathInfo) {
+                  assertNull(
+                      String.format("expected [%s] but was [%s]", expectedPathInfo, path), path);
+                } else {
+                  assertEquals(
+                      String.format("expected [%s] but was [%s]", expectedPathInfo, path),
+                      expectedPathInfo,
+                      path);
+                }
+
+                //assert memoizer
+                //noinspection StringEquality
+                assertSame("memo field did not work", path, servletRequest.getPathInfo());
+
+                run[0] = true;
+              }
+            });
+
+    expect(request.getRequestURI()).andReturn(requestUri);
+
+    expect(request.getServletPath()).andReturn(servletPath).anyTimes();
+
+    expect(request.getContextPath()).andReturn(contextPath);
 
     expect(request.getAttribute(REQUEST_DISPATCHER_REQUEST)).andReturn(null);
 
     replay(injector, binding, request);
 
-    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
-        UriPatternType.get(UriPatternType.SERVLET, mapping), new HashMap<String, String>(), null);
+    ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, mapping),
+            new HashMap<String, String>(),
+            null);
 
     servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
     servletDefinition.doService(request, response);
@@ -210,37 +219,47 @@
   public final void testPathInfoWithRegexMatching() throws IOException, ServletException {
     // first a mapping of /*
     pathInfoWithRegexMatching("/path/index.html", "/path", "/(.)*", "/index.html", "");
-    pathInfoWithRegexMatching("/path//hulaboo///index.html", "/path", "/(.)*",
-        "/hulaboo/index.html", "");
+    pathInfoWithRegexMatching(
+        "/path//hulaboo///index.html", "/path", "/(.)*", "/hulaboo/index.html", "");
     pathInfoWithRegexMatching("/path/", "/path", "/(.)*", "/", "");
     pathInfoWithRegexMatching("/path////////", "/path", "/(.)*", "/", "");
 
     // a servlet mapping of /thing/*
     pathInfoWithRegexMatching("/path/thing////////", "/path", "/thing/(.)*", "/", "/thing");
     pathInfoWithRegexMatching("/path/thing/stuff", "/path", "/thing/(.)*", "/stuff", "/thing");
-    pathInfoWithRegexMatching("/path/thing/stuff.html", "/path", "/thing/(.)*", "/stuff.html",
-        "/thing");
+    pathInfoWithRegexMatching(
+        "/path/thing/stuff.html", "/path", "/thing/(.)*", "/stuff.html", "/thing");
     pathInfoWithRegexMatching("/path/thing", "/path", "/thing/(.)*", null, "/thing");
 
     // *.xx style mapping
     pathInfoWithRegexMatching("/path/thing.thing", "/path", ".*\\.thing", null, "/thing.thing");
     pathInfoWithRegexMatching("/path///h.thing", "/path", ".*\\.thing", null, "/h.thing");
-    pathInfoWithRegexMatching("/path///...//h.thing", "/path", ".*\\.thing", null,
-        "/.../h.thing");
+    pathInfoWithRegexMatching("/path///...//h.thing", "/path", ".*\\.thing", null, "/.../h.thing");
     pathInfoWithRegexMatching("/path/my/h.thing", "/path", ".*\\.thing", null, "/my/h.thing");
 
     // path
-    pathInfoWithRegexMatching("/path/test.com/com.test.MyServletModule", "", "/path/[^/]+/(.*)",
-        "com.test.MyServletModule", "/path/test.com/com.test.MyServletModule");
+    pathInfoWithRegexMatching(
+        "/path/test.com/com.test.MyServletModule",
+        "",
+        "/path/[^/]+/(.*)",
+        "com.test.MyServletModule",
+        "/path/test.com/com.test.MyServletModule");
 
     // Encoded URLs
     pathInfoWithRegexMatching("/path/index%2B.html", "/path", "/(.)*", "/index+.html", "");
-    pathInfoWithRegexMatching("/path/a%20file%20with%20spaces%20in%20name.html", "/path", "/(.)*", "/a file with spaces in name.html", "");
-    pathInfoWithRegexMatching("/path/Tam%C3%A1s%20nem%20m%C3%A1s.html", "/path", "/(.)*", "/Tamás nem más.html", "");
+    pathInfoWithRegexMatching(
+        "/path/a%20file%20with%20spaces%20in%20name.html",
+        "/path", "/(.)*", "/a file with spaces in name.html", "");
+    pathInfoWithRegexMatching(
+        "/path/Tam%C3%A1s%20nem%20m%C3%A1s.html", "/path", "/(.)*", "/Tamás nem más.html", "");
   }
 
-  public final void pathInfoWithRegexMatching(final String requestUri, final String contextPath,
-      String mapping, final String expectedPathInfo, final String servletPath)
+  public final void pathInfoWithRegexMatching(
+      final String requestUri,
+      final String contextPath,
+      String mapping,
+      final String expectedPathInfo,
+      final String servletPath)
       throws IOException, ServletException {
 
     Injector injector = createMock(Injector.class);
@@ -248,61 +267,62 @@
     HttpServletRequest request = createMock(HttpServletRequest.class);
     HttpServletResponse response = createMock(HttpServletResponse.class);
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
 
     final boolean[] run = new boolean[1];
     //get an instance of this servlet
     expect(injector.getInstance(Key.get(HttpServlet.class)))
-        .andReturn(new HttpServlet() {
+        .andReturn(
+            new HttpServlet() {
 
-          @Override
-          protected void service(HttpServletRequest servletRequest,
-              HttpServletResponse httpServletResponse) throws ServletException, IOException {
+              @Override
+              protected void service(
+                  HttpServletRequest servletRequest, HttpServletResponse httpServletResponse)
+                  throws ServletException, IOException {
 
-            final String path = servletRequest.getPathInfo();
+                final String path = servletRequest.getPathInfo();
 
-            if (null == expectedPathInfo) {
-              assertNull(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
-                  path);
-            }
-            else {
-              assertEquals(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
-                  expectedPathInfo, path);
-            }
+                if (null == expectedPathInfo) {
+                  assertNull(
+                      String.format("expected [%s] but was [%s]", expectedPathInfo, path), path);
+                } else {
+                  assertEquals(
+                      String.format("expected [%s] but was [%s]", expectedPathInfo, path),
+                      expectedPathInfo,
+                      path);
+                }
 
-            //assert memoizer
-            //noinspection StringEquality
-            assertSame("memo field did not work", path, servletRequest.getPathInfo());
+                //assert memoizer
+                //noinspection StringEquality
+                assertSame("memo field did not work", path, servletRequest.getPathInfo());
 
-            run[0] = true;
-          }
-        });
+                run[0] = true;
+              }
+            });
 
-    expect(request.getRequestURI())
-        .andReturn(requestUri);
+    expect(request.getRequestURI()).andReturn(requestUri);
 
-    expect(request.getServletPath())
-        .andReturn(servletPath)
-        .anyTimes();
+    expect(request.getServletPath()).andReturn(servletPath).anyTimes();
 
-    expect(request.getContextPath())
-        .andReturn(contextPath);
+    expect(request.getContextPath()).andReturn(contextPath);
 
     expect(request.getAttribute(REQUEST_DISPATCHER_REQUEST)).andReturn(null);
 
     replay(injector, binding, request);
 
-    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
-        UriPatternType.get(UriPatternType.REGEX, mapping), new HashMap<String, String>(), null);
+    ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.REGEX, mapping),
+            new HashMap<String, String>(),
+            null);
 
     servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
     servletDefinition.doService(request, response);
 
     assertTrue("Servlet did not run!", run[0]);
-    
+
     verify(injector, binding, request);
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
index a6d52a2..cf69e3f 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,19 +28,16 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.spi.BindingScopingVisitor;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.Map;
-
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
 
 /**
  * Basic unit test for lifecycle of a ServletDefinition (wrapper).
@@ -53,32 +50,32 @@
     Injector injector = createMock(Injector.class);
     Binding binding = createMock(Binding.class);
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
-    final HttpServlet mockServlet = new HttpServlet() {
-    };
-    expect(injector.getInstance(Key.get(HttpServlet.class)))
-        .andReturn(mockServlet)
-        .anyTimes();
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
+    final HttpServlet mockServlet = new HttpServlet() {};
+    expect(injector.getInstance(Key.get(HttpServlet.class))).andReturn(mockServlet).anyTimes();
 
     replay(injector, binding);
 
     //some init params
     //noinspection SSBasedInspection
-    final Map<String, String> initParams = new ImmutableMap.Builder<String, String>()
-      .put("ahsd", "asdas24dok")
-      .put("ahssd", "asdasd124ok").build();
+    final Map<String, String> initParams =
+        new ImmutableMap.Builder<String, String>()
+            .put("ahsd", "asdas24dok")
+            .put("ahssd", "asdasd124ok")
+            .build();
 
     String pattern = "/*";
-    final ServletDefinition servletDefinition = new ServletDefinition(pattern,
-        Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern), initParams, null);
+    final ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            initParams,
+            null);
 
     ServletContext servletContext = createMock(ServletContext.class);
     final String contextName = "thing__!@@44__SRV" + getClass();
-    expect(servletContext.getServletContextName())
-        .andReturn(contextName);
+    expect(servletContext.getServletContextName()).andReturn(contextName);
 
     replay(servletContext);
 
@@ -100,17 +97,21 @@
     verify(injector, binding, servletContext);
   }
 
-  public void testServiceWithContextPath() throws IOException, ServletException   {
+  public void testServiceWithContextPath() throws IOException, ServletException {
     String pattern = "/*";
     //some init params
-    Map<String, String> initParams = new ImmutableMap.Builder<String, String>()
-        .put("ahsd", "asdas24dok")
-        .put("ahssd", "asdasd124ok")
-        .build();
+    Map<String, String> initParams =
+        new ImmutableMap.Builder<String, String>()
+            .put("ahsd", "asdas24dok")
+            .put("ahssd", "asdasd124ok")
+            .build();
 
-    final ServletDefinition servletDefinition = new ServletDefinition(pattern,
-        Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern),
-        initParams, null);
+    final ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            initParams,
+            null);
     HttpServletResponse servletResponse = createMock(HttpServletResponse.class);
     HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
 
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
index 03edc59..1354b9c 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,11 +26,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -41,10 +37,11 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
 
 /**
- * Tests the FilterPipeline that dispatches to guice-managed servlets,
- * is a full integration test, with a real injector.
+ * Tests the FilterPipeline that dispatches to guice-managed servlets, is a full integration test,
+ * with a real injector.
  *
  * @author Dhanji R. Prasanna (dhanji gmail com)
  */
@@ -63,19 +60,21 @@
 
   public final void testDispatchRequestToManagedPipelineServlets()
       throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        serve("/*").with(TestServlet.class);
+              @Override
+              protected void configureServlets() {
+                serve("/*").with(TestServlet.class);
 
-        // These servets should never fire... (ordering test)
-        serve("*.html").with(NeverServlet.class);
-        serve("/test/*").with(Key.get(NeverServlet.class));
-        serve("/index/*").with(Key.get(NeverServlet.class));
-        serve("*.jsp").with(Key.get(NeverServlet.class));
-      }
-    });
+                // These servets should never fire... (ordering test)
+                serve("*.html").with(NeverServlet.class);
+                serve("/test/*").with(Key.get(NeverServlet.class));
+                serve("/index/*").with(Key.get(NeverServlet.class));
+                serve("*.jsp").with(Key.get(NeverServlet.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -84,12 +83,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html")
-        .times(1);
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").times(1);
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -100,29 +95,35 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire correct number of times-- inits: " + inits + "; dos: "
-            + services + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + services
+            + "; destroys: "
+            + destroys,
         inits == 2 && services == 1 && destroys == 2);
   }
 
   public final void testDispatchRequestToManagedPipelineWithFilter()
       throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filter("/*").through(TestFilter.class);
 
-        serve("/*").with(TestServlet.class);
+                serve("/*").with(TestServlet.class);
 
-        // These servets should never fire...
-        serve("*.html").with(NeverServlet.class);
-        serve("/test/*").with(Key.get(NeverServlet.class));
-        serve("/index/*").with(Key.get(NeverServlet.class));
-        serve("*.jsp").with(Key.get(NeverServlet.class));
-
-      }
-    });
+                // These servets should never fire...
+                serve("*.html").with(NeverServlet.class);
+                serve("/test/*").with(Key.get(NeverServlet.class));
+                serve("/index/*").with(Key.get(NeverServlet.class));
+                serve("*.jsp").with(Key.get(NeverServlet.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -131,12 +132,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html")
-        .times(2);
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").times(2);
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -147,22 +144,32 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire correct number of times-- inits: " + inits + "; dos: "
-            + services + "; destroys: " + destroys + "; doFilters: " + doFilters,
+    assertTrue(
+        "lifecycle states did not fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + services
+            + "; destroys: "
+            + destroys
+            + "; doFilters: "
+            + doFilters,
         inits == 3 && services == 1 && destroys == 3 && doFilters == 1);
   }
 
   @Singleton
   public static class TestServlet extends HttpServlet {
+    @Override
     public void init(ServletConfig filterConfig) throws ServletException {
       inits++;
     }
 
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       services++;
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
@@ -170,15 +177,18 @@
 
   @Singleton
   public static class NeverServlet extends HttpServlet {
+    @Override
     public void init(ServletConfig filterConfig) throws ServletException {
       inits++;
     }
 
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       fail("NeverServlet was fired, when it should not have been.");
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
@@ -186,30 +196,33 @@
 
   @Singleton
   public static class TestFilter implements Filter {
+    @Override
     public void init(FilterConfig filterConfig) throws ServletException {
       inits++;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       doFilters++;
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
   }
 
-
   @Singleton
   public static class ForwardingServlet extends HttpServlet {
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       final HttpServletRequest request = (HttpServletRequest) servletRequest;
 
-      request.getRequestDispatcher("/blah.jsp")
-          .forward(servletRequest, servletResponse);
+      request.getRequestDispatcher("/blah.jsp").forward(servletRequest, servletResponse);
     }
   }
 
@@ -222,6 +235,7 @@
       forwardedTo = 0;
     }
 
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       final HttpServletRequest request = (HttpServletRequest) servletRequest;
@@ -232,22 +246,19 @@
   }
 
   public void testForwardUsingRequestDispatcher() throws IOException, ServletException {
-    Guice.createInjector(new ServletModule() {
-      @Override
-      protected void configureServlets() {
-        serve("/").with(ForwardingServlet.class);
-        serve("/blah.jsp").with(ForwardedServlet.class);
-      }
-    });
+    Guice.createInjector(
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            serve("/").with(ForwardingServlet.class);
+            serve("/blah.jsp").with(ForwardedServlet.class);
+          }
+        });
 
     final HttpServletRequest requestMock = createMock(HttpServletRequest.class);
     HttpServletResponse responseMock = createMock(HttpServletResponse.class);
-    expect(requestMock.getRequestURI())
-        .andReturn("/")
-        .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true);
     expect(requestMock.getAttribute(REQUEST_DISPATCHER_REQUEST)).andReturn(true);
@@ -258,24 +269,24 @@
 
     replay(requestMock, responseMock);
 
-    new GuiceFilter()
-        .doFilter(requestMock, responseMock,
-            createMock(FilterChain.class));
+    new GuiceFilter().doFilter(requestMock, responseMock, createMock(FilterChain.class));
 
     assertEquals("Incorrect number of forwards", 1, ForwardedServlet.forwardedTo);
     verify(requestMock, responseMock);
   }
 
   public final void testQueryInRequestUri_regex() throws Exception {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filterRegex("(.)*\\.html").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filterRegex("(.)*\\.html").through(TestFilter.class);
 
-        serveRegex("(.)*\\.html").with(TestServlet.class);
-      }
-    });
+                serveRegex("(.)*\\.html").with(TestServlet.class);
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -284,12 +295,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html?query=params")
-        .atLeastOnce();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html?query=params").atLeastOnce();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -305,15 +312,17 @@
   }
 
   public final void testQueryInRequestUri() throws Exception {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/index.html").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filter("/index.html").through(TestFilter.class);
 
-        serve("/index.html").with(TestServlet.class);
-      }
-    });
+                serve("/index.html").with(TestServlet.class);
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -322,12 +331,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html?query=params")
-        .atLeastOnce();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html?query=params").atLeastOnce();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletModuleTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletModuleTest.java
index 026f71e..9040ec8 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletModuleTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletModuleTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,27 +18,28 @@
 
 import com.google.common.collect.Lists;
 import com.google.inject.Binding;
+import com.google.inject.CreationException;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
 import com.google.inject.spi.Elements;
-
-import junit.framework.TestCase;
-
 import java.util.List;
+import junit.framework.TestCase;
 
 /**
  * Tests for ServletModule, to ensure it captures bindings correctly.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 public class ServletModuleTest extends TestCase {
-  
+
   public void testServletModuleCallOutsideConfigure() {
     try {
-      new ServletModule() {{
-        serve("/*").with(DummyServlet.class);
-      }};
+      new ServletModule() {
+        {
+          serve("/*").with(DummyServlet.class);
+        }
+      };
       fail();
     } catch (IllegalStateException e) {
       // Expected.
@@ -48,21 +49,38 @@
   public void testServletModuleReuse() {
     Module module = new Module();
     Elements.getElements(module); // use the module once (to, say, introspect bindings)
-    Injector injector = Guice.createInjector(module);  // use it again.
-    
-    Visitor visitor = new Visitor();    
+    Injector injector = Guice.createInjector(module); // use it again.
+
+    Visitor visitor = new Visitor();
     // Validate only a single servlet binding & a single filter binding exist.
-    for(Binding<?> binding : injector.getAllBindings().values()) {
+    for (Binding<?> binding : injector.getAllBindings().values()) {
       binding.acceptTargetVisitor(visitor);
     }
-    assertEquals("wrong linked servlets: " + visitor.linkedServlets,
-        0, visitor.linkedServlets.size());
-    assertEquals("wrong linked filters: " + visitor.linkedFilters,
-        0, visitor.linkedFilters.size());
-    assertEquals("wrong instance servlets: " + visitor.instanceServlets,
-        1, visitor.instanceServlets.size());
-    assertEquals("wrong instance filters: " + visitor.instanceFilters,
-        1, visitor.instanceFilters.size());
+    assertEquals(
+        "wrong linked servlets: " + visitor.linkedServlets, 0, visitor.linkedServlets.size());
+    assertEquals("wrong linked filters: " + visitor.linkedFilters, 0, visitor.linkedFilters.size());
+    assertEquals(
+        "wrong instance servlets: " + visitor.instanceServlets, 1, visitor.instanceServlets.size());
+    assertEquals(
+        "wrong instance filters: " + visitor.instanceFilters, 1, visitor.instanceFilters.size());
+  }
+
+  public void testServletModule_badPattern() {
+    try {
+      Guice.createInjector(
+          new ServletModule() {
+            @Override
+            protected void configureServlets() {
+              serve("/%2E/*").with(new DummyServlet());
+              serveRegex("/(foo|bar/").with(new DummyServlet());
+              filter("/%2E/*").through(new DummyFilterImpl());
+              filterRegex("/(foo|bar/").through(new DummyFilterImpl());
+            }
+          });
+      fail();
+    } catch (CreationException e) {
+      assertEquals(4, e.getErrorMessages().size());
+    }
   }
 
   private static class Module extends ServletModule {
@@ -73,32 +91,35 @@
     }
   }
 
-  private static class Visitor extends DefaultBindingTargetVisitor<Object, Void> implements
-      ServletModuleTargetVisitor<Object, Void> {
+  private static class Visitor extends DefaultBindingTargetVisitor<Object, Void>
+      implements ServletModuleTargetVisitor<Object, Void> {
     List<LinkedFilterBinding> linkedFilters = Lists.newArrayList();
     List<LinkedServletBinding> linkedServlets = Lists.newArrayList();
     List<InstanceFilterBinding> instanceFilters = Lists.newArrayList();
     List<InstanceServletBinding> instanceServlets = Lists.newArrayList();
-    
+
+    @Override
     public Void visit(LinkedFilterBinding binding) {
       linkedFilters.add(binding);
       return null;
     }
 
+    @Override
     public Void visit(InstanceFilterBinding binding) {
       instanceFilters.add(binding);
       return null;
     }
 
+    @Override
     public Void visit(LinkedServletBinding binding) {
       linkedServlets.add(binding);
       return null;
     }
 
+    @Override
     public Void visit(InstanceServletBinding binding) {
       instanceServlets.add(binding);
       return null;
     }
   }
-  
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
index 91abe9c..ceaab59 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,88 +34,81 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.BindingScopingVisitor;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.UUID;
-
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
 
 /**
- * Tests forwarding and inclusion (RequestDispatcher actions from the
- * servlet spec).
+ * Tests forwarding and inclusion (RequestDispatcher actions from the servlet spec).
  *
  * @author Dhanji R. Prasanna (dhanji@gmail com)
  */
 public class ServletPipelineRequestDispatcherTest extends TestCase {
   private static final Key<HttpServlet> HTTP_SERLVET_KEY = Key.get(HttpServlet.class);
   private static final String A_KEY = "thinglyDEgintly" + new Date() + UUID.randomUUID();
-  private static final String A_VALUE = ServletPipelineRequestDispatcherTest.class.toString()
-      + new Date() + UUID.randomUUID();
+  private static final String A_VALUE =
+      ServletPipelineRequestDispatcherTest.class.toString() + new Date() + UUID.randomUUID();
 
   public final void testIncludeManagedServlet() throws IOException, ServletException {
     String pattern = "blah.html";
-    final ServletDefinition servletDefinition = new ServletDefinition(pattern,
-        Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
 
     final Injector injector = createMock(Injector.class);
     final Binding binding = createMock(Binding.class);
     final HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getAttribute(A_KEY))
-        .andReturn(A_VALUE);
-
+    expect(requestMock.getAttribute(A_KEY)).andReturn(A_VALUE);
 
     requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true);
     requestMock.removeAttribute(REQUEST_DISPATCHER_REQUEST);
 
     final boolean[] run = new boolean[1];
-    final HttpServlet mockServlet = new HttpServlet() {
-      protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse)
-          throws ServletException, IOException {
-        run[0] = true;
+    final HttpServlet mockServlet =
+        new HttpServlet() {
+          @Override
+          protected void service(
+              HttpServletRequest request, HttpServletResponse httpServletResponse)
+              throws ServletException, IOException {
+            run[0] = true;
 
-        final Object o = request.getAttribute(A_KEY);
-        assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
-      }
-    };
+            final Object o = request.getAttribute(A_KEY);
+            assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+          }
+        };
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
-    expect(injector.getInstance(HTTP_SERLVET_KEY))
-        .andReturn(mockServlet);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
+    expect(injector.getInstance(HTTP_SERLVET_KEY)).andReturn(mockServlet);
 
-
-    final Key<ServletDefinition> servetDefsKey = Key
-        .get(TypeLiteral.get(ServletDefinition.class));
+    final Key<ServletDefinition> servetDefsKey = Key.get(TypeLiteral.get(ServletDefinition.class));
 
     Binding<ServletDefinition> mockBinding = createMock(Binding.class);
     expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral())))
         .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding));
     Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition);
-    expect(mockBinding.getProvider())
-        .andReturn(bindingProvider);
+    expect(mockBinding.getProvider()).andReturn(bindingProvider);
 
     replay(injector, binding, requestMock, mockBinding);
 
     // Have to init the Servlet before we can dispatch to it.
     servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
 
-    final RequestDispatcher dispatcher = new ManagedServletPipeline(
-        injector)
-        .getRequestDispatcher(pattern);
+    final RequestDispatcher dispatcher =
+        new ManagedServletPipeline(injector).getRequestDispatcher(pattern);
 
     assertNotNull(dispatcher);
     dispatcher.include(requestMock, createMock(HttpServletResponse.class));
@@ -127,64 +120,62 @@
 
   public final void testForwardToManagedServlet() throws IOException, ServletException {
     String pattern = "blah.html";
-    final ServletDefinition servletDefinition = new ServletDefinition(pattern,
-        Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
 
     final Injector injector = createMock(Injector.class);
     final Binding binding = createMock(Binding.class);
     final HttpServletRequest requestMock = createMock(HttpServletRequest.class);
     final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
 
-    expect(requestMock.getAttribute(A_KEY))
-        .andReturn(A_VALUE);
-
+    expect(requestMock.getAttribute(A_KEY)).andReturn(A_VALUE);
 
     requestMock.setAttribute(REQUEST_DISPATCHER_REQUEST, true);
     requestMock.removeAttribute(REQUEST_DISPATCHER_REQUEST);
 
-    expect(mockResponse.isCommitted())
-        .andReturn(false);
+    expect(mockResponse.isCommitted()).andReturn(false);
 
     mockResponse.resetBuffer();
     expectLastCall().once();
 
-    final List<String> paths = new ArrayList<String>();
-    final HttpServlet mockServlet = new HttpServlet() {
-      protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse)
-          throws ServletException, IOException {
-        paths.add(request.getRequestURI());
+    final List<String> paths = new ArrayList<>();
+    final HttpServlet mockServlet =
+        new HttpServlet() {
+          @Override
+          protected void service(
+              HttpServletRequest request, HttpServletResponse httpServletResponse)
+              throws ServletException, IOException {
+            paths.add(request.getRequestURI());
 
-        final Object o = request.getAttribute(A_KEY);
-        assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
-      }
-    };
+            final Object o = request.getAttribute(A_KEY);
+            assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+          }
+        };
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
 
-    expect(injector.getInstance(HTTP_SERLVET_KEY))
-        .andReturn(mockServlet);
+    expect(injector.getInstance(HTTP_SERLVET_KEY)).andReturn(mockServlet);
 
-    final Key<ServletDefinition> servetDefsKey = Key
-        .get(TypeLiteral.get(ServletDefinition.class));
+    final Key<ServletDefinition> servetDefsKey = Key.get(TypeLiteral.get(ServletDefinition.class));
 
     Binding<ServletDefinition> mockBinding = createMock(Binding.class);
     expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral())))
         .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding));
     Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition);
-    expect(mockBinding.getProvider())
-        .andReturn(bindingProvider);
+    expect(mockBinding.getProvider()).andReturn(bindingProvider);
 
     replay(injector, binding, requestMock, mockResponse, mockBinding);
 
     // Have to init the Servlet before we can dispatch to it.
     servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
 
-    final RequestDispatcher dispatcher = new ManagedServletPipeline(injector)
-        .getRequestDispatcher(pattern);
+    final RequestDispatcher dispatcher =
+        new ManagedServletPipeline(injector).getRequestDispatcher(pattern);
 
     assertNotNull(dispatcher);
     dispatcher.forward(requestMock, mockResponse);
@@ -199,8 +190,7 @@
     IllegalStateException expected = null;
     try {
       forwardToManagedServletFailureOnCommittedBuffer();
-    }
-    catch (IllegalStateException ise) {
+    } catch (IllegalStateException ise) {
       expected = ise;
     } finally {
       assertNotNull("Expected IllegalStateException was not thrown", expected);
@@ -210,60 +200,58 @@
   public final void forwardToManagedServletFailureOnCommittedBuffer()
       throws IOException, ServletException {
     String pattern = "blah.html";
-    final ServletDefinition servletDefinition = new ServletDefinition(pattern,
-        Key.get(HttpServlet.class), UriPatternType.get(UriPatternType.SERVLET, pattern),
-        new HashMap<String, String>(), null);
+    final ServletDefinition servletDefinition =
+        new ServletDefinition(
+            Key.get(HttpServlet.class),
+            UriPatternType.get(UriPatternType.SERVLET, pattern),
+            new HashMap<String, String>(),
+            null);
 
     final Injector injector = createMock(Injector.class);
     final Binding binding = createMock(Binding.class);
     final HttpServletRequest mockRequest = createMock(HttpServletRequest.class);
     final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
 
-    expect(mockResponse.isCommitted())
-        .andReturn(true);
+    expect(mockResponse.isCommitted()).andReturn(true);
 
-    final HttpServlet mockServlet = new HttpServlet() {
-      protected void service(HttpServletRequest request, HttpServletResponse httpServletResponse)
-          throws ServletException, IOException {
+    final HttpServlet mockServlet =
+        new HttpServlet() {
+          @Override
+          protected void service(
+              HttpServletRequest request, HttpServletResponse httpServletResponse)
+              throws ServletException, IOException {
 
-        final Object o = request.getAttribute(A_KEY);
-        assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
-      }
-    };
+            final Object o = request.getAttribute(A_KEY);
+            assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+          }
+        };
 
-    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
-        .andReturn(true);
-    expect(injector.getBinding(Key.get(HttpServlet.class)))
-        .andReturn(binding);
+    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true);
+    expect(injector.getBinding(Key.get(HttpServlet.class))).andReturn(binding);
 
-    expect(injector.getInstance(Key.get(HttpServlet.class)))
-        .andReturn(mockServlet);
+    expect(injector.getInstance(Key.get(HttpServlet.class))).andReturn(mockServlet);
 
-
-    final Key<ServletDefinition> servetDefsKey = Key
-        .get(TypeLiteral.get(ServletDefinition.class));
+    final Key<ServletDefinition> servetDefsKey = Key.get(TypeLiteral.get(ServletDefinition.class));
 
     Binding<ServletDefinition> mockBinding = createMock(Binding.class);
     expect(injector.findBindingsByType(eq(servetDefsKey.getTypeLiteral())))
         .andReturn(ImmutableList.<Binding<ServletDefinition>>of(mockBinding));
     Provider<ServletDefinition> bindingProvider = Providers.of(servletDefinition);
-    expect(mockBinding.getProvider())
-        .andReturn(bindingProvider);
+    expect(mockBinding.getProvider()).andReturn(bindingProvider);
 
     replay(injector, binding, mockRequest, mockResponse, mockBinding);
 
     // Have to init the Servlet before we can dispatch to it.
     servletDefinition.init(null, injector, Sets.<HttpServlet>newIdentityHashSet());
 
-    final RequestDispatcher dispatcher = new ManagedServletPipeline(injector)
-        .getRequestDispatcher(pattern);
+    final RequestDispatcher dispatcher =
+        new ManagedServletPipeline(injector).getRequestDispatcher(pattern);
 
     assertNotNull(dispatcher);
 
     try {
       dispatcher.forward(mockRequest, mockResponse);
-    }
-    finally {
+    } finally {
       verify(injector, mockRequest, mockResponse, mockBinding);
     }
   }
@@ -301,7 +289,6 @@
     assertEquals("http://the.server/new-uri", wrappedRequest.getRequestURL().toString());
   }
 
-
   public final void testWrappedRequestUrlDefaultHttpsPort() {
     final HttpServletRequest mockRequest = createMock(HttpServletRequest.class);
     expect(mockRequest.getScheme()).andReturn("https");
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletScopesTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletScopesTest.java
index 0ad40e3..98a5f84 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletScopesTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletScopesTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2011 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,14 +36,12 @@
 import com.google.inject.spi.Elements;
 import com.google.inject.spi.PrivateElements;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.List;
 import java.util.Map;
+import junit.framework.TestCase;
 
 /**
  * Tests for {@link ServletScopes}.
@@ -60,30 +58,32 @@
     final Key<String> f = Key.get(String.class, named("F"));
     final Key<String> g = Key.get(String.class, named("G"));
 
-    Module requestScopedBindings = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(ServletScopes.REQUEST);
-        bind(d).toProvider(Providers.of("d")).in(RequestScoped.class);
-        bind(e).to(AnnotatedRequestScopedClass.class);
-        install(new PrivateModule() {
+    Module requestScopedBindings =
+        new AbstractModule() {
           @Override
           protected void configure() {
-            bind(f).toProvider(Providers.of("f")).in(RequestScoped.class);
-            expose(f);
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(ServletScopes.REQUEST);
+            bind(d).toProvider(Providers.of("d")).in(RequestScoped.class);
+            bind(e).to(AnnotatedRequestScopedClass.class);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(f).toProvider(Providers.of("f")).in(RequestScoped.class);
+                    expose(f);
+                  }
+                });
           }
-        });
-      }
 
-      @Provides
-      @Named("G")
-      @RequestScoped
-      String provideG() {
-        return "g";
-      }
-    };
+          @Provides
+          @Named("G")
+          @RequestScoped
+          String provideG() {
+            return "g";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(requestScopedBindings);
@@ -120,34 +120,36 @@
     final Key<String> i = Key.get(String.class, named("I"));
     final Key<String> j = Key.get(String.class, named("J"));
 
-    Module requestScopedBindings = new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(a).to(b);
-        bind(b).to(c);
-        bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
-        bind(d).toInstance("d");
-        bind(e).toProvider(Providers.of("e")).asEagerSingleton();
-        bind(f).toProvider(Providers.of("f")).in(Scopes.SINGLETON);
-        bind(g).toProvider(Providers.of("g")).in(Singleton.class);
-        bind(h).toProvider(Providers.of("h")).in(CustomScoped.class);
-        bindScope(CustomScoped.class, Scopes.NO_SCOPE);
-        install(new PrivateModule() {
+    Module requestScopedBindings =
+        new AbstractModule() {
           @Override
           protected void configure() {
-            bind(i).toProvider(Providers.of("i")).in(CustomScoped.class);
-            expose(i);
+            bind(a).to(b);
+            bind(b).to(c);
+            bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
+            bind(d).toInstance("d");
+            bind(e).toProvider(Providers.of("e")).asEagerSingleton();
+            bind(f).toProvider(Providers.of("f")).in(Scopes.SINGLETON);
+            bind(g).toProvider(Providers.of("g")).in(Singleton.class);
+            bind(h).toProvider(Providers.of("h")).in(CustomScoped.class);
+            bindScope(CustomScoped.class, Scopes.NO_SCOPE);
+            install(
+                new PrivateModule() {
+                  @Override
+                  protected void configure() {
+                    bind(i).toProvider(Providers.of("i")).in(CustomScoped.class);
+                    expose(i);
+                  }
+                });
           }
-        });
-      }
 
-      @Provides
-      @Named("J")
-      @CustomScoped
-      String provideJ() {
-        return "j";
-      }
-    };
+          @Provides
+          @Named("J")
+          @CustomScoped
+          String provideJ() {
+            return "j";
+          }
+        };
 
     @SuppressWarnings("unchecked") // we know the module contains only bindings
     List<Element> moduleBindings = Elements.getElements(requestScopedBindings);
@@ -179,7 +181,7 @@
   @RequestScoped
   static class AnnotatedRequestScopedClass {}
 
-  @Target({ ElementType.TYPE, ElementType.METHOD })
+  @Target({ElementType.TYPE, ElementType.METHOD})
   @Retention(RUNTIME)
   @ScopeAnnotation
   private @interface CustomScoped {}
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletSpiVisitor.java b/extensions/servlet/test/com/google/inject/servlet/ServletSpiVisitor.java
index beff874..62781ab 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletSpiVisitor.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletSpiVisitor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,7 @@
 
 package com.google.inject.servlet;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
@@ -23,14 +24,10 @@
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.google.inject.spi.DefaultBindingTargetVisitor;
-
-import junit.framework.AssertionFailedError;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
-
 import javax.servlet.Filter;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletRequest;
@@ -39,14 +36,14 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import junit.framework.AssertionFailedError;
 
 /**
  * A visitor for testing the servlet SPI extension.
  *
  * @author sameb@google.com (Sam Berlin)
  */
-class ServletSpiVisitor
-    extends DefaultBindingTargetVisitor<Object, Integer>
+class ServletSpiVisitor extends DefaultBindingTargetVisitor<Object, Integer>
     implements ServletModuleTargetVisitor<Object, Integer> {
 
   int otherCount = 0;
@@ -59,34 +56,47 @@
   ServletSpiVisitor(boolean forInjector) {
     ImmutableSet.Builder<Class> builder = ImmutableSet.builder();
     // always ignore these things...
-    builder.add(ServletRequest.class,
-        ServletResponse.class, ManagedFilterPipeline.class, ManagedServletPipeline.class,
-        FilterPipeline.class, ServletContext.class, HttpServletRequest.class, Filter.class,
-        HttpServletResponse.class, HttpSession.class, Map.class, HttpServlet.class,
+    builder.add(
+        ServletRequest.class,
+        ServletResponse.class,
+        ManagedFilterPipeline.class,
+        ManagedServletPipeline.class,
+        FilterPipeline.class,
+        ServletContext.class,
+        HttpServletRequest.class,
+        Filter.class,
+        HttpServletResponse.class,
+        HttpSession.class,
+        Map.class,
+        HttpServlet.class,
         InternalServletModule.BackwardsCompatibleServletContextProvider.class,
         GuiceFilter.class);
-    if(forInjector) {
+    if (forInjector) {
       // only ignore these if this is for the live injector, any other time it'd be an error!
       builder.add(Injector.class, Stage.class, Logger.class);
     }
     this.allowedClasses = builder.build();
   }
 
+  @Override
   public Integer visit(InstanceFilterBinding binding) {
     actual.add(new Params(binding, binding.getFilterInstance()));
     return currentCount++;
   }
 
+  @Override
   public Integer visit(InstanceServletBinding binding) {
     actual.add(new Params(binding, binding.getServletInstance()));
     return currentCount++;
   }
 
+  @Override
   public Integer visit(LinkedFilterBinding binding) {
     actual.add(new Params(binding, binding.getLinkedKey()));
     return currentCount++;
   }
 
+  @Override
   public Integer visit(LinkedServletBinding binding) {
     actual.add(new Params(binding, binding.getLinkedKey()));
     return currentCount++;
@@ -94,7 +104,7 @@
 
   @Override
   protected Integer visitOther(Binding<? extends Object> binding) {
-    if(!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
+    if (!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
       throw new AssertionFailedError("invalid other binding: " + binding);
     }
     otherCount++;
@@ -123,8 +133,8 @@
 
     @Override
     public boolean equals(Object obj) {
-      if(obj instanceof Params) {
-        Params o = (Params)obj;
+      if (obj instanceof Params) {
+        Params o = (Params) obj;
         return Objects.equal(pattern, o.pattern)
             && Objects.equal(keyOrInstance, o.keyOrInstance)
             && Objects.equal(params, o.params)
@@ -141,12 +151,12 @@
 
     @Override
     public String toString() {
-      return Objects.toStringHelper(Params.class)
-        .add("pattern", pattern)
-        .add("keyOrInstance", keyOrInstance)
-        .add("initParams", params)
-        .add("patternType", patternType)
-        .toString();
+      return MoreObjects.toStringHelper(Params.class)
+          .add("pattern", pattern)
+          .add("keyOrInstance", keyOrInstance)
+          .add("initParams", params)
+          .add("patternType", patternType)
+          .toString();
     }
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
index beb0873..e957937 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,15 +43,11 @@
 import com.google.inject.name.Names;
 import com.google.inject.servlet.ServletScopes.NullObject;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.io.Serializable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.Map;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -64,15 +60,14 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponseWrapper;
 import javax.servlet.http.HttpSession;
+import junit.framework.TestCase;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class ServletTest extends TestCase {
   private static final Key<HttpServletRequest> HTTP_REQ_KEY = Key.get(HttpServletRequest.class);
   private static final Key<HttpServletResponse> HTTP_RESP_KEY = Key.get(HttpServletResponse.class);
-  private static final Key<Map<String, String[]>> REQ_PARAMS_KEY
-      = new Key<Map<String, String[]>>(RequestParameters.class) {};
+  private static final Key<Map<String, String[]>> REQ_PARAMS_KEY =
+      new Key<Map<String, String[]>>(RequestParameters.class) {};
 
   private static final Key<InRequest> IN_REQUEST_NULL_KEY = Key.get(InRequest.class, Null.class);
   private static final Key<InSession> IN_SESSION_KEY = Key.get(InSession.class);
@@ -83,36 +78,55 @@
     //we need to clear the reference to the pipeline every test =(
     GuiceFilter.reset();
   }
-  
+
   public void testScopeExceptions() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        install(new ServletModule());        
-      }
-      @Provides @RequestScoped String provideString() { return "foo"; }
-      @Provides @SessionScoped Integer provideInteger() { return 1; }
-      @Provides @RequestScoped @Named("foo") String provideNamedString() { return "foo"; }
-    });
-    
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new ServletModule());
+              }
+
+              @Provides
+              @RequestScoped
+              String provideString() {
+                return "foo";
+              }
+
+              @Provides
+              @SessionScoped
+              Integer provideInteger() {
+                return 1;
+              }
+
+              @Provides
+              @RequestScoped
+              @Named("foo")
+              String provideNamedString() {
+                return "foo";
+              }
+            });
+
     try {
       injector.getInstance(String.class);
       fail();
-    } catch(ProvisionException oose) {
+    } catch (ProvisionException oose) {
       assertContains(oose.getMessage(), "Cannot access scoped [java.lang.String].");
     }
-    
+
     try {
       injector.getInstance(Integer.class);
       fail();
-    } catch(ProvisionException oose) {
+    } catch (ProvisionException oose) {
       assertContains(oose.getMessage(), "Cannot access scoped [java.lang.Integer].");
     }
-    
+
     Key<?> key = Key.get(String.class, Names.named("foo"));
     try {
       injector.getInstance(key);
       fail();
-    } catch(ProvisionException oose) {
+    } catch (ProvisionException oose) {
       assertContains(oose.getMessage(), "Cannot access scoped [" + Errors.convert(key) + "]");
     }
   }
@@ -124,21 +138,22 @@
 
     final boolean[] invoked = new boolean[1];
     GuiceFilter filter = new GuiceFilter();
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
-        assertSame(request, servletRequest);
-        assertSame(request, injector.getInstance(ServletRequest.class));
-        assertSame(request, injector.getInstance(HTTP_REQ_KEY));
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
+            assertSame(request, servletRequest);
+            assertSame(request, injector.getInstance(ServletRequest.class));
+            assertSame(request, injector.getInstance(HTTP_REQ_KEY));
 
-        assertSame(response, servletResponse);
-        assertSame(response, injector.getInstance(ServletResponse.class));
-        assertSame(response, injector.getInstance(HTTP_RESP_KEY));
+            assertSame(response, servletResponse);
+            assertSame(response, injector.getInstance(ServletResponse.class));
+            assertSame(response, injector.getInstance(HTTP_RESP_KEY));
 
-        assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY));
-      }
-    };
+            assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY));
+          }
+        };
     filter.doFilter(request, response, filterChain);
 
     assertTrue(invoked[0]);
@@ -146,72 +161,85 @@
 
   public void testRequestAndResponseBindings_wrappingFilter() throws Exception {
     final HttpServletRequest request = newFakeHttpServletRequest();
-    final ImmutableMap<String, String[]> wrappedParamMap
-        = ImmutableMap.of("wrap", new String[]{"a", "b"});
-    final HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
-      @Override public Map getParameterMap() {
-        return wrappedParamMap;
-      }
+    final ImmutableMap<String, String[]> wrappedParamMap =
+        ImmutableMap.of("wrap", new String[] {"a", "b"});
+    final HttpServletRequestWrapper requestWrapper =
+        new HttpServletRequestWrapper(request) {
+          @Override
+          public Map getParameterMap() {
+            return wrappedParamMap;
+          }
 
-      @Override public Object getAttribute(String attr) {
-        // Ensure that attributes are stored on the original request object.
-        throw new UnsupportedOperationException();
-      }
-    };
+          @Override
+          public Object getAttribute(String attr) {
+            // Ensure that attributes are stored on the original request object.
+            throw new UnsupportedOperationException();
+          }
+        };
     final HttpServletResponse response = newFakeHttpServletResponse();
     final HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
 
     final boolean[] filterInvoked = new boolean[1];
-    final Injector injector = createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        filter("/*").through(new Filter() {
-          @Inject Provider<ServletRequest> servletReqProvider;
-          @Inject Provider<HttpServletRequest> reqProvider;
-          @Inject Provider<ServletResponse> servletRespProvider;
-          @Inject Provider<HttpServletResponse> respProvider;
+    final Injector injector =
+        createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                filter("/*")
+                    .through(
+                        new Filter() {
+                          @Inject Provider<ServletRequest> servletReqProvider;
+                          @Inject Provider<HttpServletRequest> reqProvider;
+                          @Inject Provider<ServletResponse> servletRespProvider;
+                          @Inject Provider<HttpServletResponse> respProvider;
 
-          public void init(FilterConfig filterConfig) {}
+                          @Override
+                          public void init(FilterConfig filterConfig) {}
 
-          public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
-              throws IOException, ServletException {
-            filterInvoked[0] = true;
-            assertSame(req, servletReqProvider.get());
-            assertSame(req, reqProvider.get());
+                          @Override
+                          public void doFilter(
+                              ServletRequest req, ServletResponse resp, FilterChain chain)
+                              throws IOException, ServletException {
+                            filterInvoked[0] = true;
+                            assertSame(req, servletReqProvider.get());
+                            assertSame(req, reqProvider.get());
 
-            assertSame(resp, servletRespProvider.get());
-            assertSame(resp, respProvider.get());
+                            assertSame(resp, servletRespProvider.get());
+                            assertSame(resp, respProvider.get());
 
-            chain.doFilter(requestWrapper, responseWrapper);
+                            chain.doFilter(requestWrapper, responseWrapper);
 
-            assertSame(req, reqProvider.get());
-            assertSame(resp, respProvider.get());
-          }
+                            assertSame(req, reqProvider.get());
+                            assertSame(resp, respProvider.get());
+                          }
 
-          public void destroy() {}
-        });
-      }
-    });
+                          @Override
+                          public void destroy() {}
+                        });
+              }
+            });
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] chainInvoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        chainInvoked[0] = true;
-        assertSame(requestWrapper, servletRequest);
-        assertSame(requestWrapper, injector.getInstance(ServletRequest.class));
-        assertSame(requestWrapper, injector.getInstance(HTTP_REQ_KEY));
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            chainInvoked[0] = true;
+            assertSame(requestWrapper, servletRequest);
+            assertSame(requestWrapper, injector.getInstance(ServletRequest.class));
+            assertSame(requestWrapper, injector.getInstance(HTTP_REQ_KEY));
 
-        assertSame(responseWrapper, servletResponse);
-        assertSame(responseWrapper, injector.getInstance(ServletResponse.class));
-        assertSame(responseWrapper, injector.getInstance(HTTP_RESP_KEY));
+            assertSame(responseWrapper, servletResponse);
+            assertSame(responseWrapper, injector.getInstance(ServletResponse.class));
+            assertSame(responseWrapper, injector.getInstance(HTTP_RESP_KEY));
 
-        assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY));
+            assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY));
 
-        InRequest inRequest = injector.getInstance(InRequest.class);
-        assertSame(inRequest, injector.getInstance(InRequest.class));
-      }
-    };
+            InRequest inRequest = injector.getInstance(InRequest.class);
+            assertSame(inRequest, injector.getInstance(InRequest.class));
+          }
+        };
     filter.doFilter(request, response, filterChain);
 
     assertTrue(chainInvoked[0]);
@@ -221,157 +249,173 @@
   public void testRequestAndResponseBindings_matchesPassedParameters() throws Exception {
     final int[] filterInvoked = new int[1];
     final boolean[] servletInvoked = new boolean[1];
-    createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        final HttpServletRequest[] previousReq = new HttpServletRequest[1];
-        final HttpServletResponse[] previousResp = new HttpServletResponse[1];
+    createInjector(
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            final HttpServletRequest[] previousReq = new HttpServletRequest[1];
+            final HttpServletResponse[] previousResp = new HttpServletResponse[1];
 
-        final Provider<ServletRequest> servletReqProvider = getProvider(ServletRequest.class);
-        final Provider<HttpServletRequest> reqProvider = getProvider(HttpServletRequest.class);
-        final Provider<ServletResponse> servletRespProvider = getProvider(ServletResponse.class);
-        final Provider<HttpServletResponse> respProvider = getProvider(HttpServletResponse.class);
+            final Provider<ServletRequest> servletReqProvider = getProvider(ServletRequest.class);
+            final Provider<HttpServletRequest> reqProvider = getProvider(HttpServletRequest.class);
+            final Provider<ServletResponse> servletRespProvider =
+                getProvider(ServletResponse.class);
+            final Provider<HttpServletResponse> respProvider =
+                getProvider(HttpServletResponse.class);
 
-        Filter filter = new Filter() {
-          public void init(FilterConfig filterConfig) {}
+            Filter filter =
+                new Filter() {
+                  @Override
+                  public void init(FilterConfig filterConfig) {}
 
-          public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
-              throws IOException, ServletException {
-            filterInvoked[0]++;
-            assertSame(req, servletReqProvider.get());
-            assertSame(req, reqProvider.get());
-            if (previousReq[0] != null) {
-              assertEquals(req, previousReq[0]);
-            }
+                  @Override
+                  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
+                      throws IOException, ServletException {
+                    filterInvoked[0]++;
+                    assertSame(req, servletReqProvider.get());
+                    assertSame(req, reqProvider.get());
+                    if (previousReq[0] != null) {
+                      assertEquals(req, previousReq[0]);
+                    }
 
-            assertSame(resp, servletRespProvider.get());
-            assertSame(resp, respProvider.get());
-            if (previousResp[0] != null) {
-              assertEquals(resp, previousResp[0]);
-            }
+                    assertSame(resp, servletRespProvider.get());
+                    assertSame(resp, respProvider.get());
+                    if (previousResp[0] != null) {
+                      assertEquals(resp, previousResp[0]);
+                    }
 
-            chain.doFilter(
-                previousReq[0] = new HttpServletRequestWrapper((HttpServletRequest) req),
-                previousResp[0] = new HttpServletResponseWrapper((HttpServletResponse) resp));
+                    chain.doFilter(
+                        previousReq[0] = new HttpServletRequestWrapper((HttpServletRequest) req),
+                        previousResp[0] =
+                            new HttpServletResponseWrapper((HttpServletResponse) resp));
 
-            assertSame(req, reqProvider.get());
-            assertSame(resp, respProvider.get());
-          }
+                    assertSame(req, reqProvider.get());
+                    assertSame(resp, respProvider.get());
+                  }
 
-          public void destroy() {}
-        };
+                  @Override
+                  public void destroy() {}
+                };
 
-        filter("/*").through(filter);
-        filter("/*").through(filter);  // filter twice to test wrapping in filters
-        serve("/*").with(new HttpServlet() {
-          @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
-            servletInvoked[0] = true;
-            assertSame(req, servletReqProvider.get());
-            assertSame(req, reqProvider.get());
+            filter("/*").through(filter);
+            filter("/*").through(filter); // filter twice to test wrapping in filters
+            serve("/*")
+                .with(
+                    new HttpServlet() {
+                      @Override
+                      protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+                        servletInvoked[0] = true;
+                        assertSame(req, servletReqProvider.get());
+                        assertSame(req, reqProvider.get());
 
-            assertSame(resp, servletRespProvider.get());
-            assertSame(resp, respProvider.get());
+                        assertSame(resp, servletRespProvider.get());
+                        assertSame(resp, respProvider.get());
+                      }
+                    });
           }
         });
-      }
-    });
 
     GuiceFilter filter = new GuiceFilter();
-    filter.doFilter(newFakeHttpServletRequest(), newFakeHttpServletResponse(), new FilterChain() {
-      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
-        throw new IllegalStateException("Shouldn't get here");
-      }
-    });
+    filter.doFilter(
+        newFakeHttpServletRequest(),
+        newFakeHttpServletResponse(),
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            throw new IllegalStateException("Shouldn't get here");
+          }
+        });
 
     assertEquals(2, filterInvoked[0]);
     assertTrue(servletInvoked[0]);
   }
 
-  public void testNewRequestObject()
-      throws CreationException, IOException, ServletException {
+  public void testNewRequestObject() throws CreationException, IOException, ServletException {
     final Injector injector = createInjector();
     final HttpServletRequest request = newFakeHttpServletRequest();
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] invoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
-        assertNotNull(injector.getInstance(InRequest.class));
-        assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
-      }
-    };
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
+            assertNotNull(injector.getInstance(InRequest.class));
+            assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
+          }
+        };
 
     filter.doFilter(request, null, filterChain);
 
     assertTrue(invoked[0]);
   }
 
-  public void testExistingRequestObject()
-      throws CreationException, IOException, ServletException {
+  public void testExistingRequestObject() throws CreationException, IOException, ServletException {
     final Injector injector = createInjector();
     final HttpServletRequest request = newFakeHttpServletRequest();
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] invoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
 
-        InRequest inRequest = injector.getInstance(InRequest.class);
-        assertSame(inRequest, injector.getInstance(InRequest.class));
+            InRequest inRequest = injector.getInstance(InRequest.class);
+            assertSame(inRequest, injector.getInstance(InRequest.class));
 
-        assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
-        assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
-      }
-    };
+            assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
+            assertNull(injector.getInstance(IN_REQUEST_NULL_KEY));
+          }
+        };
 
     filter.doFilter(request, null, filterChain);
 
     assertTrue(invoked[0]);
   }
 
-  public void testNewSessionObject()
-      throws CreationException, IOException, ServletException {
+  public void testNewSessionObject() throws CreationException, IOException, ServletException {
     final Injector injector = createInjector();
     final HttpServletRequest request = newFakeHttpServletRequest();
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] invoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
-        assertNotNull(injector.getInstance(InSession.class));
-        assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
-      }
-    };
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
+            assertNotNull(injector.getInstance(InSession.class));
+            assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
+          }
+        };
 
     filter.doFilter(request, null, filterChain);
 
     assertTrue(invoked[0]);
   }
 
-  public void testExistingSessionObject()
-      throws CreationException, IOException, ServletException {
+  public void testExistingSessionObject() throws CreationException, IOException, ServletException {
     final Injector injector = createInjector();
     final HttpServletRequest request = newFakeHttpServletRequest();
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] invoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
 
-        InSession inSession = injector.getInstance(InSession.class);
-        assertSame(inSession, injector.getInstance(InSession.class));
+            InSession inSession = injector.getInstance(InSession.class);
+            assertSame(inSession, injector.getInstance(InSession.class));
 
-        assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
-        assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
-      }
-    };
+            assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
+            assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
+          }
+        };
 
     filter.doFilter(request, null, filterChain);
 
@@ -385,14 +429,15 @@
 
     GuiceFilter filter = new GuiceFilter();
     final boolean[] invoked = new boolean[1];
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        invoked[0] = true;
-        assertNotNull(injector.getInstance(InSession.class));
-        assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
-      }
-    };
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            invoked[0] = true;
+            assertNotNull(injector.getInstance(InSession.class));
+            assertNull(injector.getInstance(IN_SESSION_NULL_KEY));
+          }
+        };
 
     filter.doFilter(request, null, filterChain);
 
@@ -409,22 +454,29 @@
   public void testGuiceFilterConstructors() throws Exception {
     final RuntimeException servletException = new RuntimeException();
     final RuntimeException chainException = new RuntimeException();
-    final Injector injector = createInjector(new ServletModule() {
-      @Override protected void configureServlets() {
-        serve("/*").with(new HttpServlet() {
-          @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
-            throw servletException;
-          }
-        });
-      }
-    });
+    final Injector injector =
+        createInjector(
+            new ServletModule() {
+              @Override
+              protected void configureServlets() {
+                serve("/*")
+                    .with(
+                        new HttpServlet() {
+                          @Override
+                          protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+                            throw servletException;
+                          }
+                        });
+              }
+            });
     final HttpServletRequest request = newFakeHttpServletRequest();
-    FilterChain filterChain = new FilterChain() {
-      public void doFilter(ServletRequest servletRequest,
-          ServletResponse servletResponse) {
-        throw chainException;
-      }
-    };
+    FilterChain filterChain =
+        new FilterChain() {
+          @Override
+          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+            throw chainException;
+          }
+        };
 
     try {
       new GuiceFilter().doFilter(request, null, filterChain);
@@ -439,7 +491,8 @@
       assertSame(servletException, e);
     }
     try {
-      injector.getInstance(Key.get(GuiceFilter.class, ScopingOnly.class))
+      injector
+          .getInstance(Key.get(GuiceFilter.class, ScopingOnly.class))
           .doFilter(request, null, filterChain);
       fail();
     } catch (RuntimeException e) {
@@ -448,16 +501,23 @@
   }
 
   private Injector createInjector(Module... modules) throws CreationException {
-    return Guice.createInjector(Lists.<Module>asList(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(new ServletModule());
-        bind(InSession.class);
-        bind(IN_SESSION_NULL_KEY).toProvider(Providers.<InSession>of(null)).in(SessionScoped.class);
-        bind(InRequest.class);
-        bind(IN_REQUEST_NULL_KEY).toProvider(Providers.<InRequest>of(null)).in(RequestScoped.class);
-      }
-    }, modules));
+    return Guice.createInjector(
+        Lists.<Module>asList(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new ServletModule());
+                bind(InSession.class);
+                bind(IN_SESSION_NULL_KEY)
+                    .toProvider(Providers.<InSession>of(null))
+                    .in(SessionScoped.class);
+                bind(InRequest.class);
+                bind(IN_REQUEST_NULL_KEY)
+                    .toProvider(Providers.<InRequest>of(null))
+                    .in(RequestScoped.class);
+              }
+            },
+            modules));
   }
 
   @SessionScoped
@@ -466,6 +526,8 @@
   @RequestScoped
   static class InRequest {}
 
-  @BindingAnnotation @Retention(RUNTIME) @Target({PARAMETER, METHOD, FIELD})
+  @BindingAnnotation
+  @Retention(RUNTIME)
+  @Target({PARAMETER, METHOD, FIELD})
   @interface Null {}
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletTestUtils.java b/extensions/servlet/test/com/google/inject/servlet/ServletTestUtils.java
index e480541..cf110d8 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletTestUtils.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletTestUtils.java
@@ -4,13 +4,11 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
-
 import java.io.Serializable;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Map;
-
 import javax.servlet.FilterChain;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -21,84 +19,93 @@
 
 /**
  * Utilities for servlet tests.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 public class ServletTestUtils {
-  
+
   private ServletTestUtils() {}
 
   private static class ThrowingInvocationHandler implements InvocationHandler {
+    @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       throw new UnsupportedOperationException("No methods are supported on this object");
     }
   }
-  
-  /**
-   * Returns a FilterChain that does nothing.
-   */
+
+  /** Returns a FilterChain that does nothing. */
   public static FilterChain newNoOpFilterChain() {
     return new FilterChain() {
-      public void doFilter(ServletRequest request, ServletResponse response) {
-      }
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response) {}
     };
   }
-  
-  /**
-   * Returns a fake, HttpServletRequest which stores attributes in a HashMap.
-   */
+
+  /** Returns a fake, HttpServletRequest which stores attributes in a HashMap. */
   public static HttpServletRequest newFakeHttpServletRequest() {
-    HttpServletRequest delegate = (HttpServletRequest) Proxy.newProxyInstance(
-        HttpServletRequest.class.getClassLoader(),
-        new Class[] { HttpServletRequest.class }, new ThrowingInvocationHandler());
-    
+    HttpServletRequest delegate =
+        (HttpServletRequest)
+            Proxy.newProxyInstance(
+                HttpServletRequest.class.getClassLoader(),
+                new Class[] {HttpServletRequest.class},
+                new ThrowingInvocationHandler());
+
     return new HttpServletRequestWrapper(delegate) {
-      final Map<String, Object> attributes = Maps.newHashMap(); 
+      final Map<String, Object> attributes = Maps.newHashMap();
       final HttpSession session = newFakeHttpSession();
 
-      @Override public String getMethod() {
+      @Override
+      public String getMethod() {
         return "GET";
       }
 
-      @Override public Object getAttribute(String name) {
+      @Override
+      public Object getAttribute(String name) {
         return attributes.get(name);
       }
-      
-      @Override public void setAttribute(String name, Object value) {
+
+      @Override
+      public void setAttribute(String name, Object value) {
         attributes.put(name, value);
       }
-      
-      @Override public Map getParameterMap() {
+
+      @Override
+      public Map getParameterMap() {
         return ImmutableMap.of();
       }
-      
-      @Override public String getRequestURI() {
+
+      @Override
+      public String getRequestURI() {
         return "/";
       }
-      
-      @Override public String getContextPath() {
+
+      @Override
+      public String getContextPath() {
         return "";
       }
-      
-      @Override public HttpSession getSession() {
+
+      @Override
+      public HttpSession getSession() {
         return session;
       }
     };
   }
-  
+
   /**
-   * Returns a fake, HttpServletResponse which throws an exception if any of its
-   * methods are called.
+   * Returns a fake, HttpServletResponse which throws an exception if any of its methods are called.
    */
   public static HttpServletResponse newFakeHttpServletResponse() {
-    return (HttpServletResponse) Proxy.newProxyInstance(
-        HttpServletResponse.class.getClassLoader(),
-        new Class[] { HttpServletResponse.class }, new ThrowingInvocationHandler());
-  }  
-  
+    return (HttpServletResponse)
+        Proxy.newProxyInstance(
+            HttpServletResponse.class.getClassLoader(),
+            new Class[] {HttpServletResponse.class},
+            new ThrowingInvocationHandler());
+  }
+
   private static class FakeHttpSessionHandler implements InvocationHandler, Serializable {
     final Map<String, Object> attributes = Maps.newHashMap();
 
+    @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       String name = method.getName();
       if ("setAttribute".equals(name)) {
@@ -112,12 +119,12 @@
     }
   }
 
-  /**
-   * Returns a fake, serializable HttpSession which stores attributes in a HashMap.
-   */
+  /** Returns a fake, serializable HttpSession which stores attributes in a HashMap. */
   public static HttpSession newFakeHttpSession() {
-    return (HttpSession) Proxy.newProxyInstance(HttpSession.class.getClassLoader(),
-        new Class[] { HttpSession.class }, new FakeHttpSessionHandler());
+    return (HttpSession)
+        Proxy.newProxyInstance(
+            HttpSession.class.getClassLoader(),
+            new Class[] {HttpSession.class},
+            new FakeHttpSessionHandler());
   }
-
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletUtilsTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletUtilsTest.java
index bd617ab..d198156 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletUtilsTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletUtilsTest.java
@@ -1,14 +1,14 @@
 // Copyright 2012 Google Inc. All Rights Reserved.
 
 package com.google.inject.servlet;
+
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
-import junit.framework.TestCase;
-
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
  * Unit test for the servlet utility class.
@@ -17,42 +17,45 @@
  */
 public class ServletUtilsTest extends TestCase {
   public void testGetContextRelativePath() {
-    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
-    expect(servletRequest.getContextPath()).andReturn("/a_context_path");
-    expect(servletRequest.getRequestURI()).andReturn("/a_context_path/test.html");
-    replay(servletRequest);
-    String path = ServletUtils.getContextRelativePath(servletRequest);
-    assertEquals("/test.html", path);
-    verify(servletRequest);
+    assertEquals(
+        "/test.html", getContextRelativePath("/a_context_path", "/a_context_path/test.html"));
+    assertEquals("/test.html", getContextRelativePath("", "/test.html"));
+    assertEquals("/test.html", getContextRelativePath("", "/foo/../test.html"));
+    assertEquals("/test.html", getContextRelativePath("", "/././foo/../test.html"));
+    assertEquals("/test.html", getContextRelativePath("", "/foo/../../../../test.html"));
+    assertEquals("/test.html", getContextRelativePath("", "/foo/%2E%2E/test.html"));
+    // %2E == '.'
+    assertEquals("/test.html", getContextRelativePath("", "/foo/%2E%2E/test.html"));
+    // %2F == '/'
+    assertEquals("/foo/%2F/test.html", getContextRelativePath("", "/foo/%2F/test.html"));
+    // %66 == 'f'
+    assertEquals("/foo.html", getContextRelativePath("", "/%66oo.html"));
+  }
+
+  public void testGetContextRelativePath_preserveQuery() {
+    assertEquals("/foo?q=f", getContextRelativePath("", "/foo?q=f"));
+    assertEquals("/foo?q=%20+%20", getContextRelativePath("", "/foo?q=%20+%20"));
   }
 
   public void testGetContextRelativePathWithWrongPath() {
-    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
-    expect(servletRequest.getContextPath()).andReturn("/a_context_path");
-    expect(servletRequest.getRequestURI()).andReturn("/test.html");
-    replay(servletRequest);
-    String path = ServletUtils.getContextRelativePath(servletRequest);
-    assertNull(path);
-    verify(servletRequest);
+    assertNull(getContextRelativePath("/a_context_path", "/test.html"));
   }
 
   public void testGetContextRelativePathWithRootPath() {
-    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
-    expect(servletRequest.getContextPath()).andReturn("/a_context_path");
-    expect(servletRequest.getRequestURI()).andReturn("/a_context_path");
-    replay(servletRequest);
-    String path = ServletUtils.getContextRelativePath(servletRequest);
-    assertEquals("/", path);
-    verify(servletRequest);
+    assertEquals("/", getContextRelativePath("/a_context_path", "/a_context_path"));
   }
 
   public void testGetContextRelativePathWithEmptyPath() {
-    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
-    expect(servletRequest.getContextPath()).andReturn("");
-    expect(servletRequest.getRequestURI()).andReturn("");
-    replay(servletRequest);
-    String path = ServletUtils.getContextRelativePath(servletRequest);
-    assertNull(path);
-    verify(servletRequest);
+    assertNull(getContextRelativePath("", ""));
+  }
+
+  private String getContextRelativePath(String contextPath, String requestPath) {
+    HttpServletRequest mock = createMock(HttpServletRequest.class);
+    expect(mock.getContextPath()).andReturn(contextPath);
+    expect(mock.getRequestURI()).andReturn(requestPath);
+    replay(mock);
+    String contextRelativePath = ServletUtils.getContextRelativePath(mock);
+    verify(mock);
+    return contextRelativePath;
   }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/TransferRequestIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/TransferRequestIntegrationTest.java
index dbd18f7..06ee1d6 100644
--- a/extensions/servlet/test/com/google/inject/servlet/TransferRequestIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/TransferRequestIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,63 +23,80 @@
 import com.google.inject.Key;
 import com.google.inject.OutOfScopeException;
 import com.google.inject.Provides;
-
-import junit.framework.TestCase;
-
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import junit.framework.TestCase;
 
 // TODO: Add test for HTTP transferring.
-/**
- * Tests transferring of entire request scope.
- */
+/** Tests transferring of entire request scope. */
 
 public class TransferRequestIntegrationTest extends TestCase {
-  private final Callable<Boolean> FALSE_CALLABLE = new Callable<Boolean>() {
-    @Override public Boolean call() {
-      return false;
-    }
-  };
+  private final Callable<Boolean> FALSE_CALLABLE =
+      new Callable<Boolean>() {
+        @Override
+        public Boolean call() {
+          return false;
+        }
+      };
 
   public void testTransferHttp_outOfScope() {
     try {
       ServletScopes.transferRequest(FALSE_CALLABLE);
       fail();
-    } catch (OutOfScopeException expected) {}
+    } catch (OutOfScopeException expected) {
+    }
   }
 
   public void testTransferNonHttp_outOfScope() {
     try {
       ServletScopes.transferRequest(FALSE_CALLABLE);
       fail();
-    } catch (OutOfScopeException expected) {}
+    } catch (OutOfScopeException expected) {
+    }
+  }
+
+  public void testTransferNonHttp_outOfScope_closeable() {
+    try {
+      ServletScopes.transferRequest();
+      fail();
+    } catch (OutOfScopeException expected) {
+    }
   }
 
   public void testTransferNonHttpRequest() throws Exception {
-    final Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override protected void configure() {
-        bindScope(RequestScoped.class, ServletScopes.REQUEST);
-      }
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(RequestScoped.class, ServletScopes.REQUEST);
+              }
 
-      @Provides @RequestScoped Object provideObject() {
-        return new Object();
-      }
-    });
+              @Provides
+              @RequestScoped
+              Object provideObject() {
+                return new Object();
+              }
+            });
 
-    Callable<Callable<Boolean>> callable = new Callable<Callable<Boolean>>() {
-      @Override public Callable<Boolean> call() {
-        final Object original = injector.getInstance(Object.class);
-        return ServletScopes.transferRequest(new Callable<Boolean>() {
-          @Override public Boolean call() {
-            return original == injector.getInstance(Object.class);
+    Callable<Callable<Boolean>> callable =
+        new Callable<Callable<Boolean>>() {
+          @Override
+          public Callable<Boolean> call() {
+            final Object original = injector.getInstance(Object.class);
+            return ServletScopes.transferRequest(
+                new Callable<Boolean>() {
+                  @Override
+                  public Boolean call() {
+                    return original == injector.getInstance(Object.class);
+                  }
+                });
           }
-        });
-      }
-    };
+        };
 
     ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
     Callable<Boolean> transfer = ServletScopes.scopeRequest(callable, seedMap).call();
@@ -89,33 +106,137 @@
     executor.shutdownNow();
   }
 
-  public void testTransferNonHttpRequest_concurrentUseBlocks() throws Exception {
-    Callable<Boolean> callable = new Callable<Boolean>() {
-      @Override public Boolean call() throws Exception {
-        ExecutorService executor = Executors.newSingleThreadExecutor();
-        try {
-          Future<Boolean> future = executor.submit(ServletScopes.transferRequest(FALSE_CALLABLE));
-          try {
-            return future.get(100, TimeUnit.MILLISECONDS);
-          } catch (TimeoutException e) {
-            return true;
+  public void testTransferNonHttpRequest_closeable() throws Exception {
+    final Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindScope(RequestScoped.class, ServletScopes.REQUEST);
+              }
+
+              @Provides
+              @RequestScoped
+              Object provideObject() {
+                return new Object();
+              }
+            });
+
+    class Data {
+      Object object;
+      RequestScoper scoper;
+    }
+
+    Callable<Data> callable =
+        new Callable<Data>() {
+          @Override
+          public Data call() {
+            Data data = new Data();
+            data.object = injector.getInstance(Object.class);
+            data.scoper = ServletScopes.transferRequest();
+            return data;
           }
-        } finally {
-          executor.shutdownNow();
-        }
-      }
-    };
+        };
+
+    ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
+    Data data = ServletScopes.scopeRequest(callable, seedMap).call();
+
+    ExecutorService executor = Executors.newSingleThreadExecutor();
+    RequestScoper.CloseableScope scope = data.scoper.open();
+    try {
+      assertSame(data.object, injector.getInstance(Object.class));
+    } finally {
+      scope.close();
+      executor.shutdownNow();
+    }
+  }
+
+  public void testTransferNonHttpRequest_concurrentUseBlocks() throws Exception {
+    Callable<Boolean> callable =
+        new Callable<Boolean>() {
+          @Override
+          public Boolean call() throws Exception {
+            ExecutorService executor = Executors.newSingleThreadExecutor();
+            try {
+              Future<Boolean> future =
+                  executor.submit(ServletScopes.transferRequest(FALSE_CALLABLE));
+              try {
+                return future.get(100, TimeUnit.MILLISECONDS);
+              } catch (TimeoutException e) {
+                return true;
+              }
+            } finally {
+              executor.shutdownNow();
+            }
+          }
+        };
+
+    ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
+    assertTrue(ServletScopes.scopeRequest(callable, seedMap).call());
+  }
+
+  public void testTransferNonHttpRequest_concurrentUseBlocks_closeable() throws Exception {
+    Callable<Boolean> callable =
+        new Callable<Boolean>() {
+          @Override
+          public Boolean call() throws Exception {
+            final RequestScoper scoper = ServletScopes.transferRequest();
+            ExecutorService executor = Executors.newSingleThreadExecutor();
+            try {
+              Future<Boolean> future =
+                  executor.submit(
+                      new Callable<Boolean>() {
+                        @Override
+                        public Boolean call() {
+                          RequestScoper.CloseableScope scope = scoper.open();
+                          try {
+                            return false;
+                          } finally {
+                            scope.close();
+                          }
+                        }
+                      });
+              try {
+                return future.get(100, TimeUnit.MILLISECONDS);
+              } catch (TimeoutException e) {
+                return true;
+              }
+            } finally {
+              executor.shutdownNow();
+            }
+          }
+        };
 
     ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
     assertTrue(ServletScopes.scopeRequest(callable, seedMap).call());
   }
 
   public void testTransferNonHttpRequest_concurrentUseSameThreadOk() throws Exception {
-    Callable<Boolean> callable = new Callable<Boolean>() {
-      @Override public Boolean call() throws Exception {
-        return ServletScopes.transferRequest(FALSE_CALLABLE).call();
-      }
-    };
+    Callable<Boolean> callable =
+        new Callable<Boolean>() {
+          @Override
+          public Boolean call() throws Exception {
+            return ServletScopes.transferRequest(FALSE_CALLABLE).call();
+          }
+        };
+
+    ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
+    assertFalse(ServletScopes.scopeRequest(callable, seedMap).call());
+  }
+
+  public void testTransferNonHttpRequest_concurrentUseSameThreadOk_closeable() throws Exception {
+    Callable<Boolean> callable =
+        new Callable<Boolean>() {
+          @Override
+          public Boolean call() throws Exception {
+            RequestScoper.CloseableScope scope = ServletScopes.transferRequest().open();
+            try {
+              return false;
+            } finally {
+              scope.close();
+            }
+          }
+        };
 
     ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of();
     assertFalse(ServletScopes.scopeRequest(callable, seedMap).call());
diff --git a/extensions/servlet/test/com/google/inject/servlet/UriPatternTypeTest.java b/extensions/servlet/test/com/google/inject/servlet/UriPatternTypeTest.java
index 5f82090..3662349 100644
--- a/extensions/servlet/test/com/google/inject/servlet/UriPatternTypeTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/UriPatternTypeTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-
 package com.google.inject.servlet;
 
+import static junit.framework.Assert.fail;
+
 import junit.framework.TestCase;
 
 public class UriPatternTypeTest extends TestCase {
@@ -56,4 +57,13 @@
     assertFalse(pattern.matches("/foo"));
     assertFalse(pattern.matches("/foo?val=1"));
   }
+
+  public void testPatternWithPercentEncodedChars_servlet() {
+    try {
+      UriPatternType.get(UriPatternType.SERVLET, "/foo/%2f/*");
+      fail();
+    } catch (IllegalArgumentException iae) {
+      assertTrue(iae.getMessage().contains("Servlet patterns cannot contain escape patterns."));
+    }
+  }
 }
diff --git a/extensions/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
index ad55230..b14daad 100644
--- a/extensions/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
@@ -9,11 +9,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -21,18 +17,17 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
+ * This tests that filter stage of the pipeline dispatches correctly to guice-managed filters.
  *
- * This tests that filter stage of the pipeline dispatches
- * correctly to guice-managed filters.
- *
- * WARNING(dhanji): Non-parallelizable test =(
+ * <p>WARNING(dhanji): Non-parallelizable test =(
  *
  * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public class VarargsFilterDispatchIntegrationTest extends TestCase {
-    private static int inits, doFilters, destroys;
+  private static int inits, doFilters, destroys;
 
   @Override
   public final void setUp() {
@@ -43,20 +38,21 @@
     GuiceFilter.reset();
   }
 
-
   public final void testDispatchRequestToManagedPipeline() throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        // This is actually a double match for "/*"
-        filter("/*", "*.html", "/*").through(Key.get(TestFilter.class));
+              @Override
+              protected void configureServlets() {
+                // This is actually a double match for "/*"
+                filter("/*", "*.html", "/*").through(Key.get(TestFilter.class));
 
-        // These filters should never fire
-        filter("/index/*").through(Key.get(TestFilter.class));
-        filter("*.jsp").through(Key.get(TestFilter.class));
-      }
-    });
+                // These filters should never fire
+                filter("/index/*").through(Key.get(TestFilter.class));
+                filter("*.jsp").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -64,12 +60,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index.html")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -78,24 +70,31 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not"
-        + " fire correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not"
+            + " fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 3 && destroys == 1);
   }
 
   public final void testDispatchThatNoFiltersFire() throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/public/*", "*.html", "*.xml").through(Key.get(TestFilter.class));
+              @Override
+              protected void configureServlets() {
+                filter("/public/*", "*.html", "*.xml").through(Key.get(TestFilter.class));
 
-        // These filters should never fire
-        filter("/index/*").through(Key.get(TestFilter.class));
-        filter("*.jsp").through(Key.get(TestFilter.class));
-      }
-    });
+                // These filters should never fire
+                filter("/index/*").through(Key.get(TestFilter.class));
+                filter("*.jsp").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -103,12 +102,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index.xhtml")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.xhtml").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -117,25 +112,32 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not "
-        + "fire correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not "
+            + "fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 0 && destroys == 1);
   }
 
-  public final void testDispatchFilterPipelineWithRegexMatching() throws ServletException,
-      IOException {
+  public final void testDispatchFilterPipelineWithRegexMatching()
+      throws ServletException, IOException {
 
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filterRegex("/[A-Za-z]*", "/index").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filterRegex("/[A-Za-z]*", "/index").through(TestFilter.class);
 
-        //these filters should never fire
-        filterRegex("\\w").through(Key.get(TestFilter.class));
-      }
-    });
+                //these filters should never fire
+                filterRegex("\\w").through(Key.get(TestFilter.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
     pipeline.initPipeline(null);
@@ -143,12 +145,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-            .andReturn("/index")
-            .anyTimes();
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index").anyTimes();
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -157,24 +155,33 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire "
-        + "correct number of times-- inits: " + inits + "; dos: " + doFilters
-        + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire "
+            + "correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + doFilters
+            + "; destroys: "
+            + destroys,
         inits == 1 && doFilters == 2 && destroys == 1);
   }
 
   @Singleton
   public static class TestFilter implements Filter {
+    @Override
     public void init(FilterConfig filterConfig) throws ServletException {
       inits++;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       doFilters++;
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
diff --git a/extensions/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java b/extensions/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
index 2309904..4788e4e 100644
--- a/extensions/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,11 +25,7 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Singleton;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
-
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -39,10 +35,11 @@
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
 
 /**
- * Tests the FilterPipeline that dispatches to guice-managed servlets,
- * is a full integration test, with a real injector.
+ * Tests the FilterPipeline that dispatches to guice-managed servlets, is a full integration test,
+ * with a real injector.
  *
  * @author Dhanji R. Prasanna (dhanji gmail com)
  */
@@ -61,16 +58,18 @@
 
   public final void testDispatchRequestToManagedPipelineServlets()
       throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        serve("/*", "/index.html").with(TestServlet.class);
+              @Override
+              protected void configureServlets() {
+                serve("/*", "/index.html").with(TestServlet.class);
 
-        // These servets should never fire... (ordering test)
-        serve("*.html", "/o/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
-      }
-    });
+                // These servets should never fire... (ordering test)
+                serve("*.html", "/o/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -79,12 +78,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html")
-        .times(1);
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").times(1);
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -94,23 +89,30 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire correct number of times-- inits: " + inits + "; dos: "
-            + services + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + services
+            + "; destroys: "
+            + destroys,
         inits == 2 && services == 1 && destroys == 2);
   }
 
   public final void testVarargsSkipDispatchRequestToManagedPipelineServlets()
       throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        serve("/notindex", "/&*", "/index.html").with(TestServlet.class);
+              @Override
+              protected void configureServlets() {
+                serve("/notindex", "/&*", "/index.html").with(TestServlet.class);
 
-        // These servets should never fire... (ordering test)
-        serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
-      }
-    });
+                // These servets should never fire... (ordering test)
+                serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -119,12 +121,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html")
-        .times(3);
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").times(3);
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -134,26 +132,32 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire correct number of times-- inits: " + inits + "; dos: "
-            + services + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + services
+            + "; destroys: "
+            + destroys,
         inits == 2 && services == 1 && destroys == 2);
   }
 
   public final void testDispatchRequestToManagedPipelineWithFilter()
       throws ServletException, IOException {
-    final Injector injector = Guice.createInjector(new ServletModule() {
+    final Injector injector =
+        Guice.createInjector(
+            new ServletModule() {
 
-      @Override
-      protected void configureServlets() {
-        filter("/*").through(TestFilter.class);
+              @Override
+              protected void configureServlets() {
+                filter("/*").through(TestFilter.class);
 
-        serve("/*").with(TestServlet.class);
+                serve("/*").with(TestServlet.class);
 
-        // These servets should never fire...
-        serve("*.html", "/y/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
-
-      }
-    });
+                // These servets should never fire...
+                serve("*.html", "/y/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+              }
+            });
 
     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
 
@@ -162,12 +166,8 @@
     //create ourselves a mock request with test URI
     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
 
-    expect(requestMock.getRequestURI())
-        .andReturn("/index.html")
-        .times(2);
-    expect(requestMock.getContextPath())
-        .andReturn("")
-        .anyTimes();
+    expect(requestMock.getRequestURI()).andReturn("/index.html").times(2);
+    expect(requestMock.getContextPath()).andReturn("").anyTimes();
 
     //dispatch request
     replay(requestMock);
@@ -178,22 +178,30 @@
 
     verify(requestMock);
 
-    assertTrue("lifecycle states did not fire correct number of times-- inits: " + inits + "; dos: "
-            + services + "; destroys: " + destroys,
+    assertTrue(
+        "lifecycle states did not fire correct number of times-- inits: "
+            + inits
+            + "; dos: "
+            + services
+            + "; destroys: "
+            + destroys,
         inits == 3 && services == 1 && destroys == 3 && doFilters == 1);
   }
 
   @Singleton
   public static class TestServlet extends HttpServlet {
+    @Override
     public void init(ServletConfig filterConfig) throws ServletException {
       inits++;
     }
 
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       services++;
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
@@ -201,15 +209,18 @@
 
   @Singleton
   public static class NeverServlet extends HttpServlet {
+    @Override
     public void init(ServletConfig filterConfig) throws ServletException {
       inits++;
     }
 
+    @Override
     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
         throws IOException, ServletException {
       fail("NeverServlet was fired, when it should not have been.");
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
@@ -217,16 +228,20 @@
 
   @Singleton
   public static class TestFilter implements Filter {
+    @Override
     public void init(FilterConfig filterConfig) throws ServletException {
       inits++;
     }
 
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-        FilterChain filterChain) throws IOException, ServletException {
+    @Override
+    public void doFilter(
+        ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
       doFilters++;
       filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    @Override
     public void destroy() {
       destroys++;
     }
diff --git a/extensions/spring/pom.xml b/extensions/spring/pom.xml
index 5501a53..15451b5 100644
--- a/extensions/spring/pom.xml
+++ b/extensions/spring/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-spring</artifactId>
@@ -22,4 +22,18 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.spring</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/spring/src/com/google/inject/spring/SpringIntegration.java b/extensions/spring/src/com/google/inject/spring/SpringIntegration.java
index fd3d0fd..be3a21a 100644
--- a/extensions/spring/src/com/google/inject/spring/SpringIntegration.java
+++ b/extensions/spring/src/com/google/inject/spring/SpringIntegration.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.name.Names;
-
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.ListableBeanFactory;
 
@@ -35,9 +34,8 @@
   private SpringIntegration() {}
 
   /**
-   * Creates a provider which looks up objects from Spring using the given name.
-   * Expects a binding to {@link
-   * org.springframework.beans.factory.BeanFactory}. Example usage:
+   * Creates a provider which looks up objects from Spring using the given name. Expects a binding
+   * to {@link org.springframework.beans.factory.BeanFactory}. Example usage:
    *
    * <pre>
    * bind(DataSource.class)
@@ -49,12 +47,11 @@
   }
 
   /**
-   * Binds all Spring beans from the given factory by name. For a Spring bean
-   * named "foo", this method creates a binding to the bean's type and
-   * {@code @Named("foo")}.
+   * Binds all Spring beans from the given factory by name. For a Spring bean named "foo", this
+   * method creates a binding to the bean's type and {@code @Named("foo")}.
    *
    * @see com.google.inject.name.Named
-   * @see com.google.inject.name.Names#named(String) 
+   * @see com.google.inject.name.Names#named(String)
    */
   public static void bindAll(Binder binder, ListableBeanFactory beanFactory) {
     binder = binder.skipSources(SpringIntegration.class);
@@ -65,21 +62,17 @@
     }
   }
 
-  static <T> void bindBean(Binder binder, ListableBeanFactory beanFactory,
-      String name, Class<T> type) {
-    SpringProvider<T> provider
-        = SpringProvider.newInstance(type, name);
+  static <T> void bindBean(
+      Binder binder, ListableBeanFactory beanFactory, String name, Class<T> type) {
+    SpringProvider<T> provider = SpringProvider.newInstance(type, name);
     try {
       provider.initialize(beanFactory);
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
       binder.addError(e);
       return;
     }
 
-    binder.bind(type)
-        .annotatedWith(Names.named(name))
-        .toProvider(provider);
+    binder.bind(type).annotatedWith(Names.named(name)).toProvider(provider);
   }
 
   static class SpringProvider<T> implements Provider<T> {
@@ -101,12 +94,13 @@
     void initialize(BeanFactory beanFactory) {
       this.beanFactory = beanFactory;
       if (!beanFactory.isTypeMatch(name, type)) {
-        throw new ClassCastException("Spring bean named '" + name
-            + "' does not implement " + type.getName() + ".");
+        throw new ClassCastException(
+            "Spring bean named '" + name + "' does not implement " + type.getName() + ".");
       }
       singleton = beanFactory.isSingleton(name);
     }
 
+    @Override
     public T get() {
       return singleton ? getSingleton() : type.cast(beanFactory.getBean(name));
     }
diff --git a/extensions/spring/src/com/google/inject/spring/package-info.java b/extensions/spring/src/com/google/inject/spring/package-info.java
index 42ca1c2..8762a26 100644
--- a/extensions/spring/src/com/google/inject/spring/package-info.java
+++ b/extensions/spring/src/com/google/inject/spring/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Spring integration; this extension requires {@code guice-spring.jar}.
- */
+/** Spring integration; this extension requires {@code guice-spring.jar}. */
 package com.google.inject.spring;
diff --git a/extensions/spring/test/com/google/inject/spring/SpringIntegrationTest.java b/extensions/spring/test/com/google/inject/spring/SpringIntegrationTest.java
index 7f9c983..9c105ae 100644
--- a/extensions/spring/test/com/google/inject/spring/SpringIntegrationTest.java
+++ b/extensions/spring/test/com/google/inject/spring/SpringIntegrationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,81 +24,70 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.name.Names;
-
 import junit.framework.TestCase;
-
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 
-/**
- * @author crazybob@google.com (Bob Lee)
- */
+/** @author crazybob@google.com (Bob Lee) */
 public class SpringIntegrationTest extends TestCase {
 
   public void testBindFromSpring() throws CreationException {
-    final DefaultListableBeanFactory beanFactory
-        = new DefaultListableBeanFactory();
+    final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 
-    RootBeanDefinition singleton
-        = new RootBeanDefinition(Singleton.class);
+    RootBeanDefinition singleton = new RootBeanDefinition(Singleton.class);
     beanFactory.registerBeanDefinition("singleton", singleton);
 
-    RootBeanDefinition prototype
-        = new RootBeanDefinition(Prototype.class, false);
+    RootBeanDefinition prototype = new RootBeanDefinition(Prototype.class, false);
     beanFactory.registerBeanDefinition("prototype", prototype);
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(BeanFactory.class).toInstance(beanFactory);
-        bind(Singleton.class)
-            .toProvider(fromSpring(Singleton.class, "singleton"));
-        bind(Prototype.class)
-            .toProvider(fromSpring(Prototype.class, "prototype"));
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(BeanFactory.class).toInstance(beanFactory);
+                bind(Singleton.class).toProvider(fromSpring(Singleton.class, "singleton"));
+                bind(Prototype.class).toProvider(fromSpring(Prototype.class, "prototype"));
+              }
+            });
 
     assertNotNull(injector.getInstance(Singleton.class));
-    assertSame(injector.getInstance(Singleton.class),
-        injector.getInstance(Singleton.class));
+    assertSame(injector.getInstance(Singleton.class), injector.getInstance(Singleton.class));
 
     assertNotNull(injector.getInstance(Prototype.class));
-    assertNotSame(injector.getInstance(Prototype.class),
-        injector.getInstance(Prototype.class));
+    assertNotSame(injector.getInstance(Prototype.class), injector.getInstance(Prototype.class));
   }
 
   public void testBindAll() throws CreationException {
-    final DefaultListableBeanFactory beanFactory
-        = new DefaultListableBeanFactory();
+    final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 
-    RootBeanDefinition singleton
-        = new RootBeanDefinition(Singleton.class);
+    RootBeanDefinition singleton = new RootBeanDefinition(Singleton.class);
     beanFactory.registerBeanDefinition("singleton", singleton);
 
-    RootBeanDefinition prototype
-        = new RootBeanDefinition(Prototype.class, false);
+    RootBeanDefinition prototype = new RootBeanDefinition(Prototype.class, false);
     beanFactory.registerBeanDefinition("prototype", prototype);
 
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        SpringIntegration.bindAll(binder(), beanFactory);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                SpringIntegration.bindAll(binder(), beanFactory);
+              }
+            });
 
-    Key<Singleton> singletonKey
-        = Key.get(Singleton.class, Names.named("singleton"));
-    Key<Prototype> prototypeKey
-        = Key.get(Prototype.class, Names.named("prototype"));
+    Key<Singleton> singletonKey = Key.get(Singleton.class, Names.named("singleton"));
+    Key<Prototype> prototypeKey = Key.get(Prototype.class, Names.named("prototype"));
 
     assertNotNull(injector.getInstance(singletonKey));
-    assertSame(injector.getInstance(singletonKey),
-        injector.getInstance(singletonKey));
+    assertSame(injector.getInstance(singletonKey), injector.getInstance(singletonKey));
 
     assertNotNull(injector.getInstance(prototypeKey));
-    assertNotSame(injector.getInstance(prototypeKey),
-        injector.getInstance(prototypeKey));
+    assertNotSame(injector.getInstance(prototypeKey), injector.getInstance(prototypeKey));
   }
 
   static class Singleton {}
+
   static class Prototype {}
 }
diff --git a/extensions/struts2/example/src/com/google/inject/struts2/example/Count.java b/extensions/struts2/example/src/com/google/inject/struts2/example/Count.java
index 76e7ec9..8379cdf 100644
--- a/extensions/struts2/example/src/com/google/inject/struts2/example/Count.java
+++ b/extensions/struts2/example/src/com/google/inject/struts2/example/Count.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +16,10 @@
 
 package com.google.inject.struts2.example;
 
-import com.google.inject.Inject;
 import static com.opensymphony.xwork2.Action.SUCCESS;
 
+import com.google.inject.Inject;
+
 public class Count {
 
   final Counter counter;
diff --git a/extensions/struts2/example/src/com/google/inject/struts2/example/Counter.java b/extensions/struts2/example/src/com/google/inject/struts2/example/Counter.java
index c375b98..251bc09 100644
--- a/extensions/struts2/example/src/com/google/inject/struts2/example/Counter.java
+++ b/extensions/struts2/example/src/com/google/inject/struts2/example/Counter.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,7 @@
 
 import com.google.inject.servlet.SessionScoped;
 
-/**
- * Session-scoped counter.
- */
+/** Session-scoped counter. */
 @SessionScoped
 public class Counter {
 
diff --git a/extensions/struts2/example/src/com/google/inject/struts2/example/ExampleListener.java b/extensions/struts2/example/src/com/google/inject/struts2/example/ExampleListener.java
index 244d34b..c865be9 100644
--- a/extensions/struts2/example/src/com/google/inject/struts2/example/ExampleListener.java
+++ b/extensions/struts2/example/src/com/google/inject/struts2/example/ExampleListener.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,14 +16,13 @@
 
 package com.google.inject.struts2.example;
 
-import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
 import com.google.inject.servlet.GuiceServletContextListener;
 import com.google.inject.servlet.ServletModule;
 import com.google.inject.struts2.Struts2GuicePluginModule;
+import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
 
 /**
  * Example application module.
@@ -34,18 +33,17 @@
 
   public Injector getInjector() {
     return Guice.createInjector(
-      new Struts2GuicePluginModule(),
-      new ServletModule() {
-        @Override
-        protected void configureServlets() {      
-          // Struts 2 setup
-          bind(StrutsPrepareAndExecuteFilter.class).in(Singleton.class);
-          filter("/*").through(StrutsPrepareAndExecuteFilter.class);
+        new Struts2GuicePluginModule(),
+        new ServletModule() {
+          @Override
+          protected void configureServlets() {
+            // Struts 2 setup
+            bind(StrutsPrepareAndExecuteFilter.class).in(Singleton.class);
+            filter("/*").through(StrutsPrepareAndExecuteFilter.class);
 
-          // Our app-specific code
-          bind(Service.class).to(ServiceImpl.class);
-      }
-    });
+            // Our app-specific code
+            bind(Service.class).to(ServiceImpl.class);
+          }
+        });
   }
-
 }
diff --git a/extensions/struts2/example/src/com/google/inject/struts2/example/Main.java b/extensions/struts2/example/src/com/google/inject/struts2/example/Main.java
index eb4f0e2..fb2c4a4 100644
--- a/extensions/struts2/example/src/com/google/inject/struts2/example/Main.java
+++ b/extensions/struts2/example/src/com/google/inject/struts2/example/Main.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,9 +21,7 @@
 import org.mortbay.jetty.nio.SelectChannelConnector;
 import org.mortbay.jetty.webapp.WebAppContext;
 
-/**
- * Starts the example web server on port 8080. Run from "./struts2/example".
- */
+/** Starts the example web server on port 8080. Run from "./struts2/example". */
 public class Main {
 
   public static void main(String[] args) throws Exception {
@@ -31,7 +29,7 @@
 
     Connector connector = new SelectChannelConnector();
     connector.setPort(8080);
-    server.setConnectors(new Connector[] { connector });
+    server.setConnectors(new Connector[] {connector});
 
     WebAppContext webapp = new WebAppContext("./root", "/example");
     server.addHandler(webapp);
diff --git a/extensions/struts2/pom.xml b/extensions/struts2/pom.xml
index 87e60d5..e183787 100644
--- a/extensions/struts2/pom.xml
+++ b/extensions/struts2/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-struts2</artifactId>
@@ -33,4 +33,18 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.struts2</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/struts2/src/com/google/inject/struts2/GuiceObjectFactory.java b/extensions/struts2/src/com/google/inject/struts2/GuiceObjectFactory.java
index 4d7c485..403cb38 100644
--- a/extensions/struts2/src/com/google/inject/struts2/GuiceObjectFactory.java
+++ b/extensions/struts2/src/com/google/inject/struts2/GuiceObjectFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2006 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,14 +23,12 @@
 import com.google.inject.Module;
 import com.google.inject.internal.Annotations;
 import com.google.inject.servlet.ServletModule;
-
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ObjectFactory;
 import com.opensymphony.xwork2.config.ConfigurationException;
 import com.opensymphony.xwork2.config.entities.InterceptorConfig;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.interceptor.Interceptor;
-
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -39,20 +37,16 @@
 import java.util.Set;
 import java.util.logging.Logger;
 
-/**
- * @deprecated Use {@link com.google.inject.struts2.Struts2Factory} instead.
- */
+/** @deprecated Use {@link com.google.inject.struts2.Struts2Factory} instead. */
 @Deprecated
 public class GuiceObjectFactory extends ObjectFactory {
 
-  static final Logger logger =
-      Logger.getLogger(GuiceObjectFactory.class.getName());
+  static final Logger logger = Logger.getLogger(GuiceObjectFactory.class.getName());
 
   Module module;
   volatile Injector injector;
   boolean developmentMode = false;
-  List<ProvidedInterceptor> interceptors
-      = new ArrayList<ProvidedInterceptor>();
+  List<ProvidedInterceptor> interceptors = new ArrayList<>();
 
   @Override
   public boolean isNoArgConstructorRequired() {
@@ -66,7 +60,7 @@
       @SuppressWarnings({"unchecked"})
       Class<? extends Module> moduleClass =
           (Class<? extends Module>) Class.forName(moduleClassName);
-      this.module = moduleClass.newInstance();
+      this.module = moduleClass.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
@@ -77,8 +71,9 @@
     this.developmentMode = developmentMode.trim().equals("true");
   }
 
-  Set<Class<?>> boundClasses = new HashSet<Class<?>>();
+  Set<Class<?>> boundClasses = new HashSet<>();
 
+  @Override
   public Class getClassInstance(String name) throws ClassNotFoundException {
     Class<?> clazz = super.getClassInstance(name);
 
@@ -106,6 +101,7 @@
     return clazz;
   }
 
+  @Override
   @SuppressWarnings("unchecked")
   public Object buildBean(Class clazz, Map extraContext) {
     if (injector == null) {
@@ -122,34 +118,37 @@
   private void createInjector() {
     try {
       logger.info("Creating injector...");
-      this.injector = Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          // Install default servlet bindings.
-          install(new ServletModule());
+      this.injector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  // Install default servlet bindings.
+                  install(new ServletModule());
 
-          // Install user's module.
-          if (module != null) {
-            logger.info("Installing " + module + "...");
-            install(module);
-          }
-          else {
-            logger.info("No module found. Set 'guice.module' to a Module "
-                + "class name if you'd like to use one.");
-          }
+                  // Install user's module.
+                  if (module != null) {
+                    logger.info("Installing " + module + "...");
+                    install(module);
+                  } else {
+                    logger.info(
+                        "No module found. Set 'guice.module' to a Module "
+                            + "class name if you'd like to use one.");
+                  }
 
-          // Tell the injector about all the action classes, etc., so it
-          // can validate them at startup.
-          for (Class<?> boundClass : boundClasses) {
-            // TODO: Set source from Struts XML.
-            bind(boundClass);
-          }
+                  // Tell the injector about all the action classes, etc., so it
+                  // can validate them at startup.
+                  for (Class<?> boundClass : boundClasses) {
+                    // TODO: Set source from Struts XML.
+                    bind(boundClass);
+                  }
 
-          // Validate the interceptor class.
-          for (ProvidedInterceptor interceptor : interceptors) {
-            interceptor.validate(binder());
-          }
-        }
-      });
+                  // Validate the interceptor class.
+                  for (ProvidedInterceptor interceptor : interceptors) {
+                    interceptor.validate(binder());
+                  }
+                }
+              });
 
       // Inject interceptors.
       for (ProvidedInterceptor interceptor : interceptors) {
@@ -163,9 +162,10 @@
     logger.info("Injector created successfully.");
   }
 
+  @Override
   @SuppressWarnings("unchecked")
-  public Interceptor buildInterceptor(InterceptorConfig interceptorConfig,
-      Map interceptorRefParams) throws ConfigurationException {
+  public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams)
+      throws ConfigurationException {
     // Ensure the interceptor class is present.
     Class<? extends Interceptor> interceptorClass;
     try {
@@ -174,14 +174,14 @@
       throw new RuntimeException(e);
     }
 
-    ProvidedInterceptor providedInterceptor = new ProvidedInterceptor(
-        interceptorConfig, interceptorRefParams, interceptorClass);
+    ProvidedInterceptor providedInterceptor =
+        new ProvidedInterceptor(interceptorConfig, interceptorRefParams, interceptorClass);
     interceptors.add(providedInterceptor);
     return providedInterceptor;
   }
 
-  Interceptor superBuildInterceptor(InterceptorConfig interceptorConfig,
-      Map interceptorRefParams) throws ConfigurationException {
+  Interceptor superBuildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams)
+      throws ConfigurationException {
     return super.buildInterceptor(interceptorConfig, interceptorRefParams);
   }
 
@@ -192,8 +192,8 @@
     final Class<? extends Interceptor> interceptorClass;
     Interceptor delegate;
 
-    ProvidedInterceptor(InterceptorConfig config, Map params,
-        Class<? extends Interceptor> interceptorClass) {
+    ProvidedInterceptor(
+        InterceptorConfig config, Map params, Class<? extends Interceptor> interceptorClass) {
       this.config = config;
       this.params = params;
       this.interceptorClass = interceptorClass;
@@ -202,15 +202,17 @@
     void validate(Binder binder) {
       // TODO: Set source from Struts XML.
       if (hasScope(interceptorClass)) {
-        binder.addError("Scoping interceptors is not currently supported."
-            + " Please remove the scope annotation from "
-            + interceptorClass.getName() + ".");
+        binder.addError(
+            "Scoping interceptors is not currently supported."
+                + " Please remove the scope annotation from "
+                + interceptorClass.getName()
+                + ".");
       }
 
       // Make sure it implements Interceptor.
       if (!Interceptor.class.isAssignableFrom(interceptorClass)) {
-        binder.addError(interceptorClass.getName() + " must implement "
-          + Interceptor.class.getName() + ".");
+        binder.addError(
+            interceptorClass.getName() + " must implement " + Interceptor.class.getName() + ".");
       }
     }
 
@@ -218,24 +220,25 @@
       delegate = superBuildInterceptor(config, params);
     }
 
+    @Override
     public void destroy() {
       if (null != delegate) {
         delegate.destroy();
       }
     }
 
+    @Override
     public void init() {
       throw new AssertionError();
     }
 
+    @Override
     public String intercept(ActionInvocation invocation) throws Exception {
       return delegate.intercept(invocation);
     }
   }
 
-  /**
-   * Returns true if the given class has a scope annotation.
-   */
+  /** Returns true if the given class has a scope annotation. */
   private static boolean hasScope(Class<? extends Interceptor> interceptorClass) {
     for (Annotation annotation : interceptorClass.getAnnotations()) {
       if (Annotations.isScopeAnnotation(annotation.annotationType())) {
diff --git a/extensions/struts2/src/com/google/inject/struts2/Struts2Factory.java b/extensions/struts2/src/com/google/inject/struts2/Struts2Factory.java
index 6e9263a..1e30048 100644
--- a/extensions/struts2/src/com/google/inject/struts2/Struts2Factory.java
+++ b/extensions/struts2/src/com/google/inject/struts2/Struts2Factory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,14 +20,12 @@
 import com.google.inject.Binder;
 import com.google.inject.Injector;
 import com.google.inject.internal.Annotations;
-
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ObjectFactory;
 import com.opensymphony.xwork2.config.ConfigurationException;
 import com.opensymphony.xwork2.config.entities.InterceptorConfig;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.interceptor.Interceptor;
-
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -37,8 +35,8 @@
 import java.util.logging.Logger;
 
 /**
- * Cleanup up version from Bob's GuiceObjectFactory. Now works properly with
- * GS2 and fixes several bugs.
+ * Cleanup up version from Bob's GuiceObjectFactory. Now works properly with GS2 and fixes several
+ * bugs.
  *
  * @author dhanji@gmail.com
  * @author benmccann.com
@@ -49,11 +47,11 @@
   private static final Logger logger = Logger.getLogger(Struts2Factory.class.getName());
   private static final String ERROR_NO_INJECTOR =
       "Cannot find a Guice injector.  Are you sure you registered a GuiceServletContextListener "
-    + "that uses the Struts2GuicePluginModule in your application's web.xml?";
+          + "that uses the Struts2GuicePluginModule in your application's web.xml?";
 
   private static @com.google.inject.Inject Injector injector;
 
-  private final List<ProvidedInterceptor> interceptors = new ArrayList<ProvidedInterceptor>();
+  private final List<ProvidedInterceptor> interceptors = new ArrayList<>();
   private volatile Injector strutsInjector;
 
   @Override
@@ -63,13 +61,15 @@
 
   @Inject(value = "guice.module", required = false)
   void setModule(String moduleClassName) {
-    throw new RuntimeException("The struts2 plugin no longer supports"
-        + " specifying a module via the 'guice.module' property in XML."
-        + " Please install your module via a GuiceServletContextListener instead.");
+    throw new RuntimeException(
+        "The struts2 plugin no longer supports"
+            + " specifying a module via the 'guice.module' property in XML."
+            + " Please install your module via a GuiceServletContextListener instead.");
   }
 
-  Set<Class<?>> boundClasses = new HashSet<Class<?>>();
+  Set<Class<?>> boundClasses = new HashSet<>();
 
+  @Override
   public Class<?> getClassInstance(String name) throws ClassNotFoundException {
     Class<?> clazz = super.getClassInstance(name);
 
@@ -97,7 +97,8 @@
     return clazz;
   }
 
-  @Override @SuppressWarnings("unchecked")
+  @Override
+  @SuppressWarnings("unchecked")
   public Object buildBean(Class clazz, Map<String, Object> extraContext) {
     if (strutsInjector == null) {
       synchronized (this) {
@@ -119,22 +120,25 @@
       throw new RuntimeException(ERROR_NO_INJECTOR);
     }
 
-    this.strutsInjector = injector.createChildInjector(new AbstractModule() {
-      protected void configure() {
+    this.strutsInjector =
+        injector.createChildInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
 
-        // Tell the injector about all the action classes, etc., so it
-        // can validate them at startup.
-        for (Class<?> boundClass : boundClasses) {
-          // TODO: Set source from Struts XML.
-          bind(boundClass);
-        }
+                // Tell the injector about all the action classes, etc., so it
+                // can validate them at startup.
+                for (Class<?> boundClass : boundClasses) {
+                  // TODO: Set source from Struts XML.
+                  bind(boundClass);
+                }
 
-        // Validate the interceptor class.
-        for (ProvidedInterceptor interceptor : interceptors) {
-          interceptor.validate(binder());
-        }
-      }
-    });
+                // Validate the interceptor class.
+                for (ProvidedInterceptor interceptor : interceptors) {
+                  interceptor.validate(binder());
+                }
+              }
+            });
 
     // Inject interceptors.
     for (ProvidedInterceptor interceptor : interceptors) {
@@ -144,26 +148,35 @@
     logger.info("Injector created successfully.");
   }
 
+  @Override
   @SuppressWarnings("unchecked")
-  public Interceptor buildInterceptor(InterceptorConfig interceptorConfig,
-      Map interceptorRefParams) throws ConfigurationException {
+  public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams)
+      throws ConfigurationException {
     // Ensure the interceptor class is present.
     Class<? extends Interceptor> interceptorClass;
     try {
-      interceptorClass = (Class<? extends Interceptor>)
-          getClassInstance(interceptorConfig.getClassName());
+      interceptorClass =
+          (Class<? extends Interceptor>) getClassInstance(interceptorConfig.getClassName());
     } catch (ClassNotFoundException e) {
       throw new RuntimeException(e);
     }
 
-    ProvidedInterceptor providedInterceptor = new ProvidedInterceptor(
-        interceptorConfig, interceptorRefParams, interceptorClass);
+    ProvidedInterceptor providedInterceptor =
+        new ProvidedInterceptor(interceptorConfig, interceptorRefParams, interceptorClass);
     interceptors.add(providedInterceptor);
+    if (strutsInjector != null) {
+      synchronized (this) {
+        if (strutsInjector != null) {
+          providedInterceptor.inject();
+        }
+      }
+    }
     return providedInterceptor;
   }
 
-  private Interceptor superBuildInterceptor(InterceptorConfig interceptorConfig,
-      Map<String, String> interceptorRefParams) throws ConfigurationException {
+  private Interceptor superBuildInterceptor(
+      InterceptorConfig interceptorConfig, Map<String, String> interceptorRefParams)
+      throws ConfigurationException {
     return super.buildInterceptor(interceptorConfig, interceptorRefParams);
   }
 
@@ -176,7 +189,9 @@
     private final Class<? extends Interceptor> interceptorClass;
     private Interceptor delegate;
 
-    ProvidedInterceptor(InterceptorConfig config, Map<String, String> params,
+    ProvidedInterceptor(
+        InterceptorConfig config,
+        Map<String, String> params,
         Class<? extends Interceptor> interceptorClass) {
       this.config = config;
       this.params = params;
@@ -186,15 +201,17 @@
     void validate(Binder binder) {
       // TODO: Set source from Struts XML.
       if (hasScope(interceptorClass)) {
-        binder.addError("Scoping interceptors is not currently supported."
-            + " Please remove the scope annotation from "
-            + interceptorClass.getName() + ".");
+        binder.addError(
+            "Scoping interceptors is not currently supported."
+                + " Please remove the scope annotation from "
+                + interceptorClass.getName()
+                + ".");
       }
 
       // Make sure it implements Interceptor.
       if (!Interceptor.class.isAssignableFrom(interceptorClass)) {
-        binder.addError(interceptorClass.getName() + " must implement "
-          + Interceptor.class.getName() + ".");
+        binder.addError(
+            interceptorClass.getName() + " must implement " + Interceptor.class.getName() + ".");
       }
     }
 
@@ -202,24 +219,25 @@
       delegate = superBuildInterceptor(config, params);
     }
 
+    @Override
     public void destroy() {
       if (null != delegate) {
         delegate.destroy();
       }
     }
 
+    @Override
     public void init() {
       throw new AssertionError();
     }
 
+    @Override
     public String intercept(ActionInvocation invocation) throws Exception {
       return delegate.intercept(invocation);
     }
   }
 
-  /**
-   * Returns true if the given class has a scope annotation.
-   */
+  /** Returns true if the given class has a scope annotation. */
   private static boolean hasScope(Class<? extends Interceptor> interceptorClass) {
     for (Annotation annotation : interceptorClass.getAnnotations()) {
       if (Annotations.isScopeAnnotation(annotation.annotationType())) {
diff --git a/extensions/struts2/src/com/google/inject/struts2/Struts2GuicePluginModule.java b/extensions/struts2/src/com/google/inject/struts2/Struts2GuicePluginModule.java
index a20ee53..57d2620 100644
--- a/extensions/struts2/src/com/google/inject/struts2/Struts2GuicePluginModule.java
+++ b/extensions/struts2/src/com/google/inject/struts2/Struts2GuicePluginModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,8 +19,8 @@
 import com.google.inject.AbstractModule;
 
 /**
- * Initializes the Struts 2 Guice Plugin. Must be added to the injector returned
- * by {@link com.google.inject.servlet.GuiceServletContextListener#getInjector}.
+ * Initializes the Struts 2 Guice Plugin. Must be added to the injector returned by {@link
+ * com.google.inject.servlet.GuiceServletContextListener#getInjector}.
  *
  * @author benmccann.com
  */
@@ -30,5 +30,4 @@
   protected void configure() {
     requestStaticInjection(Struts2Factory.class);
   }
-
 }
diff --git a/extensions/struts2/test/com/google/inject/struts2/Struts2FactoryTest.java b/extensions/struts2/test/com/google/inject/struts2/Struts2FactoryTest.java
index 3beca7f..c69ce3d 100644
--- a/extensions/struts2/test/com/google/inject/struts2/Struts2FactoryTest.java
+++ b/extensions/struts2/test/com/google/inject/struts2/Struts2FactoryTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,13 +22,10 @@
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.Provides;
-import com.google.inject.Singleton;
 import com.google.inject.servlet.GuiceServletContextListener;
 import com.google.inject.servlet.ServletModule;
-
-import junit.framework.TestCase;
-
 import java.util.Date;
+import junit.framework.TestCase;
 
 /**
  * Test for Struts2Factory
@@ -55,30 +52,28 @@
             @Override
             protected void configureServlets() {
               // Struts 2 setup
-              bind(StrutsPrepareAndExecuteFilter.class).in(Singleton.class);
+              bind(StrutsPrepareAndExecuteFilter.class)
+                  .in(com.google.inject.Singleton.class);
               filter("/*").through(StrutsPrepareAndExecuteFilter.class);
             }
           },
-          module
-      );
+          module);
     }
-
   }
 
   public void testStruts2Factory() {
     Struts2Factory s2Factory = new Struts2Factory();
-    TestListener testListener = new TestListener(new AbstractModule() {
-      @Override
-      protected void configure() {
-      }
+    TestListener testListener =
+        new TestListener(
+            new AbstractModule() {
 
-      @Provides @SuppressWarnings("unused")
-      Date provideDate() {
-        return TODAY;
-      }
-    });
+              @Provides
+              @SuppressWarnings("unused")
+              Date provideDate() {
+                return TODAY;
+              }
+            });
     assertEquals(TODAY, testListener.getInjector().getInstance(Date.class));
     assertEquals(TODAY, s2Factory.buildBean(Date.class, null));
   }
-
 }
diff --git a/extensions/testlib/build.xml b/extensions/testlib/build.xml
index b85d6ec..d6b0059 100644
--- a/extensions/testlib/build.xml
+++ b/extensions/testlib/build.xml
@@ -4,10 +4,23 @@
 
   <import file="../../common.xml"/>
 
+  <target name="compile" description="Compile Java source." depends="common.compile">
+    <!--
+      Build the throwingproviders extension using an ant subtask. This could be
+      accomplished using either the "include" [1] directive, or extension points [2],
+      but both were introduced in Ant 1.8 and we're using ant 1.6. This does
+      mean that we will compile guice-throwingproviders twice.
+      [1]: https://ant.apache.org/manual/Tasks/include.html
+      [2]: https://ant.apache.org/manual/targets.html#extension-points
+    -->
+    <ant antfile="../throwingproviders/build.xml" target="compile"/>
+  </target>
+
   <path id="compile.classpath">
     <fileset dir="${lib.dir}" includes="*.jar"/>
     <fileset dir="${lib.dir}/build" includes="*.jar"/>
     <pathelement path="../../build/classes"/>
+    <pathelement path="../throwingproviders/build/classes"/>
   </path>
 
   <target name="jar" depends="compile, manifest" description="Build jar.">
diff --git a/extensions/testlib/pom.xml b/extensions/testlib/pom.xml
index 49c45b4..061b232 100644
--- a/extensions/testlib/pom.xml
+++ b/extensions/testlib/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-testlib</artifactId>
@@ -23,6 +23,33 @@
           </excludes>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.testlib</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.inject.extensions</groupId>
+      <artifactId>guice-throwingproviders</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+    </dependency>
+  </dependencies>
 </project>
diff --git a/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java b/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
index 6c75fc7..e955910 100644
--- a/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
+++ b/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
@@ -23,8 +23,12 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotation used by {@link BoundFieldModule} to indicate that a field should be bound to its
- * value using Guice.
+ * Annotation used by {@link BoundFieldModule} to indicate that a field should be bound to its value
+ * using Guice.
+ *
+ * <p>Binding to {@code null} is only allowed for fields that are annotated {@code @Nullable}. See
+ * <a
+ * href="https://github.com/google/guice/wiki/UseNullable">https://github.com/google/guice/wiki/UseNullable</a>
  *
  * @see BoundFieldModule
  * @author eatnumber1@google.com (Russ Harmon)
@@ -39,10 +43,11 @@
   Class<?> to() default Bind.class;
 
   /**
-   * If true, {@link BoundFieldModule} will delay retrieving the field's value until injection time
-   * rather than eagerly fetching it at configure time.
-   * 
-   * <p>This option is not supported with Provider valued fields.
+   * If true, {@link BoundFieldModule} will delay reading the field until injection time rather than
+   * eagerly reading it at configure time.
+   *
+   * <p>When used with Provider valued fields, the provider will be read from the field and {@code
+   * .get()} will be called for each provision. This may be useful for testing provision failures.
    */
   boolean lazy() default false;
 }
diff --git a/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java b/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
index c280848..f5f2264 100644
--- a/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
+++ b/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
@@ -26,8 +26,9 @@
 import com.google.inject.binder.AnnotatedBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.internal.Annotations;
+import com.google.inject.internal.Nullability;
 import com.google.inject.spi.Message;
-
+import com.google.inject.util.Providers;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.ParameterizedType;
@@ -42,43 +43,40 @@
  * <p>The following rules are followed in determining how fields are bound using this module:
  *
  * <ul>
- * <li>
- * For each {@link Bind} annotated field of an object and its superclasses, this module will bind
- * that field's type to that field's value at injector creation time. This includes both instance
- * and static fields.
- * </li>
- * <li>
- * If {@link Bind#to} is specified, the field's value will be bound to the class specified by
- * {@link Bind#to} instead of the field's actual type.
- * </li>
- * <li>
- * If a {@link BindingAnnotation} or {@link javax.inject.Qualifier} is present on the field,
- * that field will be bound using that annotation via {@link AnnotatedBindingBuilder#annotatedWith}.
- * For example, {@code bind(Foo.class).annotatedWith(BarAnnotation.class).toInstance(theValue)}.
- * It is an error to supply more than one {@link BindingAnnotation} or
- * {@link javax.inject.Qualifier}.
- * </li>
- * <li>
- * If the field is of type {@link Provider}, the field's value will be bound as a {@link Provider}
- * using {@link LinkedBindingBuilder#toProvider} to the provider's parameterized type. For example,
- * {@code Provider<Integer>} binds to {@link Integer}. Attempting to bind a non-parameterized
- * {@link Provider} without a {@link Bind#to} clause is an error.
- * </li>
+ *   <li>For each {@link Bind} annotated field of an object and its superclasses, this module will
+ *       bind that field's type to that field's value at injector creation time. This includes both
+ *       instance and static fields.
+ *   <li>If {@link Bind#to} is specified, the field's value will be bound to the class specified by
+ *       {@link Bind#to} instead of the field's actual type.
+ *   <li>If {@link Bind#lazy} is true, this module will delay reading the value from the field until
+ *       injection time, allowing the field's value to be reassigned during the course of a test's
+ *       execution.
+ *   <li>If a {@link BindingAnnotation} or {@link javax.inject.Qualifier} is present on the field,
+ *       that field will be bound using that annotation via {@link
+ *       AnnotatedBindingBuilder#annotatedWith}. For example, {@code
+ *       bind(Foo.class).annotatedWith(BarAnnotation.class).toInstance(theValue)}. It is an error to
+ *       supply more than one {@link BindingAnnotation} or {@link javax.inject.Qualifier}.
+ *   <li>If the field is of type {@link Provider}, the field's value will be bound as a {@link
+ *       Provider} using {@link LinkedBindingBuilder#toProvider} to the provider's parameterized
+ *       type. For example, {@code Provider<Integer>} binds to {@link Integer}. Attempting to bind a
+ *       non-parameterized {@link Provider} without a {@link Bind#to} clause is an error.
  * </ul>
  *
  * <p>Example use:
+ *
  * <pre><code>
  * public class TestFoo {
  *   // bind(new TypeLiteral{@code <List<Object>>}() {}).toInstance(listOfObjects);
  *   {@literal @}Bind private List{@code <Object>} listOfObjects = Lists.of();
- *   
+ *
+ *   // private String userName = "string_that_changes_over_time";
  *   // bind(String.class).toProvider(new Provider() { public String get() { return userName; }});
  *   {@literal @}Bind(lazy = true) private String userName;
  *
  *   // bind(SuperClass.class).toInstance(aSubClass);
  *   {@literal @}Bind(to = SuperClass.class) private SubClass aSubClass = new SubClass();
  *
- *   // bind(Object.class).annotatedWith(MyBindingAnnotation.class).toInstance(object2);
+ *   // bind(String.class).annotatedWith(MyBindingAnnotation.class).toInstance(myString);
  *   {@literal @}Bind
  *   {@literal @}MyBindingAnnotation
  *   private String myString = "hello";
@@ -131,8 +129,8 @@
     /**
      * The actual type of the field.
      *
-     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be
-     * {@link Number}.
+     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be {@link
+     * Number}.
      */
     final TypeLiteral<?> type;
 
@@ -142,26 +140,23 @@
     /**
      * The type this field will bind to.
      *
-     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be
-     * {@link Object} and {@code @Bind Number one = new Integer(1);} will be {@link Number}.
+     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be {@link
+     * Object} and {@code @Bind Number one = new Integer(1);} will be {@link Number}.
      */
     final TypeLiteral<?> boundType;
 
     /**
      * The "natural" type of this field.
      *
-     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be
-     * {@link Number}, and {@code @Bind(to = Object.class) Provider<Number> one = new Integer(1);}
-     * will be {@link Number}.
+     * <p>For example, {@code @Bind(to = Object.class) Number one = new Integer(1);} will be {@link
+     * Number}, and {@code @Bind(to = Object.class) Provider<Number> one = new Integer(1);} will be
+     * {@link Number}.
      *
      * @see #getNaturalFieldType
      */
     final Optional<TypeLiteral<?>> naturalType;
 
-    BoundFieldInfo(
-        Field field,
-        Bind bindAnnotation,
-        TypeLiteral<?> fieldType) {
+    BoundFieldInfo(Field field, Bind bindAnnotation, TypeLiteral<?> fieldType) {
       this.field = field;
       this.type = fieldType;
       this.bindAnnotation = bindAnnotation;
@@ -182,7 +177,7 @@
           throwBoundFieldException(
               field,
               "Non parameterized Provider fields must have an explicit "
-              + "binding class via @Bind(to = Foo.class)");
+                  + "binding class via @Bind(to = Foo.class)");
         }
         return this.naturalType.get();
       } else {
@@ -199,7 +194,7 @@
      * is the field's actual type.
      *
      * @return the type this field binds to naturally, or {@link Optional#absent()} if this field is
-     * a non-parameterized {@link Provider}.
+     *     a non-parameterized {@link Provider}.
      */
     private Optional<TypeLiteral<?>> getNaturalFieldType() {
       if (isTransparentProvider(type.getRawType())) {
@@ -225,6 +220,12 @@
         throw new AssertionError(e);
       }
     }
+
+    /** Returns whether a binding supports null values. */
+    boolean allowsNull() {
+      return !isTransparentProvider(type.getRawType())
+          && Nullability.allowsNull(field.getAnnotations());
+    }
   }
 
   private static boolean hasInject(Field field) {
@@ -235,31 +236,24 @@
   /**
    * Retrieve a {@link BoundFieldInfo}.
    *
-   * <p>This returns a {@link BoundFieldInfo} if the field has a {@link Bind} annotation.
-   * Otherwise it returns {@link Optional#absent()}.
+   * <p>This returns a {@link BoundFieldInfo} if the field has a {@link Bind} annotation. Otherwise
+   * it returns {@link Optional#absent()}.
    */
   private Optional<BoundFieldInfo> getBoundFieldInfo(
-      TypeLiteral<?> containingClassType,
-      Field field) {
+      TypeLiteral<?> containingClassType, Field field) {
     Bind bindAnnotation = field.getAnnotation(Bind.class);
     if (bindAnnotation == null) {
       return Optional.absent();
     }
     if (hasInject(field)) {
-      throwBoundFieldException(
-          field,
-          "Fields annotated with both @Bind and @Inject are illegal.");
+      throwBoundFieldException(field, "Fields annotated with both @Bind and @Inject are illegal.");
     }
     return Optional.of(
-        new BoundFieldInfo(
-            field,
-            bindAnnotation,
-            containingClassType.getFieldType(field)));
+        new BoundFieldInfo(field, bindAnnotation, containingClassType.getFieldType(field)));
   }
 
   private LinkedBindingBuilder<?> verifyBindingAnnotations(
-      Field field,
-      AnnotatedBindingBuilder<?> annotatedBinder) {
+      Field field, AnnotatedBindingBuilder<?> annotatedBinder) {
     LinkedBindingBuilder<?> binderRet = annotatedBinder;
     for (Annotation annotation : field.getAnnotations()) {
       Class<? extends Annotation> annotationType = annotation.annotationType();
@@ -275,14 +269,17 @@
   /**
    * Determines if {@code clazz} is a "transparent provider".
    *
-   * <p>A transparent provider is a {@link com.google.inject.Provider} or
-   * {@link javax.inject.Provider} which binds to it's parameterized type when used as the argument
-   * to {@link Binder#bind}.
+   * <p>A transparent provider is a {@link com.google.inject.Provider} or {@link
+   * javax.inject.Provider} which binds to it's parameterized type when used as the argument to
+   * {@link Binder#bind}.
    *
    * <p>A {@link Provider} is transparent if the base class of that object is {@link Provider}. In
-   * other words, subclasses of {@link Provider} are not transparent. As a special case, if a
-   * {@link Provider} has no parameterized type but is otherwise transparent, then it is considered
+   * other words, subclasses of {@link Provider} are not transparent. As a special case, if a {@link
+   * Provider} has no parameterized type but is otherwise transparent, then it is considered
    * transparent.
+   *
+   * <p>Subclasses of {@link Provider} are not considered transparent in order to allow users to
+   * bind those subclasses directly, enabling them to inject the providers themselves.
    */
   private static boolean isTransparentProvider(Class<?> clazz) {
     return com.google.inject.Provider.class == clazz || javax.inject.Provider.class == clazz;
@@ -315,43 +312,72 @@
 
     if (isTransparentProvider(fieldInfo.type.getRawType())) {
       if (fieldInfo.bindAnnotation.lazy()) {
-        // We don't support this because it is confusing about when values are captured.
-        throwBoundFieldException(fieldInfo.field, 
-            "'lazy' is incompatible with Provider valued fields");
+        binderUnsafe.toProvider(
+            new Provider<Object>() {
+              @Override
+              // @Nullable
+              public Object get() {
+                // This is safe because we checked that the field's type is Provider above.
+                @SuppressWarnings("unchecked")
+                javax.inject.Provider<?> provider =
+                    (javax.inject.Provider<?>) getFieldValue(fieldInfo);
+                return provider.get();
+              }
+            });
+      } else {
+        // This is safe because we checked that the field's type is Provider above.
+        @SuppressWarnings("unchecked")
+        javax.inject.Provider<?> fieldValueUnsafe =
+            (javax.inject.Provider<?>) getFieldValue(fieldInfo);
+        binderUnsafe.toProvider(fieldValueUnsafe);
       }
-      // This is safe because we checked that the field's type is Provider above.
-      @SuppressWarnings("unchecked")
-      Provider<?> fieldValueUnsafe = (Provider<?>) getFieldValue(fieldInfo);
-      binderUnsafe.toProvider(fieldValueUnsafe);
     } else if (fieldInfo.bindAnnotation.lazy()) {
-      binderUnsafe.toProvider(new Provider<Object>() {
-        @Override public Object get() {
-          return getFieldValue(fieldInfo);
-        }
-      });
+      binderUnsafe.toProvider(
+          new Provider<Object>() {
+            @Override
+            // @Nullable
+            public Object get() {
+              return getFieldValue(fieldInfo);
+            }
+          });
     } else {
-      binderUnsafe.toInstance(getFieldValue(fieldInfo));
+      Object fieldValue = getFieldValue(fieldInfo);
+      if (fieldValue == null) {
+        binderUnsafe.toProvider(Providers.of(null));
+      } else {
+        binderUnsafe.toInstance(fieldValue);
+      }
     }
   }
 
+  // @Nullable
+  /**
+   * Returns the field value to bind, throwing for non-{@code @Nullable} fields with null values,
+   * and for null "transparent providers".
+   */
   private Object getFieldValue(final BoundFieldInfo fieldInfo) {
     Object fieldValue = fieldInfo.getValue();
-    if (fieldValue == null) {
-      throwBoundFieldException(
-          fieldInfo.field,
-          "Binding to null values is not allowed. "
-              + "Use Providers.of(null) if this is your intended behavior.",
-              fieldInfo.field.getName());
+    if (fieldValue == null && !fieldInfo.allowsNull()) {
+      if (isTransparentProvider(fieldInfo.type.getRawType())) {
+        throwBoundFieldException(
+            fieldInfo.field,
+            "Binding to null is not allowed. Use Providers.of(null) if this is your intended "
+                + "behavior.",
+            fieldInfo.field.getName());
+      } else {
+        throwBoundFieldException(
+            fieldInfo.field,
+            "Binding to null values is only allowed for fields that are annotated @Nullable.",
+            fieldInfo.field.getName());
+      }
     }
     return fieldValue;
   }
 
   private void throwBoundFieldException(Field field, String format, Object... args) {
     Preconditions.checkNotNull(binder);
-    String source = String.format(
-        "%s field %s",
-        field.getDeclaringClass().getName(),
-        field.getName());
+    String source =
+        String.format("%s field %s", field.getDeclaringClass().getName(), field.getName());
     throw new BoundFieldException(new Message(source, String.format(format, args)));
   }
 
@@ -364,8 +390,7 @@
     while (currentClassType.getRawType() != Object.class) {
       for (Field field : currentClassType.getRawType().getDeclaredFields()) {
         try {
-          Optional<BoundFieldInfo> fieldInfoOpt =
-              getBoundFieldInfo(currentClassType, field);
+          Optional<BoundFieldInfo> fieldInfoOpt = getBoundFieldInfo(currentClassType, field);
           if (fieldInfoOpt.isPresent()) {
             bindField(fieldInfoOpt.get());
           }
diff --git a/extensions/testlib/src/com/google/inject/testing/throwingproviders/CheckedProviderSubject.java b/extensions/testlib/src/com/google/inject/testing/throwingproviders/CheckedProviderSubject.java
new file mode 100644
index 0000000..aa0ae2f
--- /dev/null
+++ b/extensions/testlib/src/com/google/inject/testing/throwingproviders/CheckedProviderSubject.java
@@ -0,0 +1,83 @@
+package com.google.inject.testing.throwingproviders;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.ThrowableSubject;
+import com.google.inject.throwingproviders.CheckedProvider;
+import javax.annotation.Nullable;
+
+/**
+ * Truth {@link Subject} for use with {@link CheckedProvider} classes.
+ *
+ * @author eatnumber1@google.com (Russ Harmon)
+ */
+public final class CheckedProviderSubject<T, P extends CheckedProvider<T>>
+    extends Subject<CheckedProviderSubject<T, P>, P> {
+
+  private static final class CheckedProviderSubjectFactory<T, P extends CheckedProvider<T>>
+      implements Subject.Factory<CheckedProviderSubject<T, P>, P> {
+    @Override
+    public CheckedProviderSubject<T, P> createSubject(
+        FailureMetadata failureMetadata, @Nullable P target) {
+      return new CheckedProviderSubject<T, P>(failureMetadata, target);
+    }
+  }
+
+  public static <T, P extends CheckedProvider<T>>
+      Subject.Factory<CheckedProviderSubject<T, P>, P> checkedProviders() {
+    return new CheckedProviderSubjectFactory<>();
+  }
+
+  public static <T, P extends CheckedProvider<T>> CheckedProviderSubject<T, P> assertThat(
+      @Nullable P provider) {
+    return assertAbout(CheckedProviderSubject.<T, P>checkedProviders()).that(provider);
+  }
+
+  private CheckedProviderSubject(FailureMetadata failureMetadata, @Nullable P subject) {
+    super(failureMetadata, subject);
+  }
+
+  /**
+   * Allows for assertions on the value provided by this provider.
+   *
+   * <p>The value provided by a checked provider is the object returned by a call to {@link
+   * CheckedProvider#get}
+   *
+   * @return a {@link Subject} for asserting against the return value of {@link CheckedProvider#get}
+   */
+  public Subject<?, Object> providedValue() {
+    P provider = actual();
+    T got;
+    try {
+      got = provider.get();
+    } catch (Exception e) {
+      failWithRawMessageAndCause(
+          String.format("checked provider <%s> threw an exception", provider), e);
+      return ignoreCheck().that(new Object());
+    }
+    return check().withMessage("value provided by <%s>", provider).that(got);
+  }
+
+  /**
+   * Allows for assertions on the exception thrown by this provider.
+   *
+   * <p>The exception thrown by a checked provider is the {@link Throwable} thrown by a call to
+   * {@link CheckedProvider#get}
+   *
+   * @return a {@link ThrowableSubject} for asserting against the {@link Throwable} thrown by {@link
+   *     CheckedProvider#get}
+   */
+  public ThrowableSubject thrownException() {
+    P provider = actual();
+    T got;
+    try {
+      got = provider.get();
+    } catch (Throwable e) {
+      return check().withMessage("exception thrown by <%s>", provider).that(e);
+    }
+    failWithBadResults("threw", "an exception", "provided", got);
+    return ignoreCheck().that(new Throwable());
+  }
+}
diff --git a/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java b/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
index 2db1215..d15b229 100644
--- a/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
+++ b/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
@@ -31,14 +31,11 @@
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Retention;
 import java.util.Arrays;
 import java.util.List;
-
 import javax.inject.Qualifier;
+import junit.framework.TestCase;
 
 /** Unit tests for {@link BoundFieldModule}. */
 public class BoundFieldModuleTest extends TestCase {
@@ -53,9 +50,10 @@
 
   public void testBindingOnePrivate() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue;
-    };
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -65,9 +63,10 @@
 
   public void testBindingOnePublic() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind public Integer anInt = testValue;
-    };
+    Object instance =
+        new Object() {
+          @Bind public Integer anInt = testValue;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -101,10 +100,11 @@
   public void testBindingTwo() {
     final Integer testValue = 1024;
     final String testString = "Hello World!";
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue;
-      @Bind private String aString = testString;
-    };
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue;
+          @Bind private String aString = testString;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -115,9 +115,11 @@
 
   public void testBindingSuperType() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = Number.class) private Integer anInt = testValue;
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = Number.class)
+          private Integer anInt = testValue;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -127,31 +129,36 @@
 
   public void testBindingSuperTypeAccessSubType() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = Number.class) private Integer anInt = testValue;
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = Number.class)
+          private Integer anInt = testValue;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
 
     try {
       injector.getInstance(Integer.class);
+      fail();
     } catch (ConfigurationException e) {
-      assertContains(
-          e.getMessage(),
-          "Could not find a suitable constructor in java.lang.Integer");
+      assertContains(e.getMessage(), "Could not find a suitable constructor in java.lang.Integer");
     }
   }
 
   public void testBindingIncorrectTypeProviderFails() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = String.class) private Provider<Integer> anIntProvider = new Provider<Integer>() {
-        @Override public Integer get() {
-          return testValue;
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = String.class)
+          private Provider<Integer> anIntProvider =
+              new Provider<Integer>() {
+                @Override
+                public Integer get() {
+                  return testValue;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -162,7 +169,7 @@
       assertContains(
           e.getMessage(),
           "Requested binding type \"java.lang.String\" is not "
-          + "assignable from field binding type \"java.lang.Integer\"");
+              + "assignable from field binding type \"java.lang.Integer\"");
     }
   }
 
@@ -172,21 +179,19 @@
 
   public void testBindingWithBindingAnnotation() {
     final Integer testValue1 = 1024, testValue2 = 2048;
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue1;
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue1;
 
-      @Bind
-      @SomeBindingAnnotation
-      private Integer anotherInt = testValue2;
-    };
+          @Bind @SomeBindingAnnotation private Integer anotherInt = testValue2;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
 
     assertEquals(testValue1, injector.getInstance(Integer.class));
     assertEquals(
-        testValue2,
-        injector.getInstance(Key.get(Integer.class, SomeBindingAnnotation.class)));
+        testValue2, injector.getInstance(Key.get(Integer.class, SomeBindingAnnotation.class)));
   }
 
   @Qualifier
@@ -195,74 +200,68 @@
 
   public void testBindingWithQualifier() {
     final Integer testValue1 = 1024, testValue2 = 2048;
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue1;
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue1;
 
-      @Bind
-      @SomeQualifier
-      private Integer anotherInt = testValue2;
-    };
+          @Bind @SomeQualifier private Integer anotherInt = testValue2;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
 
     assertEquals(testValue1, injector.getInstance(Integer.class));
-    assertEquals(
-        testValue2,
-        injector.getInstance(Key.get(Integer.class, SomeQualifier.class)));
+    assertEquals(testValue2, injector.getInstance(Key.get(Integer.class, SomeQualifier.class)));
   }
 
   public void testCanReuseBindingAnnotationsWithDifferentValues() {
     final Integer testValue1 = 1024, testValue2 = 2048;
     final String name1 = "foo", name2 = "bar";
-    Object instance = new Object() {
-      @Bind
-      @Named(name1)
-      private Integer anInt = testValue1;
+    Object instance =
+        new Object() {
+          @Bind
+          @Named(name1)
+          private Integer anInt = testValue1;
 
-      @Bind
-      @Named(name2)
-      private Integer anotherInt = testValue2;
-    };
+          @Bind
+          @Named(name2)
+          private Integer anotherInt = testValue2;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
 
-    assertEquals(
-        testValue1,
-        injector.getInstance(Key.get(Integer.class, Names.named(name1))));
-    assertEquals(
-        testValue2,
-        injector.getInstance(Key.get(Integer.class, Names.named(name2))));
+    assertEquals(testValue1, injector.getInstance(Key.get(Integer.class, Names.named(name1))));
+    assertEquals(testValue2, injector.getInstance(Key.get(Integer.class, Names.named(name2))));
   }
 
   public void testBindingWithValuedBindingAnnotation() {
     final Integer testValue1 = 1024, testValue2 = 2048;
     final String name = "foo";
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue1;
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue1;
 
-      @Bind
-      @Named(name)
-      private Integer anotherInt = testValue2;
-    };
+          @Bind
+          @Named(name)
+          private Integer anotherInt = testValue2;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
 
     assertEquals(testValue1, injector.getInstance(Integer.class));
-    assertEquals(
-        testValue2,
-        injector.getInstance(Key.get(Integer.class, Names.named(name))));
+    assertEquals(testValue2, injector.getInstance(Key.get(Integer.class, Names.named(name))));
   }
 
   public void testBindingWithGenerics() {
     final List<Integer> testIntList = Arrays.asList(new Integer[] {1, 2, 3});
     final List<Boolean> testBoolList = Arrays.asList(new Boolean[] {true, true, false});
-    Object instance = new Object() {
-      @Bind private List<Integer> anIntList = testIntList;
-      @Bind private List<Boolean> aBoolList = testBoolList;
-    };
+    Object instance =
+        new Object() {
+          @Bind private List<Integer> anIntList = testIntList;
+          @Bind private List<Boolean> aBoolList = testBoolList;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -285,9 +284,11 @@
 
   public void testIncompatibleBindingType() {
     final Integer testInt = 1024;
-    Object instance = new Object() {
-      @Bind(to = String.class) private Integer anInt = testInt;
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = String.class)
+          private Integer anInt = testInt;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -295,25 +296,28 @@
       Guice.createInjector(module);
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Requested binding type \"java.lang.String\" is not assignable from field binding type "
-          + "\"java.lang.Integer\"");
+              + "\"java.lang.Integer\"");
     }
   }
 
   public void testFailureOnMultipleBindingAnnotations() {
     final Integer testInt = 1024;
-    Object instance = new Object() {
-      @Bind
-      @Named("a")
-      @SomeBindingAnnotation
-      private Integer anInt = testInt;
-    };
+    Object instance =
+        new Object() {
+          @Bind
+          @Named("a")
+          @SomeBindingAnnotation
+          private Integer anInt = testInt;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
     try {
       Guice.createInjector(module);
+      fail();
     } catch (CreationException e) {
       assertContains(e.getMessage(), "More than one annotation is specified for this binding.");
     }
@@ -321,11 +325,12 @@
 
   public void testBindingSuperTypeAndBindingAnnotation() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = Number.class)
-      @Named("foo")
-      private Integer anInt = testValue;
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = Number.class)
+          @Named("foo")
+          private Integer anInt = testValue;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -335,13 +340,17 @@
 
   public void testBindingProvider() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private Provider<Integer> anInt = new Provider<Integer>() {
-        @Override public Integer get() {
-          return testValue;
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind
+          private Provider<Integer> anInt =
+              new Provider<Integer>() {
+                @Override
+                public Integer get() {
+                  return testValue;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -349,10 +358,31 @@
     assertEquals(testValue, injector.getInstance(Integer.class));
   }
 
-  public void testBindingNullField() {
-    Object instance = new Object() {
-      @Bind private Integer anInt = null;
-    };
+  public void testBindingJavaxProvider() {
+    final Integer testValue = 1024;
+    Object instance =
+        new Object() {
+          @Bind
+          private javax.inject.Provider<Integer> anInt =
+              new javax.inject.Provider<Integer>() {
+                @Override
+                public Integer get() {
+                  return testValue;
+                }
+              };
+        };
+
+    BoundFieldModule module = BoundFieldModule.of(instance);
+    Injector injector = Guice.createInjector(module);
+
+    assertEquals(testValue, injector.getInstance(Integer.class));
+  }
+
+  public void testBindingNonNullableNullField() {
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = null;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -360,16 +390,30 @@
       Guice.createInjector(module);
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
-          "Binding to null values is not allowed. "
-          + "Use Providers.of(null) if this is your intended behavior.");
+      assertContains(
+          e.getMessage(),
+          "Binding to null values is only allowed for fields that are annotated @Nullable.");
     }
   }
 
+  @Retention(RUNTIME)
+  private @interface Nullable {}
+
+  public void testBindingNullableNullField() {
+    Object instance =
+        new Object() {
+          @Bind @Nullable private Integer anInt = null;
+        };
+
+    Injector injector = Guice.createInjector(BoundFieldModule.of(instance));
+    assertNull(injector.getInstance(Integer.class));
+  }
+
   public void testBindingNullProvider() {
-    Object instance = new Object() {
-      @Bind private Provider<Integer> anIntProvider = null;
-    };
+    Object instance =
+        new Object() {
+          @Bind private Provider<Integer> anIntProvider = null;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -377,9 +421,29 @@
       Guice.createInjector(module);
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
-          "Binding to null values is not allowed. "
-          + "Use Providers.of(null) if this is your intended behavior.");
+      assertContains(
+          e.getMessage(),
+          "Binding to null is not allowed. Use Providers.of(null) if this is your intended "
+              + "behavior.");
+    }
+  }
+
+  public void testBindingNullableNullProvider() {
+    Object instance =
+        new Object() {
+          @Bind @Nullable private Provider<Integer> anIntProvider = null;
+        };
+
+    BoundFieldModule module = BoundFieldModule.of(instance);
+
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException e) {
+      assertContains(
+          e.getMessage(),
+          "Binding to null is not allowed. Use Providers.of(null) if this is your intended "
+              + "behavior.");
     }
   }
 
@@ -390,16 +454,18 @@
       this.value = value;
     }
 
-    @Override public Integer get() {
+    @Override
+    public Integer get() {
       return value;
     }
   }
 
   public void testProviderSubclassesBindToTheProviderItself() {
     final IntegerProvider integerProvider = new IntegerProvider(1024);
-    Object instance = new Object() {
-      @Bind private IntegerProvider anIntProvider = integerProvider;
-    };
+    Object instance =
+        new Object() {
+          @Bind private IntegerProvider anIntProvider = integerProvider;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -409,9 +475,10 @@
 
   public void testProviderSubclassesDoNotBindParameterizedType() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private IntegerProvider anIntProvider = new IntegerProvider(testValue);
-    };
+    Object instance =
+        new Object() {
+          @Bind private IntegerProvider anIntProvider = new IntegerProvider(testValue);
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -424,6 +491,18 @@
     }
   }
 
+  public void testNullableProviderSubclassesAllowNull() {
+    Object instance =
+        new Object() {
+          @Bind @Nullable private IntegerProvider anIntProvider = null;
+        };
+
+    BoundFieldModule module = BoundFieldModule.of(instance);
+    Injector injector = Guice.createInjector(module);
+
+    assertNull(injector.getInstance(IntegerProvider.class));
+  }
+
   private static class ParameterizedObject<T> {
     ParameterizedObject(T instance) {
       this.instance = instance;
@@ -433,7 +512,7 @@
   }
 
   public void testBindParameterizedTypeFails() {
-    ParameterizedObject<Integer> instance = new ParameterizedObject<Integer>(0);
+    ParameterizedObject<Integer> instance = new ParameterizedObject<>(0);
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -456,10 +535,11 @@
   }
 
   public void testBindArray() {
-    final Integer[] testArray = new Integer[] { 1024, 2048 };
-    Object instance = new Object() {
-      @Bind private Integer[] anIntArray = testArray;
-    };
+    final Integer[] testArray = new Integer[] {1024, 2048};
+    Object instance =
+        new Object() {
+          @Bind private Integer[] anIntArray = testArray;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -469,13 +549,17 @@
 
   public void testRawProviderCannotBeBound() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private Provider anIntProvider = new Provider() {
-        @Override public Object get() {
-          return testValue;
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind
+          private Provider anIntProvider =
+              new Provider() {
+                @Override
+                public Object get() {
+                  return testValue;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
@@ -483,21 +567,26 @@
       Guice.createInjector(module);
       fail();
     } catch (CreationException e) {
-      assertContains(e.getMessage(),
+      assertContains(
+          e.getMessage(),
           "Non parameterized Provider fields must have an "
-          + "explicit binding class via @Bind(to = Foo.class)");
+              + "explicit binding class via @Bind(to = Foo.class)");
     }
   }
 
   public void testExplicitlyBoundRawProviderCanBeBound() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = Integer.class) private Provider anIntProvider = new Provider() {
-        @Override public Object get() {
-          return testValue;
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = Integer.class)
+          private Provider anIntProvider =
+              new Provider() {
+                @Override
+                public Object get() {
+                  return testValue;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -507,13 +596,17 @@
 
   public void testRawProviderCanBindToIncorrectType() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind(to = String.class) private Provider anIntProvider = new Provider() {
-        @Override public Object get() {
-          return testValue;
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind(to = String.class)
+          private Provider anIntProvider =
+              new Provider() {
+                @Override
+                public Object get() {
+                  return testValue;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -522,14 +615,18 @@
   }
 
   public void testMultipleErrorsAreAggregated() {
-    Object instance = new Object() {
-      @Bind private Provider aProvider;
-      @Bind(to = String.class) private Integer anInt;
-    };
+    Object instance =
+        new Object() {
+          @Bind private Provider aProvider;
+
+          @Bind(to = String.class)
+          private Integer anInt;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     try {
       Guice.createInjector(module);
+      fail();
     } catch (CreationException e) {
       assertEquals(2, e.getErrorMessages().size());
     }
@@ -537,9 +634,10 @@
 
   public void testBindingProviderWithProviderSubclassValue() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private Provider<Integer> anIntProvider = new IntegerProvider(testValue);
-    };
+    Object instance =
+        new Object() {
+          @Bind private Provider<Integer> anIntProvider = new IntegerProvider(testValue);
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -548,34 +646,36 @@
   }
 
   public void testBoundFieldsCannotBeInjected() {
-    Object instance = new Object() {
-      @Bind
-      @Inject
-      Integer anInt = 0;
-    };
+    Object instance =
+        new Object() {
+          @Bind @Inject Integer anInt = 0;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
 
     try {
       Guice.createInjector(module);
+      fail();
     } catch (CreationException e) {
-      assertContains(
-          e.getMessage(),
-          "Fields annotated with both @Bind and @Inject are illegal.");
+      assertContains(e.getMessage(), "Fields annotated with both @Bind and @Inject are illegal.");
     }
   }
 
   public void testIncrementingProvider() {
     final Integer testBaseValue = 1024;
-    Object instance = new Object() {
-      @Bind private Provider<Integer> anIntProvider = new Provider<Integer>() {
-        private int value = testBaseValue;
+    Object instance =
+        new Object() {
+          @Bind
+          private Provider<Integer> anIntProvider =
+              new Provider<Integer>() {
+                private int value = testBaseValue;
 
-        @Override public Integer get() {
-          return value++;
-        }
-      };
-    };
+                @Override
+                public Integer get() {
+                  return value++;
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -586,13 +686,17 @@
   }
 
   public void testProviderDoesNotProvideDuringInjectorConstruction() {
-    Object instance = new Object() {
-      @Bind private Provider<Integer> myIntProvider = new Provider<Integer>() {
-        @Override public Integer get() {
-          throw new UnsupportedOperationException();
-        }
-      };
-    };
+    Object instance =
+        new Object() {
+          @Bind
+          private Provider<Integer> myIntProvider =
+              new Provider<Integer>() {
+                @Override
+                public Integer get() {
+                  throw new UnsupportedOperationException();
+                }
+              };
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Guice.createInjector(module);
@@ -601,7 +705,8 @@
   }
 
   private static class InvalidBindableClass {
-    @Bind(to = String.class) Integer anInt;
+    @Bind(to = String.class)
+    Integer anInt;
   }
 
   public void testIncompatibleBindingTypeStackTraceHasUserFrame() {
@@ -620,17 +725,19 @@
   private static class InjectedNumberProvider implements Provider<Number> {
     @Inject Integer anInt;
 
-    @Override public Number get() {
+    @Override
+    public Number get() {
       return anInt;
     }
   }
 
   public void testBoundProvidersAreInjected() {
     final Integer testValue = 1024;
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue;
-      @Bind private Provider<Number> aNumberProvider = new InjectedNumberProvider();
-    };
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue;
+          @Bind private Provider<Number> aNumberProvider = new InjectedNumberProvider();
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Injector injector = Guice.createInjector(module);
@@ -641,10 +748,11 @@
   public void testBoundInstancesAreInjected() {
     final Integer testValue = 1024;
     final InjectedNumberProvider testNumberProvider = new InjectedNumberProvider();
-    Object instance = new Object() {
-      @Bind private Integer anInt = testValue;
-      @Bind private InjectedNumberProvider aNumberProvider = testNumberProvider;
-    };
+    Object instance =
+        new Object() {
+          @Bind private Integer anInt = testValue;
+          @Bind private InjectedNumberProvider aNumberProvider = testNumberProvider;
+        };
 
     BoundFieldModule module = BoundFieldModule.of(instance);
     Guice.createInjector(module);
@@ -661,11 +769,12 @@
 
     try {
       Guice.createInjector(module);
+      fail();
     } catch (CreationException e) {
       assertContains(
           e.getMessage(),
           "Requested binding type \"java.lang.String\" is not assignable from field binding type "
-          + "\"java.lang.Integer\"");
+              + "\"java.lang.Integer\"");
     }
   }
 
@@ -690,7 +799,8 @@
   }
 
   static final class LazyClass {
-    @Bind(lazy = true) Integer foo = 1;
+    @Bind(lazy = true)
+    Integer foo = 1;
   }
 
   public void testFieldBound_lazy() {
@@ -701,7 +811,7 @@
     assertEquals(2, injector.getInstance(Integer.class).intValue());
   }
 
-  public void testFieldBound_lazy_rejectNull() {
+  public void testNonNullableFieldBound_lazy_rejectNull() {
     LazyClass asProvider = new LazyClass();
     Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
     assertEquals(1, injector.getInstance(Integer.class).intValue());
@@ -710,23 +820,72 @@
       injector.getInstance(Integer.class);
       fail();
     } catch (ProvisionException e) {
-      assertContains(e.getMessage(),
-          "Binding to null values is not allowed. "
-          + "Use Providers.of(null) if this is your intended behavior.");
+      assertContains(
+          e.getMessage(),
+          "Binding to null values is only allowed for fields that are annotated @Nullable.");
     }
   }
 
-  static final class LazyProviderClass {
-    @Bind(lazy = true) Provider<Integer> foo = Providers.of(null);
+  static final class LazyClassNullable {
+    @Bind(lazy = true)
+    @Nullable
+    Integer foo = 1;
   }
 
-  public void testFieldBoundAsProvider_rejectProvider() {
+  public void testNullableFieldBound_lazy_allowNull() {
+    LazyClassNullable asProvider = new LazyClassNullable();
+    Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    asProvider.foo = null;
+    assertNull(injector.getInstance(Integer.class));
+  }
+
+  static final class LazyProviderClass {
+    @Bind(lazy = true)
+    Provider<Integer> foo = Providers.of(null);
+  }
+
+  public void testFieldBoundAsProvider_lazy() {
     LazyProviderClass asProvider = new LazyProviderClass();
+    Provider<Integer> provider =
+        Guice.createInjector(BoundFieldModule.of(asProvider)).getProvider(Integer.class);
+    assertNull(provider.get());
+    asProvider.foo = Providers.of(1);
+    assertEquals(1, provider.get().intValue());
+    asProvider.foo =
+        new Provider<Integer>() {
+          @Override
+          public Integer get() {
+            throw new RuntimeException("boom");
+          }
+        };
     try {
-      Guice.createInjector(BoundFieldModule.of(asProvider));
+      provider.get();
       fail();
-    } catch (CreationException e) {
-      assertContains(e.getMessage(), "'lazy' is incompatible with Provider valued fields");
+    } catch (ProvisionException e) {
+      assertContains(e.getMessage(), "boom");
+    }
+  }
+
+  private static final class LazyNonTransparentProvider {
+    @Bind(lazy = true)
+    @Nullable
+    private IntegerProvider anIntProvider = null;
+  }
+
+  public void testFieldBoundAsNonTransparentProvider_lazy() {
+    LazyNonTransparentProvider instance = new LazyNonTransparentProvider();
+    BoundFieldModule module = BoundFieldModule.of(instance);
+    Injector injector = Guice.createInjector(module);
+
+    assertNull(injector.getInstance(IntegerProvider.class));
+    instance.anIntProvider = new IntegerProvider(3);
+    assertEquals(3, injector.getInstance(IntegerProvider.class).get().intValue());
+    try {
+      injector.getInstance(Integer.class);
+      fail();
+    } catch (ConfigurationException expected) {
+      // expected because we don't interpret IntegerProvider as a Provider<Integer>
     }
   }
 }
diff --git a/extensions/testlib/test/com/google/inject/testing/throwingproviders/CheckedProviderSubjectTest.java b/extensions/testlib/test/com/google/inject/testing/throwingproviders/CheckedProviderSubjectTest.java
new file mode 100644
index 0000000..337fc07
--- /dev/null
+++ b/extensions/testlib/test/com/google/inject/testing/throwingproviders/CheckedProviderSubjectTest.java
@@ -0,0 +1,120 @@
+package com.google.inject.testing.throwingproviders;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.inject.testing.throwingproviders.CheckedProviderSubject.assertThat;
+
+import com.google.common.truth.ExpectFailure;
+import com.google.common.truth.SimpleSubjectBuilder;
+import com.google.inject.throwingproviders.CheckedProvider;
+import com.google.inject.throwingproviders.CheckedProviders;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit tests for {@link CheckedProviderSubject}.
+ *
+ * @author eatnumber1@google.com (Russ Harmon)
+ */
+@RunWith(JUnit4.class)
+public class CheckedProviderSubjectTest {
+  public @Rule ExpectFailure expect = new ExpectFailure();
+
+  private interface StringCheckedProvider extends CheckedProvider<String> {}
+
+  @Test
+  public void providedValue_gotExpected_expectSuccess() {
+    String expected = "keep Summer safe";
+    CheckedProvider<String> provider = CheckedProviders.of(StringCheckedProvider.class, expected);
+
+    assertThat(provider).providedValue().isEqualTo(expected);
+  }
+
+  @Test
+  public void providedValue_gotUnexpected_expectFailure() {
+    String expected = "keep Summer safe";
+    String unexpected = "Summer is unsafe";
+    CheckedProvider<String> provider = CheckedProviders.of(StringCheckedProvider.class, unexpected);
+    String message =
+        String.format(
+            "value provided by <%s>: Not true that <%s> is equal to <%s>",
+            getReturningProviderName(unexpected), unexpected, expected);
+
+    expectWhenTesting().that(provider).providedValue().isEqualTo(expected);
+    assertThat(expect.getFailure()).hasMessageThat().isEqualTo(message);
+  }
+
+  private static final class SummerException extends RuntimeException {}
+
+  @Test
+  public void providedValue_throws_expectFailure() {
+    CheckedProvider<String> provider =
+        CheckedProviders.throwing(StringCheckedProvider.class, SummerException.class);
+    String message =
+        String.format(
+            "checked provider <%s> threw an exception",
+            getThrowingProviderName(SummerException.class.getName()));
+
+    expectWhenTesting().that(provider).providedValue();
+    AssertionError expected = expect.getFailure();
+    assertThat(expected).hasCauseThat().isInstanceOf(SummerException.class);
+    assertThat(expected).hasMessageThat().isEqualTo(message);
+  }
+
+  @Test
+  public void thrownException_threwExpected_expectSuccess() {
+    CheckedProvider<?> provider =
+        CheckedProviders.throwing(StringCheckedProvider.class, SummerException.class);
+
+    assertThat(provider).thrownException().isInstanceOf(SummerException.class);
+  }
+
+  @Test
+  public void thrownException_threwUnexpected_expectFailure() {
+    Class<? extends Throwable> expected = SummerException.class;
+    Class<? extends Throwable> unexpected = UnsupportedOperationException.class;
+    CheckedProvider<String> provider =
+        CheckedProviders.throwing(StringCheckedProvider.class, unexpected);
+    String message =
+        String.format(
+            "exception thrown by <%s>: Not true that <%s> is an instance of <%s>. "
+                + "It is an instance of <%s>",
+            getThrowingProviderName(UnsupportedOperationException.class.getName()),
+            UnsupportedOperationException.class.getName(),
+            SummerException.class.getName(),
+            UnsupportedOperationException.class.getName());
+
+    expectWhenTesting().that(provider).thrownException().isInstanceOf(expected);
+    assertThat(expect.getFailure()).hasMessageThat().isEqualTo(message);
+  }
+
+  @Test
+  public void thrownException_gets_expectFailure() {
+    String getValue = "keep WINTER IS COMING safe";
+    CheckedProvider<String> provider = CheckedProviders.of(StringCheckedProvider.class, getValue);
+    String message =
+        String.format(
+            "Not true that <%s> threw <an exception>. It provided <%s>",
+            getReturningProviderName(getValue), getValue);
+
+    expectWhenTesting().that(provider).thrownException();
+    assertThat(expect.getFailure()).hasMessageThat().isEqualTo(message);
+  }
+
+  private SimpleSubjectBuilder<
+          CheckedProviderSubject<String, CheckedProvider<String>>, CheckedProvider<String>>
+      expectWhenTesting() {
+    return expect
+        .whenTesting()
+        .about(CheckedProviderSubject.<String, CheckedProvider<String>>checkedProviders());
+  }
+
+  private String getReturningProviderName(String providing) {
+    return String.format("generated CheckedProvider returning <%s>", providing);
+  }
+
+  private String getThrowingProviderName(String throwing) {
+    return String.format("generated CheckedProvider throwing <%s>", throwing);
+  }
+}
diff --git a/extensions/throwingproviders/pom.xml b/extensions/throwingproviders/pom.xml
index 472c107..e39051f 100644
--- a/extensions/throwingproviders/pom.xml
+++ b/extensions/throwingproviders/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
 
   <artifactId>guice-throwingproviders</artifactId>
@@ -23,6 +23,27 @@
           </excludes>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.guice.extensions.throwingproviders</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+    </dependency>
+  </dependencies>
 </project>
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
index ca5ab77..d9cbe0e 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,46 +21,48 @@
 import com.google.inject.internal.Annotations;
 import com.google.inject.internal.Errors;
 import com.google.inject.spi.Message;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 
 /**
  * Utilities for the throwing provider module.
- * 
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 class CheckedProvideUtils {
-  
+
   private CheckedProvideUtils() {}
-  
+
   private static final String CONSTRUCTOR_RULES =
       "Classes must have either one (and only one) constructor annotated with @ThrowingInject.";
-  
+
   @SuppressWarnings("unchecked") // safe because it's a constructor of the typeLiteral
   static <T> Constructor<? extends T> findThrowingConstructor(
       TypeLiteral<? extends T> typeLiteral, Binder binder) {
-    
+
     Class<?> rawType = typeLiteral.getRawType();
     Errors errors = new Errors(rawType);
     Constructor<?> cxtor = null;
     for (Constructor<?> constructor : rawType.getDeclaredConstructors()) {
       if (constructor.isAnnotationPresent(ThrowingInject.class)) {
         if (cxtor != null) {
-          errors.addMessage("%s has more than one constructor annotated with @ThrowingInject. "
-              + CONSTRUCTOR_RULES, rawType);
+          errors.addMessage(
+              "%s has more than one constructor annotated with @ThrowingInject. "
+                  + CONSTRUCTOR_RULES,
+              rawType);
         }
 
         cxtor = constructor;
-        Annotation misplacedBindingAnnotation = Annotations.findBindingAnnotation(
-            errors, cxtor, ((AnnotatedElement) cxtor).getAnnotations());
+        Annotation misplacedBindingAnnotation =
+            Annotations.findBindingAnnotation(
+                errors, cxtor, ((AnnotatedElement) cxtor).getAnnotations());
         if (misplacedBindingAnnotation != null) {
           errors.misplacedBindingAnnotation(cxtor, misplacedBindingAnnotation);
         }
       }
     }
-    
+
     if (cxtor == null) {
       errors.addMessage(
           "Could not find a suitable constructor in %s. " + CONSTRUCTOR_RULES, rawType);
@@ -71,9 +73,10 @@
     }
     return (Constructor<? extends T>) cxtor;
   }
-  
+
   /** Adds errors to the binder if the exceptions aren't valid. */
-  static void validateExceptions(Binder binder,
+  static void validateExceptions(
+      Binder binder,
       Iterable<TypeLiteral<?>> actualExceptionTypes,
       Iterable<Class<? extends Throwable>> expectedExceptionTypes,
       Class<? extends CheckedProvider> checkedProvider) {
@@ -96,11 +99,10 @@
       }
       if (notAssignable) {
         binder.addError(
-            "%s is not compatible with the exceptions (%s) declared in " 
-            + "the CheckedProvider interface (%s)",
+            "%s is not compatible with the exceptions (%s) declared in "
+                + "the CheckedProvider interface (%s)",
             exActual, expectedExceptionTypes, checkedProvider);
       }
     }
   }
-
 }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvider.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvider.java
index 3ee2260..567a98c 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvider.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,21 +17,22 @@
 package com.google.inject.throwingproviders;
 
 /**
- * Alternative to the Guice {@link com.google.inject.Provider} that throws
- * a checked Exception. Users may not inject {@code T} directly.
+ * Alternative to the Guice {@link com.google.inject.Provider} that throws a checked Exception.
+ * Users may not inject {@code T} directly.
  *
- * <p>This interface must be extended to use application-specific exception types.
- * Such subinterfaces may not define new methods, but may narrow the exception type.
+ * <p>This interface must be extended to use application-specific exception types. Such
+ * subinterfaces may not define new methods, but may narrow the exception type.
+ *
  * <pre>
- * public interface RemoteProvider&lt;T&gt; extends CheckedProvider&lt;T&gt; { 
+ * public interface RemoteProvider&lt;T&gt; extends CheckedProvider&lt;T&gt; {
  *   T get() throws CustomExceptionOne, CustomExceptionTwo;
  * }
  * </pre>
  *
- * <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned
- * or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get}
- * will invoked at most once within each scope.
- * 
+ * <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned or exception
+ * thrown by {@link #get} will be scoped. As a consequence, {@link #get} will invoked at most once
+ * within each scope.
+ *
  * @since 3.0
  */
 public interface CheckedProvider<T> {
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
index a76d64c..e15b5d9 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2008 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,7 +28,6 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -79,17 +78,16 @@
   void configure(Binder binder) {
     binder = binder.withSource(method);
 
-    SecondaryBinder<?, ?> sbinder = 
-        ThrowingProviderBinder.create(binder)
-          .bind(checkedProvider, key.getTypeLiteral());
-    if(key.getAnnotation() != null) {
+    SecondaryBinder<?, ?> sbinder =
+        ThrowingProviderBinder.create(binder).bind(checkedProvider, key.getTypeLiteral());
+    if (key.getAnnotation() != null) {
       sbinder = sbinder.annotatedWith(key.getAnnotation());
-    } else if(key.getAnnotationType() != null) {
+    } else if (key.getAnnotationType() != null) {
       sbinder = sbinder.annotatedWith(key.getAnnotationType());
     }
     sbinder.scopeExceptions(scopeExceptions);
     ScopedBindingBuilder sbbuilder = sbinder.toProviderMethod(this);
-    if(scopeAnnotation != null) {
+    if (scopeAnnotation != null) {
       sbbuilder.in(scopeAnnotation);
     }
 
@@ -98,11 +96,12 @@
       // misplaced @Exposed, calling this will add an error to the binder's error queue
       ((PrivateBinder) binder).expose(sbinder.getKey());
     }
-    
+
     CheckedProvideUtils.validateExceptions(
         binder, exceptionTypes, sbinder.getExceptionTypes(), checkedProvider);
   }
 
+  @Override
   public T get() throws Exception {
     Object[] parameters = new Object[parameterProviders.size()];
     for (int i = 0; i < parameters.length; i++) {
@@ -111,28 +110,30 @@
 
     try {
       // We know this cast is safe becase T is the method's return type.
-      @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
+      @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
       T result = (T) method.invoke(instance, parameters);
       return result;
     } catch (IllegalAccessException e) {
       throw new AssertionError(e);
     } catch (InvocationTargetException e) {
       Throwable t = e.getCause();
-      if(t instanceof Exception) {
-        throw (Exception)t;
-      } else if(t instanceof Error) {
-        throw (Error)t;
+      if (t instanceof Exception) {
+        throw (Exception) t;
+      } else if (t instanceof Error) {
+        throw (Error) t;
       } else {
         throw new IllegalStateException(t);
       }
     }
   }
 
+  @Override
   public Set<Dependency<?>> getDependencies() {
     return dependencies;
   }
 
-  @Override public String toString() {
+  @Override
+  public String toString() {
     return "@CheckedProvides " + StackTraceElements.forMember(method);
   }
 }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
index f88c507..1d07644 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,7 +31,6 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.Message;
 import com.google.inject.util.Modules;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -39,9 +38,9 @@
 import java.util.logging.Logger;
 
 /**
- * Creates bindings to methods annotated with {@literal @}{@link CheckedProvides}. Use the scope
- * and binding annotations on the provider method to configure the binding.
- * 
+ * Creates bindings to methods annotated with {@literal @}{@link CheckedProvides}. Use the scope and
+ * binding annotations on the provider method to configure the binding.
+ *
  * @author sameb@google.com (Sam Berlin)
  */
 final class CheckedProviderMethodsModule implements Module {
@@ -55,9 +54,7 @@
     this.typeLiteral = TypeLiteral.get(this.delegate.getClass());
   }
 
-  /**
-   * Returns a module which creates bindings for provider methods from the given module.
-   */
+  /** Returns a module which creates bindings for provider methods from the given module. */
   static Module forModule(Module module) {
     // avoid infinite recursion, since installing a module always installs itself
     if (module instanceof CheckedProviderMethodsModule) {
@@ -66,7 +63,8 @@
 
     return new CheckedProviderMethodsModule(module);
   }
-  
+
+  @Override
   public synchronized void configure(Binder binder) {
     for (CheckedProviderMethod<?> throwingProviderMethod : getProviderMethods(binder)) {
       throwingProviderMethod.configure(binder);
@@ -78,7 +76,7 @@
     for (Class<?> c = delegate.getClass(); c != Object.class; c = c.getSuperclass()) {
       for (Method method : c.getDeclaredMethods()) {
         CheckedProvides checkedProvides = method.getAnnotation(CheckedProvides.class);
-        if(checkedProvides != null) {
+        if (checkedProvides != null) {
           result.add(createProviderMethod(binder, method, checkedProvides));
         }
       }
@@ -86,8 +84,8 @@
     return result;
   }
 
-  <T> CheckedProviderMethod<T> createProviderMethod(Binder binder, final Method method,
-      CheckedProvides checkedProvides) {
+  <T> CheckedProviderMethod<T> createProviderMethod(
+      Binder binder, final Method method, CheckedProvides checkedProvides) {
     @SuppressWarnings("rawtypes")
     Class<? extends CheckedProvider> throwingProvider = checkedProvides.value();
     binder = binder.withSource(method);
@@ -109,7 +107,7 @@
         key = loggerKey;
       }
       dependencies.add(Dependency.get(key));
-      parameterProviders.add(binder.getProvider(key));        
+      parameterProviders.add(binder.getProvider(key));
     }
 
     @SuppressWarnings("unchecked") // Define T as the method's return type.
@@ -117,16 +115,23 @@
     List<TypeLiteral<?>> exceptionTypes = typeLiteral.getExceptionTypes(method);
 
     Key<T> key = getKey(errors, returnType, method, method.getAnnotations());
-    Class<? extends Annotation> scopeAnnotation
-        = Annotations.findScopeAnnotation(errors, method.getAnnotations());
+    Class<? extends Annotation> scopeAnnotation =
+        Annotations.findScopeAnnotation(errors, method.getAnnotations());
 
     for (Message message : errors.getMessages()) {
       binder.addError(message);
     }
 
-    return new CheckedProviderMethod<T>(key, method, delegate, ImmutableSet.copyOf(dependencies),
-        parameterProviders, scopeAnnotation, throwingProvider, exceptionTypes, 
-        checkedProvides.scopeExceptions()); 
+    return new CheckedProviderMethod<T>(
+        key,
+        method,
+        delegate,
+        ImmutableSet.copyOf(dependencies),
+        parameterProviders,
+        scopeAnnotation,
+        throwingProvider,
+        exceptionTypes,
+        checkedProvides.scopeExceptions());
   }
 
   <T> Key<T> getKey(Errors errors, TypeLiteral<T> type, Member member, Annotation[] annotations) {
@@ -134,23 +139,26 @@
     return bindingAnnotation == null ? Key.get(type) : Key.get(type, bindingAnnotation);
   }
 
-  @Override public boolean equals(Object o) {
+  @Override
+  public boolean equals(Object o) {
     return o instanceof CheckedProviderMethodsModule
         && ((CheckedProviderMethodsModule) o).delegate == delegate;
   }
 
-  @Override public int hashCode() {
+  @Override
+  public int hashCode() {
     return delegate.hashCode();
   }
-  
+
   /** A provider that returns a logger based on the method name. */
   private static final class LogProvider implements Provider<Logger> {
     private final String name;
-    
+
     public LogProvider(Method method) {
       this.name = method.getDeclaringClass().getName() + "." + method.getName();
     }
-    
+
+    @Override
     public Logger get() {
       return Logger.getLogger(name);
     }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
index 79df84d..e4752a3 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,11 +20,9 @@
 import com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder;
 
 /**
- * A checked provider with dependencies, so {@link HasDependencies} can be implemented
- * when using the {@link SecondaryBinder#using} methods.
- * 
+ * A checked provider with dependencies, so {@link HasDependencies} can be implemented when using
+ * the {@link SecondaryBinder#using} methods.
+ *
  * @author sameb@google.com (Sam Berlin)
  */
-interface CheckedProviderWithDependencies<T> extends CheckedProvider<T>, HasDependencies {
-
-}
+interface CheckedProviderWithDependencies<T> extends CheckedProvider<T>, HasDependencies {}
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviders.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviders.java
new file mode 100644
index 0000000..bd7f6cc
--- /dev/null
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviders.java
@@ -0,0 +1,238 @@
+package com.google.inject.throwingproviders;
+
+import static com.google.inject.throwingproviders.ProviderChecker.checkInterface;
+
+import com.google.common.base.Optional;
+import com.google.inject.TypeLiteral;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * Static utility methods for creating and working with instances of {@link CheckedProvider}.
+ *
+ * @author eatnumber1@google.com (Russ Harmon)
+ * @since 4.2
+ */
+public final class CheckedProviders {
+  private abstract static class CheckedProviderInvocationHandler<T> implements InvocationHandler {
+    private boolean isGetMethod(Method method) {
+      // Since Java does not allow multiple methods with the same name and number & type of
+      // arguments, this is all we need to check to see if it is an overriding method of
+      // CheckedProvider#get().
+      return method.getName().equals("get") && method.getParameterTypes().length == 0;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+      if (method.getDeclaringClass() == Object.class) {
+        return method.invoke(this, args);
+      } else if (isGetMethod(method)) {
+        return invokeGet(proxy, method);
+      }
+      throw new UnsupportedOperationException(
+          String.format(
+              "Unsupported method <%s> with args <%s> invoked on <%s>",
+              method, Arrays.toString(args), proxy));
+    }
+
+    protected abstract T invokeGet(Object proxy, Method method) throws Throwable;
+
+    @Override
+    public abstract String toString();
+  }
+
+  private static final class ReturningHandler<T> extends CheckedProviderInvocationHandler<T> {
+    private final T returned;
+
+    ReturningHandler(T returned) {
+      this.returned = returned;
+    }
+
+    @Override
+    protected T invokeGet(Object proxy, Method method) throws Throwable {
+      return returned;
+    }
+
+    @Override
+    public String toString() {
+      return String.format("generated CheckedProvider returning <%s>", returned);
+    }
+  }
+
+  private static final class ThrowingHandler extends CheckedProviderInvocationHandler<Object> {
+    private final Constructor<? extends Throwable> throwableCtor;
+    private final String typeName;
+
+    private ThrowingHandler(Constructor<? extends Throwable> throwableCtor, String typeName) {
+      this.throwableCtor = throwableCtor;
+      this.typeName = typeName;
+
+      this.throwableCtor.setAccessible(true);
+    }
+
+    static ThrowingHandler forClass(Class<? extends Throwable> throwable) {
+      try {
+        return new ThrowingHandler(throwable.getDeclaredConstructor(), throwable.getName());
+      } catch (NoSuchMethodException e) {
+        // This should have been caught by checkThrowable
+        throw new AssertionError(
+            String.format(
+                "Throwable <%s> does not have a no-argument constructor", throwable.getName()));
+      }
+    }
+
+    @Override
+    protected Object invokeGet(Object proxy, Method method) throws Throwable {
+      throw this.throwableCtor.newInstance();
+    }
+
+    @Override
+    public String toString() {
+      return String.format("generated CheckedProvider throwing <%s>", this.typeName);
+    }
+  }
+
+  private CheckedProviders() {}
+
+  private static <T, P extends CheckedProvider<? super T>> P generateProvider(
+      Class<P> providerType, Optional<T> value, InvocationHandler handler) {
+    checkInterface(providerType, getClassOptional(value));
+    Object proxy =
+        Proxy.newProxyInstance(
+            providerType.getClassLoader(), new Class<?>[] {providerType}, handler);
+    @SuppressWarnings("unchecked") // guaranteed by the newProxyInstance API
+    P proxyP = (P) proxy;
+    return proxyP;
+  }
+
+  private static <T, P extends CheckedProvider<? super T>> P generateProvider(
+      TypeLiteral<P> providerType, Optional<T> value, InvocationHandler handler) {
+    // TODO(eatnumber1): Understand why TypeLiteral#getRawType returns a Class<? super T> rather
+    // than a Class<T> and remove this unsafe cast.
+    Class<P> providerRaw = (Class) providerType.getRawType();
+    return generateProvider(providerRaw, value, handler);
+  }
+
+  private static Optional<Class<?>> getClassOptional(Optional<?> value) {
+    if (!value.isPresent()) {
+      return Optional.absent();
+    }
+    return Optional.<Class<?>>of(value.get().getClass());
+  }
+
+  /**
+   * Returns a {@link CheckedProvider} which always provides {@code instance}.
+   *
+   * <p>The provider type passed as {@code providerType} must be an interface. Calls to methods
+   * other than {@link CheckedProvider#get} will throw {@link UnsupportedOperationException}.
+   *
+   * @param providerType the type of the {@link CheckedProvider} to return
+   * @param instance the instance that should always be provided
+   */
+  public static <T, P extends CheckedProvider<? super T>> P of(
+      TypeLiteral<P> providerType, @Nullable T instance) {
+    return generateProvider(
+        providerType, Optional.fromNullable(instance), new ReturningHandler<T>(instance));
+  }
+
+  /**
+   * Returns a {@link CheckedProvider} which always provides {@code instance}.
+   *
+   * @param providerType the type of the {@link CheckedProvider} to return
+   * @param instance the instance that should always be provided
+   * @see #of(TypeLiteral, T)
+   */
+  public static <T, P extends CheckedProvider<? super T>> P of(
+      Class<P> providerType, @Nullable T instance) {
+    return of(TypeLiteral.get(providerType), instance);
+  }
+
+  /**
+   * Returns a {@link CheckedProvider} which always throws exceptions.
+   *
+   * <p>This method uses the nullary (no argument) constructor of {@code throwable} to create a new
+   * instance of the given {@link Throwable} on each method invocation which is then thrown
+   * immediately.
+   *
+   * <p>See {@link #of(TypeLiteral, T)} for more information.
+   *
+   * @param providerType the type of the {@link CheckedProvider} to return
+   * @param throwable the type of the {@link Throwable} to throw
+   * @see #of(TypeLiteral, T)
+   */
+  public static <T, P extends CheckedProvider<? super T>> P throwing(
+      TypeLiteral<P> providerType, Class<? extends Throwable> throwable) {
+    // TODO(eatnumber1): Understand why TypeLiteral#getRawType returns a Class<? super T> rather
+    // than a Class<T> and remove this unsafe cast.
+    Class<P> providerRaw = (Class) providerType.getRawType();
+    checkThrowable(providerRaw, throwable);
+    return generateProvider(
+        providerType, Optional.<T>absent(), ThrowingHandler.forClass(throwable));
+  }
+
+  /**
+   * Returns a {@link CheckedProvider} which always throws exceptions.
+   *
+   * @param providerType the type of the {@link CheckedProvider} to return
+   * @param throwable the type of the {@link Throwable} to throw
+   * @see #throwing(TypeLiteral, Class)
+   */
+  public static <T, P extends CheckedProvider<? super T>> P throwing(
+      Class<P> providerType, Class<? extends Throwable> throwable) {
+    return throwing(TypeLiteral.get(providerType), throwable);
+  }
+
+  private static boolean isCheckedException(Class<? extends Throwable> thrownType) {
+    return Exception.class.isAssignableFrom(thrownType)
+        && !RuntimeException.class.isAssignableFrom(thrownType);
+  }
+
+  private static void checkThrowable(
+      Class<? extends CheckedProvider<?>> providerType, Class<? extends Throwable> thrownType) {
+    try {
+      thrownType.getDeclaredConstructor();
+    } catch (NoSuchMethodException e) {
+      throw new IllegalArgumentException(
+          String.format(
+              "Thrown exception <%s> must have a no-argument constructor", thrownType.getName()),
+          e);
+    }
+
+    if (!isCheckedException(thrownType)) {
+      return;
+    }
+
+    Method getMethod;
+    try {
+      getMethod = providerType.getMethod("get");
+    } catch (NoSuchMethodException e) {
+      throw new IllegalArgumentException(
+          String.format("Provider class <%s> must have a get() method", providerType.getName()), e);
+    }
+
+    @SuppressWarnings("unchecked") // guaranteed by getExceptionTypes
+    List<Class<? extends Throwable>> exceptionTypes =
+        Arrays.asList((Class<? extends Throwable>[]) getMethod.getExceptionTypes());
+
+    if (exceptionTypes.size() == 0) {
+      return;
+    }
+
+    // Check if the thrown exception is declared to be thrown in the method signature.
+    for (Class<? extends Throwable> exceptionType : exceptionTypes) {
+      if (exceptionType.isAssignableFrom(thrownType)) {
+        return;
+      }
+    }
+
+    throw new IllegalArgumentException(
+        String.format(
+            "Thrown exception <%s> is not declared to be thrown by <%s>",
+            thrownType.getName(), getMethod));
+  }
+}
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
index b401620..d4fab32 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2010 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,30 +24,29 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotates methods of a {@link com.google.inject.Module} to create a
- * {@link CheckedProvider} method binding that can throw exceptions. The
- * method's return type is bound to a {@link CheckedProvider} that can be
- * injected. Guice will pass dependencies to the method as parameters. Install
- * {@literal @}CheckedProvides methods by using
- * {@link ThrowingProviderBinder#forModule(com.google.inject.Module)} on the
- * module where the methods are declared.
- * 
+ * Annotates methods of a {@link com.google.inject.Module} to create a {@link CheckedProvider}
+ * method binding that can throw exceptions. The method's return type is bound to a {@link
+ * CheckedProvider} that can be injected. Guice will pass dependencies to the method as parameters.
+ * Install {@literal @}CheckedProvides methods by using {@link
+ * ThrowingProviderBinder#forModule(com.google.inject.Module)} on the module where the methods are
+ * declared.
+ *
  * @author sameb@google.com (Sam Berlin)
  * @since 3.0
  */
-@Documented @Target(METHOD) @Retention(RUNTIME)
+@Documented
+@Target(METHOD)
+@Retention(RUNTIME)
 public @interface CheckedProvides {
-  
-  /**
-   * The interface that provides this value, a subinterface of {@link CheckedProvider}.
-   */
+
+  /** The interface that provides this value, a subinterface of {@link CheckedProvider}. */
   Class<? extends CheckedProvider> value();
 
   /**
-   * Whether exceptions should be put into the Guice scope.
-   * Default behavior is that exceptions are scoped.
+   * Whether exceptions should be put into the Guice scope. Default behavior is that exceptions are
+   * scoped.
    *
    * @since 4.0
    */
-  boolean scopeExceptions() default true;  
+  boolean scopeExceptions() default true;
 }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ProviderChecker.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ProviderChecker.java
new file mode 100644
index 0000000..cc9746c
--- /dev/null
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ProviderChecker.java
@@ -0,0 +1,120 @@
+package com.google.inject.throwingproviders;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.inject.internal.Errors;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Arrays;
+import java.util.List;
+
+/** Helper methods to verify the correctness of CheckedProvider interfaces. */
+final class ProviderChecker {
+
+  private ProviderChecker() {}
+
+  static <P extends CheckedProvider<?>> void checkInterface(
+      Class<P> interfaceType, Optional<? extends Type> valueType) {
+    checkArgument(interfaceType.isInterface(), "%s must be an interface", interfaceType.getName());
+    checkArgument(
+        interfaceType.getGenericInterfaces().length == 1,
+        "%s must extend CheckedProvider (and only CheckedProvider)",
+        interfaceType);
+
+    boolean tpMode = interfaceType.getInterfaces()[0] == ThrowingProvider.class;
+    if (!tpMode) {
+      checkArgument(
+          interfaceType.getInterfaces()[0] == CheckedProvider.class,
+          "%s must extend CheckedProvider (and only CheckedProvider)",
+          interfaceType);
+    }
+
+    // Ensure that T is parameterized and unconstrained.
+    ParameterizedType genericThrowingProvider =
+        (ParameterizedType) interfaceType.getGenericInterfaces()[0];
+    if (interfaceType.getTypeParameters().length == 1) {
+      String returnTypeName = interfaceType.getTypeParameters()[0].getName();
+      Type returnType = genericThrowingProvider.getActualTypeArguments()[0];
+      checkArgument(
+          returnType instanceof TypeVariable,
+          "%s does not properly extend CheckedProvider, the first type parameter of CheckedProvider"
+              + " (%s) is not a generic type",
+          interfaceType,
+          returnType);
+      checkArgument(
+          returnTypeName.equals(((TypeVariable) returnType).getName()),
+          "The generic type (%s) of %s does not match the generic type of CheckedProvider (%s)",
+          returnTypeName,
+          interfaceType,
+          ((TypeVariable) returnType).getName());
+    } else {
+      checkArgument(
+          interfaceType.getTypeParameters().length == 0,
+          "%s has more than one generic type parameter: %s",
+          interfaceType,
+          Arrays.asList(interfaceType.getTypeParameters()));
+      if (valueType.isPresent()) {
+        checkArgument(
+            genericThrowingProvider.getActualTypeArguments()[0].equals(valueType.get()),
+            "%s expects the value type to be %s, but it was %s",
+            interfaceType,
+            genericThrowingProvider.getActualTypeArguments()[0],
+            valueType.get());
+      }
+    }
+
+    if (tpMode) { // only validate exception in ThrowingProvider mode.
+      Type exceptionType = genericThrowingProvider.getActualTypeArguments()[1];
+      checkArgument(
+          exceptionType instanceof Class,
+          "%s has the wrong Exception generic type (%s) when extending CheckedProvider",
+          interfaceType,
+          exceptionType);
+    }
+
+    // Skip synthetic/bridge methods because java8 generates
+    // a default method on the interface w/ the superinterface type that
+    // just delegates directly to the overridden method.
+    List<Method> declaredMethods =
+        FluentIterable.from(Arrays.asList(interfaceType.getDeclaredMethods()))
+            .filter(NotSyntheticOrBridgePredicate.INSTANCE)
+            .toList();
+    if (declaredMethods.size() == 1) {
+      Method method = declaredMethods.get(0);
+      checkArgument(
+          method.getName().equals("get"),
+          "%s may not declare any new methods, but declared %s",
+          interfaceType,
+          method);
+      checkArgument(
+          method.getParameterTypes().length == 0,
+          "%s may not declare any new methods, but declared %s",
+          interfaceType,
+          method.toGenericString());
+    } else {
+      checkArgument(
+          declaredMethods.isEmpty(),
+          "%s may not declare any new methods, but declared %s",
+          interfaceType,
+          Arrays.asList(interfaceType.getDeclaredMethods()));
+    }
+  }
+
+  private static void checkArgument(boolean condition, String messageFormat, Object... args) {
+    if (!condition) {
+      throw new IllegalArgumentException(Errors.format(messageFormat, args));
+    }
+  }
+
+  private static class NotSyntheticOrBridgePredicate implements Predicate<Method> {
+    static final NotSyntheticOrBridgePredicate INSTANCE = new NotSyntheticOrBridgePredicate();
+
+    @Override
+    public boolean apply(Method input) {
+      return !input.isBridge() && !input.isSynthetic();
+    }
+  }
+}
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java
index 445d697..19756b8 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingInject.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2012 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,24 +20,24 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.google.inject.Inject;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
 /**
- * A version of {@literal @}{@link Inject} designed for ThrowingProviders.  Use by:
+ * A version of {@literal @}{@link Inject} designed for ThrowingProviders. Use by:
+ *
  * <pre><code>ThrowingProviderBinder.create(binder())
  *    .bind(RemoteProvider.class, Customer.class)
  *    .providing(CustomerImpl.class);
  * </code></pre>
+ *
  * where CustomerImpl has a constructor annotated with ThrowingInject.
  *
  * @author sameb@google.com (Sam Berlin)
  * @since 4.0
  */
-@Target({ CONSTRUCTOR })
+@Target({CONSTRUCTOR})
 @Retention(RUNTIME)
 @Documented
-public @interface ThrowingInject {
-}
+public @interface ThrowingInject {}
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProvider.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProvider.java
index 4ecab4d..5462d60 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProvider.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,24 +17,26 @@
 package com.google.inject.throwingproviders;
 
 /**
- * Alternative to the Guice {@link com.google.inject.Provider} that throws
- * a checked Exception. Users may not inject {@code T} directly.
+ * Alternative to the Guice {@link com.google.inject.Provider} that throws a checked Exception.
+ * Users may not inject {@code T} directly.
  *
- * <p>This interface must be extended to use application-specific exception types.
- * Such subinterfaces may not define new methods:
+ * <p>This interface must be extended to use application-specific exception types. Such
+ * subinterfaces may not define new methods:
+ *
  * <pre>
  * public interface RemoteProvider&lt;T&gt; extends ThrowingProvider&lt;T, RemoteException&gt; { }
  * </pre>
  *
- * <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned
- * or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get}
- * will invoked at most once within each scope.
+ * <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned or exception
+ * thrown by {@link #get} will be scoped. As a consequence, {@link #get} will invoked at most once
+ * within each scope.
  *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  * @deprecated use {@link CheckedProvider} instead.
  */
 @Deprecated
-public interface ThrowingProvider<T,E extends Exception> extends CheckedProvider<T> {
+public interface ThrowingProvider<T, E extends Exception> extends CheckedProvider<T> {
+  @Override
   T get() throws E;
 }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
index 546a242..331b699 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +18,7 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
@@ -35,7 +34,6 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.ProviderWithDependencies;
 import com.google.inject.util.Types;
-
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
@@ -44,26 +42,27 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 
 /**
- * <p>Builds a binding for a {@link CheckedProvider}.
- * 
+ * Builds a binding for a {@link CheckedProvider}.
+ *
  * <p>You can use a fluent API and custom providers:
+ *
  * <pre><code>ThrowingProviderBinder.create(binder())
  *    .bind(RemoteProvider.class, Customer.class)
  *    .to(RemoteCustomerProvider.class)
  *    .in(RequestScope.class);
  * </code></pre>
+ *
  * or, you can use throwing provider methods:
+ *
  * <pre><code>class MyModule extends AbstractModule {
  *   configure() {
- *     ThrowingProviderBinder.install(this, binder());
+ *     install(ThrowingProviderBinder.forModule(this));
  *   }
- *   
+ *
  *   {@literal @}CheckedProvides(RemoteProvider.class)
  *   {@literal @}RequestScope
  *   Customer provideCustomer(FlakyCustomerCreator creator) throws RemoteException {
@@ -71,25 +70,27 @@
  *   }
  * }
  * </code></pre>
- * You also can declare that a CheckedProvider construct
- * a particular class whose constructor throws an exception:
+ *
+ * You also can declare that a CheckedProvider construct a particular class whose constructor throws
+ * an exception:
+ *
  * <pre><code>ThrowingProviderBinder.create(binder())
  *    .bind(RemoteProvider.class, Customer.class)
  *    .providing(CustomerImpl.class)
  *    .in(RequestScope.class);
  * </code></pre>
- * 
+ *
  * @author jmourits@google.com (Jerome Mourits)
  * @author jessewilson@google.com (Jesse Wilson)
  * @author sameb@google.com (Sam Berlin)
  */
 public class ThrowingProviderBinder {
 
-  private static final TypeLiteral<CheckedProvider<?>> CHECKED_PROVIDER_TYPE
-      = new TypeLiteral<CheckedProvider<?>>() { };
+  private static final TypeLiteral<CheckedProvider<?>> CHECKED_PROVIDER_TYPE =
+      new TypeLiteral<CheckedProvider<?>>() {};
 
-  private static final TypeLiteral<CheckedProviderMethod<?>> CHECKED_PROVIDER_METHOD_TYPE
-      = new TypeLiteral<CheckedProviderMethod<?>>() { };
+  private static final TypeLiteral<CheckedProviderMethod<?>> CHECKED_PROVIDER_METHOD_TYPE =
+      new TypeLiteral<CheckedProviderMethod<?>>() {};
 
   private final Binder binder;
 
@@ -98,42 +99,36 @@
   }
 
   public static ThrowingProviderBinder create(Binder binder) {
-    return new ThrowingProviderBinder(binder.skipSources(
-        ThrowingProviderBinder.class,
-        ThrowingProviderBinder.SecondaryBinder.class));
+    return new ThrowingProviderBinder(
+        binder.skipSources(
+            ThrowingProviderBinder.class, ThrowingProviderBinder.SecondaryBinder.class));
   }
-  
+
   /**
    * Returns a module that installs {@literal @}{@link CheckedProvides} methods.
-   * 
+   *
    * @since 3.0
    */
   public static Module forModule(Module module) {
     return CheckedProviderMethodsModule.forModule(module);
   }
-  
-  /**
-   * @deprecated Use {@link #bind(Class, Class)} or {@link #bind(Class, TypeLiteral)} instead. 
-   */
+
+  /** @deprecated Use {@link #bind(Class, Class)} or {@link #bind(Class, TypeLiteral)} instead. */
   @Deprecated
-  public <P extends CheckedProvider> SecondaryBinder<P, ?> 
-      bind(Class<P> interfaceType, Type clazz) {
+  public <P extends CheckedProvider> SecondaryBinder<P, ?> bind(
+      Class<P> interfaceType, Type clazz) {
     return new SecondaryBinder<P, Object>(interfaceType, clazz);
   }
 
-  /**
-   * @since 4.0
-   */
-  public <P extends CheckedProvider, T> SecondaryBinder<P, T> 
-      bind(Class<P> interfaceType, Class<T> clazz) {
+  /** @since 4.0 */
+  public <P extends CheckedProvider, T> SecondaryBinder<P, T> bind(
+      Class<P> interfaceType, Class<T> clazz) {
     return new SecondaryBinder<P, T>(interfaceType, clazz);
   }
-  
-  /**
-   * @since 4.0
-   */
-  public <P extends CheckedProvider, T> SecondaryBinder<P, T> 
-      bind(Class<P> interfaceType, TypeLiteral<T> typeLiteral) {
+
+  /** @since 4.0 */
+  public <P extends CheckedProvider, T> SecondaryBinder<P, T> bind(
+      Class<P> interfaceType, TypeLiteral<T> typeLiteral) {
     return new SecondaryBinder<P, T>(interfaceType, typeLiteral.getType());
   }
 
@@ -151,19 +146,19 @@
     public SecondaryBinder(Class<P> interfaceType, Type valueType) {
       this.interfaceType = checkNotNull(interfaceType, "interfaceType");
       this.valueType = checkNotNull(valueType, "valueType");
-      if(checkInterface()) {
+      if (checkInterface()) {
         this.exceptionTypes = getExceptionType(interfaceType);
         valid = true;
       } else {
         valid = false;
         this.exceptionTypes = ImmutableList.of();
-      }      
+      }
     }
-    
+
     List<Class<? extends Throwable>> getExceptionTypes() {
       return exceptionTypes;
     }
-    
+
     Key<P> getKey() {
       return interfaceKey;
     }
@@ -194,13 +189,13 @@
       this.scopeExceptions = scopeExceptions;
       return this;
     }
-    
+
     public ScopedBindingBuilder to(P target) {
       Key<P> targetKey = Key.get(interfaceType, UniqueAnnotations.create());
       binder.bind(targetKey).toInstance(target);
       return to(targetKey);
     }
-    
+
     public ScopedBindingBuilder to(Class<? extends P> targetType) {
       return to(Key.get(targetType));
     }
@@ -212,7 +207,7 @@
 
     /** @since 4.0 */
     @SuppressWarnings("unchecked") // safe because this is the cxtor of the literal
-    public ScopedBindingBuilder providing(TypeLiteral<? extends T> cxtorLiteral) {     
+    public ScopedBindingBuilder providing(TypeLiteral<? extends T> cxtorLiteral) {
       // Find a constructor that has @ThrowingInject.
       Constructor<? extends T> cxtor =
           CheckedProvideUtils.findThrowingConstructor(cxtorLiteral, binder);
@@ -224,7 +219,7 @@
         // Validate the exceptions are consistent with the CheckedProvider interface.
         CheckedProvideUtils.validateExceptions(
             binder, cxtorLiteral.getExceptionTypes(cxtor), exceptionTypes, interfaceType);
-        
+
         typeKey = Key.get(cxtorLiteral, UniqueAnnotations.create());
         binder.bind(typeKey).toConstructor((Constructor) cxtor).in(Scopes.NO_SCOPE);
         typeProvider = binder.getProvider((Key<T>) typeKey);
@@ -233,43 +228,44 @@
         typeProvider = null;
         typeKey = null;
       }
-        
+
       // Create a CheckedProvider that calls our cxtor
-      CheckedProvider<T> checkedProvider = new CheckedProviderWithDependencies<T>() {
-        @Override
-        public T get() throws Exception {
-          try {
-            return typeProvider.get();
-          } catch (ProvisionException pe) {
-            // Rethrow the provision cause as the actual exception
-            if (pe.getCause() instanceof Exception) {
-              throw (Exception) pe.getCause();
-            } else if (pe.getCause() instanceof Error) {
-              throw (Error) pe.getCause();
-            } else {
-              // If this failed because of multiple reasons (ie, more than
-              // one dependency failed due to scoping errors), then
-              // the ProvisionException won't have a cause, so we need
-              // to rethrow it as-is.
-              throw pe;
+      CheckedProvider<T> checkedProvider =
+          new CheckedProviderWithDependencies<T>() {
+            @Override
+            public T get() throws Exception {
+              try {
+                return typeProvider.get();
+              } catch (ProvisionException pe) {
+                // Rethrow the provision cause as the actual exception
+                if (pe.getCause() instanceof Exception) {
+                  throw (Exception) pe.getCause();
+                } else if (pe.getCause() instanceof Error) {
+                  throw (Error) pe.getCause();
+                } else {
+                  // If this failed because of multiple reasons (ie, more than
+                  // one dependency failed due to scoping errors), then
+                  // the ProvisionException won't have a cause, so we need
+                  // to rethrow it as-is.
+                  throw pe;
+                }
+              }
             }
-          }
-        }
-        
-        @Override
-        public Set<Dependency<?>> getDependencies() {
-          return ImmutableSet.<Dependency<?>>of(Dependency.get(typeKey));
-        }
-      };
-      
-      Key<CheckedProvider<?>> targetKey = Key.get(CHECKED_PROVIDER_TYPE,
-          UniqueAnnotations.create());
+
+            @Override
+            public Set<Dependency<?>> getDependencies() {
+              return ImmutableSet.<Dependency<?>>of(Dependency.get(typeKey));
+            }
+          };
+
+      Key<CheckedProvider<?>> targetKey =
+          Key.get(CHECKED_PROVIDER_TYPE, UniqueAnnotations.create());
       binder.bind(targetKey).toInstance(checkedProvider);
       return toInternal(targetKey);
     }
-    
+
     ScopedBindingBuilder toProviderMethod(CheckedProviderMethod<?> target) {
-      Key<CheckedProviderMethod<?>> targetKey = 
+      Key<CheckedProviderMethod<?>> targetKey =
           Key.get(CHECKED_PROVIDER_METHOD_TYPE, UniqueAnnotations.create());
       binder.bind(targetKey).toInstance(target);
 
@@ -279,9 +275,9 @@
     @SuppressWarnings("unchecked") // P only extends the raw type of CheckedProvider
     public ScopedBindingBuilder to(Key<? extends P> targetKey) {
       checkNotNull(targetKey, "targetKey");
-      return toInternal((Key<? extends CheckedProvider<?>>)targetKey);
+      return toInternal((Key<? extends CheckedProvider<?>>) targetKey);
     }
-    
+
     private ScopedBindingBuilder toInternal(final Key<? extends CheckedProvider<?>> targetKey) {
       final Key<Result> resultKey = Key.get(Result.class, UniqueAnnotations.create());
       // Note that this provider will behave like the final provider Guice creates.
@@ -291,53 +287,59 @@
       interfaceKey = createKey();
 
       // don't bother binding the proxy type if this is in an invalid state.
-      if(valid) {
-        binder.bind(interfaceKey).toProvider(new ProviderWithDependencies<P>() {
-          private final P instance = interfaceType.cast(Proxy.newProxyInstance(
-              interfaceType.getClassLoader(), new Class<?>[] { interfaceType },
-              new InvocationHandler() {
-                public Object invoke(Object proxy, Method method, Object[] args)
-                    throws Throwable {
-                  // Allow methods like .equals(..), .hashcode(..), .toString(..) to work.
-                  if (method.getDeclaringClass() == Object.class) {
-                    return method.invoke(this, args);
+      if (valid) {
+        binder
+            .bind(interfaceKey)
+            .toProvider(
+                new ProviderWithDependencies<P>() {
+                  private final P instance =
+                      interfaceType.cast(
+                          Proxy.newProxyInstance(
+                              interfaceType.getClassLoader(),
+                              new Class<?>[] {interfaceType},
+                              new InvocationHandler() {
+                                @Override
+                                public Object invoke(Object proxy, Method method, Object[] args)
+                                    throws Throwable {
+                                  // Allow methods like .equals(..), .hashcode(..), .toString(..) to work.
+                                  if (method.getDeclaringClass() == Object.class) {
+                                    return method.invoke(this, args);
+                                  }
+
+                                  if (scopeExceptions) {
+                                    return resultProvider.get().getOrThrow();
+                                  } else {
+                                    Result result;
+                                    try {
+                                      result = resultProvider.get();
+                                    } catch (ProvisionException pe) {
+                                      Throwable cause = pe.getCause();
+                                      if (cause instanceof ResultException) {
+                                        throw ((ResultException) cause).getCause();
+                                      } else {
+                                        throw pe;
+                                      }
+                                    }
+                                    return result.getOrThrow();
+                                  }
+                                }
+                              }));
+
+                  @Override
+                  public P get() {
+                    return instance;
                   }
-                  
-                  if (scopeExceptions) {
-                    return resultProvider.get().getOrThrow();
-                  } else {
-                    Result result;
-                    try {
-                      result = resultProvider.get();
-                    } catch (ProvisionException pe) {
-                      Throwable cause = pe.getCause();
-                      if (cause instanceof ResultException) {
-                        throw ((ResultException)cause).getCause();
-                      } else {
-                        throw pe;
-                      }
-                    }
-                    return result.getOrThrow();
+
+                  @Override
+                  public Set<Dependency<?>> getDependencies() {
+                    return ImmutableSet.<Dependency<?>>of(Dependency.get(resultKey));
                   }
-                }
-              }));
-            
-            @Override
-            public P get() {
-              return instance;
-            }
-  
-            @Override
-            public Set<Dependency<?>> getDependencies() {
-              return ImmutableSet.<Dependency<?>>of(Dependency.get(resultKey));
-            }
-          });
+                });
       }
 
-      // The provider is unscoped, but the user may apply a scope to it through the 
+      // The provider is unscoped, but the user may apply a scope to it through the
       // ScopedBindingBuilder this returns.
-      return binder.bind(resultKey).toProvider(
-          createResultProvider(targetKey, targetProvider));
+      return binder.bind(resultKey).toProvider(createResultProvider(targetKey, targetProvider));
     }
 
     private ProviderWithDependencies<Result> createResultProvider(
@@ -374,10 +376,9 @@
         }
       };
     }
-    
+
     /**
-     * Returns the exception type declared to be thrown by the get method of
-     * {@code interfaceType}.
+     * Returns the exception type declared to be thrown by the get method of {@code interfaceType}.
      */
     private List<Class<? extends Throwable>> getExceptionType(Class<P> interfaceType) {
       try {
@@ -397,100 +398,12 @@
     }
 
     private boolean checkInterface() {
-      if(!checkArgument(interfaceType.isInterface(),
-         "%s must be an interface", interfaceType.getName())) {
-        return false;
-      }
-      if(!checkArgument(interfaceType.getGenericInterfaces().length == 1,
-          "%s must extend CheckedProvider (and only CheckedProvider)",
-          interfaceType)) {
-        return false;
-      }
-      
-      boolean tpMode = interfaceType.getInterfaces()[0] == ThrowingProvider.class;      
-      if(!tpMode) {
-        if(!checkArgument(interfaceType.getInterfaces()[0] == CheckedProvider.class,
-            "%s must extend CheckedProvider (and only CheckedProvider)",
-            interfaceType)) {
-          return false;
-        }
-      }
-
-      // Ensure that T is parameterized and unconstrained.
-      ParameterizedType genericThrowingProvider
-          = (ParameterizedType) interfaceType.getGenericInterfaces()[0];
-      if (interfaceType.getTypeParameters().length == 1) {
-        String returnTypeName = interfaceType.getTypeParameters()[0].getName();
-        Type returnType = genericThrowingProvider.getActualTypeArguments()[0];
-        if(!checkArgument(returnType instanceof TypeVariable,
-            "%s does not properly extend CheckedProvider, the first type parameter of CheckedProvider (%s) is not a generic type",
-            interfaceType, returnType)) {
-          return false;
-        }
-        if(!checkArgument(returnTypeName.equals(((TypeVariable) returnType).getName()),
-            "The generic type (%s) of %s does not match the generic type of CheckedProvider (%s)",
-            returnTypeName, interfaceType, ((TypeVariable)returnType).getName())) {
-          return false;
-        }
-      } else {
-        if(!checkArgument(interfaceType.getTypeParameters().length == 0,
-            "%s has more than one generic type parameter: %s",
-            interfaceType, Arrays.asList(interfaceType.getTypeParameters()))) {
-          return false;
-        }
-        if(!checkArgument(genericThrowingProvider.getActualTypeArguments()[0].equals(valueType),
-            "%s expects the value type to be %s, but it was %s",
-            interfaceType, genericThrowingProvider.getActualTypeArguments()[0], valueType)) {
-          return false;
-        }
-      }
-
-      if(tpMode) { // only validate exception in ThrowingProvider mode.
-        Type exceptionType = genericThrowingProvider.getActualTypeArguments()[1];
-        if(!checkArgument(exceptionType instanceof Class,
-            "%s has the wrong Exception generic type (%s) when extending CheckedProvider",
-            interfaceType, exceptionType)) {
-          return false;
-        }
-      }
-      
-      // Skip synthetic/bridge methods because java8 generates
-      // a default method on the interface w/ the superinterface type that
-      // just delegates directly to the overridden method.
-      List<Method> declaredMethods = FluentIterable
-          .from(Arrays.asList(interfaceType.getDeclaredMethods()))
-          .filter(NotSyntheticOrBridgePredicate.INSTANCE)
-          .toList();
-      if (declaredMethods.size() == 1) {
-        Method method = declaredMethods.get(0);
-        if(!checkArgument(method.getName().equals("get"),
-            "%s may not declare any new methods, but declared %s",
-            interfaceType, method)) {
-          return false;
-        }
-        if(!checkArgument(method.getParameterTypes().length == 0,
-            "%s may not declare any new methods, but declared %s",
-            interfaceType, method.toGenericString())) {
-          return false;
-        }
-      } else {
-        if(!checkArgument(declaredMethods.isEmpty(),
-            "%s may not declare any new methods, but declared %s",
-            interfaceType, Arrays.asList(interfaceType.getDeclaredMethods()))) {
-          return false;
-        }
-      }
-      
-      return true;
-    }
-
-    private boolean checkArgument(boolean condition,
-        String messageFormat, Object... args) {
-      if (!condition) {
-        binder.addError(messageFormat, args);
-        return false;
-      } else {
+      try {
+        ProviderChecker.checkInterface(interfaceType, Optional.of(valueType));
         return true;
+      } catch (IllegalArgumentException e) {
+        binder.addError(e.getMessage());
+        return false;
       }
     }
 
@@ -498,8 +411,9 @@
     private Key<P> createKey() {
       TypeLiteral<P> typeLiteral;
       if (interfaceType.getTypeParameters().length == 1) {
-        ParameterizedType type = Types.newParameterizedTypeWithOwner(
-            interfaceType.getEnclosingClass(), interfaceType, valueType);
+        ParameterizedType type =
+            Types.newParameterizedTypeWithOwner(
+                interfaceType.getEnclosingClass(), interfaceType, valueType);
         typeLiteral = (TypeLiteral<P>) TypeLiteral.get(type);
       } else {
         typeLiteral = TypeLiteral.get(interfaceType);
@@ -507,10 +421,10 @@
 
       if (annotation != null) {
         return Key.get(typeLiteral, annotation);
-        
+
       } else if (annotationType != null) {
         return Key.get(typeLiteral, annotationType);
-        
+
       } else {
         return Key.get(typeLiteral);
       }
@@ -539,7 +453,7 @@
     public static Result forException(Exception e) {
       return new Result(null, e);
     }
-    
+
     public Object getOrThrow() throws Exception {
       if (exception != null) {
         throw exception;
@@ -550,20 +464,12 @@
   }
 
   /**
-   * RuntimeException class to wrap exceptions from the checked provider.
-   * The regular guice provider can throw it and the checked provider proxy extracts
-   * the underlying exception and rethrows it.
+   * RuntimeException class to wrap exceptions from the checked provider. The regular guice provider
+   * can throw it and the checked provider proxy extracts the underlying exception and rethrows it.
    */
   private static class ResultException extends RuntimeException {
     ResultException(Exception cause) {
       super(cause);
     }
   }
-  
-  private static class NotSyntheticOrBridgePredicate implements Predicate<Method> {
-    static NotSyntheticOrBridgePredicate INSTANCE = new NotSyntheticOrBridgePredicate();
-    @Override public boolean apply(Method input) {
-      return !input.isBridge() && !input.isSynthetic();
-    }
-  }
 }
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderMethodsModuleTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderMethodsModuleTest.java
index b7a8335..5485236 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderMethodsModuleTest.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderMethodsModuleTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2009 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,40 +27,36 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.BindException;
 import java.rmi.RemoteException;
+import junit.framework.TestCase;
 
-/**
- * Test methods for {@link CheckedProviderMethodsModule}.
- */
+/** Test methods for {@link CheckedProviderMethodsModule}. */
 public class CheckedProviderMethodsModuleTest extends TestCase {
 
-  private final TypeLiteral<RpcProvider<String>> rpcProviderOfString
-      = new TypeLiteral<RpcProvider<String>>() { };
-  private final TypeLiteral<RpcProvider<Integer>> rpcProviderOfInteger
-      = new TypeLiteral<RpcProvider<Integer>>() { };
-  private final TypeLiteral<RpcProvider<Long>> rpcProviderOfLong
-      = new TypeLiteral<RpcProvider<Long>>() { };
-  private final TypeLiteral<RpcProvider<Float>> rpcProviderOfFloat
-      = new TypeLiteral<RpcProvider<Float>>() { };
-  private final TypeLiteral<RpcProvider<Pair<Double, String>>> rpcProviderOfPair
-      = new TypeLiteral<RpcProvider<Pair<Double, String>>>() { };
+  private final TypeLiteral<RpcProvider<String>> rpcProviderOfString =
+      new TypeLiteral<RpcProvider<String>>() {};
+  private final TypeLiteral<RpcProvider<Integer>> rpcProviderOfInteger =
+      new TypeLiteral<RpcProvider<Integer>>() {};
+  private final TypeLiteral<RpcProvider<Long>> rpcProviderOfLong =
+      new TypeLiteral<RpcProvider<Long>>() {};
+  private final TypeLiteral<RpcProvider<Float>> rpcProviderOfFloat =
+      new TypeLiteral<RpcProvider<Float>>() {};
+  private final TypeLiteral<RpcProvider<Pair<Double, String>>> rpcProviderOfPair =
+      new TypeLiteral<RpcProvider<Pair<Double, String>>>() {};
 
   private final TestScope testScope = new TestScope();
 
   interface RpcProvider<T> extends CheckedProvider<T> {
+    @Override
     T get() throws RemoteException, BindException;
   }
 
   @Retention(RetentionPolicy.RUNTIME)
   @BindingAnnotation
-  @interface TestAnnotation {
-  }
+  @interface TestAnnotation {}
 
   class TestModule extends AbstractModule {
 
@@ -78,12 +74,14 @@
       return "Works";
     }
 
-    @CheckedProvides(RpcProvider.class) @TestScope.Scoped
+    @CheckedProvides(RpcProvider.class)
+    @TestScope.Scoped
     int getSomeIntegerFromServer() {
       return nextIntToReturn;
     }
 
-    @CheckedProvides(RpcProvider.class) @TestAnnotation
+    @CheckedProvides(RpcProvider.class)
+    @TestAnnotation
     long getSomeLongFromServer() {
       return 0xffL;
     }
@@ -115,55 +113,52 @@
       install(ThrowingProviderBinder.forModule(this));
     }
 
-    @CheckedProvides(RpcProvider.class) @Named("fruit") @Exposed
+    @CheckedProvides(RpcProvider.class)
+    @Named("fruit")
+    @Exposed
     String provideApples() {
       return "apple";
     }
   }
-  
 
   public void testNoAnnotationNoScope() throws BindException, RemoteException {
     Injector injector = Guice.createInjector(new TestModule());
-    RpcProvider<String> provider = injector
-        .getInstance(Key.get(rpcProviderOfString));
+    RpcProvider<String> provider = injector.getInstance(Key.get(rpcProviderOfString));
     assertEquals("Works", provider.get());
   }
 
   public void testWithScope() throws BindException, RemoteException {
     TestModule testModule = new TestModule();
     Injector injector = Guice.createInjector(testModule);
-    RpcProvider<Integer> provider = injector
-        .getInstance(Key.get(rpcProviderOfInteger));
+    RpcProvider<Integer> provider = injector.getInstance(Key.get(rpcProviderOfInteger));
 
-    assertEquals((Integer)100, provider.get());
+    assertEquals((Integer) 100, provider.get());
     testModule.setNextIntToReturn(120);
-    assertEquals((Integer)100, provider.get());
+    assertEquals((Integer) 100, provider.get());
     testScope.beginNewScope();
-    assertEquals((Integer)120, provider.get());
+    assertEquals((Integer) 120, provider.get());
   }
 
   public void testWithAnnotation() throws BindException, RemoteException {
     TestModule testModule = new TestModule();
     Injector injector = Guice.createInjector(testModule);
-    RpcProvider<Long> provider = injector
-        .getInstance(Key.get(rpcProviderOfLong, TestAnnotation.class));
-    assertEquals((Long)0xffL, provider.get());
+    RpcProvider<Long> provider =
+        injector.getInstance(Key.get(rpcProviderOfLong, TestAnnotation.class));
+    assertEquals((Long) 0xffL, provider.get());
   }
 
   public void testWithInjectedParameters() throws BindException, RemoteException {
     TestModule testModule = new TestModule();
     Injector injector = Guice.createInjector(testModule);
-    RpcProvider<Pair<Double, String>> provider = injector
-        .getInstance(Key.get(rpcProviderOfPair));
+    RpcProvider<Pair<Double, String>> provider = injector.getInstance(Key.get(rpcProviderOfPair));
     Pair<Double, String> pair = provider.get();
-    assertEquals(pair.first, 4.0d);
+    assertEquals(pair.first, 4.0d, 0.0);
   }
 
   public void testWithThrownException() {
     TestModule testModule = new TestModule();
     Injector injector = Guice.createInjector(testModule);
-    RpcProvider<Float> provider = injector
-        .getInstance(Key.get(rpcProviderOfFloat));
+    RpcProvider<Float> provider = injector.getInstance(Key.get(rpcProviderOfFloat));
     try {
       provider.get();
       fail();
@@ -177,19 +172,18 @@
   public void testExposedMethod() throws BindException, RemoteException {
     TestModule testModule = new TestModule();
     Injector injector = Guice.createInjector(testModule);
-    RpcProvider<String> provider = injector
-        .getInstance(Key.get(rpcProviderOfString, Names.named("fruit")));
+    RpcProvider<String> provider =
+        injector.getInstance(Key.get(rpcProviderOfString, Names.named("fruit")));
     assertEquals("apple", provider.get());
-
   }
-  
+
   private static class Pair<A, B> {
     A first;
     B second;
 
     Pair(A a, B b) {
-      this.first= a;
+      this.first = a;
       this.second = b;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
index 1f4f977..5f716c7 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
 import com.google.inject.AbstractModule;
 import com.google.inject.Asserts;
 import com.google.inject.BindingAnnotation;
@@ -45,9 +44,6 @@
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.Message;
 import com.google.inject.throwingproviders.ThrowingProviderBinder.Result;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
@@ -62,6 +58,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.TooManyListenersException;
+import junit.framework.TestCase;
 
 /**
  * @author jmourits@google.com (Jerome Mourits)
@@ -69,108 +66,113 @@
  * @author sameb@google.com (Sam Berlin)
  */
 public class CheckedProviderTest extends TestCase {
-  @Target(METHOD) @Retention(RUNTIME) @BindingAnnotation
-  @interface NotExceptionScoping { };
-  
+  @Target(METHOD)
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface NotExceptionScoping {};
+
   private static final Function<Dependency<?>, Key<?>> DEPENDENCY_TO_KEY =
       new Function<Dependency<?>, Key<?>>() {
+        @Override
         public Key<?> apply(Dependency<?> from) {
           return from.getKey();
         }
       };
 
-  private final TypeLiteral<RemoteProvider<Foo>> remoteProviderOfFoo
-      = new TypeLiteral<RemoteProvider<Foo>>() { };
-  private final MockRemoteProvider<Foo> mockRemoteProvider = new MockRemoteProvider<Foo>();
+  private final TypeLiteral<RemoteProvider<Foo>> remoteProviderOfFoo =
+      new TypeLiteral<RemoteProvider<Foo>>() {};
+  private final MockRemoteProvider<Foo> mockRemoteProvider = new MockRemoteProvider<>();
   private final TestScope testScope = new TestScope();
-  
-  private Injector bindInjector;  
+
+  private Injector bindInjector;
   private Injector providesInjector;
   private Injector cxtorInjector;
-  
+
   @Override
   protected void setUp() throws Exception {
     MockFoo.nextToThrow = null;
     MockFoo.nextToReturn = null;
     AnotherMockFoo.nextToThrow = null;
     AnotherMockFoo.nextToReturn = null;
-    
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .to(mockRemoteProvider)
-            .in(testScope);
 
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .annotatedWith(NotExceptionScoping.class)
-            .scopeExceptions(false)
-            .to(mockRemoteProvider)
-            .in(testScope);
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .to(mockRemoteProvider)
+                    .in(testScope);
 
-      }
-    });  
-    
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-       install(ThrowingProviderBinder.forModule(this));
-       bindScope(TestScope.Scoped.class, testScope);
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      @TestScope.Scoped
-      Foo throwOrGet() throws RemoteException, BindException {
-        return mockRemoteProvider.get();
-      }
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .annotatedWith(NotExceptionScoping.class)
+                    .scopeExceptions(false)
+                    .to(mockRemoteProvider)
+                    .in(testScope);
+              }
+            });
 
-      @SuppressWarnings("unused")
-      @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
-      @NotExceptionScoping
-      @TestScope.Scoped
-      Foo notExceptionScopingThrowOrGet() throws RemoteException, BindException {
-        return mockRemoteProvider.get();
-      }    
-      
-    });
-    
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-          .bind(RemoteProvider.class, Foo.class)
-          .providing(MockFoo.class)
-          .in(testScope);
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+                bindScope(TestScope.Scoped.class, testScope);
+              }
 
-        ThrowingProviderBinder.create(binder())
-          .bind(RemoteProvider.class, Foo.class)
-          .annotatedWith(NotExceptionScoping.class)
-          .scopeExceptions(false)
-          .providing(MockFoo.class)
-          .in(testScope);
-        
-      }
-    });
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              @TestScope.Scoped
+              Foo throwOrGet() throws RemoteException, BindException {
+                return mockRemoteProvider.get();
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
+              @NotExceptionScoping
+              @TestScope.Scoped
+              Foo notExceptionScopingThrowOrGet() throws RemoteException, BindException {
+                return mockRemoteProvider.get();
+              }
+            });
+
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(MockFoo.class)
+                    .in(testScope);
+
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .annotatedWith(NotExceptionScoping.class)
+                    .scopeExceptions(false)
+                    .providing(MockFoo.class)
+                    .in(testScope);
+              }
+            });
   }
 
   public void testExceptionsThrown_Bind() throws Exception {
     tExceptionsThrown(bindInjector);
   }
-  
+
   public void testExceptionsThrown_Provides() throws Exception {
     tExceptionsThrown(providesInjector);
   }
-  
+
   public void testExceptionsThrown_Cxtor() throws Exception {
     tExceptionsThrown(cxtorInjector);
   }
-  
+
   private void tExceptionsThrown(Injector injector) throws Exception {
-    RemoteProvider<Foo> remoteProvider = 
-      injector.getInstance(Key.get(remoteProviderOfFoo));
+    RemoteProvider<Foo> remoteProvider = injector.getInstance(Key.get(remoteProviderOfFoo));
 
     mockRemoteProvider.throwOnNextGet(new BindException("kaboom!"));
     MockFoo.nextToThrow = new BindException("kaboom!");
@@ -182,29 +184,30 @@
     }
   }
 
-  public void testValuesScoped_Bind() throws Exception  {
+  public void testValuesScoped_Bind() throws Exception {
     tValuesScoped(bindInjector, null);
   }
-  
-  public void testValuesScoped_Provides() throws Exception  {
+
+  public void testValuesScoped_Provides() throws Exception {
     tValuesScoped(providesInjector, null);
   }
-  
-  public void testValuesScopedWhenNotExceptionScoping_Bind() throws Exception  {
+
+  public void testValuesScopedWhenNotExceptionScoping_Bind() throws Exception {
     tValuesScoped(bindInjector, NotExceptionScoping.class);
   }
-  
-  public void testValuesScopedWhenNotExceptionScoping_Provides() throws Exception  {
+
+  public void testValuesScopedWhenNotExceptionScoping_Provides() throws Exception {
     tValuesScoped(providesInjector, NotExceptionScoping.class);
   }
 
-  private void tValuesScoped(Injector injector, 
-      Class<? extends Annotation> annotation) throws Exception {
-    Key<RemoteProvider<Foo>> key = annotation != null ? 
-        Key.get(remoteProviderOfFoo, annotation) :
-        Key.get(remoteProviderOfFoo);
+  private void tValuesScoped(Injector injector, Class<? extends Annotation> annotation)
+      throws Exception {
+    Key<RemoteProvider<Foo>> key =
+        annotation != null
+            ? Key.get(remoteProviderOfFoo, annotation)
+            : Key.get(remoteProviderOfFoo);
     RemoteProvider<Foo> remoteProvider = injector.getInstance(key);
-    
+
     mockRemoteProvider.setNextToReturn(new SimpleFoo("A"));
     assertEquals("A", remoteProvider.get().s());
 
@@ -214,14 +217,13 @@
     testScope.beginNewScope();
     assertEquals("B", remoteProvider.get().s());
   }
-  
+
   public void testValuesScoped_Cxtor() throws Exception {
-    RemoteProvider<Foo> remoteProvider = 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
+    RemoteProvider<Foo> remoteProvider = cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
 
     Foo retrieved = remoteProvider.get();
     assertSame(retrieved, remoteProvider.get()); // same, not in new scope.
-    
+
     testScope.beginNewScope();
     assertNotSame(retrieved, remoteProvider.get()); // different, new scope.
   }
@@ -229,18 +231,17 @@
   public void testExceptionsScoped_Bind() throws Exception {
     tExceptionsScoped(bindInjector);
   }
-  
+
   public void testExceptionsScoped_Provides() throws Exception {
     tExceptionsScoped(providesInjector);
   }
-  
+
   public void testExceptionScopes_Cxtor() throws Exception {
     tExceptionsScoped(cxtorInjector);
   }
-  
+
   private void tExceptionsScoped(Injector injector) throws Exception {
-    RemoteProvider<Foo> remoteProvider = 
-        injector.getInstance(Key.get(remoteProviderOfFoo));
+    RemoteProvider<Foo> remoteProvider = injector.getInstance(Key.get(remoteProviderOfFoo));
 
     mockRemoteProvider.throwOnNextGet(new RemoteException("A"));
     MockFoo.nextToThrow = new RemoteException("A");
@@ -250,7 +251,7 @@
     } catch (RemoteException expected) {
       assertEquals("A", expected.getMessage());
     }
-    
+
     mockRemoteProvider.throwOnNextGet(new RemoteException("B"));
     MockFoo.nextToThrow = new RemoteException("B");
     try {
@@ -260,21 +261,21 @@
       assertEquals("A", expected.getMessage());
     }
   }
-  
+
   public void testExceptionsNotScopedWhenNotExceptionScoping_Bind() throws Exception {
     tExceptionsNotScopedWhenNotExceptionScoping(bindInjector);
   }
-  
+
   public void testExceptionsNotScopedWhenNotExceptionScoping_Provides() throws Exception {
     tExceptionsNotScopedWhenNotExceptionScoping(providesInjector);
   }
-  
+
   public void testExceptionNotScopedWhenNotExceptionScoping_Cxtor() throws Exception {
     tExceptionsNotScopedWhenNotExceptionScoping(cxtorInjector);
   }
-  
+
   private void tExceptionsNotScopedWhenNotExceptionScoping(Injector injector) throws Exception {
-    RemoteProvider<Foo> remoteProvider = 
+    RemoteProvider<Foo> remoteProvider =
         injector.getInstance(Key.get(remoteProviderOfFoo, NotExceptionScoping.class));
 
     mockRemoteProvider.throwOnNextGet(new RemoteException("A"));
@@ -285,7 +286,7 @@
     } catch (RemoteException expected) {
       assertEquals("A", expected.getMessage());
     }
-    
+
     mockRemoteProvider.throwOnNextGet(new RemoteException("B"));
     MockFoo.nextToThrow = new RemoteException("B");
     try {
@@ -295,100 +296,104 @@
       assertEquals("B", expected.getMessage());
     }
   }
-  
-  public void testAnnotations_Bind() throws Exception {
-    final MockRemoteProvider<Foo> mockRemoteProviderA = new MockRemoteProvider<Foo>();
-    final MockRemoteProvider<Foo> mockRemoteProviderB = new MockRemoteProvider<Foo>();
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .annotatedWith(Names.named("a"))
-            .to(mockRemoteProviderA);
 
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .to(mockRemoteProviderB);
-      }
-    });
+  public void testAnnotations_Bind() throws Exception {
+    final MockRemoteProvider<Foo> mockRemoteProviderA = new MockRemoteProvider<>();
+    final MockRemoteProvider<Foo> mockRemoteProviderB = new MockRemoteProvider<>();
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .annotatedWith(Names.named("a"))
+                    .to(mockRemoteProviderA);
+
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .to(mockRemoteProviderB);
+              }
+            });
     tAnnotations(bindInjector, mockRemoteProviderA, mockRemoteProviderB);
   }
-  
+
   public void testAnnotations_Provides() throws Exception {
-    final MockRemoteProvider<Foo> mockRemoteProviderA = new MockRemoteProvider<Foo>();
-    final MockRemoteProvider<Foo> mockRemoteProviderB = new MockRemoteProvider<Foo>();
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-       }
-       
-       @SuppressWarnings("unused")
-       @CheckedProvides(RemoteProvider.class)
-       @Named("a")
-       Foo throwOrGet() throws RemoteException, BindException {
-         return mockRemoteProviderA.get();
-       }
-       
-       @SuppressWarnings("unused")
-       @CheckedProvides(RemoteProvider.class)
-       Foo throwOrGet2() throws RemoteException, BindException {
-         return mockRemoteProviderB.get();
-       }
-    });
+    final MockRemoteProvider<Foo> mockRemoteProviderA = new MockRemoteProvider<>();
+    final MockRemoteProvider<Foo> mockRemoteProviderB = new MockRemoteProvider<>();
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              @Named("a")
+              Foo throwOrGet() throws RemoteException, BindException {
+                return mockRemoteProviderA.get();
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              Foo throwOrGet2() throws RemoteException, BindException {
+                return mockRemoteProviderB.get();
+              }
+            });
     tAnnotations(providesInjector, mockRemoteProviderA, mockRemoteProviderB);
   }
-  
-  private void tAnnotations(Injector injector, MockRemoteProvider<Foo> mockA,
-      MockRemoteProvider<Foo> mockB) throws Exception {
+
+  private void tAnnotations(
+      Injector injector, MockRemoteProvider<Foo> mockA, MockRemoteProvider<Foo> mockB)
+      throws Exception {
     mockA.setNextToReturn(new SimpleFoo("A"));
     mockB.setNextToReturn(new SimpleFoo("B"));
-    assertEquals("A", 
-        injector.getInstance(Key.get(remoteProviderOfFoo, Names.named("a"))).get().s());
+    assertEquals(
+        "A", injector.getInstance(Key.get(remoteProviderOfFoo, Names.named("a"))).get().s());
 
-    assertEquals("B", 
-        injector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
+    assertEquals("B", injector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
   }
-  
-  public void testAnnotations_Cxtor() throws Exception {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .annotatedWith(Names.named("a"))
-            .providing(MockFoo.class);
 
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .providing(AnotherMockFoo.class);
-      }
-    });
+  public void testAnnotations_Cxtor() throws Exception {
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .annotatedWith(Names.named("a"))
+                    .providing(MockFoo.class);
+
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(AnotherMockFoo.class);
+              }
+            });
     MockFoo.nextToReturn = "A";
     AnotherMockFoo.nextToReturn = "B";
-    assertEquals("A", 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo, Names.named("a"))).get().s());
+    assertEquals(
+        "A", cxtorInjector.getInstance(Key.get(remoteProviderOfFoo, Names.named("a"))).get().s());
 
-    assertEquals("B", 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
+    assertEquals("B", cxtorInjector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
   }
-  
+
   public void testUndeclaredExceptions_Bind() throws Exception {
     tUndeclaredExceptions(bindInjector);
   }
-  
+
   public void testUndeclaredExceptions_Provides() throws Exception {
     tUndeclaredExceptions(providesInjector);
   }
-  
+
   public void testUndeclaredExceptions_Cxtor() throws Exception {
     tUndeclaredExceptions(cxtorInjector);
   }
 
-  private void tUndeclaredExceptions(Injector injector) throws Exception { 
-    RemoteProvider<Foo> remoteProvider = 
-        injector.getInstance(Key.get(remoteProviderOfFoo));
+  private void tUndeclaredExceptions(Injector injector) throws Exception {
+    RemoteProvider<Foo> remoteProvider = injector.getInstance(Key.get(remoteProviderOfFoo));
     mockRemoteProvider.throwOnNextGet(new IndexOutOfBoundsException("A"));
     MockFoo.nextToThrow = new IndexOutOfBoundsException("A");
     try {
@@ -413,215 +418,257 @@
     final SubMockRemoteProvider aProvider = new SubMockRemoteProvider();
     aProvider.setNextToReturn(new SimpleFoo("A"));
 
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .to(aProvider);
-      }
-    });
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .to(aProvider);
+              }
+            });
 
-    assertEquals("A",
-        bindInjector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
+    assertEquals("A", bindInjector.getInstance(Key.get(remoteProviderOfFoo)).get().s());
   }
 
-  static class SubMockRemoteProvider extends MockRemoteProvider<Foo> { }
+  static class SubMockRemoteProvider extends MockRemoteProvider<Foo> {}
 
   public void testBindingToNonInterfaceType_Bind() throws Exception {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(MockRemoteProvider.class, Foo.class)
-              .to(mockRemoteProvider);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(MockRemoteProvider.class, Foo.class)
+                  .to(mockRemoteProvider);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(MockRemoteProvider.class.getName() + " must be an interface",
+      assertEquals(
+          MockRemoteProvider.class.getName() + " must be an interface",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testBindingToNonInterfaceType_Provides() throws Exception {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(MockRemoteProvider.class)
-        Foo foo() {
-          return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(MockRemoteProvider.class)
+            Foo foo() {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(MockRemoteProvider.class.getName() + " must be an interface",
-          Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
-    }
-  }  
-  
-  public void testBindingToSubSubInterface_Bind() throws Exception {
-    try {
-      bindInjector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(SubRemoteProvider.class, Foo.class);
-        }
-      });
-      fail();
-    } catch (CreationException expected) {
-      assertEquals(SubRemoteProvider.class.getName() + " must extend CheckedProvider (and only CheckedProvider)",
+      assertEquals(
+          MockRemoteProvider.class.getName() + " must be an interface",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
-  public void testBindingToSubSubInterface_Provides() throws Exception {
+
+  public void testBindingToSubSubInterface_Bind() throws Exception {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(SubRemoteProvider.class)
-        Foo foo() {
-          return null;
-        }
-      });
+      bindInjector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ThrowingProviderBinder.create(binder()).bind(SubRemoteProvider.class, Foo.class);
+                }
+              });
       fail();
     } catch (CreationException expected) {
-      assertEquals(SubRemoteProvider.class.getName() + " must extend CheckedProvider (and only CheckedProvider)",
+      assertEquals(
+          SubRemoteProvider.class.getName()
+              + " must extend CheckedProvider (and only CheckedProvider)",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
-  }    
+  }
 
-  interface SubRemoteProvider extends RemoteProvider<String> { }
+  public void testBindingToSubSubInterface_Provides() throws Exception {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(SubRemoteProvider.class)
+            Foo foo() {
+              return null;
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+      assertEquals(
+          SubRemoteProvider.class.getName()
+              + " must extend CheckedProvider (and only CheckedProvider)",
+          Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
+    }
+  }
+
+  interface SubRemoteProvider extends RemoteProvider<String> {}
 
   public void testBindingToInterfaceWithExtraMethod_Bind() throws Exception {
     try {
-      bindInjector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProviderWithExtraMethod.class, Foo.class);
-        }
-      });
+      bindInjector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ThrowingProviderBinder.create(binder())
+                      .bind(RemoteProviderWithExtraMethod.class, Foo.class);
+                }
+              });
       fail();
     } catch (CreationException expected) {
-      assertEquals(RemoteProviderWithExtraMethod.class.getName() + " may not declare any new methods, but declared " 
-          + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
+      assertEquals(
+          RemoteProviderWithExtraMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testBindingToInterfaceWithExtraMethod_Provides() throws Exception {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProviderWithExtraMethod.class)
-        Foo foo() {
-          return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProviderWithExtraMethod.class)
+            Foo foo() {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(RemoteProviderWithExtraMethod.class.getName() + " may not declare any new methods, but declared " 
-          + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
+      assertEquals(
+          RemoteProviderWithExtraMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testDependencies_Bind() {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("Foo");
-        bind(Integer.class).toInstance(5);
-        bind(Double.class).toInstance(5d);
-        bind(Long.class).toInstance(5L);
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .to(DependentRemoteProvider.class);
-      }
-    });
-    
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("Foo");
+                bind(Integer.class).toInstance(5);
+                bind(Double.class).toInstance(5d);
+                bind(Long.class).toInstance(5L);
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .to(DependentRemoteProvider.class);
+              }
+            });
+
     HasDependencies hasDependencies =
-        (HasDependencies)bindInjector.getBinding(Key.get(remoteProviderOfFoo));
-    hasDependencies = 
-        (HasDependencies)bindInjector.getBinding(
-            Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+        (HasDependencies) bindInjector.getBinding(Key.get(remoteProviderOfFoo));
+    hasDependencies =
+        (HasDependencies)
+            bindInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
     // Make sure that that is dependent on DependentRemoteProvider.
-    assertEquals(Dependency.get(Key.get(DependentRemoteProvider.class)), 
+    assertEquals(
+        Dependency.get(Key.get(DependentRemoteProvider.class)),
         Iterables.getOnlyElement(hasDependencies.getDependencies()));
     // And make sure DependentRemoteProvider has the proper dependencies.
-    hasDependencies = (HasDependencies)bindInjector.getBinding(DependentRemoteProvider.class);
-    Set<Key<?>> dependencyKeys = ImmutableSet.copyOf(
-        Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class), Key.get(Integer.class),
-        Key.get(Long.class), Key.get(Double.class)), dependencyKeys);
+    hasDependencies = (HasDependencies) bindInjector.getBinding(DependentRemoteProvider.class);
+    Set<Key<?>> dependencyKeys =
+        ImmutableSet.copyOf(
+            Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
+    assertEquals(
+        ImmutableSet.<Key<?>>of(
+            Key.get(String.class),
+            Key.get(Integer.class),
+            Key.get(Long.class),
+            Key.get(Double.class)),
+        dependencyKeys);
   }
-  
+
   public void testDependencies_Provides() {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("Foo");
-        bind(Integer.class).toInstance(5);
-        bind(Double.class).toInstance(5d);
-        bind(Long.class).toInstance(5L);
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      Foo foo(String s, Integer i, Double d, Long l) {
-        return null;
-      }
-    });
-    
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("Foo");
+                bind(Integer.class).toInstance(5);
+                bind(Double.class).toInstance(5d);
+                bind(Long.class).toInstance(5L);
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              Foo foo(String s, Integer i, Double d, Long l) {
+                return null;
+              }
+            });
+
     HasDependencies hasDependencies =
         (HasDependencies) providesInjector.getBinding(Key.get(remoteProviderOfFoo));
     // RemoteProvider<String> is dependent on the provider method..
-    hasDependencies = (HasDependencies) providesInjector.getBinding(
-        Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+    hasDependencies =
+        (HasDependencies)
+            providesInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
     // And the provider method has our real dependencies..
-    hasDependencies = (HasDependencies)providesInjector.getBinding(
-        Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
-    Set<Key<?>> dependencyKeys = ImmutableSet.copyOf(
-        Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class), Key.get(Integer.class),
-        Key.get(Long.class), Key.get(Double.class)), dependencyKeys);
-  }  
-  
+    hasDependencies =
+        (HasDependencies)
+            providesInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+    Set<Key<?>> dependencyKeys =
+        ImmutableSet.copyOf(
+            Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
+    assertEquals(
+        ImmutableSet.<Key<?>>of(
+            Key.get(String.class),
+            Key.get(Integer.class),
+            Key.get(Long.class),
+            Key.get(Double.class)),
+        dependencyKeys);
+  }
+
   public void testDependencies_Cxtor() {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toInstance("Foo");
-        bind(Integer.class).toInstance(5);
-        bind(Double.class).toInstance(5d);
-        bind(Long.class).toInstance(5L);
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .providing(DependentMockFoo.class);
-      }
-    });
-    
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("Foo");
+                bind(Integer.class).toInstance(5);
+                bind(Double.class).toInstance(5d);
+                bind(Long.class).toInstance(5L);
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(DependentMockFoo.class);
+              }
+            });
+
     Key<?> key = Key.get(remoteProviderOfFoo);
-    
+
     // RemoteProvider<String> is dependent on Result.
     HasDependencies hasDependencies = (HasDependencies) cxtorInjector.getBinding(key);
     key = Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey();
@@ -631,81 +678,91 @@
     hasDependencies = (HasDependencies) cxtorInjector.getBinding(key);
     key = Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey();
     assertTrue(CheckedProvider.class.isAssignableFrom(key.getTypeLiteral().getRawType()));
-    
+
     // And the CheckedProvider is dependent on DependentMockFoo...
     hasDependencies = (HasDependencies) cxtorInjector.getBinding(key);
     key = Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey();
     assertEquals(DependentMockFoo.class, key.getTypeLiteral().getRawType());
-    
+
     // And DependentMockFoo is dependent on the goods.
-    hasDependencies = (HasDependencies) cxtorInjector.getBinding(key); 
-    Set<Key<?>> dependencyKeys = ImmutableSet.copyOf(
-        Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class), Key.get(Integer.class),
-        Key.get(Long.class), Key.get(Double.class)), dependencyKeys);
-  }  
+    hasDependencies = (HasDependencies) cxtorInjector.getBinding(key);
+    Set<Key<?>> dependencyKeys =
+        ImmutableSet.copyOf(
+            Iterables.transform(hasDependencies.getDependencies(), DEPENDENCY_TO_KEY));
+    assertEquals(
+        ImmutableSet.<Key<?>>of(
+            Key.get(String.class),
+            Key.get(Integer.class),
+            Key.get(Long.class),
+            Key.get(Double.class)),
+        dependencyKeys);
+  }
 
   interface RemoteProviderWithExtraMethod<T> extends CheckedProvider<T> {
     T get(T defaultValue) throws RemoteException, BindException;
   }
 
-  interface RemoteProvider<T> extends CheckedProvider<T> { 
+  interface RemoteProvider<T> extends CheckedProvider<T> {
+    @Override
     public T get() throws RemoteException, BindException;
   }
-  
+
   static class DependentMockFoo implements Foo {
     @Inject double foo;
-    
-    @ThrowingInject public DependentMockFoo(String foo, int bar) {
-    }
-    
-    @Inject void initialize(long foo) {}
-    
+
+    @ThrowingInject
+    public DependentMockFoo(String foo, int bar) {}
+
+    @Inject
+    void initialize(long foo) {}
+
     @Override
     public String s() {
       return null;
     }
   }
-  
+
   static class DependentRemoteProvider<T> implements RemoteProvider<T> {
     @Inject double foo;
-    
-    @Inject public DependentRemoteProvider(String foo, int bar) {
-    }
-    
-    @Inject void initialize(long foo) {}
-    
+
+    @Inject
+    public DependentRemoteProvider(String foo, int bar) {}
+
+    @Inject
+    void initialize(long foo) {}
+
+    @Override
     public T get() {
       return null;
     }
   }
-  
+
   interface Foo {
     String s();
   }
-  
+
   static class SimpleFoo implements Foo {
     private String s;
-    
+
     SimpleFoo(String s) {
       this.s = s;
     }
-    
+
     @Override
     public String s() {
       return s;
     }
-    
+
     @Override
     public String toString() {
       return s;
     }
   }
-  
+
   static class MockFoo implements Foo {
-    static Exception nextToThrow;    
+    static Exception nextToThrow;
     static String nextToReturn;
-    
+
     @ThrowingInject
     MockFoo() throws RemoteException, BindException {
       if (nextToThrow instanceof RemoteException) {
@@ -720,22 +777,22 @@
         throw new AssertionError("nextToThrow must be a runtime or remote exception");
       }
     }
-    
+
     @Override
     public String s() {
       return nextToReturn;
     }
-    
+
     @Override
     public String toString() {
       return nextToReturn;
     }
   }
-  
+
   static class AnotherMockFoo implements Foo {
-    static Exception nextToThrow;    
+    static Exception nextToThrow;
     static String nextToReturn;
-    
+
     @ThrowingInject
     AnotherMockFoo() throws RemoteException, BindException {
       if (nextToThrow instanceof RemoteException) {
@@ -750,18 +807,18 @@
         throw new AssertionError("nextToThrow must be a runtime or remote exception");
       }
     }
-    
+
     @Override
     public String s() {
       return nextToReturn;
     }
-    
+
     @Override
     public String toString() {
       return nextToReturn;
     }
   }
-  
+
   static class MockRemoteProvider<T> implements RemoteProvider<T> {
     Exception nextToThrow;
     T nextToReturn;
@@ -773,7 +830,8 @@
     public void setNextToReturn(T nextToReturn) {
       this.nextToReturn = nextToReturn;
     }
-    
+
+    @Override
     public T get() throws RemoteException, BindException {
       if (nextToThrow instanceof RemoteException) {
         throw (RemoteException) nextToThrow;
@@ -790,196 +848,225 @@
   }
 
   public void testBindingToInterfaceWithBoundValueType_Bind() throws RemoteException {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(StringRemoteProvider.class, String.class)
-            .to(new StringRemoteProvider() {
-              public String get() {
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(StringRemoteProvider.class, String.class)
+                    .to(
+                        new StringRemoteProvider() {
+                          @Override
+                          public String get() {
+                            return "A";
+                          }
+                        });
+              }
+            });
+
+    assertEquals("A", bindInjector.getInstance(StringRemoteProvider.class).get());
+  }
+
+  public void testBindingToInterfaceWithBoundValueType_Provides() throws RemoteException {
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(StringRemoteProvider.class)
+              String foo() throws RemoteException {
                 return "A";
               }
             });
-      }
-    });
-    
-    assertEquals("A", bindInjector.getInstance(StringRemoteProvider.class).get());
-  }
-  
-  public void testBindingToInterfaceWithBoundValueType_Provides() throws RemoteException {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(StringRemoteProvider.class)
-      String foo() throws RemoteException {
-          return "A";
-      }
-    });
-    
+
     assertEquals("A", providesInjector.getInstance(StringRemoteProvider.class).get());
   }
 
   interface StringRemoteProvider extends CheckedProvider<String> {
-    @Override String get() throws RemoteException;  
+    @Override
+    String get() throws RemoteException;
   }
 
   @SuppressWarnings("deprecation")
   public void testBindingToInterfaceWithGeneric_Bind() throws Exception {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, new TypeLiteral<List<String>>() { }.getType())
-            .to(new RemoteProvider<List<String>>() {
-              public List<String> get() {
-                return Arrays.asList("A", "B");
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {}.getType())
+                    .to(
+                        new RemoteProvider<List<String>>() {
+                          @Override
+                          public List<String> get() {
+                            return Arrays.asList("A", "B");
+                          }
+                        });
               }
             });
-      }
-    });
 
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
     assertEquals(Arrays.asList("A", "B"), bindInjector.getInstance(key).get());
   }
-  
+
   public void testBindingToInterfaceWithGeneric_BindUsingTypeLiteral() throws Exception {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {})
-            .to(new RemoteProvider<List<String>>() {
-              public List<String> get() {
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {})
+                    .to(
+                        new RemoteProvider<List<String>>() {
+                          @Override
+                          public List<String> get() {
+                            return Arrays.asList("A", "B");
+                          }
+                        });
+              }
+            });
+
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
+    assertEquals(Arrays.asList("A", "B"), bindInjector.getInstance(key).get());
+  }
+
+  public void testBindingToInterfaceWithGeneric_Provides() throws Exception {
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              List<String> foo() throws RemoteException {
                 return Arrays.asList("A", "B");
               }
             });
-      }
-    });
 
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
-    assertEquals(Arrays.asList("A", "B"), bindInjector.getInstance(key).get());
-  }
-  
-  public void testBindingToInterfaceWithGeneric_Provides() throws Exception {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      List<String> foo() throws RemoteException {
-          return Arrays.asList("A", "B");
-      }
-    });
-
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
     assertEquals(Arrays.asList("A", "B"), providesInjector.getInstance(key).get());
   }
-  
-  public void testBindingToInterfaceWithGeneric_Cxtor() throws Exception {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-        .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {})
-        .providing(new TypeLiteral<ThrowingArrayList<String>>() {});
-      }
-    });
 
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
+  public void testBindingToInterfaceWithGeneric_Cxtor() throws Exception {
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {})
+                    .providing(new TypeLiteral<ThrowingArrayList<String>>() {});
+              }
+            });
+
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
     assertEquals(Arrays.asList(), cxtorInjector.getInstance(key).get());
   }
-  
+
   private static class ThrowingArrayList<T> extends ArrayList<T> {
     @SuppressWarnings("unused")
     @ThrowingInject
     ThrowingArrayList() {}
   }
-  
+
   public void testProviderMethodWithWrongException() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        String foo() throws InterruptedException {
-            return null;
-        }
-      });
-      fail();
-    } catch(CreationException ce) {
-      assertEquals(InterruptedException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
-          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }
-  }
-  
-  public void testCxtorWithWrongException() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(WrongExceptionFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            String foo() throws InterruptedException {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException ce) {
-      assertEquals(InterruptedException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
+  public void testCxtorWithWrongException() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, Foo.class)
+                  .providing(WrongExceptionFoo.class);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
+          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
+    }
+  }
+
   static class WrongExceptionFoo implements Foo {
     @SuppressWarnings("unused")
     @ThrowingInject
-    public WrongExceptionFoo() throws InterruptedException {
-    }
-    
+    public WrongExceptionFoo() throws InterruptedException {}
+
     @Override
-    public String s() { return null; }
+    public String s() {
+      return null;
+    }
   }
-  
+
   public void testProviderMethodWithSubclassOfExceptionIsOk() throws Exception {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      Foo foo() throws AccessException {
-        throw new AccessException("boo!");
-      }
-    });
-    
-    RemoteProvider<Foo> remoteProvider = 
-      providesInjector.getInstance(Key.get(remoteProviderOfFoo));
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              Foo foo() throws AccessException {
+                throw new AccessException("boo!");
+              }
+            });
+
+    RemoteProvider<Foo> remoteProvider = providesInjector.getInstance(Key.get(remoteProviderOfFoo));
 
     try {
       remoteProvider.get();
@@ -989,113 +1076,126 @@
       assertEquals("boo!", expected.getMessage());
     }
   }
-  
-  public void testCxtorWithSubclassOfExceptionIsOk() throws Exception {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(SubclassExceptionFoo.class);
-        }
-      });
-    
-    RemoteProvider<Foo> remoteProvider = 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
 
-      try {
-        remoteProvider.get();
-        fail();
-      } catch (RemoteException expected) {
-        assertTrue(expected instanceof AccessException);
-        assertEquals("boo!", expected.getMessage());
-      }
+  public void testCxtorWithSubclassOfExceptionIsOk() throws Exception {
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(SubclassExceptionFoo.class);
+              }
+            });
+
+    RemoteProvider<Foo> remoteProvider = cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
+
+    try {
+      remoteProvider.get();
+      fail();
+    } catch (RemoteException expected) {
+      assertTrue(expected instanceof AccessException);
+      assertEquals("boo!", expected.getMessage());
+    }
   }
-  
+
   static class SubclassExceptionFoo implements Foo {
     @ThrowingInject
     public SubclassExceptionFoo() throws AccessException {
       throw new AccessException("boo!");
     }
-    
+
     @Override
-    public String s() { return null; }
+    public String s() {
+      return null;
+    }
   }
-  
+
   public void testProviderMethodWithSuperclassExceptionFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        Foo foo() throws IOException {
-            return null;
-        }
-      });
-      fail();
-    } catch(CreationException ce) {
-      assertEquals(IOException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
-          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }
-  }
-  
-  public void testCxtorWithSuperclassExceptionFails() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(SuperclassExceptionFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            Foo foo() throws IOException {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException ce) {
-      assertEquals(IOException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
+      assertEquals(
+          IOException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
+  public void testCxtorWithSuperclassExceptionFails() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, Foo.class)
+                  .providing(SuperclassExceptionFoo.class);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(
+          IOException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
+          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
+    }
+  }
+
   static class SuperclassExceptionFoo implements Foo {
     @SuppressWarnings("unused")
     @ThrowingInject
-    public SuperclassExceptionFoo() throws IOException {
-    }
-    
+    public SuperclassExceptionFoo() throws IOException {}
+
     @Override
-    public String s() { return null; }
+    public String s() {
+      return null;
+    }
   }
-  
+
   public void testProviderMethodWithRuntimeExceptionsIsOk() throws Exception {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      Foo foo() throws RuntimeException {
-        throw new RuntimeException("boo!");
-      }
-    });
-    
-    RemoteProvider<Foo> remoteProvider = 
-      providesInjector.getInstance(Key.get(remoteProviderOfFoo));
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              Foo foo() throws RuntimeException {
+                throw new RuntimeException("boo!");
+              }
+            });
+
+    RemoteProvider<Foo> remoteProvider = providesInjector.getInstance(Key.get(remoteProviderOfFoo));
 
     try {
       remoteProvider.get();
@@ -1104,19 +1204,20 @@
       assertEquals("boo!", expected.getCause().getMessage());
     }
   }
-  
+
   public void testCxtorWithRuntimeExceptionsIsOk() throws Exception {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, Foo.class)
-            .providing(RuntimeExceptionFoo.class);
-      }
-    });
-    
-    RemoteProvider<Foo> remoteProvider = 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(RuntimeExceptionFoo.class);
+              }
+            });
+
+    RemoteProvider<Foo> remoteProvider = cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
 
     try {
       remoteProvider.get();
@@ -1125,428 +1226,477 @@
       assertEquals("boo!", expected.getCause().getMessage());
     }
   }
-    
+
   static class RuntimeExceptionFoo implements Foo {
     @ThrowingInject
     public RuntimeExceptionFoo() throws RuntimeException {
       throw new RuntimeException("boo!");
     }
-    
+
     @Override
-    public String s() { return null; }
-  }
-  
-  private static class SubBindException extends BindException {}
-  
-  public void testProviderMethodWithManyExceptions() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        String foo() throws InterruptedException, RuntimeException, RemoteException, 
-                            AccessException, TooManyListenersException,
-                            BindException, SubBindException {
-            return null;
-        }
-      });
-      fail();
-    } catch(CreationException ce) {
-      // The only two that should fail are Interrupted & TooManyListeners.. the rest are OK.
-      List<Message> errors = ImmutableList.copyOf(ce.getErrorMessages());
-      assertEquals(InterruptedException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
-          errors.get(0).getMessage());
-      assertEquals(TooManyListenersException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
-          errors.get(1).getMessage());
-      assertEquals(2, errors.size());
+    public String s() {
+      return null;
     }
   }
-  
-  public void testCxtorWithManyExceptions() {
+
+  private static class SubBindException extends BindException {}
+
+  public void testProviderMethodWithManyExceptions() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(ManyExceptionFoo.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            String foo()
+                throws InterruptedException, RuntimeException, RemoteException, AccessException,
+                    TooManyListenersException, BindException, SubBindException {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException ce) {
       // The only two that should fail are Interrupted & TooManyListeners.. the rest are OK.
       List<Message> errors = ImmutableList.copyOf(ce.getErrorMessages());
-      assertEquals(InterruptedException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           errors.get(0).getMessage());
-      assertEquals(TooManyListenersException.class.getName()
-          + " is not compatible with the exceptions (["
-          + RemoteException.class + ", " + BindException.class
-          + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName()
-          + ")", 
+      assertEquals(
+          TooManyListenersException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           errors.get(1).getMessage());
       assertEquals(2, errors.size());
     }
   }
-  
+
+  public void testCxtorWithManyExceptions() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, Foo.class)
+                  .providing(ManyExceptionFoo.class);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      // The only two that should fail are Interrupted & TooManyListeners.. the rest are OK.
+      List<Message> errors = ImmutableList.copyOf(ce.getErrorMessages());
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
+          errors.get(0).getMessage());
+      assertEquals(
+          TooManyListenersException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + ", "
+              + BindException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
+          errors.get(1).getMessage());
+      assertEquals(2, errors.size());
+    }
+  }
+
   static class ManyExceptionFoo implements Foo {
     @SuppressWarnings("unused")
     @ThrowingInject
     public ManyExceptionFoo()
-        throws InterruptedException,
-        RuntimeException,
-        RemoteException,
-        AccessException,
-        TooManyListenersException,
-        BindException,
-        SubBindException {
-    }
-    
+        throws InterruptedException, RuntimeException, RemoteException, AccessException,
+            TooManyListenersException, BindException, SubBindException {}
+
     @Override
-    public String s() { return null; }
+    public String s() {
+      return null;
+    }
   }
-  
+
   public void testMoreTypeParameters() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(TooManyTypeParameters.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(TooManyTypeParameters.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(TooManyTypeParameters.class.getName() + " has more than one generic type parameter: [T, P]",
+    } catch (CreationException ce) {
+      assertEquals(
+          TooManyTypeParameters.class.getName()
+              + " has more than one generic type parameter: [T, P]",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }    
+    }
   }
-  
+
   public void testWrongThrowingProviderType() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(WrongThrowingProviderType.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(WrongThrowingProviderType.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(WrongThrowingProviderType.class.getName() 
-          + " does not properly extend CheckedProvider, the first type parameter of CheckedProvider "
-          + "(java.lang.String) is not a generic type",
+    } catch (CreationException ce) {
+      assertEquals(
+          WrongThrowingProviderType.class.getName()
+              + " does not properly extend CheckedProvider, the first type parameter of CheckedProvider "
+              + "(java.lang.String) is not a generic type",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }    
+    }
   }
-  
+
   public void testOneMethodThatIsntGet() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(OneNoneGetMethod.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(OneNoneGetMethod.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(OneNoneGetMethod.class.getName() 
-          + " may not declare any new methods, but declared " + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]),
+    } catch (CreationException ce) {
+      assertEquals(
+          OneNoneGetMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]),
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testManyMethods() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(ManyMethods.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(ManyMethods.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(ManyMethods.class.getName() 
-          + " may not declare any new methods, but declared " + Arrays.asList(ManyMethods.class.getDeclaredMethods()),
+    } catch (CreationException ce) {
+      assertEquals(
+          ManyMethods.class.getName()
+              + " may not declare any new methods, but declared "
+              + Arrays.asList(ManyMethods.class.getDeclaredMethods()),
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testIncorrectPredefinedType_Bind() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(StringRemoteProvider.class, Integer.class)
-              .to(new StringRemoteProvider() {
-                public String get() {
-                  return "A";
-                }
-              });
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(StringRemoteProvider.class, Integer.class)
+                  .to(
+                      new StringRemoteProvider() {
+                        @Override
+                        public String get() {
+                          return "A";
+                        }
+                      });
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(StringRemoteProvider.class.getName() 
-          + " expects the value type to be java.lang.String, but it was java.lang.Integer",
+    } catch (CreationException ce) {
+      assertEquals(
+          StringRemoteProvider.class.getName()
+              + " expects the value type to be java.lang.String, but it was java.lang.Integer",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testIncorrectPredefinedType_Provides() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(StringRemoteProvider.class)
-        Integer foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(StringRemoteProvider.class)
+            Integer foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(StringRemoteProvider.class.getName() 
-          + " expects the value type to be java.lang.String, but it was java.lang.Integer",
+    } catch (CreationException ce) {
+      assertEquals(
+          StringRemoteProvider.class.getName()
+              + " expects the value type to be java.lang.String, but it was java.lang.Integer",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
-  private static interface TooManyTypeParameters<T, P> extends CheckedProvider<T> {    
-  }
-  
-  private static interface WrongThrowingProviderType<T> extends CheckedProvider<String> {    
-  }
-  
+
+  private static interface TooManyTypeParameters<T, P> extends CheckedProvider<T> {}
+
+  private static interface WrongThrowingProviderType<T> extends CheckedProvider<String> {}
+
   private static interface OneNoneGetMethod<T> extends CheckedProvider<T> {
     T bar();
   }
-  
+
   private static interface ManyMethods<T> extends CheckedProvider<T> {
     T bar();
+
     String baz();
   }
-  
+
   public void testResultSerializes() throws Exception {
     Result result = Result.forValue("foo");
     result = Asserts.reserialize(result);
     assertEquals("foo", result.getOrThrow());
   }
-  
+
   public void testResultExceptionSerializes() throws Exception {
     Result result = Result.forException(new Exception("boo"));
     result = Asserts.reserialize(result);
     try {
       result.getOrThrow();
       fail();
-    } catch(Exception ex) {
+    } catch (Exception ex) {
       assertEquals("boo", ex.getMessage());
     }
   }
-  
+
   public void testEarlyBindingError() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(StringRemoteProvider.class, String.class)
-              .to(FailingProvider.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(StringRemoteProvider.class, String.class)
+                  .to(FailingProvider.class);
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals("Could not find a suitable constructor in " + FailingProvider.class.getName()
-          + ". Classes must have either one (and only one) constructor annotated with @Inject"
-          + " or a zero-argument constructor that is not private.",
+    } catch (CreationException ce) {
+      assertEquals(
+          "Could not find a suitable constructor in "
+              + FailingProvider.class.getName()
+              + ". Classes must have either one (and only one) constructor annotated with @Inject"
+              + " or a zero-argument constructor that is not private.",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   private static class FailingProvider implements StringRemoteProvider {
     // no @Inject.
     @SuppressWarnings("unused")
     FailingProvider(Integer foo) {}
-    
+
+    @Override
     public String get() {
       return null;
     }
   }
-  
+
   public void testNoInjectionPointForUsing() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(InvalidFoo.class);
-        }
-      });
-      fail();
-    } catch (CreationException ce) {
-      assertEquals("Could not find a suitable constructor in " + InvalidFoo.class.getName()
-          + ". Classes must have either one (and only one) constructor annotated with "
-          + "@ThrowingInject.",
-          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }
-  }
-  
-  static class InvalidFoo implements Foo {
-    public InvalidFoo(String dep) {
-    }
-    
-    @Override public String s() { return null; }
-  }
-  
-  public void testNoThrowingInject() {
-    try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(NormalInjectableFoo.class);
-        }
-      });
-      fail();
-    } catch (CreationException ce) {
-      assertEquals("Could not find a suitable constructor in " + NormalInjectableFoo.class.getName()
-          + ". Classes must have either one (and only one) constructor annotated with "
-          + "@ThrowingInject.",
-          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }
-  }
-  
-  static class NormalInjectableFoo implements Foo {
-    @Inject
-    public NormalInjectableFoo() {
-    }
-    
-    @Override public String s() { return null; }
-  }
-  
-  public void testProvisionExceptionOnDependenciesOfCxtor() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(ProvisionExceptionFoo.class);
-          bindScope(BadScope.class, new Scope() {
+      Guice.createInjector(
+          new AbstractModule() {
             @Override
-            public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
-              return new Provider<T>() {
-                @Override
-                public T get() {
-                  throw new OutOfScopeException("failure");
-                }
-              };
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, Foo.class)
+                  .providing(InvalidFoo.class);
             }
           });
-        }
-      });
-    
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(
+          "Could not find a suitable constructor in "
+              + InvalidFoo.class.getName()
+              + ". Classes must have either one (and only one) constructor annotated with "
+              + "@ThrowingInject.",
+          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
+    }
+  }
+
+  static class InvalidFoo implements Foo {
+    public InvalidFoo(String dep) {}
+
+    @Override
+    public String s() {
+      return null;
+    }
+  }
+
+  public void testNoThrowingInject() {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, Foo.class)
+                  .providing(NormalInjectableFoo.class);
+            }
+          });
+      fail();
+    } catch (CreationException ce) {
+      assertEquals(
+          "Could not find a suitable constructor in "
+              + NormalInjectableFoo.class.getName()
+              + ". Classes must have either one (and only one) constructor annotated with "
+              + "@ThrowingInject.",
+          Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
+    }
+  }
+
+  static class NormalInjectableFoo implements Foo {
+    @Inject
+    public NormalInjectableFoo() {}
+
+    @Override
+    public String s() {
+      return null;
+    }
+  }
+
+  public void testProvisionExceptionOnDependenciesOfCxtor() throws Exception {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(ProvisionExceptionFoo.class);
+                bindScope(
+                    BadScope.class,
+                    new Scope() {
+                      @Override
+                      public <T> Provider<T> scope(final Key<T> key, Provider<T> unscoped) {
+                        return new Provider<T>() {
+                          @Override
+                          public T get() {
+                            throw new OutOfScopeException("failure: " + key.toString());
+                          }
+                        };
+                      }
+                    });
+              }
+            });
+
     try {
       injector.getInstance(Key.get(remoteProviderOfFoo)).get();
       fail();
-    } catch(ProvisionException pe) {
-      assertEquals(2, pe.getErrorMessages().size());
-      List<Message> messages = Lists.newArrayList(pe.getErrorMessages());
-      assertEquals("Error in custom provider, com.google.inject.OutOfScopeException: failure",
-          messages.get(0).getMessage());
-      assertEquals("Error in custom provider, com.google.inject.OutOfScopeException: failure",
-          messages.get(1).getMessage());
+    } catch (ProvisionException pe) {
+      Message message = Iterables.getOnlyElement(pe.getErrorMessages());
+      assertEquals(
+          "Error in custom provider, com.google.inject.OutOfScopeException: failure: "
+              + Key.get(Unscoped1.class),
+          message.getMessage());
     }
   }
-  
+
   @ScopeAnnotation
   @Target(ElementType.TYPE)
   @Retention(RetentionPolicy.RUNTIME)
-  private @interface BadScope { }
-  
-  @BadScope private static class Unscoped1 {}
-  @BadScope private static class Unscoped2 {}
-  
+  private @interface BadScope {}
+
+  @BadScope
+  private static class Unscoped1 {}
+
+  @BadScope
+  private static class Unscoped2 {}
+
   static class ProvisionExceptionFoo implements Foo {
     @ThrowingInject
-    public ProvisionExceptionFoo(Unscoped1 a, Unscoped2 b) {
+    public ProvisionExceptionFoo(Unscoped1 a, Unscoped2 b) {}
+
+    @Override
+    public String s() {
+      return null;
     }
-    
-    @Override public String s() { return null; }
   }
-  
+
   public void testUsingDoesntClashWithBindingsOfSameType() throws Exception {
-    cxtorInjector = Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProvider.class, Foo.class)
-              .providing(MockFoo.class);
-          bind(Foo.class).to(MockFoo.class);
-          bind(MockFoo.class).to(SubMockFoo.class);
-        }
-      });
-    
-    RemoteProvider<Foo> remoteProvider = 
-        cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
+    cxtorInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, Foo.class)
+                    .providing(MockFoo.class);
+                bind(Foo.class).to(MockFoo.class);
+                bind(MockFoo.class).to(SubMockFoo.class);
+              }
+            });
+
+    RemoteProvider<Foo> remoteProvider = cxtorInjector.getInstance(Key.get(remoteProviderOfFoo));
     Foo providerGot = remoteProvider.get();
     Foo fooGot = cxtorInjector.getInstance(Foo.class);
     Foo mockGot = cxtorInjector.getInstance(MockFoo.class);
-    
+
     assertEquals(MockFoo.class, providerGot.getClass());
     assertEquals(SubMockFoo.class, fooGot.getClass());
     assertEquals(SubMockFoo.class, mockGot.getClass());
   }
-  
+
   static class SubMockFoo extends MockFoo {
-    public SubMockFoo() throws RemoteException, BindException {
-    }
-    
+    public SubMockFoo() throws RemoteException, BindException {}
   }
 }
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProvidersTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProvidersTest.java
new file mode 100644
index 0000000..380284c
--- /dev/null
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProvidersTest.java
@@ -0,0 +1,161 @@
+package com.google.inject.throwingproviders;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.inject.TypeLiteral;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link CheckedProviders}.
+ *
+ * @author eatnumber1@google.com (Russ Harmon)
+ */
+public final class CheckedProvidersTest extends TestCase {
+  private static interface StringCheckedProvider extends CheckedProvider<String> {}
+
+  public void testCheckedProviderClass_get_returnsValidString() throws Exception {
+    String expected = "rick";
+
+    StringCheckedProvider provider = CheckedProviders.of(StringCheckedProvider.class, expected);
+    assertThat(provider.get()).isEqualTo(expected);
+  }
+
+  public void testCheckedProviderTypeLiteral_get_returnsValidString() throws Exception {
+    String expected = "morty";
+
+    StringCheckedProvider provider =
+        CheckedProviders.of(TypeLiteral.get(StringCheckedProvider.class), expected);
+    assertThat(provider.get()).isEqualTo(expected);
+  }
+
+  public void testCheckedProviderClassNull_get_returnsNull() throws Exception {
+    StringCheckedProvider provider = CheckedProviders.of(StringCheckedProvider.class, null);
+    assertThat(provider.get()).isNull();
+  }
+
+  public void testCheckedProviderTypeLiteralNull_get_returnsNull() throws Exception {
+    StringCheckedProvider provider =
+        CheckedProviders.of(TypeLiteral.get(StringCheckedProvider.class), null);
+    assertThat(provider.get()).isNull();
+  }
+
+  private static final class FooException extends Exception {}
+
+  private interface FooCheckedProvider extends CheckedProvider<Object> {
+    @Override
+    Object get() throws FooException;
+  }
+
+  public void testThrowingCheckedProviderClass_get_throwsException() {
+    FooCheckedProvider provider =
+        CheckedProviders.throwing(FooCheckedProvider.class, FooException.class);
+    try {
+      provider.get();
+      fail();
+    } catch (FooException expected) {
+    }
+  }
+
+  public void testThrowingCheckedProviderTypeLiteral_get_throwsException() {
+    FooCheckedProvider provider =
+        CheckedProviders.throwing(TypeLiteral.get(FooCheckedProvider.class), FooException.class);
+    try {
+      provider.get();
+      fail();
+    } catch (FooException expected) {
+    }
+  }
+
+  private interface MoreMethodsCheckedProvider<T> extends CheckedProvider<T> {
+    @Override
+    T get() throws FooException;
+
+    void otherMethod();
+  }
+
+  public void testUnsupportedMethods_otherMethod_throwsIllegalArgumentException()
+      throws NoSuchMethodException {
+    String message =
+        String.format(
+            "%s may not declare any new methods, but declared %s",
+            MoreMethodsCheckedProvider.class.getName(),
+            Arrays.toString(MoreMethodsCheckedProvider.class.getDeclaredMethods()));
+
+    try {
+      CheckedProviders.of(
+          new TypeLiteral<MoreMethodsCheckedProvider<String>>() {}, "SHOW ME WHAT YOU GOT");
+      fail("Expected an exception to be thrown");
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage(message);
+    }
+  }
+
+  private static final class StringException extends RuntimeException {
+    StringException(String arg) {}
+  }
+
+  public void testCheckThrowable_unsupportedThrowableConstructor_throwsIllegalArgumentException() {
+    String message =
+        String.format(
+            "Thrown exception <%s> must have a no-argument constructor",
+            StringException.class.getName());
+
+    try {
+      CheckedProviders.throwing(FooCheckedProvider.class, StringException.class);
+      fail("Expected an exception to be thrown");
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage(message);
+      assertWithMessage(String.format("exception <%s> with cause", e))
+          .that(e.getCause())
+          .isInstanceOf(NoSuchMethodException.class);
+    }
+  }
+
+  private static final class BarException extends Exception {}
+
+  public void testCheckThrowable_checkedExceptionNotDeclared_throwsIllegalArgumentException()
+      throws Exception {
+    String message =
+        String.format(
+            "Thrown exception <%s> is not declared to be thrown by <%s>",
+            BarException.class.getName(), FooCheckedProvider.class.getMethod("get"));
+
+    try {
+      CheckedProviders.throwing(FooCheckedProvider.class, BarException.class);
+      fail("Expected an exception to be thrown");
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage(message);
+    }
+  }
+
+  private static final class ExpectedRuntimeException extends RuntimeException {}
+
+  public void testCheckThrowable_runtimeExceptionNotDeclared_throwsExpectedRuntimeException()
+      throws Exception {
+    FooCheckedProvider provider =
+        CheckedProviders.throwing(FooCheckedProvider.class, ExpectedRuntimeException.class);
+
+    try {
+      provider.get();
+      fail("Expected an exception to be thrown");
+    } catch (ExpectedRuntimeException e) {
+      // expected
+    }
+  }
+
+  private static final class ExpectedError extends Error {}
+
+  public void testCheckThrowable_errorNotDeclared_throwsExpectedError() throws Exception {
+    FooCheckedProvider provider =
+        CheckedProviders.throwing(FooCheckedProvider.class, ExpectedError.class);
+
+    try {
+      provider.get();
+      fail("Expected an exception to be thrown");
+    } catch (ExpectedError e) {
+      // expected
+    }
+  }
+}
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/TestScope.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/TestScope.java
index 79445a6..fa51485 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/TestScope.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/TestScope.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
 import com.google.inject.Provider;
 import com.google.inject.Scope;
 import com.google.inject.ScopeAnnotation;
-
 import java.lang.annotation.Retention;
 import java.util.HashMap;
 import java.util.Map;
@@ -34,14 +33,16 @@
  */
 class TestScope implements Scope {
 
-  @Retention(RUNTIME) @ScopeAnnotation
-  public @interface Scoped { }
+  @Retention(RUNTIME)
+  @ScopeAnnotation
+  public @interface Scoped {}
 
-  private Map<Key, Object> inScopeObjectsMap = new HashMap<Key, Object>();
+  private Map<Key, Object> inScopeObjectsMap = new HashMap<>();
 
-  public <T> Provider<T> scope(
-      final Key<T> key, final Provider<T> provider) {
+  @Override
+  public <T> Provider<T> scope(final Key<T> key, final Provider<T> provider) {
     return new Provider<T>() {
+      @Override
       @SuppressWarnings({"unchecked"})
       public T get() {
         T t = (T) inScopeObjectsMap.get(key);
@@ -55,6 +56,6 @@
   }
 
   public void beginNewScope() {
-    inScopeObjectsMap = new HashMap<Key, Object>();
+    inScopeObjectsMap = new HashMap<>();
   }
 }
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
index 373c68d..74e9935 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2007 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,9 +37,6 @@
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.Message;
-
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
@@ -50,6 +47,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.TooManyListenersException;
+import junit.framework.TestCase;
 
 /**
  * @author jmourits@google.com (Jerome Mourits)
@@ -57,61 +55,68 @@
  */
 @SuppressWarnings("deprecation")
 public class ThrowingProviderTest extends TestCase {
-  @Target(METHOD) @Retention(RUNTIME) @BindingAnnotation
-  @interface NotExceptionScoping { };
+  @Target(METHOD)
+  @Retention(RUNTIME)
+  @BindingAnnotation
+  @interface NotExceptionScoping {};
 
-  private final TypeLiteral<RemoteProvider<String>> remoteProviderOfString
-      = new TypeLiteral<RemoteProvider<String>>() { };
-  private final MockRemoteProvider<String> mockRemoteProvider = new MockRemoteProvider<String>();
+  private final TypeLiteral<RemoteProvider<String>> remoteProviderOfString =
+      new TypeLiteral<RemoteProvider<String>>() {};
+  private final MockRemoteProvider<String> mockRemoteProvider = new MockRemoteProvider<>();
   private final TestScope testScope = new TestScope();
-  private Injector bindInjector = Guice.createInjector(new AbstractModule() {
-    protected void configure() {
-      ThrowingProviderBinder.create(binder())
-          .bind(RemoteProvider.class, String.class)
-          .to(mockRemoteProvider)
-          .in(testScope);
-      
-      ThrowingProviderBinder.create(binder())
-        .bind(RemoteProvider.class, String.class)
-        .annotatedWith(NotExceptionScoping.class)
-        .scopeExceptions(false)
-        .to(mockRemoteProvider)
-        .in(testScope);
-    }
-  });
-  private Injector providesInjector = Guice.createInjector(new AbstractModule() {
-    protected void configure() {
-      install(ThrowingProviderBinder.forModule(this));
-     bindScope(TestScope.Scoped.class, testScope);
-    }
-    
-    @SuppressWarnings("unused")
-    @CheckedProvides(RemoteProvider.class)
-    @TestScope.Scoped
-    String throwOrGet() throws RemoteException {
-      return mockRemoteProvider.get();
-    }
-    
-    @SuppressWarnings("unused")
-    @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
-    @NotExceptionScoping
-    @TestScope.Scoped
-    String notExceptionScopingThrowOrGet() throws RemoteException {
-      return mockRemoteProvider.get();
-    }    
-  });
+  private Injector bindInjector =
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, String.class)
+                  .to(mockRemoteProvider)
+                  .in(testScope);
+
+              ThrowingProviderBinder.create(binder())
+                  .bind(RemoteProvider.class, String.class)
+                  .annotatedWith(NotExceptionScoping.class)
+                  .scopeExceptions(false)
+                  .to(mockRemoteProvider)
+                  .in(testScope);
+            }
+          });
+  private Injector providesInjector =
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+              bindScope(TestScope.Scoped.class, testScope);
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            @TestScope.Scoped
+            String throwOrGet() throws RemoteException {
+              return mockRemoteProvider.get();
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
+            @NotExceptionScoping
+            @TestScope.Scoped
+            String notExceptionScopingThrowOrGet() throws RemoteException {
+              return mockRemoteProvider.get();
+            }
+          });
 
   public void testExceptionsThrown_Bind() {
     tExceptionsThrown(bindInjector);
   }
-  
+
   public void testExceptionsThrown_Provides() {
     tExceptionsThrown(providesInjector);
   }
-  
+
   private void tExceptionsThrown(Injector injector) {
-    RemoteProvider<String> remoteProvider = 
-      injector.getInstance(Key.get(remoteProviderOfString));
+    RemoteProvider<String> remoteProvider = injector.getInstance(Key.get(remoteProviderOfString));
 
     mockRemoteProvider.throwOnNextGet("kaboom!");
     try {
@@ -125,24 +130,25 @@
   public void testValuesScoped_Bind() throws RemoteException {
     tValuesScoped(bindInjector, null);
   }
-  
+
   public void testValuesScoped_Provides() throws RemoteException {
     tValuesScoped(providesInjector, null);
   }
-  
+
   public void testValuesScopedWhenNotExceptionScoping_Bind() throws RemoteException {
     tValuesScoped(bindInjector, NotExceptionScoping.class);
   }
-  
+
   public void testValuesScopedWhenNotExceptionScoping_Provides() throws RemoteException {
     tValuesScoped(providesInjector, NotExceptionScoping.class);
   }
-  
-  private void tValuesScoped(Injector injector, Class<? extends Annotation> annotation) 
+
+  private void tValuesScoped(Injector injector, Class<? extends Annotation> annotation)
       throws RemoteException {
-    Key<RemoteProvider<String>> key = annotation != null ? 
-        Key.get(remoteProviderOfString, annotation) :
-        Key.get(remoteProviderOfString);
+    Key<RemoteProvider<String>> key =
+        annotation != null
+            ? Key.get(remoteProviderOfString, annotation)
+            : Key.get(remoteProviderOfString);
     RemoteProvider<String> remoteProvider = injector.getInstance(key);
 
     mockRemoteProvider.setNextToReturn("A");
@@ -158,14 +164,13 @@
   public void testExceptionsScoped_Bind() {
     tExceptionsScoped(bindInjector);
   }
-  
+
   public void testExceptionsScoped_Provides() {
     tExceptionsScoped(providesInjector);
   }
-  
+
   private void tExceptionsScoped(Injector injector) {
-    RemoteProvider<String> remoteProvider = 
-        injector.getInstance(Key.get(remoteProviderOfString));
+    RemoteProvider<String> remoteProvider = injector.getInstance(Key.get(remoteProviderOfString));
 
     mockRemoteProvider.throwOnNextGet("A");
     try {
@@ -174,7 +179,7 @@
     } catch (RemoteException expected) {
       assertEquals("A", expected.getMessage());
     }
-    
+
     mockRemoteProvider.throwOnNextGet("B");
     try {
       remoteProvider.get();
@@ -187,13 +192,13 @@
   public void testExceptionsNotScopedWhenNotExceptionScoping_Bind() {
     tExceptionsNotScopedWhenNotExceptionScoping(bindInjector);
   }
-  
+
   public void testExceptionsNotScopedWhenNotExceptionScoping_Provides() {
     tExceptionsNotScopedWhenNotExceptionScoping(providesInjector);
   }
-  
+
   private void tExceptionsNotScopedWhenNotExceptionScoping(Injector injector) {
-    RemoteProvider<String> remoteProvider = 
+    RemoteProvider<String> remoteProvider =
         injector.getInstance(Key.get(remoteProviderOfString, NotExceptionScoping.class));
 
     mockRemoteProvider.throwOnNextGet("A");
@@ -203,7 +208,7 @@
     } catch (RemoteException expected) {
       assertEquals("A", expected.getMessage());
     }
-    
+
     mockRemoteProvider.throwOnNextGet("B");
     try {
       remoteProvider.get();
@@ -212,71 +217,76 @@
       assertEquals("B", expected.getMessage());
     }
   }
-  
-  public void testAnnotations_Bind() throws RemoteException {
-    final MockRemoteProvider<String> mockRemoteProviderA = new MockRemoteProvider<String>();
-    final MockRemoteProvider<String> mockRemoteProviderB = new MockRemoteProvider<String>();
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, String.class)
-            .annotatedWith(Names.named("a"))
-            .to(mockRemoteProviderA);
 
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, String.class)
-            .to(mockRemoteProviderB);
-      }
-    });
+  public void testAnnotations_Bind() throws RemoteException {
+    final MockRemoteProvider<String> mockRemoteProviderA = new MockRemoteProvider<>();
+    final MockRemoteProvider<String> mockRemoteProviderB = new MockRemoteProvider<>();
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, String.class)
+                    .annotatedWith(Names.named("a"))
+                    .to(mockRemoteProviderA);
+
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, String.class)
+                    .to(mockRemoteProviderB);
+              }
+            });
     tAnnotations(bindInjector, mockRemoteProviderA, mockRemoteProviderB);
   }
-  
+
   public void testAnnotations_Provides() throws RemoteException {
-    final MockRemoteProvider<String> mockRemoteProviderA = new MockRemoteProvider<String>();
-    final MockRemoteProvider<String> mockRemoteProviderB = new MockRemoteProvider<String>();
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-       }
-       
-       @SuppressWarnings("unused")
-       @CheckedProvides(RemoteProvider.class)
-       @Named("a")
-       String throwOrGet() throws RemoteException {
-         return mockRemoteProviderA.get();
-       }
-       
-       @SuppressWarnings("unused")
-       @CheckedProvides(RemoteProvider.class)
-       String throwOrGet2() throws RemoteException {
-         return mockRemoteProviderB.get();
-       }
-    });
+    final MockRemoteProvider<String> mockRemoteProviderA = new MockRemoteProvider<>();
+    final MockRemoteProvider<String> mockRemoteProviderB = new MockRemoteProvider<>();
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              @Named("a")
+              String throwOrGet() throws RemoteException {
+                return mockRemoteProviderA.get();
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              String throwOrGet2() throws RemoteException {
+                return mockRemoteProviderB.get();
+              }
+            });
     tAnnotations(providesInjector, mockRemoteProviderA, mockRemoteProviderB);
   }
-  
-  private void tAnnotations(Injector injector, MockRemoteProvider<String> mockA,
-      MockRemoteProvider<String> mockB) throws RemoteException {
+
+  private void tAnnotations(
+      Injector injector, MockRemoteProvider<String> mockA, MockRemoteProvider<String> mockB)
+      throws RemoteException {
     mockA.setNextToReturn("A");
     mockB.setNextToReturn("B");
-    assertEquals("A", 
-        injector.getInstance(Key.get(remoteProviderOfString, Names.named("a"))).get());
+    assertEquals(
+        "A", injector.getInstance(Key.get(remoteProviderOfString, Names.named("a"))).get());
 
-    assertEquals("B", 
-        injector.getInstance(Key.get(remoteProviderOfString)).get());
+    assertEquals("B", injector.getInstance(Key.get(remoteProviderOfString)).get());
   }
-  
+
   public void testUndeclaredExceptions_Bind() throws RemoteException {
     tUndeclaredExceptions(bindInjector);
   }
-  
+
   public void testUndeclaredExceptions_Provides() throws RemoteException {
     tUndeclaredExceptions(providesInjector);
   }
 
-  private void tUndeclaredExceptions(Injector injector) throws RemoteException { 
-    RemoteProvider<String> remoteProvider = 
-        injector.getInstance(Key.get(remoteProviderOfString));
+  private void tUndeclaredExceptions(Injector injector) throws RemoteException {
+    RemoteProvider<String> remoteProvider = injector.getInstance(Key.get(remoteProviderOfString));
     mockRemoteProvider.throwOnNextGet(new IndexOutOfBoundsException("A"));
     try {
       remoteProvider.get();
@@ -299,224 +309,279 @@
     final SubMockRemoteProvider aProvider = new SubMockRemoteProvider();
     aProvider.setNextToReturn("A");
 
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, String.class)
-            .to(aProvider);
-      }
-    });
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, String.class)
+                    .to(aProvider);
+              }
+            });
 
-    assertEquals("A",
-        bindInjector.getInstance(Key.get(remoteProviderOfString)).get());
+    assertEquals("A", bindInjector.getInstance(Key.get(remoteProviderOfString)).get());
   }
 
-  static class SubMockRemoteProvider extends MockRemoteProvider<String> { }
+  static class SubMockRemoteProvider extends MockRemoteProvider<String> {}
 
   public void testBindingToNonInterfaceType_Bind() throws RemoteException {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(MockRemoteProvider.class, String.class)
-              .to(mockRemoteProvider);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(MockRemoteProvider.class, String.class)
+                  .to(mockRemoteProvider);
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(MockRemoteProvider.class.getName() + " must be an interface",
+      assertEquals(
+          MockRemoteProvider.class.getName() + " must be an interface",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testBindingToNonInterfaceType_Provides() throws RemoteException {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(MockRemoteProvider.class)
-        String foo() {
-          return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(MockRemoteProvider.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(MockRemoteProvider.class.getName() + " must be an interface",
-          Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
-    }
-  }  
-  
-  public void testBindingToSubSubInterface_Bind() throws RemoteException {
-    try {
-      bindInjector = Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(SubRemoteProvider.class, String.class);
-        }
-      });
-      fail();
-    } catch (CreationException expected) {
-      assertEquals(SubRemoteProvider.class.getName() + " must extend CheckedProvider (and only CheckedProvider)",
+      assertEquals(
+          MockRemoteProvider.class.getName() + " must be an interface",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
-  public void testBindingToSubSubInterface_Provides() throws RemoteException {
+
+  public void testBindingToSubSubInterface_Bind() throws RemoteException {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(SubRemoteProvider.class)
-        String foo() {
-          return null;
-        }
-      });
+      bindInjector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ThrowingProviderBinder.create(binder())
+                      .bind(SubRemoteProvider.class, String.class);
+                }
+              });
       fail();
     } catch (CreationException expected) {
-      assertEquals(SubRemoteProvider.class.getName() + " must extend CheckedProvider (and only CheckedProvider)",
+      assertEquals(
+          SubRemoteProvider.class.getName()
+              + " must extend CheckedProvider (and only CheckedProvider)",
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
-  }    
+  }
 
-  interface SubRemoteProvider extends RemoteProvider<String> { }
+  public void testBindingToSubSubInterface_Provides() throws RemoteException {
+    try {
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(SubRemoteProvider.class)
+            String foo() {
+              return null;
+            }
+          });
+      fail();
+    } catch (CreationException expected) {
+      assertEquals(
+          SubRemoteProvider.class.getName()
+              + " must extend CheckedProvider (and only CheckedProvider)",
+          Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
+    }
+  }
+
+  interface SubRemoteProvider extends RemoteProvider<String> {}
 
   public void testBindingToInterfaceWithExtraMethod_Bind() throws RemoteException {
     try {
-      bindInjector = Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(RemoteProviderWithExtraMethod.class, String.class);
-        }
-      });
+      bindInjector =
+          Guice.createInjector(
+              new AbstractModule() {
+                @Override
+                protected void configure() {
+                  ThrowingProviderBinder.create(binder())
+                      .bind(RemoteProviderWithExtraMethod.class, String.class);
+                }
+              });
       fail();
     } catch (CreationException expected) {
-      assertEquals(RemoteProviderWithExtraMethod.class.getName() + " may not declare any new methods, but declared " 
-          + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
+      assertEquals(
+          RemoteProviderWithExtraMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testBindingToInterfaceWithExtraMethod_Provides() throws RemoteException {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-          
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProviderWithExtraMethod.class)
-        String foo() {
-          return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProviderWithExtraMethod.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
     } catch (CreationException expected) {
-      assertEquals(RemoteProviderWithExtraMethod.class.getName() + " may not declare any new methods, but declared " 
-          + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
+      assertEquals(
+          RemoteProviderWithExtraMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + RemoteProviderWithExtraMethod.class.getDeclaredMethods()[0].toGenericString(),
           Iterables.getOnlyElement(expected.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testDependencies_Bind() {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("Foo");
-        bind(Integer.class).toInstance(5);
-        bind(Double.class).toInstance(5d);
-        bind(Long.class).toInstance(5L);
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, String.class)
-            .to(DependentRemoteProvider.class);
-      }
-    });
-    
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("Foo");
+                bind(Integer.class).toInstance(5);
+                bind(Double.class).toInstance(5d);
+                bind(Long.class).toInstance(5L);
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, String.class)
+                    .to(DependentRemoteProvider.class);
+              }
+            });
+
     HasDependencies hasDependencies =
-        (HasDependencies)bindInjector.getBinding(Key.get(remoteProviderOfString));
-    hasDependencies = 
-        (HasDependencies)bindInjector.getBinding(
-            Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+        (HasDependencies) bindInjector.getBinding(Key.get(remoteProviderOfString));
+    hasDependencies =
+        (HasDependencies)
+            bindInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
     // Make sure that that is dependent on DependentRemoteProvider.
-    assertEquals(Dependency.get(Key.get(DependentRemoteProvider.class)), 
+    assertEquals(
+        Dependency.get(Key.get(DependentRemoteProvider.class)),
         Iterables.getOnlyElement(hasDependencies.getDependencies()));
     // And make sure DependentRemoteProvider has the proper dependencies.
-    hasDependencies = (HasDependencies)bindInjector.getBinding(DependentRemoteProvider.class);
-    Set<Key<?>> dependencyKeys = ImmutableSet.copyOf(
-        Iterables.transform(hasDependencies.getDependencies(),
-          new Function<Dependency<?>, Key<?>>() {
-            public Key<?> apply(Dependency<?> from) {
-              return from.getKey();
-            }
-          }));
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class), Key.get(Integer.class),
-        Key.get(Long.class), Key.get(Double.class)), dependencyKeys);
+    hasDependencies = (HasDependencies) bindInjector.getBinding(DependentRemoteProvider.class);
+    Set<Key<?>> dependencyKeys =
+        ImmutableSet.copyOf(
+            Iterables.transform(
+                hasDependencies.getDependencies(),
+                new Function<Dependency<?>, Key<?>>() {
+                  @Override
+                  public Key<?> apply(Dependency<?> from) {
+                    return from.getKey();
+                  }
+                }));
+    assertEquals(
+        ImmutableSet.<Key<?>>of(
+            Key.get(String.class),
+            Key.get(Integer.class),
+            Key.get(Long.class),
+            Key.get(Double.class)),
+        dependencyKeys);
   }
-  
+
   public void testDependencies_Provides() {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(String.class).toInstance("Foo");
-        bind(Integer.class).toInstance(5);
-        bind(Double.class).toInstance(5d);
-        bind(Long.class).toInstance(5L);
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      String foo(String s, Integer i, Double d, Long l) {
-        return null;
-      }
-    });
-    
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toInstance("Foo");
+                bind(Integer.class).toInstance(5);
+                bind(Double.class).toInstance(5d);
+                bind(Long.class).toInstance(5L);
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              String foo(String s, Integer i, Double d, Long l) {
+                return null;
+              }
+            });
+
     HasDependencies hasDependencies =
-        (HasDependencies)providesInjector.getBinding(Key.get(remoteProviderOfString));
+        (HasDependencies) providesInjector.getBinding(Key.get(remoteProviderOfString));
     // RemoteProvider<String> is dependent on the provider method..
-    hasDependencies = 
-        (HasDependencies)providesInjector.getBinding(
-            Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+    hasDependencies =
+        (HasDependencies)
+            providesInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
     // And the provider method has our real dependencies..
-    hasDependencies = (HasDependencies)providesInjector.getBinding(
-        Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
-    Set<Key<?>> dependencyKeys = ImmutableSet.copyOf(
-        Iterables.transform(hasDependencies.getDependencies(),
-          new Function<Dependency<?>, Key<?>>() {
-            public Key<?> apply(Dependency<?> from) {
-              return from.getKey();
-            }
-          }));
-    assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class), Key.get(Integer.class),
-        Key.get(Long.class), Key.get(Double.class)), dependencyKeys);
-  }  
+    hasDependencies =
+        (HasDependencies)
+            providesInjector.getBinding(
+                Iterables.getOnlyElement(hasDependencies.getDependencies()).getKey());
+    Set<Key<?>> dependencyKeys =
+        ImmutableSet.copyOf(
+            Iterables.transform(
+                hasDependencies.getDependencies(),
+                new Function<Dependency<?>, Key<?>>() {
+                  @Override
+                  public Key<?> apply(Dependency<?> from) {
+                    return from.getKey();
+                  }
+                }));
+    assertEquals(
+        ImmutableSet.<Key<?>>of(
+            Key.get(String.class),
+            Key.get(Integer.class),
+            Key.get(Long.class),
+            Key.get(Double.class)),
+        dependencyKeys);
+  }
 
   interface RemoteProviderWithExtraMethod<T> extends ThrowingProvider<T, RemoteException> {
     T get(T defaultValue) throws RemoteException;
   }
 
-  interface RemoteProvider<T> extends ThrowingProvider<T, RemoteException> { }
-  
+  interface RemoteProvider<T> extends ThrowingProvider<T, RemoteException> {}
+
   static class DependentRemoteProvider<T> implements RemoteProvider<T> {
     @Inject double foo;
-    
-    @Inject public DependentRemoteProvider(String foo, int bar) {
-    }
-    
-    @Inject void initialize(long foo) {}
-    
+
+    @Inject
+    public DependentRemoteProvider(String foo, int bar) {}
+
+    @Inject
+    void initialize(long foo) {}
+
+    @Override
     public T get() throws RemoteException {
       return null;
     }
   }
-  
+
   static class MockRemoteProvider<T> implements RemoteProvider<T> {
     Exception nextToThrow;
     T nextToReturn;
-    
+
     public void throwOnNextGet(String message) {
       throwOnNextGet(new RemoteException(message));
     }
@@ -528,7 +593,8 @@
     public void setNextToReturn(T nextToReturn) {
       this.nextToReturn = nextToReturn;
     }
-    
+
+    @Override
     public T get() throws RemoteException {
       if (nextToThrow instanceof RemoteException) {
         throw (RemoteException) nextToThrow;
@@ -543,112 +609,137 @@
   }
 
   public void testBindingToInterfaceWithBoundValueType_Bind() throws RemoteException {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(StringRemoteProvider.class, String.class)
-            .to(new StringRemoteProvider() {
-              public String get() throws RemoteException {
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(StringRemoteProvider.class, String.class)
+                    .to(
+                        new StringRemoteProvider() {
+                          @Override
+                          public String get() throws RemoteException {
+                            return "A";
+                          }
+                        });
+              }
+            });
+
+    assertEquals("A", bindInjector.getInstance(StringRemoteProvider.class).get());
+  }
+
+  public void testBindingToInterfaceWithBoundValueType_Provides() throws RemoteException {
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(StringRemoteProvider.class)
+              String foo() throws RemoteException {
                 return "A";
               }
             });
-      }
-    });
-    
-    assertEquals("A", bindInjector.getInstance(StringRemoteProvider.class).get());
-  }
-  
-  public void testBindingToInterfaceWithBoundValueType_Provides() throws RemoteException {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(StringRemoteProvider.class)
-      String foo() throws RemoteException {
-          return "A";
-      }
-    });
-    
+
     assertEquals("A", providesInjector.getInstance(StringRemoteProvider.class).get());
   }
 
-  interface StringRemoteProvider extends ThrowingProvider<String, RemoteException> { }
+  interface StringRemoteProvider extends ThrowingProvider<String, RemoteException> {}
 
   public void testBindingToInterfaceWithGeneric_Bind() throws RemoteException {
-    bindInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        ThrowingProviderBinder.create(binder())
-            .bind(RemoteProvider.class, new TypeLiteral<List<String>>() { }.getType())
-            .to(new RemoteProvider<List<String>>() {
-              public List<String> get() throws RemoteException {
+    bindInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                ThrowingProviderBinder.create(binder())
+                    .bind(RemoteProvider.class, new TypeLiteral<List<String>>() {}.getType())
+                    .to(
+                        new RemoteProvider<List<String>>() {
+                          @Override
+                          public List<String> get() throws RemoteException {
+                            return Arrays.asList("A", "B");
+                          }
+                        });
+              }
+            });
+
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
+    assertEquals(Arrays.asList("A", "B"), bindInjector.getInstance(key).get());
+  }
+
+  public void testBindingToInterfaceWithGeneric_Provides() throws RemoteException {
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              List<String> foo() throws RemoteException {
                 return Arrays.asList("A", "B");
               }
             });
-      }
-    });
 
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
-    assertEquals(Arrays.asList("A", "B"), bindInjector.getInstance(key).get());
-  }
-  
-  public void testBindingToInterfaceWithGeneric_Provides() throws RemoteException {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      List<String> foo() throws RemoteException {
-          return Arrays.asList("A", "B");
-      }
-    });
-
-    Key<RemoteProvider<List<String>>> key
-        = Key.get(new TypeLiteral<RemoteProvider<List<String>>>() { });
+    Key<RemoteProvider<List<String>>> key =
+        Key.get(new TypeLiteral<RemoteProvider<List<String>>>() {});
     assertEquals(Arrays.asList("A", "B"), providesInjector.getInstance(key).get());
   }
-  
+
   public void testProviderMethodWithWrongException() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        String foo() throws InterruptedException {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            String foo() throws InterruptedException {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(InterruptedException.class.getName() + " is not compatible with the exceptions (["
-          + RemoteException.class + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName() + ")",
+    } catch (CreationException ce) {
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testProviderMethodWithSubclassOfExceptionIsOk() {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      String foo() throws AccessException {
-        throw new AccessException("boo!");
-      }
-    });
-    
-    RemoteProvider<String> remoteProvider = 
-      providesInjector.getInstance(Key.get(remoteProviderOfString));
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              String foo() throws AccessException {
+                throw new AccessException("boo!");
+              }
+            });
+
+    RemoteProvider<String> remoteProvider =
+        providesInjector.getInstance(Key.get(remoteProviderOfString));
 
     try {
       remoteProvider.get();
@@ -658,44 +749,53 @@
       assertEquals("boo!", expected.getMessage());
     }
   }
-  
+
   public void testProviderMethodWithSuperclassFails() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        String foo() throws IOException {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            String foo() throws IOException {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(IOException.class.getName() + " is not compatible with the exceptions (["
-          + RemoteException.class + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName() + ")",
+    } catch (CreationException ce) {
+      assertEquals(
+          IOException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testProviderMethodWithRuntimeExceptionsIsOk() throws RemoteException {
-    providesInjector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        install(ThrowingProviderBinder.forModule(this));
-      }
-      
-      @SuppressWarnings("unused")
-      @CheckedProvides(RemoteProvider.class)
-      String foo() throws RuntimeException {
-        throw new RuntimeException("boo!");
-      }
-    });
-    
-    RemoteProvider<String> remoteProvider = 
-      providesInjector.getInstance(Key.get(remoteProviderOfString));
+    providesInjector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(ThrowingProviderBinder.forModule(this));
+              }
+
+              @SuppressWarnings("unused")
+              @CheckedProvides(RemoteProvider.class)
+              String foo() throws RuntimeException {
+                throw new RuntimeException("boo!");
+              }
+            });
+
+    RemoteProvider<String> remoteProvider =
+        providesInjector.getInstance(Key.get(remoteProviderOfString));
 
     try {
       remoteProvider.get();
@@ -704,175 +804,209 @@
       assertEquals("boo!", expected.getCause().getMessage());
     }
   }
-  
+
   public void testProviderMethodWithManyExceptions() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(RemoteProvider.class)
-        String foo() throws InterruptedException, RuntimeException, RemoteException, 
-                            AccessException, TooManyListenersException {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(RemoteProvider.class)
+            String foo()
+                throws InterruptedException, RuntimeException, RemoteException, AccessException,
+                    TooManyListenersException {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
+    } catch (CreationException ce) {
       // The only two that should fail are Interrupted & TooManyListeners.. the rest are OK.
       List<Message> errors = ImmutableList.copyOf(ce.getErrorMessages());
-      assertEquals(InterruptedException.class.getName() + " is not compatible with the exceptions (["
-          + RemoteException.class + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName() + ")",
+      assertEquals(
+          InterruptedException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           errors.get(0).getMessage());
-      assertEquals(TooManyListenersException.class.getName() + " is not compatible with the exceptions (["
-          + RemoteException.class + "]) declared in the CheckedProvider interface ("
-          + RemoteProvider.class.getName() + ")",
+      assertEquals(
+          TooManyListenersException.class.getName()
+              + " is not compatible with the exceptions (["
+              + RemoteException.class
+              + "]) declared in the CheckedProvider interface ("
+              + RemoteProvider.class.getName()
+              + ")",
           errors.get(1).getMessage());
       assertEquals(2, errors.size());
     }
   }
-  
+
   public void testMoreTypeParameters() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(TooManyTypeParameters.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(TooManyTypeParameters.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(TooManyTypeParameters.class.getName() + " has more than one generic type parameter: [T, P]",
+    } catch (CreationException ce) {
+      assertEquals(
+          TooManyTypeParameters.class.getName()
+              + " has more than one generic type parameter: [T, P]",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }    
+    }
   }
-  
+
   public void testWrongThrowingProviderType() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(WrongThrowingProviderType.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(WrongThrowingProviderType.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(WrongThrowingProviderType.class.getName() 
-          + " does not properly extend CheckedProvider, the first type parameter of CheckedProvider "
-          + "(java.lang.String) is not a generic type",
+    } catch (CreationException ce) {
+      assertEquals(
+          WrongThrowingProviderType.class.getName()
+              + " does not properly extend CheckedProvider, the first type parameter of CheckedProvider "
+              + "(java.lang.String) is not a generic type",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
-    }    
+    }
   }
-  
+
   public void testOneMethodThatIsntGet() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(OneNoneGetMethod.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(OneNoneGetMethod.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(OneNoneGetMethod.class.getName() 
-          + " may not declare any new methods, but declared " + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]),
+    } catch (CreationException ce) {
+      assertEquals(
+          OneNoneGetMethod.class.getName()
+              + " may not declare any new methods, but declared "
+              + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]),
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testManyMethods() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(ManyMethods.class)
-        String foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(ManyMethods.class)
+            String foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(ManyMethods.class.getName() 
-          + " may not declare any new methods, but declared " + Arrays.asList(ManyMethods.class.getDeclaredMethods()),
+    } catch (CreationException ce) {
+      assertEquals(
+          ManyMethods.class.getName()
+              + " may not declare any new methods, but declared "
+              + Arrays.asList(ManyMethods.class.getDeclaredMethods()),
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testIncorrectPredefinedType_Bind() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          ThrowingProviderBinder.create(binder())
-              .bind(StringRemoteProvider.class, Integer.class)
-              .to(new StringRemoteProvider() {
-                public String get() throws RemoteException {
-                  return "A";
-                }
-              });
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              ThrowingProviderBinder.create(binder())
+                  .bind(StringRemoteProvider.class, Integer.class)
+                  .to(
+                      new StringRemoteProvider() {
+                        @Override
+                        public String get() throws RemoteException {
+                          return "A";
+                        }
+                      });
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(StringRemoteProvider.class.getName() 
-          + " expects the value type to be java.lang.String, but it was java.lang.Integer",
+    } catch (CreationException ce) {
+      assertEquals(
+          StringRemoteProvider.class.getName()
+              + " expects the value type to be java.lang.String, but it was java.lang.Integer",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
+
   public void testIncorrectPredefinedType_Provides() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        protected void configure() {
-          install(ThrowingProviderBinder.forModule(this));
-        }
-        
-        @SuppressWarnings("unused")
-        @CheckedProvides(StringRemoteProvider.class)
-        Integer foo() {
-            return null;
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              install(ThrowingProviderBinder.forModule(this));
+            }
+
+            @SuppressWarnings("unused")
+            @CheckedProvides(StringRemoteProvider.class)
+            Integer foo() {
+              return null;
+            }
+          });
       fail();
-    } catch(CreationException ce) {
-      assertEquals(StringRemoteProvider.class.getName() 
-          + " expects the value type to be java.lang.String, but it was java.lang.Integer",
+    } catch (CreationException ce) {
+      assertEquals(
+          StringRemoteProvider.class.getName()
+              + " expects the value type to be java.lang.String, but it was java.lang.Integer",
           Iterables.getOnlyElement(ce.getErrorMessages()).getMessage());
     }
   }
-  
-  private static interface TooManyTypeParameters<T, P> extends ThrowingProvider<T, Exception> {    
-  }
-  
-  private static interface WrongThrowingProviderType<T> extends ThrowingProvider<String, Exception> {    
-  }
-  
+
+  private static interface TooManyTypeParameters<T, P> extends ThrowingProvider<T, Exception> {}
+
+  private static interface WrongThrowingProviderType<T>
+      extends ThrowingProvider<String, Exception> {}
+
   private static interface OneNoneGetMethod<T> extends ThrowingProvider<T, Exception> {
     T bar();
   }
-  
+
   private static interface ManyMethods<T> extends ThrowingProvider<T, Exception> {
     T bar();
+
     String baz();
   }
 }
diff --git a/jdk8-tests/pom.xml b/jdk8-tests/pom.xml
index 7e04d21..936bbaa 100644
--- a/jdk8-tests/pom.xml
+++ b/jdk8-tests/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <artifactId>guice-parent</artifactId>
     <groupId>com.google.inject</groupId>
-    <version>4.0</version>
+    <version>4.2.0</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -35,6 +35,12 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>com.google.inject.extensions</groupId>
+      <artifactId>guice-assistedinject</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>cglib</groupId>
       <artifactId>cglib</artifactId>
       <scope>test</scope>
diff --git a/jdk8-tests/test/com/google/inject/jdk8/DefaultMethodInterceptionTest.java b/jdk8-tests/test/com/google/inject/jdk8/DefaultMethodInterceptionTest.java
index 29e0681..e9cd465 100644
--- a/jdk8-tests/test/com/google/inject/jdk8/DefaultMethodInterceptionTest.java
+++ b/jdk8-tests/test/com/google/inject/jdk8/DefaultMethodInterceptionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,14 +24,11 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.matcher.Matchers;
-
-import junit.framework.TestCase;
-
-import org.aopalliance.intercept.MethodInterceptor;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.util.concurrent.atomic.AtomicInteger;
+import junit.framework.TestCase;
+import org.aopalliance.intercept.MethodInterceptor;
 
 /**
  * Tests for interception of default methods.
@@ -44,10 +41,11 @@
   private static final AtomicInteger interceptedCallCount = new AtomicInteger(0);
 
   // the interceptor's a lambda too
-  private final MethodInterceptor interceptor = invocation -> {
-    interceptedCallCount.incrementAndGet();
-    return invocation.proceed();
-  };
+  private final MethodInterceptor interceptor =
+      invocation -> {
+        interceptedCallCount.incrementAndGet();
+        return invocation.proceed();
+      };
 
   @Override
   protected void setUp() throws Exception {
@@ -76,14 +74,16 @@
   }
 
   public void testInterceptedDefaultMethod() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.annotatedWith(InterceptMe.class),
-            interceptor);
-        bind(Foo.class).to(NonOverridingFoo.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.annotatedWith(InterceptMe.class), interceptor);
+                bind(Foo.class).to(NonOverridingFoo.class);
+              }
+            });
 
     Foo foo = injector.getInstance(Foo.class);
     assertEquals("Foo", foo.defaultMethod());
@@ -92,13 +92,15 @@
   }
 
   public void testInterceptedDefaultMethod_calledByAnotherMethod() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.annotatedWith(InterceptMe.class),
-            interceptor);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.annotatedWith(InterceptMe.class), interceptor);
+              }
+            });
 
     NonOverridingFoo foo = injector.getInstance(NonOverridingFoo.class);
     assertEquals("NonOverriding-Foo", foo.methodCallingDefault());
@@ -116,18 +118,19 @@
   }
 
   /** Foo implementation that should use superclass method rather than default method. */
-  public static class InheritingFoo extends BaseClass implements Foo {
-  }
+  public static class InheritingFoo extends BaseClass implements Foo {}
 
   public void testInterceptedDefaultMethod_whenParentClassDefinesNonInterceptedMethod() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.annotatedWith(InterceptMe.class),
-            interceptor);
-        bind(Foo.class).to(InheritingFoo.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.annotatedWith(InterceptMe.class), interceptor);
+                bind(Foo.class).to(InheritingFoo.class);
+              }
+            });
 
     // the concrete implementation that wins is not annotated
     Foo foo = injector.getInstance(Foo.class);
@@ -151,18 +154,19 @@
   /**
    * Foo implementation that should use intercepted superclass method rather than default method.
    */
-  public static class InheritingFoo2 extends BaseClass2 implements Foo {
-  }
+  public static class InheritingFoo2 extends BaseClass2 implements Foo {}
 
   public void testInterceptedDefaultMethod_whenParentClassDefinesInterceptedMethod() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.any(), Matchers.annotatedWith(InterceptMe.class),
-            interceptor);
-        bind(Foo.class).to(InheritingFoo2.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(
+                    Matchers.any(), Matchers.annotatedWith(InterceptMe.class), interceptor);
+                bind(Foo.class).to(InheritingFoo2.class);
+              }
+            });
 
     // the concrete implementation that wins is not annotated
     Foo foo = injector.getInstance(Foo.class);
@@ -188,13 +192,15 @@
   }
 
   public void testInterception_ofAllMethodsOnType() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.subclassesOf(Baz.class), Matchers.any(), interceptor);
-        bind(Baz.class).to(BazImpl.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(Matchers.subclassesOf(Baz.class), Matchers.any(), interceptor);
+                bind(Baz.class).to(BazImpl.class);
+              }
+            });
 
     Baz baz = injector.getInstance(Baz.class);
 
@@ -205,13 +211,15 @@
   }
 
   public void testInterception_ofAllMethodsOnType_interceptsInheritedDefaultMethod() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bindInterceptor(Matchers.subclassesOf(BazImpl.class), Matchers.any(), interceptor);
-        bind(Baz.class).to(BazImpl.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bindInterceptor(Matchers.subclassesOf(BazImpl.class), Matchers.any(), interceptor);
+                bind(Baz.class).to(BazImpl.class);
+              }
+            });
 
     Baz baz = injector.getInstance(Baz.class);
 
diff --git a/jdk8-tests/test/com/google/inject/jdk8/Java8LanguageFeatureBindingTest.java b/jdk8-tests/test/com/google/inject/jdk8/Java8LanguageFeatureBindingTest.java
index 39a7498..07e1ee6 100644
--- a/jdk8-tests/test/com/google/inject/jdk8/Java8LanguageFeatureBindingTest.java
+++ b/jdk8-tests/test/com/google/inject/jdk8/Java8LanguageFeatureBindingTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,14 +26,12 @@
 import com.google.inject.Provides;
 import com.google.inject.ProvisionException;
 import com.google.inject.TypeLiteral;
-
-import junit.framework.TestCase;
-
 import java.util.Collections;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Predicate;
+import junit.framework.TestCase;
 
 /**
  * Test bindings to lambdas, method references, etc.
@@ -46,12 +44,14 @@
   // See https://github.com/google/guice/issues/757 for more on why they exist.
 
   public void testBinding_lambdaToInterface() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(new TypeLiteral<Predicate<Object>>() {}).toInstance(o -> o != null);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(new TypeLiteral<Predicate<Object>>() {}).toInstance(o -> o != null);
+              }
+            });
 
     Predicate<Object> predicate = injector.getInstance(new Key<Predicate<Object>>() {});
     assertTrue(predicate.test(new Object()));
@@ -59,34 +59,34 @@
   }
 
   public void testProviderMethod_returningLambda() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
 
-      @Provides
-      public Callable<String> provideCallable() {
-        return () -> "foo";
-      }
-    });
+              @Provides
+              public Callable<String> provideCallable() {
+                return () -> "foo";
+              }
+            });
 
     Callable<String> callable = injector.getInstance(new Key<Callable<String>>() {});
     assertEquals("foo", callable.call());
   }
 
   public void testProviderMethod_containingLambda_throwingException() throws Exception {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {}
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
 
-      @Provides
-      public Callable<String> provideCallable() {
-        if (Boolean.parseBoolean("false")) { // avoid dead code warnings
-          return () -> "foo";
-        } else {
-          throw new RuntimeException("foo");
-        }
-      }
-    });
+              @Provides
+              public Callable<String> provideCallable() {
+                if (Boolean.parseBoolean("false")) { // avoid dead code warnings
+                  return () -> "foo";
+                } else {
+                  throw new RuntimeException("foo");
+                }
+              }
+            });
 
     try {
       injector.getInstance(new Key<Callable<String>>() {});
@@ -98,25 +98,28 @@
 
   public void testProvider_usingJdk8Features() {
     try {
-      Guice.createInjector(new AbstractModule() {
-        @Override
-        protected void configure() {
-          bind(String.class).toProvider(StringProvider.class);
-        }
-      });
+      Guice.createInjector(
+          new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(String.class).toProvider(StringProvider.class);
+            }
+          });
 
       fail();
     } catch (CreationException expected) {
     }
 
     UUID uuid = UUID.randomUUID();
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(UUID.class).toInstance(uuid);
-        bind(String.class).toProvider(StringProvider.class);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(UUID.class).toInstance(uuid);
+                bind(String.class).toProvider(StringProvider.class);
+              }
+            });
 
     assertEquals(uuid.toString(), injector.getInstance(String.class));
   }
@@ -131,32 +134,34 @@
 
     @Override
     public String get() {
-      return Collections.singleton(uuid).stream()
-          .map(UUID::toString)
-          .findFirst().get();
+      return Collections.singleton(uuid).stream().map(UUID::toString).findFirst().get();
     }
   }
 
   public void testBinding_toProvider_lambda() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        AtomicInteger i = new AtomicInteger();
-        bind(String.class).toProvider(() -> "Hello" + i.incrementAndGet());
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                AtomicInteger i = new AtomicInteger();
+                bind(String.class).toProvider(() -> "Hello" + i.incrementAndGet());
+              }
+            });
 
     assertEquals("Hello1", injector.getInstance(String.class));
     assertEquals("Hello2", injector.getInstance(String.class));
   }
 
   public void testBinding_toProvider_methodReference() {
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(String.class).toProvider(Java8LanguageFeatureBindingTest.this::provideString);
-      }
-    });
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                bind(String.class).toProvider(Java8LanguageFeatureBindingTest.this::provideString);
+              }
+            });
 
     Provider<String> provider = injector.getProvider(String.class);
     assertEquals("Hello", provider.get());
diff --git a/jdk8-tests/test/com/google/inject/jdk8/StaticInterfaceMethodsTest.java b/jdk8-tests/test/com/google/inject/jdk8/StaticInterfaceMethodsTest.java
new file mode 100644
index 0000000..b2375da
--- /dev/null
+++ b/jdk8-tests/test/com/google/inject/jdk8/StaticInterfaceMethodsTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 com.google.inject.jdk8;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import junit.framework.TestCase;
+
+/**
+ * Test static methods in interfaces.
+ *
+ * @author tavianator@tavianator.com (Tavian Barnes)
+ */
+public class StaticInterfaceMethodsTest extends TestCase {
+
+  private static class Thing {
+    final int i;
+
+    @Inject
+    Thing(@Assisted int i) {
+      this.i = i;
+    }
+  }
+
+  private interface Factory {
+    Thing create(int i);
+
+    static Factory getDefault() {
+      return Thing::new;
+    }
+  }
+
+  public void testAssistedInjection() {
+    Injector injector =
+        Guice.createInjector(
+            new AbstractModule() {
+              @Override
+              protected void configure() {
+                install(new FactoryModuleBuilder().build(Factory.class));
+              }
+            });
+    Factory factory = injector.getInstance(Factory.class);
+    assertEquals(1, factory.create(1).i);
+  }
+}
diff --git a/latest-api-diffs/4.0.xml b/latest-api-diffs/4.0.xml
index 1b1e7d2..9ff6a10 100644
--- a/latest-api-diffs/4.0.xml
+++ b/latest-api-diffs/4.0.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
 <!-- Generated by the JDiff Javadoc doclet -->
 <!-- (http://www.jdiff.org) -->
-<!-- on Thu Mar 20 20:36:47 PDT 2014 -->
+<!-- on Tue Apr 28 17:33:25 EDT 2015 -->
 
 <api
   xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
@@ -9,7 +9,7 @@
   name="4.0"
   jdversion="1.1.1">
 
-<!--  Command line arguments =  -doclet jdiff.JDiff -docletpath /Users/cgruber/OpenSource/guice/googlecode-master/lib/build/jdiff/jdiff.jar:/Users/cgruber/OpenSource/guice/googlecode-master/lib/build/jdiff/xerces.jar -classpath /Users/cgruber/OpenSource/guice/googlecode-master/lib/javax.inject.jar:/Users/cgruber/OpenSource/guice/googlecode-master/lib/aopalliance.jar:/Users/cgruber/OpenSource/guice/googlecode-master/lib/guava-16.0.1.jar -doclet jdiff.JDiff -docletpath /Users/cgruber/OpenSource/guice/googlecode-master/lib/build/jdiff/jdiff.jar:/Users/cgruber/OpenSource/guice/googlecode-master/lib/build/jdiff/xerces.jar -apidir build/docs/latest-api-diffs -apiname 4.0 -->
+<!--  Command line arguments =  -doclet jdiff.JDiff -docletpath /usr/local/google/home/cgdecker/Projects/guice/lib/build/jdiff/jdiff.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/jdiff/xerces.jar -classpath /usr/local/google/home/cgdecker/Projects/guice/lib/aopalliance.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/guava-16.0.1.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/javax.inject.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/asm-5.0.3.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/bnd-0.0.384.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/cglib-3.1.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/commons-logging-1.0.4.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/easymock.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/felix-2.0.5.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/guava-testlib-16.0.1.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/jarjar-1.1.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/javax.inject-tck.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/jsr305.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/junit.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/munge.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/safesax.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/spring-beans.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/spring-core.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/dagger-adapter/lib/dagger-2.0.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/antlr-2.7.5h3.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/aopalliance.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/cglib-nodep-3.0.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/commons-collections.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/commons-io.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/commons-logging-1.0.4.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/db4o-6.4.14.8131-java5.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/dom4j-1.6.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/easymock.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/ejb3-persistence.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/hibernate-annotations.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/hibernate-entitymanager.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/hibernate-search.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/hibernate3.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/hsqldb.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/javassist.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/jaxen-1.1-beta-7.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/jboss-archive-browsing.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/jta.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/log4j-1.2.14.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/ognl-2.6.7.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/oro-2.0.8.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/servlet-api-2.5.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/persist/lib/xwork-2.0.4.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/ant-1.6.5.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/commons-fileupload-1.2.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/commons-io-1.3.2.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/commons-logging-1.0.4.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/core-3.1.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/freemarker-2.3.16.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/javassist.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/jetty-6.1.0.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/jetty-util-6.1.0.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/jsp-2.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/jsp-api-2.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/ognl-3.0.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/servlet-api-2.5.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/struts2-core-2.2.1.jar:/usr/local/google/home/cgdecker/Projects/guice/extensions/struts2/lib/xwork-core-2.2.1.jar:/usr/local/google/home/cgdecker/Projects/guice/build/classes -doclet jdiff.JDiff -docletpath /usr/local/google/home/cgdecker/Projects/guice/lib/build/jdiff/jdiff.jar:/usr/local/google/home/cgdecker/Projects/guice/lib/build/jdiff/xerces.jar -apidir build/docs/latest-api-diffs -apiname 4.0 -->
 <package name="com.google.inject">
   <!-- start class com.google.inject.AbstractModule -->
   <class name="AbstractModule" extends="java.lang.Object"
@@ -476,6 +476,22 @@
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <param name="dependency" type="com.google.inject.spi.Dependency&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection key.
+ The returned provider will be attached to the injection point and will
+ follow the nullability specified in the dependency.
+ Additionally, the returned provider will not be valid until the {@link Injector} 
+ has been created. The provider will throw an {@code IllegalStateException} if you
+ try to use it beforehand.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
       <param name="type" type="java.lang.Class&lt;T&gt;"/>
       <doc>
       <![CDATA[Returns the provider used to obtain instances for the given injection type.
@@ -619,8 +635,8 @@
       <doc>
       <![CDATA[Instructs the Injector that bindings must be listed in a Module in order to
  be injected. Classes that are not explicitly bound in a module cannot be
- injected. Bindings created through a linked binding (
- <code>bind(Foo.class).to(FooImpl.class)</code>) are allowed, but the
+ injected. Bindings created through a linked binding
+ (<code>bind(Foo.class).to(FooImpl.class)</code>) are allowed, but the
  implicit binding (<code>FooImpl</code>) cannot be directly injected unless
  it is also explicitly bound (<code>bind(FooImpl.class)</code>).
  <p>
@@ -637,10 +653,11 @@
  does, the behavior is limited only to that child or any grandchildren. No
  siblings of the child will require explicit bindings.
  <p>
- If the parent did not require explicit bindings but the child does, it is
- possible that a linked binding in the child may add a JIT binding to the
- parent. The child will not be allowed to reference the target binding
- directly, but the parent and other children of the parent may be able to.
+ In the absence of an explicit binding for the target, linked bindings in
+ child injectors create a binding for the target in the parent. Since this
+ behavior can be surprising, it causes an error instead if explicit bindings
+ are required. To avoid this error, add an explicit binding for the target,
+ either in the child or the parent.
  
  @since 3.0]]>
       </doc>
@@ -692,6 +709,21 @@
  @since 4.0]]>
       </doc>
     </method>
+    <method name="scanModulesForAnnotatedMethods"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scanner" type="com.google.inject.spi.ModuleAnnotatedMethodScanner"/>
+      <doc>
+      <![CDATA[Adds a scanner that will look in all installed modules for annotations the scanner can parse,
+ and binds them like {@literal @}Provides methods. Scanners apply to all modules installed in
+ the injector. Scanners installed in child injectors or private modules do not impact modules in
+ siblings or parents, however scanners installed in parents do apply to all child injectors and
+ private modules.
+
+ @since 4.0]]>
+      </doc>
+    </method>
     <doc>
     <![CDATA[Collects configuration information (primarily <i>bindings</i>) which will be
  used to create an {@link Injector}. Guice provides this object to your
@@ -1776,7 +1808,7 @@
  TypeLiteral}.
 
  <p>Keys do not differentiate between primitive types (int, char, etc.) and
- their correpsonding wrapper types (Integer, Character, etc.). Primitive
+ their corresponding wrapper types (Integer, Character, etc.). Primitive
  types will be replaced with their wrapper types when keys are created.
 
  @author crazybob@google.com (Bob Lee)]]>
@@ -2195,7 +2227,8 @@
       <param name="bindingMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.Binding&lt;?&gt;&gt;"/>
       <param name="listeners" type="com.google.inject.spi.ProvisionListener[]"/>
       <doc>
-      <![CDATA[@see Binder#bindListener(Matcher, ProvisionListener...)]]>
+      <![CDATA[@see Binder#bindListener(Matcher, ProvisionListener...)
+ @since 4.0]]>
       </doc>
     </method>
     <doc>
@@ -2477,7 +2510,8 @@
 
  @param binding binding to check
  @param scope scope implementation instance
- @param scopeAnnotation scope annotation class]]>
+ @param scopeAnnotation scope annotation class
+ @since 4.0]]>
       </doc>
     </method>
     <method name="isCircularProxy" return="boolean"
@@ -2491,7 +2525,9 @@
  implementations should be careful to <b>not cache circular proxies</b>,
  because the proxies are not intended for general purpose use. (They are
  designed just to fulfill the immediate injection, not all injections.
- Caching them can lead to IllegalArgumentExceptions or ClassCastExceptions.)]]>
+ Caching them can lead to IllegalArgumentExceptions or ClassCastExceptions.)
+
+ @since 4.0]]>
       </doc>
     </method>
     <field name="SINGLETON" type="com.google.inject.Scope"
@@ -3119,7 +3155,7 @@
 
  <pre>install(new FactoryModuleBuilder()
      .implement(Payment.class, RealPayment.class)
-     .build(PaymentFactory.class);</pre>
+     .build(PaymentFactory.class));</pre>
 
  As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
  factory cannot be used until the injector has been initialized.
@@ -3141,7 +3177,7 @@
      // excluding .implement for Shipment means the implementation class
      // will be 'Shipment' itself, which is legal if it's not an interface.
      .implement(Receipt.class, RealReceipt.class)
-     .build(OrderFactory.class);</pre>
+     .build(OrderFactory.class));</pre>
  </pre>
 
  <h3>Using the factory</h3>
@@ -3260,6 +3296,17 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
     </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
     <doc>
     <![CDATA[<strong>Obsolete.</strong> Prefer {@link FactoryModuleBuilder} for its more concise API and
  additional capability.
@@ -3628,7 +3675,8 @@
       <doc>
       <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
 
- @see com.google.inject.Injector#injectMembers]]>
+ @see com.google.inject.Injector#injectMembers
+ @since 4.0]]>
       </doc>
     </method>
     <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
@@ -3729,6 +3777,53 @@
   </interface>
   <!-- end interface com.google.inject.binder.ScopedBindingBuilder -->
 </package>
+<package name="com.google.inject.daggeradapter">
+  <!-- start class com.google.inject.daggeradapter.DaggerAdapter -->
+  <class name="DaggerAdapter" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="from" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="daggerModuleObjects" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[Returns a guice module from a dagger module.
+
+ <p>Note: At present, it does not honor {@code @Module(includes=...)} directives.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A utility to adapt classes annotated with {@link @dagger.Module} such that their
+ {@link @dagger.Provides} methods can be properly invoked by Guice to perform their
+ provision operations.
+
+ <p>Simple example: <pre>{@code
+   Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter()));
+ }</pre>
+
+ <p>Some notes on usage and compatibility.
+   <ul>
+     <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice.
+     <li>MapBindings are not yet implemented (pending).
+     <li>Be careful about stateful modules. In contrast to Dagger (where components are
+         expected to be recreated on-demand with new Module instances), Guice typically
+         has a single injector with a long lifetime, so your module instance will be used
+         throughout the lifetime of the entire app.
+     <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes
+         like per-request or per-activity.  Using modules written with Dagger 1.x usage
+         in mind may result in mis-scoped objects.
+     <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope
+         implementation must be registered in order to support the custom lifetime of that
+         annotation.
+   </ul>
+
+ @author cgruber@google.com (Christian Gruber)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.daggeradapter.DaggerAdapter -->
+</package>
 <package name="com.google.inject.grapher">
   <!-- start class com.google.inject.grapher.AbstractInjectorGrapher -->
   <class name="AbstractInjectorGrapher" extends="java.lang.Object"
@@ -3830,7 +3925,8 @@
     <doc>
     <![CDATA[Abstract injector grapher that builds the dependency graph but doesn't render it.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.AbstractInjectorGrapher -->
@@ -3888,7 +3984,8 @@
       <param name="edgeCreator" type="com.google.inject.grapher.EdgeCreator"/>
     </method>
     <doc>
-    <![CDATA[Parameters used to override default settings of the grapher.]]>
+    <![CDATA[Parameters used to override default settings of the grapher.
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters -->
@@ -3915,7 +4012,8 @@
     <![CDATA[Alias between two nodes. Causes the 'from' node to be aliased with the 'to' node, which means
  that the 'from' node is not rendered and all edges going to it instead go to the 'to' node.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.Alias -->
@@ -3941,7 +4039,8 @@
     <![CDATA[Creator of node aliases. Used by dependency graphers to merge nodes in the internal Guice graph
  into a single node on the rendered graph.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.grapher.AliasCreator -->
@@ -3985,7 +4084,8 @@
     <doc>
     <![CDATA[Edge that connects an interface to the type or instance that is bound to implement it.
 
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.BindingEdge -->
@@ -4030,7 +4130,8 @@
     <![CDATA[Root key set creator that starts with all types that are not Guice internal types or the
  {@link Logger} type.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.DefaultRootKeySetCreator -->
@@ -4075,7 +4176,8 @@
     <![CDATA[Edge from a class or {@link InjectionPoint} to the interface node that will satisfy the
  dependency.
 
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.DependencyEdge -->
@@ -4126,7 +4228,8 @@
     <doc>
     <![CDATA[Edge in a guice dependency graph.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.Edge -->
@@ -4147,7 +4250,8 @@
     <![CDATA[Creator of graph edges to render. All edges will be rendered on the graph after node aliasing is
  performed.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.grapher.EdgeCreator -->
@@ -4188,12 +4292,13 @@
       <param name="id" type="com.google.inject.grapher.NodeId"/>
     </method>
     <doc>
-    <![CDATA[Node for types that have {@link Dependency}s and are bound to {@link InterfaceNode}s. These
- nodes will often have fields for {@link Member}s that are {@link InjectionPoint}s.
+    <![CDATA[Node for types that have {@link com.google.inject.spi.Dependency}s and are
+ bound to {@link InterfaceNode}s. These nodes will often have fields for
+ {@link Member}s that are {@link com.google.inject.spi.InjectionPoint}s.
 
  @see DependencyEdge
-
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.ImplementationNode -->
@@ -4227,7 +4332,8 @@
     <![CDATA[Guice injector grapher. Renders the guice dependency graph for an injector. It can render the
  whole dependency graph or just transitive dependencies of a given set of nodes.
 
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as a concrete class with a different API)]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.grapher.InjectorGrapher -->
@@ -4275,7 +4381,8 @@
     <doc>
     <![CDATA[Node for instances. Used when a type is bound to an instance.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.InstanceNode -->
@@ -4309,8 +4416,8 @@
     <![CDATA[Node for an interface type that has been bound to an implementation class or instance.
 
  @see BindingEdge
-
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.InterfaceNode -->
@@ -4350,7 +4457,8 @@
     </method>
     <doc>
     <![CDATA[Interface for a service that provides nice {@link String}s that we can
- display in the graph for the types that come up in {@link Binding}s.
+ display in the graph for the types that come up in
+ {@link com.google.inject.Binding}s.
 
  @author phopkins@gmail.com (Pete Hopkins)]]>
     </doc>
@@ -4401,7 +4509,8 @@
     <doc>
     <![CDATA[Node in a guice dependency graph.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.Node -->
@@ -4421,7 +4530,8 @@
     <doc>
     <![CDATA[Creator of graph nodes.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.grapher.NodeCreator -->
@@ -4470,7 +4580,8 @@
  interface node with the key of {@code Key<Integer>} and an instance node with the same
  {@link Key} and value of 42.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.NodeId -->
@@ -4491,7 +4602,9 @@
       <param name="name" type="java.lang.String"/>
     </method>
     <doc>
-    <![CDATA[Type of node.]]>
+    <![CDATA[Type of node.
+
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.NodeId.NodeType -->
@@ -4512,7 +4625,8 @@
     <![CDATA[Creator of the default starting set of keys to graph. These keys and their transitive
  dependencies will be graphed.
 
- @author bojand@google.com (Bojan Djordjevic)]]>
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.grapher.RootKeySetCreator -->
@@ -4638,12 +4752,15 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="binding" type="com.google.inject.Binding&lt;?&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <doc>
-    <![CDATA[{@link BindingTargetVisitor} that returns a {@link Collection} of the
- {@link Key}s of each {@link Binding}'s dependencies. Used by
- {@link InjectorGrapher} to walk the dependency graph from a starting set of
- {@link Binding}s.
+    <![CDATA[{@link com.google.inject.spi.BindingTargetVisitor} that returns a
+ {@link Collection} of the {@link Key}s of each {@link Binding}'s
+ dependencies. Used by {@link InjectorGrapher} to walk the dependency graph
+ from a starting set of {@link Binding}s.
 
  @author phopkins@gmail.com (Pete Hopkins)]]>
     </doc>
@@ -4756,6 +4873,9 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="getHeadPortId" return="java.lang.String"
       abstract="false" native="false" synchronized="false"
@@ -4794,6 +4914,9 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="getTailPortId" return="java.lang.String"
       abstract="false" native="false" synchronized="false"
@@ -4986,12 +5109,13 @@
       <param name="edge" type="com.google.inject.grapher.BindingEdge"/>
     </method>
     <doc>
-    <![CDATA[{@link InjectorGrapher} implementation that writes out a Graphviz DOT file of the graph.
- Dependencies are bound in {@link GraphvizModule}.
+    <![CDATA[{@link com.google.inject.grapher.InjectorGrapher} implementation that writes out a Graphviz DOT
+ file of the graph. Dependencies are bound in {@link GraphvizModule}.
  <p>
  Specify the {@link PrintWriter} to output to with {@link #setOut(PrintWriter)}.
 
- @author phopkins@gmail.com (Pete Hopkins)]]>
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.grapher.graphviz.GraphvizGrapher -->
@@ -5024,11 +5148,17 @@
     <constructor name="GraphvizNode" type="com.google.inject.grapher.NodeId"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </constructor>
     <method name="getNodeId" return="com.google.inject.grapher.NodeId"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="getShape" return="com.google.inject.grapher.graphviz.NodeShape"
       abstract="false" native="false" synchronized="false"
@@ -5113,12 +5243,18 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="setIdentifier"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="identifier" type="java.lang.String"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <doc>
     <![CDATA[Data object to encapsulate the attributes of Graphviz nodes that we're
@@ -5200,7 +5336,7 @@
     </method>
     <doc>
     <![CDATA[Interface for a service that returns Graphviz port IDs, used for naming the
- rows in {@link ImplementationNode}-displaying {@link GraphvizNode}s.
+ rows in {@link com.google.inject.grapher.ImplementationNode}-displaying {@link GraphvizNode}s.
 
  @author phopkins@gmail.com (Pete Hopkins)]]>
     </doc>
@@ -5440,6 +5576,18 @@
   <!-- end class com.google.inject.matcher.Matchers -->
 </package>
 <package name="com.google.inject.multibindings">
+  <!-- start class com.google.inject.multibindings.ClassMapKey -->
+  <class name="ClassMapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows {@literal @}{@link ProvidesIntoMap} to specify a class map key.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ClassMapKey -->
   <!-- start class com.google.inject.multibindings.MapBinder -->
   <class name="MapBinder" extends="java.lang.Object"
     abstract="true"
@@ -5723,6 +5871,37 @@
     </doc>
   </interface>
   <!-- end interface com.google.inject.multibindings.MapBinderBinding -->
+  <!-- start class com.google.inject.multibindings.MapKey -->
+  <class name="MapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows users define customized key type annotations for map bindings by annotating an annotation
+ of a {@code Map}'s key type. The custom key annotation can be applied to methods also annotated
+ with {@literal @}{@link ProvidesIntoMap}.
+ 
+ <p>A {@link StringMapKey} and {@link ClassMapKey} are provided for convenience with maps whose
+ keys are strings or classes. For maps with enums or primitive types as keys, you must provide
+ your own MapKey annotation, such as this one for an enum:
+
+ <pre>
+ {@literal @}MapKey(unwrapValue = true)
+ {@literal @}Retention(RUNTIME)
+ public {@literal @}interface MyCustomEnumKey {
+   MyCustomEnum value();
+ }
+ </pre>
+
+ You can also use the whole annotation as the key, if {@code unwrapValue=false}.
+ When unwrapValue is false, the annotation type will be the key type for the injected map and
+ the annotation instances will be the key values. If {@code unwrapValue=true}, the value() type
+ will be the key type for injected map and the value() instances will be the keys values.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.MapKey -->
   <!-- start class com.google.inject.multibindings.Multibinder -->
   <class name="Multibinder" extends="java.lang.Object"
     abstract="true"
@@ -5791,6 +5970,19 @@
       static="true" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="binder" type="com.google.inject.Binder"/>
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of the key's type in a {@link Set} that is
+ itself bound with the annotation (if any) of the key.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
       <param name="type" type="java.lang.Class&lt;T&gt;"/>
       <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
       <doc>
@@ -5849,6 +6041,8 @@
    public SnackMachine(Set&lt;Snack&gt; snacks) { ... }
  }</code></pre>
 
+ If desired, {@link Collection}{@code <Provider<Snack>>} can also be injected.
+
  <p>Contributing multibindings from different modules is supported. For
  example, it is okay for both {@code CandyModule} and {@code ChipsModule}
  to create their own {@code Multibinder<Snack>}, and to each contribute
@@ -5958,6 +6152,41 @@
     </doc>
   </interface>
   <!-- end interface com.google.inject.multibindings.MultibinderBinding -->
+  <!-- start class com.google.inject.multibindings.MultibindingsScanner -->
+  <class name="MultibindingsScanner" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="asModule" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a module that, when installed, will scan all modules for methods with the annotations
+ {@literal @}{@link ProvidesIntoMap}, {@literal @}{@link ProvidesIntoSet}, and
+ {@literal @}{@link ProvidesIntoOptional}.
+ 
+ <p>This is a convenience method, equivalent to doing
+ {@code binder().scanModulesForAnnotatedMethods(MultibindingsScanner.scanner())}.]]>
+      </doc>
+    </method>
+    <method name="scanner" return="com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a {@link ModuleAnnotatedMethodScanner} that, when bound, will scan all modules for
+ methods with the annotations {@literal @}{@link ProvidesIntoMap},
+ {@literal @}{@link ProvidesIntoSet}, and {@literal @}{@link ProvidesIntoOptional}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Scans a module for annotations that signal multibindings, mapbindings, and optional bindings.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.MultibindingsScanner -->
   <!-- start interface com.google.inject.multibindings.MultibindingsTargetVisitor -->
   <interface name="MultibindingsTargetVisitor"    abstract="true"
     static="false" final="false" visibility="public"
@@ -5981,17 +6210,384 @@
       <![CDATA[Visits a binding created through {@link MapBinder}.]]>
       </doc>
     </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="optionalbinding" type="com.google.inject.multibindings.OptionalBinderBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits a binding created through {@link OptionalBinder}.
+ 
+ @since 4.0]]>
+      </doc>
+    </method>
     <doc>
     <![CDATA[A visitor for the multibinder extension.
  <p>
  If your {@link BindingTargetVisitor} implements this interface, bindings created by using
- {@link Multibinder} or {@link MapBinder} will be visited through this interface.
- 
+ {@link Multibinder}, {@link MapBinder} or {@link OptionalBinderBinding} will be visited through
+ this interface.
+
  @since 3.0
  @author sameb@google.com (Sam Berlin)]]>
     </doc>
   </interface>
   <!-- end interface com.google.inject.multibindings.MultibindingsTargetVisitor -->
+  <!-- start class com.google.inject.multibindings.OptionalBinder -->
+  <class name="OptionalBinder" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+    </method>
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+    </method>
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.Key&lt;T&gt;"/>
+    </method>
+    <method name="setDefault" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a binding builder used to set the default value that will be injected.
+ The binding set by this method will be ignored if {@link #setBinding} is called.
+ 
+ <p>It is an error to call this method without also calling one of the {@code to}
+ methods on the returned binding builder.]]>
+      </doc>
+    </method>
+    <method name="setBinding" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a binding builder used to set the actual value that will be injected.
+ This overrides any binding set by {@link #setDefault}.
+ 
+ <p>It is an error to call this method without also calling one of the {@code to}
+ methods on the returned binding builder.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An API to bind optional values, optionally with a default value.
+ OptionalBinder fulfills two roles: <ol>
+ <li>It allows a framework to define an injection point that may or
+     may not be bound by users.
+ <li>It allows a framework to supply a default value that can be changed
+     by users.
+ </ol>
+ 
+ <p>When an OptionalBinder is added, it will always supply the bindings:
+ {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
+ {@link #setBinding} or {@link #setDefault} are called, it will also
+ bind {@code T}.
+ 
+ <p>{@code setDefault} is intended for use by frameworks that need a default
+ value.  User code can call {@code setBinding} to override the default.
+ <b>Warning: Even if setBinding is called, the default binding
+ will still exist in the object graph.  If it is a singleton, it will be
+ instantiated in {@code Stage.PRODUCTION}.</b>
+ 
+ <p>If setDefault or setBinding are linked to Providers, the Provider may return
+ {@code null}.  If it does, the Optional bindings will be absent.  Binding
+ setBinding to a Provider that returns null will not cause OptionalBinder
+ to fall back to the setDefault binding.
+ 
+ <p>If neither setDefault nor setBinding are called, it will try to link to a
+ user-supplied binding of the same type.  If no binding exists, the optionals
+ will be absent.  Otherwise, if a user-supplied binding of that type exists,
+ or if setBinding or setDefault are called, the optionals will return present
+ if they are bound to a non-null value.
+
+ <p>Values are resolved at injection time. If a value is bound to a
+ provider, that provider's get method will be called each time the optional
+ is injected (unless the binding is also scoped, or an optional of provider is
+ injected).
+ 
+ <p>Annotations are used to create different optionals of the same key/value
+ type. Each distinct annotation gets its own independent binding.
+  
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
+   }
+ }</code></pre>
+
+ <p>With this module, an {@link Optional}{@code <Renamer>} can now be
+ injected.  With no other bindings, the optional will be absent.
+ Users can specify bindings in one of two ways:
+ 
+ <p>Option 1:
+ <pre><code>
+ public class UserRenamerModule extends AbstractModule {
+   protected void configure() {
+     bind(Renamer.class).to(ReplacingRenamer.class);
+   }
+ }</code></pre>
+ 
+ <p>or Option 2:
+ <pre><code>
+ public class UserRenamerModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
+         .setBinding().to(ReplacingRenamer.class);
+   }
+ }</code></pre>
+ With both options, the {@code Optional<Renamer>} will be present and supply the
+ ReplacingRenamer. 
+ 
+ <p>Default values can be supplied using:
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+   }
+ }</code></pre>
+ With the above module, code can inject an {@code @LookupUrl String} and it
+ will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
+ <pre><code>
+ public class UserLookupModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
+   }
+ }</code></pre>
+ ... which will override the default value.
+ 
+ <p>If one module uses setDefault the only way to override the default is to use setBinding.
+ It is an error for a user to specify the binding without using OptionalBinder if
+ setDefault or setBinding are called.  For example, 
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+   }
+ }
+ public class UserLookupModule extends AbstractModule {
+   protected void configure() {
+     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
+   } 
+ }</code></pre>
+ ... would generate an error, because both the framework and the user are trying to bind
+ {@code @LookupUrl String}. 
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.OptionalBinder -->
+  <!-- start interface com.google.inject.multibindings.OptionalBinderBinding -->
+  <interface name="OptionalBinderBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the {@link Key} for this binding.]]>
+      </doc>
+    </method>
+    <method name="getDefaultBinding" return="com.google.inject.Binding&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the default binding (set by {@link OptionalBinder#setDefault}) if one exists or null
+ if no default binding is set. This will throw {@link UnsupportedOperationException} if it is
+ called on an element retrieved from {@link Elements#getElements}.
+ <p>
+ The Binding's type will always match the type Optional's generic type. For example, if getKey
+ returns a key of <code>Optional&lt;String></code>, then this will always return a
+ <code>Binding&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="getActualBinding" return="com.google.inject.Binding&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the actual binding (set by {@link OptionalBinder#setBinding}) or null if not set.
+ This will throw {@link UnsupportedOperationException} if it is called on an element retrieved
+ from {@link Elements#getElements}.
+ <p>
+ The Binding's type will always match the type Optional's generic type. For example, if getKey
+ returns a key of <code>Optional&lt;String></code>, then this will always return a
+ <code>Binding&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="containsElement" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="element" type="com.google.inject.spi.Element"/>
+      <doc>
+      <![CDATA[Returns true if this OptionalBinder contains the given Element in order to build the optional
+ binding or uses the given Element in order to support building and injecting its data. This
+ will work for OptionalBinderBinding retrieved from an injector and
+ {@link Elements#getElements}. Usually this is only necessary if you are working with elements
+ retrieved from modules (without an Injector), otherwise {@link #getDefaultBinding} and
+ {@link #getActualBinding} are better options.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding for a OptionalBinder.
+ 
+ <p>Although OptionalBinders may be injected through a variety of types
+ {@code T}, {@code Optional<T>}, {@code Optional<Provider<T>>}, etc..), an
+ OptionalBinderBinding exists only on the Binding associated with the
+ {@code Optional<T>} key.  Other bindings can be validated to be derived from this
+ OptionalBinderBinding using {@link #containsElement}.
+ 
+ @param <T> The fully qualified type of the optional binding, including Optional.
+        For example: {@code Optional<String>}.
+ 
+ @since 4.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.multibindings.OptionalBinderBinding -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoMap -->
+  <class name="ProvidesIntoMap"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link MapBinder}.
+ The method's return type, binding annotation and additional key annotation determines
+ what Map this will contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoMap
+ {@literal @}StringMapKey("Foo")
+ {@literal @}Named("plugins")
+ Plugin provideFooUrl(FooManager fm) { returm fm.getPlugin(); }
+
+ {@literal @}ProvidesIntoMap
+ {@literal @}StringMapKey("Bar")
+ {@literal @}Named("urls")
+ Plugin provideBarUrl(BarManager bm) { return bm.getPlugin(); }
+ </pre>
+
+ will add two items to the {@code @Named("urls") Map<String, Plugin>} map. The key 'Foo'
+ will map to the provideFooUrl method, and the key 'Bar' will map to the provideBarUrl method.
+ The values are bound as providers and will be evaluated at injection time.
+
+ <p>Because the key is specified as an annotation, only Strings, Classes, enums, primitive
+ types and annotation instances are supported as keys.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoMap -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoOptional -->
+  <class name="ProvidesIntoOptional"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
+ The method's return type and binding annotation determines what Optional this will
+ contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoOptional(DEFAULT)
+ {@literal @}Named("url")
+ String provideFooUrl(FooManager fm) { returm fm.getUrl(); }
+
+ {@literal @}ProvidesIntoOptional(ACTUAL)
+ {@literal @}Named("url")
+ String provideBarUrl(BarManager bm) { return bm.getUrl(); }
+ </pre>
+
+ will set the default value of {@code @Named("url") Optional<String>} to foo's URL,
+ and then override it to bar's URL.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoOptional -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoOptional.Type -->
+  <class name="ProvidesIntoOptional.Type" extends="java.lang.Enum&lt;com.google.inject.multibindings.ProvidesIntoOptional.Type&gt;"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.multibindings.ProvidesIntoOptional.Type[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.multibindings.ProvidesIntoOptional.Type"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[@since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoOptional.Type -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoSet -->
+  <class name="ProvidesIntoSet"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
+ The method's return type and binding annotation determines what Set this will
+ contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoSet
+ {@literal @}Named("urls")
+ String provideFooUrl(FooManager fm) { returm fm.getUrl(); }
+
+ {@literal @}ProvidesIntoSet
+ {@literal @}Named("urls")
+ String provideBarUrl(BarManager bm) { return bm.getUrl(); }
+ </pre>
+
+ will add two items to the {@code @Named("urls") Set<String>} set. The items are bound as
+ providers and will be evaluated at injection time.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoSet -->
+  <!-- start class com.google.inject.multibindings.StringMapKey -->
+  <class name="StringMapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows {@literal @}{@link ProvidesIntoMap} to specify a string map key.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.StringMapKey -->
 </package>
 <package name="com.google.inject.name">
   <!-- start class com.google.inject.name.Named -->
@@ -6057,6 +6653,7 @@
     abstract="false"
     static="false" final="true" visibility="public"
     deprecated="not deprecated">
+    <implements name="javax.servlet.Filter"/>
     <constructor name="PersistFilter" type="com.google.inject.persist.UnitOfWork, com.google.inject.persist.PersistService"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6065,8 +6662,8 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterConfig" type="FilterConfig"/>
-      <exception name="ServletException" type="ServletException"/>
+      <param name="filterConfig" type="javax.servlet.FilterConfig"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
     </method>
     <method name="destroy"
       abstract="false" native="false" synchronized="false"
@@ -6077,11 +6674,11 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletRequest" type="ServletRequest"/>
-      <param name="servletResponse" type="ServletResponse"/>
-      <param name="filterChain" type="FilterChain"/>
+      <param name="servletRequest" type="javax.servlet.ServletRequest"/>
+      <param name="servletResponse" type="javax.servlet.ServletResponse"/>
+      <param name="filterChain" type="javax.servlet.FilterChain"/>
       <exception name="IOException" type="java.io.IOException"/>
-      <exception name="ServletException" type="ServletException"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
     </method>
     <doc>
     <![CDATA[Apply this filter to enable the HTTP Request unit of work and to have
@@ -6197,7 +6794,8 @@
     <implements name="java.lang.annotation.Annotation"/>
     <doc>
     <![CDATA[<p> Any method or class marked with this annotation will be considered for transactionality.
- Consult the documentation on http://code.google.com/p/google-guice for detailed semantics.
+ Consult the documentation on https://github.com/google/guice/wiki/GuicePersist for detailed
+ semantics.
  Marking a method {@code @Transactional} will start a new transaction before the method
  executes and commit it after the method returns.
  <p>
@@ -6361,12 +6959,13 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="properties" type="java.util.Properties"/>
+      <param name="properties" type="java.util.Map&lt;?, ?&gt;"/>
       <doc>
       <![CDATA[Configures the JPA persistence provider with a set of properties.
  
  @param properties A set of name value pairs that configure a JPA persistence
- provider as per the specification.]]>
+     provider as per the specification.
+ @since 4.0 (since 3.0 with a parameter type of {@code java.util.Properties})]]>
       </doc>
     </method>
     <method name="addFinder" return="com.google.inject.persist.jpa.JpaPersistModule"
@@ -6394,6 +6993,7 @@
     abstract="false"
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
+    <implements name="javax.servlet.Filter"/>
     <constructor name="GuiceFilter"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6402,18 +7002,18 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletRequest" type="ServletRequest"/>
-      <param name="servletResponse" type="ServletResponse"/>
-      <param name="filterChain" type="FilterChain"/>
+      <param name="servletRequest" type="javax.servlet.ServletRequest"/>
+      <param name="servletResponse" type="javax.servlet.ServletResponse"/>
+      <param name="filterChain" type="javax.servlet.FilterChain"/>
       <exception name="IOException" type="java.io.IOException"/>
-      <exception name="ServletException" type="ServletException"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
     </method>
     <method name="init"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterConfig" type="FilterConfig"/>
-      <exception name="ServletException" type="ServletException"/>
+      <param name="filterConfig" type="javax.servlet.FilterConfig"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
     </method>
     <method name="destroy"
       abstract="false" native="false" synchronized="false"
@@ -6451,6 +7051,7 @@
     abstract="true"
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
+    <implements name="javax.servlet.ServletContextListener"/>
     <constructor name="GuiceServletContextListener"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6459,13 +7060,13 @@
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletContextEvent" type="ServletContextEvent"/>
+      <param name="servletContextEvent" type="javax.servlet.ServletContextEvent"/>
     </method>
     <method name="contextDestroyed"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletContextEvent" type="ServletContextEvent"/>
+      <param name="servletContextEvent" type="javax.servlet.ServletContextEvent"/>
     </method>
     <method name="getInjector" return="com.google.inject.Injector"
       abstract="true" native="false" synchronized="false"
@@ -6491,7 +7092,7 @@
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
     <implements name="com.google.inject.servlet.ServletModuleBinding"/>
-    <method name="getFilterInstance" return="Filter"
+    <method name="getFilterInstance" return="javax.servlet.Filter"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6512,7 +7113,7 @@
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
     <implements name="com.google.inject.servlet.ServletModuleBinding"/>
-    <method name="getServletInstance" return="HttpServlet"
+    <method name="getServletInstance" return="javax.servlet.http.HttpServlet"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6533,7 +7134,7 @@
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
     <implements name="com.google.inject.servlet.ServletModuleBinding"/>
-    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends Filter&gt;"
+    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6554,7 +7155,7 @@
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
     <implements name="com.google.inject.servlet.ServletModuleBinding"/>
-    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends HttpServlet&gt;"
+    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -6607,7 +7208,8 @@
     <doc>
     <![CDATA[Exception thrown when there was a failure entering request scope.
 
- @author Chris Nokleberg]]>
+ @author Chris Nokleberg
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.servlet.ScopingException -->
@@ -6620,7 +7222,8 @@
     <![CDATA[Annotates a {@link GuiceFilter} that provides scope functionality, but
  doesn't dispatch to {@link ServletModule} bound servlets or filters.
 
- @author iqshum@google.com (Isaac Shum)]]>
+ @author iqshum@google.com (Isaac Shum)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.servlet.ScopingOnly -->
@@ -6854,7 +7457,7 @@
  @since 2.0]]>
       </doc>
     </method>
-    <method name="getServletContext" return="ServletContext"
+    <method name="getServletContext" return="javax.servlet.ServletContext"
       abstract="false" native="false" synchronized="false"
       static="false" final="true" visibility="protected"
       deprecated="not deprecated">
@@ -6886,19 +7489,19 @@
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterKey" type="java.lang.Class&lt;? extends Filter&gt;"/>
+      <param name="filterKey" type="java.lang.Class&lt;? extends javax.servlet.Filter&gt;"/>
     </method>
     <method name="through"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterKey" type="com.google.inject.Key&lt;? extends Filter&gt;"/>
+      <param name="filterKey" type="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"/>
     </method>
     <method name="through"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filter" type="Filter"/>
+      <param name="filter" type="javax.servlet.Filter"/>
       <doc>
       <![CDATA[@since 3.0]]>
       </doc>
@@ -6907,21 +7510,21 @@
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterKey" type="java.lang.Class&lt;? extends Filter&gt;"/>
+      <param name="filterKey" type="java.lang.Class&lt;? extends javax.servlet.Filter&gt;"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
     </method>
     <method name="through"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filterKey" type="com.google.inject.Key&lt;? extends Filter&gt;"/>
+      <param name="filterKey" type="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
     </method>
     <method name="through"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="filter" type="Filter"/>
+      <param name="filter" type="javax.servlet.Filter"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
       <doc>
       <![CDATA[@since 3.0]]>
@@ -6942,19 +7545,19 @@
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletKey" type="java.lang.Class&lt;? extends HttpServlet&gt;"/>
+      <param name="servletKey" type="java.lang.Class&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
     </method>
     <method name="with"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletKey" type="com.google.inject.Key&lt;? extends HttpServlet&gt;"/>
+      <param name="servletKey" type="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
     </method>
     <method name="with"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servlet" type="HttpServlet"/>
+      <param name="servlet" type="javax.servlet.http.HttpServlet"/>
       <doc>
       <![CDATA[@since 3.0]]>
       </doc>
@@ -6963,21 +7566,21 @@
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletKey" type="java.lang.Class&lt;? extends HttpServlet&gt;"/>
+      <param name="servletKey" type="java.lang.Class&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
     </method>
     <method name="with"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servletKey" type="com.google.inject.Key&lt;? extends HttpServlet&gt;"/>
+      <param name="servletKey" type="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
     </method>
     <method name="with"
       abstract="true" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="servlet" type="HttpServlet"/>
+      <param name="servlet" type="javax.servlet.http.HttpServlet"/>
       <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
       <doc>
       <![CDATA[@since 3.0]]>
@@ -7158,22 +7761,18 @@
  where you can detach the request processing thread while waiting for data,
  and reattach to a different thread to finish processing at a later time.
 
- <p>Because {@code HttpServletRequest} objects are not typically
- thread-safe, the callable returned by this method must not be run on a
- different thread until the current request scope has terminated. In other
- words, do not use this method to propagate the current request scope to
- worker threads that may run concurrently with the current thread.
-
- <p>The returned callable will throw a {@link ScopingException} when called
- if the request scope being transferred is still active on a different
- thread.
+ <p>Because request-scoped objects are not typically thread-safe, the
+ callable returned by this method must not be run on a different thread
+ until the current request scope has terminated. The returned callable will
+ block until the current thread has released the request scope.
 
  @param callable code to be executed in another thread, which depends on
      the request scope.
  @return a callable that will invoke the given callable, making the request
      context available to it.
  @throws OutOfScopeException if this method is called from a non-request
-     thread, or if the request has completed.]]>
+     thread, or if the request has completed.
+ @since 4.0]]>
       </doc>
     </method>
     <method name="isRequestScoped" return="boolean"
@@ -7186,7 +7785,9 @@
  {@link com.google.inject.spi.LinkedKeyBinding linked key binding} and
  belongs to an injector (i. e. it was retrieved via
  {@link Injector#getBinding Injector.getBinding()}), then this method will
- also return true if the target binding is request-scoped.]]>
+ also return true if the target binding is request-scoped.
+
+ @since 4.0]]>
       </doc>
     </method>
     <method name="scopeRequest" return="java.util.concurrent.Callable&lt;T&gt;"
@@ -7781,6 +8382,12 @@
       deprecated="not deprecated">
       <param name="option" type="com.google.inject.spi.RequireExactBindingAnnotationsOption"/>
     </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ModuleAnnotatedMethodScannerBinding"/>
+    </method>
     <doc>
     <![CDATA[No-op visitor for subclassing. All interface methods simply delegate to
  {@link #visitOther(Element)}, returning its result.
@@ -7921,7 +8528,8 @@
     <![CDATA[A combination of a {@link Dependency} and the {@link Binding#getSource()
  source} where the dependency was bound.
  
- @author sameb@google.com (Sam Berlin)]]>
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.spi.DependencyAndSource -->
@@ -8099,8 +8707,9 @@
       deprecated="not deprecated">
       <doc>
       <![CDATA[Returns a single location in source code that defines the element. It can be any object
- such as {@link Constructor}, {@link Method}, {@link Field}, {@link StackTraceElement}, etc. For
- example, if the element is created from a method annotated by {@literal @Provides}, the 
+ such as {@link java.lang.reflect.Constructor}, {@link java.lang.reflect.Method},
+ {@link java.lang.reflect.Field}, {@link StackTraceElement}, etc. For
+ example, if the element is created from a method annotated by {@literal @Provides}, the
  declaring source of element would be the method itself.]]>
       </doc>
     </method>
@@ -8119,9 +8728,9 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <doc>
-      <![CDATA[Returns the position of {@link Module#configure(Binder) configure(Binder)} method call in the
- {@link #getStackTrace() stack trace} for modules that their classes returned by
- {@link #getModuleClassNames()}. For example, if the stack trace looks like the following:
+      <![CDATA[Returns the position of {@link com.google.inject.Module#configure configure(Binder)} method
+ call in the {@link #getStackTrace stack trace} for modules that their classes returned by
+ {@link #getModuleClassNames}. For example, if the stack trace looks like the following:
  <p>
  {@code
   0 - Binder.bind(),
@@ -8142,12 +8751,12 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <doc>
-      <![CDATA[Returns the sequence of method calls that ends at one of {@link Binder} {@code bindXXX()} 
- methods and eventually defines the element. Note that {@link #getStackTrace()} lists {@link 
- StackTraceElement StackTraceElements} in reverse chronological order. The first element (index 
- zero) is the last method call and the last element is the first method invocation. In the cases
- where stack trace is not available (i.e.,the stack trace was not collected), it returns an 
- empty array.]]>
+      <![CDATA[Returns the sequence of method calls that ends at one of {@link com.google.inject.Binder}
+ {@code bindXXX()} methods and eventually defines the element. Note that
+ {@link #getStackTrace} lists {@link StackTraceElement StackTraceElements} in reverse
+ chronological order. The first element (index zero) is the last method call and the last
+ element is the first method invocation. In the cases where stack trace is not available
+ (i.e.,the stack trace was not collected), it returns an empty array.]]>
       </doc>
     </method>
     <method name="toString" return="java.lang.String"
@@ -8159,29 +8768,38 @@
       </doc>
     </method>
     <doc>
-    <![CDATA[Contains information about where and how an {@link Element element} was bound.
- <p> 
- The {@link #getDeclaringSource() declaring source} refers to a location in source code that 
- defines the Guice {@link Element element}. For example, if the element is created from a method
- annotated by {@literal @Provides}, the declaring source of element would be the method itself. 
+    <![CDATA[Contains information about where and how an {@link Element element} was
+ bound.
  <p>
- The {@link #getStackTrace()} refers to the sequence of calls ends at one of {@link Binder} 
- {@code bindXXX()} methods and eventually defines the element. Note that {@link #getStackTrace()} 
- lists {@link StackTraceElement StackTraceElements} in reverse chronological order. The first 
- element (index zero) is the last method call and the last element is the first method invocation.
- By default, the stack trace is not collected. The default behavior can be changed by setting the 
- {@code guice_include_stack_traces} flag value. The value can be either {@code OFF}, {@code
- ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that collecting stack traces for every
- binding can cause a performance hit when the injector is created.
+ The {@link #getDeclaringSource() declaring source} refers to a location in
+ source code that defines the Guice {@link Element element}. For example, if
+ the element is created from a method annotated by {@literal @Provides}, the
+ declaring source of element would be the method itself.
  <p>
- The sequence of class names of {@link Module modules} involved in the element creation can be 
- retrieved by {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the order is 
- reverse chronological. The first module (index 0) is the module that installs the {@link Element 
- element}. The last module is the root module.
+ The {@link #getStackTrace()} refers to the sequence of calls ends at one of
+ {@link com.google.inject.Binder} {@code bindXXX()} methods and eventually
+ defines the element. Note that {@link #getStackTrace()} lists
+ {@link StackTraceElement StackTraceElements} in reverse chronological order.
+ The first element (index zero) is the last method call and the last element
+ is the first method invocation. By default, the stack trace is not collected.
+ The default behavior can be changed by setting the
+ {@code guice_include_stack_traces} flag value. The value can be either
+ {@code OFF}, {@code ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that
+ collecting stack traces for every binding can cause a performance hit when
+ the injector is created.
  <p>
- In order to support the cases where a Guice {@link Element element} is created from another
- Guice {@link Element element} (original) (e.g., by {@link Element#applyTo()}), it also
- provides a reference to the original element source ({@link #getOriginalElementSource()}).]]>
+ The sequence of class names of {@link com.google.inject.Module modules}
+ involved in the element creation can be retrieved by
+ {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the
+ order is reverse chronological. The first module (index 0) is the module that
+ installs the {@link Element element}. The last module is the root module.
+ <p>
+ In order to support the cases where a Guice {@link Element element} is
+ created from another Guice {@link Element element} (original) (e.g., by
+ {@link Element#applyTo}), it also provides a reference to the original
+ element source ({@link #getOriginalElementSource()}).
+
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.spi.ElementSource -->
@@ -8296,7 +8914,9 @@
       deprecated="not deprecated">
       <param name="binding" type="com.google.inject.spi.ProvisionListenerBinding"/>
       <doc>
-      <![CDATA[Visit a provision listener binding.]]>
+      <![CDATA[Visit a provision listener binding.
+
+ @since 4.0]]>
       </doc>
     </method>
     <method name="visit" return="V"
@@ -8343,6 +8963,17 @@
  @since 4.0]]>
       </doc>
     </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ModuleAnnotatedMethodScannerBinding"/>
+      <doc>
+      <![CDATA[Visits a {@link Binder#scanModulesForAnnotatedMethods} command.
+
+ @since 4.0]]>
+      </doc>
+    </method>
     <doc>
     <![CDATA[Visit elements.
 
@@ -8568,6 +9199,23 @@
      parameter with multiple binding annotations.]]>
       </doc>
     </method>
+    <method name="forMethod" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="method" type="java.lang.reflect.Method"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the specified method of {@code type}.
+ This is useful for extensions that need to build dependency graphs from
+ arbitrary methods.
+
+ @param method any single method present on {@code type}.
+ @param type the concrete type that defines {@code method}.
+
+ @since 4.0]]>
+      </doc>
+    </method>
     <method name="forStaticMethodsAndFields" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
       abstract="false" native="false" synchronized="false"
       static="true" final="false" visibility="public"
@@ -9011,6 +9659,99 @@
     </doc>
   </class>
   <!-- end class com.google.inject.spi.Message -->
+  <!-- start class com.google.inject.spi.ModuleAnnotatedMethodScanner -->
+  <class name="ModuleAnnotatedMethodScanner" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ModuleAnnotatedMethodScanner"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="annotationClasses" return="java.util.Set&lt;? extends java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the annotations this should scan for. Every method in the module that has one of these
+ annotations will create a Provider binding, with the return value of the binding being what's
+ provided and the parameters of the method being dependencies of the provider.]]>
+      </doc>
+    </method>
+    <method name="prepareMethod" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <param name="injectionPoint" type="com.google.inject.spi.InjectionPoint"/>
+      <doc>
+      <![CDATA[Prepares a method for binding. This {@code key} parameter is the key discovered from looking at
+ the binding annotation and return value of the method. Implementations can modify the key to
+ instead bind to another key. For example, Multibinder may want to change
+ {@code @SetProvides String provideFoo()} to bind into a unique Key within the multibinder
+ instead of binding {@code String}.
+
+ <p>The injection point and annotation are provided in case the implementation wants to set the
+ key based on the property of the annotation or if any additional preparation is needed for any
+ of the dependencies. The annotation is guaranteed to be an instance of one the classes returned
+ by {@link #annotationClasses}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Allows extensions to scan modules for annotated methods and bind those methods
+ as providers, similar to {@code @Provides} methods.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ModuleAnnotatedMethodScanner -->
+  <!-- start class com.google.inject.spi.ModuleAnnotatedMethodScannerBinding -->
+  <class name="ModuleAnnotatedMethodScannerBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="ModuleAnnotatedMethodScannerBinding" type="java.lang.Object, com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getScanner" return="com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Represents a call to {@link Binder#scanModulesForAnnotatedMethods} in a module.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ModuleAnnotatedMethodScannerBinding -->
   <!-- start interface com.google.inject.spi.PrivateElements -->
   <interface name="PrivateElements"    abstract="true"
     static="false" final="false" visibility="public"
@@ -9112,7 +9853,8 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <doc>
-      <![CDATA[Returns the user-supplied, unscoped provider.]]>
+      <![CDATA[Returns the user-supplied, unscoped provider.
+ @since 4.0]]>
       </doc>
     </method>
     <method name="getInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
@@ -9169,6 +9911,13 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
     </constructor>
+    <constructor name="ProviderLookup" type="java.lang.Object, com.google.inject.spi.Dependency&lt;T&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </constructor>
     <method name="getSource" return="java.lang.Object"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
@@ -9179,6 +9928,14 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
     </method>
+    <method name="getDependency" return="com.google.inject.spi.Dependency&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
     <method name="acceptVisitor" return="T"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
@@ -9325,9 +10082,21 @@
       <![CDATA[Returns the key of the binding.]]>
       </doc>
     </method>
+    <method name="getAnnotation" return="java.lang.annotation.Annotation"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the annotation that caused this binding to be created. For {@code @Provides} methods,
+ this is an instance of the {@code @Provides} annotation. For bindings from
+ {@link ModuleAnnotatedMethodScanner}, this is the annotation that caused the scanner to produce
+ the binding.]]>
+      </doc>
+    </method>
     <doc>
-    <![CDATA[An {@literal @}{@link Provides} binding.
- 
+    <![CDATA[An {@literal @}{@link Provides} binding or binding produced by a
+ {@link ModuleAnnotatedMethodScanner}.
+
  @since 4.0
  @author sameb@google.com (Sam Berlin)]]>
     </doc>
@@ -9430,7 +10199,9 @@
       </doc>
     </method>
     <doc>
-    <![CDATA[Encapsulates a single act of provisioning.]]>
+    <![CDATA[Encapsulates a single act of provisioning.
+
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.spi.ProvisionListener.ProvisionInvocation -->
@@ -9832,7 +10603,7 @@
       <param name="type" type="java.lang.Class&lt;T&gt;"/>
       <doc>
       <![CDATA[Returns the provider used to obtain instances for the given injection type. The returned
- provider will not be valid until the injetor has been created. The provider will throw an
+ provider will not be valid until the injector has been created. The provider will throw an
  {@code IllegalStateException} if you try to use it beforehand.]]>
       </doc>
     </method>
@@ -10046,7 +10817,7 @@
       static="true" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="binder" type="com.google.inject.Binder"/>
-      <param name="beanFactory" type="ListableBeanFactory"/>
+      <param name="beanFactory" type="org.springframework.beans.factory.ListableBeanFactory"/>
       <doc>
       <![CDATA[Binds all Spring beans from the given factory by name. For a Spring bean
  named "foo", this method creates a binding to the bean's type and
@@ -10066,10 +10837,10 @@
 </package>
 <package name="com.google.inject.struts2">
   <!-- start class com.google.inject.struts2.GuiceObjectFactory -->
-  <class name="GuiceObjectFactory" extends="ObjectFactory"
+  <class name="GuiceObjectFactory" extends="com.opensymphony.xwork2.ObjectFactory"
     abstract="false"
     static="false" final="false" visibility="public"
-    deprecated="Use {@link com.google.inject.servlet.Struts2Factory} instead.">
+    deprecated="Use {@link com.google.inject.struts2.Struts2Factory} instead.">
     <constructor name="GuiceObjectFactory"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
@@ -10093,21 +10864,21 @@
       <param name="clazz" type="java.lang.Class"/>
       <param name="extraContext" type="java.util.Map"/>
     </method>
-    <method name="buildInterceptor" return="Interceptor"
+    <method name="buildInterceptor" return="com.opensymphony.xwork2.interceptor.Interceptor"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="interceptorConfig" type="InterceptorConfig"/>
+      <param name="interceptorConfig" type="com.opensymphony.xwork2.config.entities.InterceptorConfig"/>
       <param name="interceptorRefParams" type="java.util.Map"/>
-      <exception name="ConfigurationException" type="ConfigurationException"/>
+      <exception name="ConfigurationException" type="com.opensymphony.xwork2.config.ConfigurationException"/>
     </method>
     <doc>
-    <![CDATA[@deprecated Use {@link com.google.inject.servlet.Struts2Factory} instead.]]>
+    <![CDATA[@deprecated Use {@link com.google.inject.struts2.Struts2Factory} instead.]]>
     </doc>
   </class>
   <!-- end class com.google.inject.struts2.GuiceObjectFactory -->
   <!-- start class com.google.inject.struts2.Struts2Factory -->
-  <class name="Struts2Factory" extends="ObjectFactory"
+  <class name="Struts2Factory" extends="com.opensymphony.xwork2.ObjectFactory"
     abstract="false"
     static="false" final="false" visibility="public"
     deprecated="not deprecated">
@@ -10134,13 +10905,13 @@
       <param name="clazz" type="java.lang.Class"/>
       <param name="extraContext" type="java.util.Map&lt;java.lang.String, java.lang.Object&gt;"/>
     </method>
-    <method name="buildInterceptor" return="Interceptor"
+    <method name="buildInterceptor" return="com.opensymphony.xwork2.interceptor.Interceptor"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
-      <param name="interceptorConfig" type="InterceptorConfig"/>
+      <param name="interceptorConfig" type="com.opensymphony.xwork2.config.entities.InterceptorConfig"/>
       <param name="interceptorRefParams" type="java.util.Map"/>
-      <exception name="ConfigurationException" type="ConfigurationException"/>
+      <exception name="ConfigurationException" type="com.opensymphony.xwork2.config.ConfigurationException"/>
     </method>
     <doc>
     <![CDATA[Cleanup up version from Bob's GuiceObjectFactory. Now works properly with
@@ -10166,15 +10937,118 @@
       deprecated="not deprecated">
     </method>
     <doc>
-    <![CDATA[Initializes the Struts 2 Guice Plugin.
- Must be added to the injector returned by
-     {@link GuiceServletContextListener.getInjector()}.
+    <![CDATA[Initializes the Struts 2 Guice Plugin. Must be added to the injector returned
+ by {@link com.google.inject.servlet.GuiceServletContextListener#getInjector}.
 
  @author benmccann.com]]>
     </doc>
   </class>
   <!-- end class com.google.inject.struts2.Struts2GuicePluginModule -->
 </package>
+<package name="com.google.inject.testing.fieldbinder">
+  <!-- start class com.google.inject.testing.fieldbinder.Bind -->
+  <class name="Bind"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotation used by {@link BoundFieldModule} to indicate that a field should be bound to its
+ value using Guice.
+
+ @see BoundFieldModule
+ @author eatnumber1@google.com (Russ Harmon)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.testing.fieldbinder.Bind -->
+  <!-- start class com.google.inject.testing.fieldbinder.BoundFieldModule -->
+  <class name="BoundFieldModule" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Module"/>
+    <method name="of" return="com.google.inject.testing.fieldbinder.BoundFieldModule"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Create a BoundFieldModule which binds the {@link Bind} annotated fields of {@code instance}.
+
+ @param instance the instance whose fields will be bound.
+ @return a module which will bind the {@link Bind} annotated fields of {@code instance}.]]>
+      </doc>
+    </method>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Automatically creates Guice bindings for fields in an object annotated with {@link Bind}.
+
+ <p>This module is intended for use in tests to reduce the code needed to bind local fields
+ (usually mocks) for injection.
+
+ <p>The following rules are followed in determining how fields are bound using this module:
+
+ <ul>
+ <li>
+ For each {@link Bind} annotated field of an object and its superclasses, this module will bind
+ that field's type to that field's value at injector creation time. This includes both instance
+ and static fields.
+ </li>
+ <li>
+ If {@link Bind#to} is specified, the field's value will be bound to the class specified by
+ {@link Bind#to} instead of the field's actual type.
+ </li>
+ <li>
+ If a {@link BindingAnnotation} or {@link javax.inject.Qualifier} is present on the field,
+ that field will be bound using that annotation via {@link AnnotatedBindingBuilder#annotatedWith}.
+ For example, {@code bind(Foo.class).annotatedWith(BarAnnotation.class).toInstance(theValue)}.
+ It is an error to supply more than one {@link BindingAnnotation} or
+ {@link javax.inject.Qualifier}.
+ </li>
+ <li>
+ If the field is of type {@link Provider}, the field's value will be bound as a {@link Provider}
+ using {@link LinkedBindingBuilder#toProvider} to the provider's parameterized type. For example,
+ {@code Provider<Integer>} binds to {@link Integer}. Attempting to bind a non-parameterized
+ {@link Provider} without a {@link Bind#to} clause is an error.
+ </li>
+ </ul>
+
+ <p>Example use:
+ <pre><code>
+ public class TestFoo {
+   // bind(new TypeLiteral{@code <List<Object>>}() {}).toInstance(listOfObjects);
+   {@literal @}Bind private List{@code <Object>} listOfObjects = Lists.of();
+   
+   // bind(String.class).toProvider(new Provider() { public String get() { return userName; }});
+   {@literal @}Bind(lazy = true) private String userName;
+
+   // bind(SuperClass.class).toInstance(aSubClass);
+   {@literal @}Bind(to = SuperClass.class) private SubClass aSubClass = new SubClass();
+
+   // bind(Object.class).annotatedWith(MyBindingAnnotation.class).toInstance(object2);
+   {@literal @}Bind
+   {@literal @}MyBindingAnnotation
+   private String myString = "hello";
+
+   // bind(Object.class).toProvider(myProvider);
+   {@literal @}Bind private Provider{@code <Object>} myProvider = getProvider();
+
+   {@literal @}Before public void setUp() {
+     Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
+   }
+ }
+ </code></pre>
+
+ @see Bind
+ @author eatnumber1@google.com (Russ Harmon)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.testing.fieldbinder.BoundFieldModule -->
+</package>
 <package name="com.google.inject.throwingproviders">
   <!-- start interface com.google.inject.throwingproviders.CheckedProvider -->
   <interface name="CheckedProvider"    abstract="true"
@@ -10212,11 +11086,11 @@
     deprecated="not deprecated">
     <implements name="java.lang.annotation.Annotation"/>
     <doc>
-    <![CDATA[Annotates methods of a {@link Module} to create a {@link CheckedProvider}
- method binding that can throw exceptions. The method's return type is bound
- to a {@link CheckedProvider} that can be injected. Guice will pass
- dependencies to the method as parameters. Install {@literal @}CheckedProvides
- methods by using
+    <![CDATA[Annotates methods of a {@link com.google.inject.Module} to create a
+ {@link CheckedProvider} method binding that can throw exceptions. The
+ method's return type is bound to a {@link CheckedProvider} that can be
+ injected. Guice will pass dependencies to the method as parameters. Install
+ {@literal @}CheckedProvides methods by using
  {@link ThrowingProviderBinder#forModule(com.google.inject.Module)} on the
  module where the methods are declared.
  
@@ -10238,7 +11112,8 @@
  </code></pre>
  where CustomerImpl has a constructor annotated with ThrowingInject.
 
- @author sameb@google.com (Sam Berlin)]]>
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
     </doc>
   </class>
   <!-- end class com.google.inject.throwingproviders.ThrowingInject -->
@@ -10311,6 +11186,9 @@
       deprecated="not deprecated">
       <param name="interfaceType" type="java.lang.Class&lt;P&gt;"/>
       <param name="clazz" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="bind" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
       abstract="false" native="false" synchronized="false"
@@ -10318,6 +11196,9 @@
       deprecated="not deprecated">
       <param name="interfaceType" type="java.lang.Class&lt;P&gt;"/>
       <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <doc>
     <![CDATA[<p>Builds a binding for a {@link CheckedProvider}.
@@ -10376,6 +11257,18 @@
       deprecated="not deprecated">
       <param name="annotation" type="java.lang.annotation.Annotation"/>
     </method>
+    <method name="scopeExceptions" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeExceptions" type="boolean"/>
+      <doc>
+      <![CDATA[Determines if exceptions should be scoped. By default exceptions are scoped.
+
+ @param scopeExceptions whether exceptions should be scoped.
+ @since 4.0]]>
+      </doc>
+    </method>
     <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
@@ -10393,12 +11286,18 @@
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="cxtorClass" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="providing" return="com.google.inject.binder.ScopedBindingBuilder"
       abstract="false" native="false" synchronized="false"
       static="false" final="false" visibility="public"
       deprecated="not deprecated">
       <param name="cxtorLiteral" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
     </method>
     <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
       abstract="false" native="false" synchronized="false"
diff --git a/latest-api-diffs/4.1.xml b/latest-api-diffs/4.1.xml
new file mode 100644
index 0000000..98a5958
--- /dev/null
+++ b/latest-api-diffs/4.1.xml
@@ -0,0 +1,11825 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<!-- on Fri Jun 17 16:00:51 EDT 2016 -->
+
+<api
+  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+  xsi:noNamespaceSchemaLocation='api.xsd'
+  name="4.1"
+  jdversion="1.1.1">
+
+<!--  Command line arguments =  -doclet jdiff.JDiff -docletpath /tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jdiff/jdiff.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jdiff/xerces.jar -classpath /tmp/moe_git_clone_googlecode_6763913321787039468/lib/aopalliance.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/guava-19.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/javax.inject.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/asm-5.0.3.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/bnd-0.0.384.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/cglib-3.2.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/commons-logging-1.0.4.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/easymock.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/felix-2.0.5.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/guava-testlib-19.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jarjar-1.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/javax.inject-tck.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jsr305.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/junit.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/munge.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/safesax.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/spring-beans.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/spring-core.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/dagger-adapter/lib/dagger-2.4.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/antlr-2.7.5h3.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/aopalliance.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/cglib-nodep-3.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/commons-collections.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/commons-io.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/commons-logging-1.0.4.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/db4o-6.4.14.8131-java5.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/dom4j-1.6.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/easymock.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/ejb3-persistence.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/hibernate-annotations.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/hibernate-entitymanager.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/hibernate-search.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/hibernate3.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/hsqldb.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/javassist.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/jaxen-1.1-beta-7.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/jboss-archive-browsing.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/jta.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/log4j-1.2.14.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/ognl-2.6.7.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/oro-2.0.8.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/servlet-api-2.5.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/persist/lib/xwork-2.0.4.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/ant-1.6.5.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/commons-fileupload-1.2.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/commons-io-1.3.2.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/commons-logging-1.0.4.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/core-3.1.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/freemarker-2.3.16.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/javassist.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/jetty-6.1.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/jetty-util-6.1.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/jsp-2.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/jsp-api-2.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/ognl-3.0.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/servlet-api-2.5.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/struts2-core-2.2.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/extensions/struts2/lib/xwork-core-2.2.1.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/build/classes -doclet jdiff.JDiff -docletpath /tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jdiff/jdiff.jar:/tmp/moe_git_clone_googlecode_6763913321787039468/lib/build/jdiff/xerces.jar -apidir build/docs/latest-api-diffs -apiname 4.1 -->
+<package name="com.google.inject">
+  <!-- start class com.google.inject.AbstractModule -->
+  <class name="AbstractModule" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Module"/>
+    <constructor name="AbstractModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="true"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="builder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="configure"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Configures a {@link Binder} via the exposed methods.]]>
+      </doc>
+    </method>
+    <method name="binder" return="com.google.inject.Binder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets direct access to the underlying {@code Binder}.]]>
+      </doc>
+    </method>
+    <method name="bindScope"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="scope" type="com.google.inject.Scope"/>
+      <doc>
+      <![CDATA[@see Binder#bindScope(Class, Scope)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(Key)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(TypeLiteral)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="clazz" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(Class)]]>
+      </doc>
+    </method>
+    <method name="bindConstant" return="com.google.inject.binder.AnnotatedConstantBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@see Binder#bindConstant()]]>
+      </doc>
+    </method>
+    <method name="install"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="module" type="com.google.inject.Module"/>
+      <doc>
+      <![CDATA[@see Binder#install(Module)]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="message" type="java.lang.String"/>
+      <param name="arguments" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[@see Binder#addError(String, Object[])]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="t" type="java.lang.Throwable"/>
+      <doc>
+      <![CDATA[@see Binder#addError(Throwable)]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+      <doc>
+      <![CDATA[@see Binder#addError(Message)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requestInjection"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[@see Binder#requestInjection(Object)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requestStaticInjection"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="types" type="java.lang.Class[]"/>
+      <doc>
+      <![CDATA[@see Binder#requestStaticInjection(Class[])]]>
+      </doc>
+    </method>
+    <method name="bindInterceptor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="classMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.Class&lt;?&gt;&gt;"/>
+      <param name="methodMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.reflect.Method&gt;"/>
+      <param name="interceptors" type="org.aopalliance.intercept.MethodInterceptor[]"/>
+      <doc>
+      <![CDATA[@see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
+  com.google.inject.matcher.Matcher,
+  org.aopalliance.intercept.MethodInterceptor[])]]>
+      </doc>
+    </method>
+    <method name="requireBinding"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Adds a dependency from this module to {@code key}. When the injector is
+ created, Guice will report an error if {@code key} cannot be injected.
+ Note that this requirement may be satisfied by implicit binding, such as
+ a public no-arguments constructor.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requireBinding"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Adds a dependency from this module to {@code type}. When the injector is
+ created, Guice will report an error if {@code type} cannot be injected.
+ Note that this requirement may be satisfied by implicit binding, such as
+ a public no-arguments constructor.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getProvider(Key)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getProvider(Class)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="convertToTypes"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="converter" type="com.google.inject.spi.TypeConverter"/>
+      <doc>
+      <![CDATA[@see Binder#convertToTypes
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="currentStage" return="com.google.inject.Stage"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@see Binder#currentStage() 
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getMembersInjector(Class)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getMembersInjector(TypeLiteral)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="listener" type="com.google.inject.spi.TypeListener"/>
+      <doc>
+      <![CDATA[@see Binder#bindListener(com.google.inject.matcher.Matcher,
+  com.google.inject.spi.TypeListener)
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="bindingMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <param name="listener" type="com.google.inject.spi.ProvisionListener[]"/>
+      <doc>
+      <![CDATA[@see Binder#bindListener(Matcher, ProvisionListener...)
+ @since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A support class for {@link Module}s which reduces repetition and results in
+ a more readable configuration. Simply extend this class, implement {@link
+ #configure()}, and call the inherited methods which mirror those found in
+ {@link Binder}. For example:
+
+ <pre>
+ public class MyModule extends AbstractModule {
+   protected void configure() {
+     bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
+     bind(CreditCardPaymentService.class);
+     bind(PaymentService.class).to(CreditCardPaymentService.class);
+     bindConstant().annotatedWith(Names.named("port")).to(8080);
+   }
+ }
+ </pre>
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.AbstractModule -->
+  <!-- start interface com.google.inject.Binder -->
+  <interface name="Binder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="bindInterceptor"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="classMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.Class&lt;?&gt;&gt;"/>
+      <param name="methodMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.reflect.Method&gt;"/>
+      <param name="interceptors" type="org.aopalliance.intercept.MethodInterceptor[]"/>
+      <doc>
+      <![CDATA[Binds method interceptor[s] to methods matched by class and method matchers. A method is
+ eligible for interception if:
+
+ <ul>
+  <li>Guice created the instance the method is on</li>
+  <li>Neither the enclosing type nor the method is final</li>
+  <li>And the method is package-private, protected, or public</li>
+ </ul>
+
+ @param classMatcher matches classes the interceptor should apply to. For
+     example: {@code only(Runnable.class)}.
+ @param methodMatcher matches methods the interceptor should apply to. For
+     example: {@code annotatedWith(Transactional.class)}.
+ @param interceptors to bind.  The interceptors are called in the order they
+     are given.]]>
+      </doc>
+    </method>
+    <method name="bindScope"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="scope" type="com.google.inject.Scope"/>
+      <doc>
+      <![CDATA[Binds a scope to an annotation.]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link Binder}.]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link Binder}.]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link Binder}.]]>
+      </doc>
+    </method>
+    <method name="bindConstant" return="com.google.inject.binder.AnnotatedConstantBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[See the EDSL examples at {@link Binder}.]]>
+      </doc>
+    </method>
+    <method name="requestInjection"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="instance" type="T"/>
+      <doc>
+      <![CDATA[Upon successful creation, the {@link Injector} will inject instance fields
+ and methods of the given object.
+
+ @param type of instance
+ @param instance for which members will be injected
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requestInjection"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Upon successful creation, the {@link Injector} will inject instance fields
+ and methods of the given object.
+
+ @param instance for which members will be injected
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requestStaticInjection"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="types" type="java.lang.Class[]"/>
+      <doc>
+      <![CDATA[Upon successful creation, the {@link Injector} will inject static fields
+ and methods in the given classes.
+
+ @param types for which static members will be injected]]>
+      </doc>
+    </method>
+    <method name="install"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="module" type="com.google.inject.Module"/>
+      <doc>
+      <![CDATA[Uses the given module to configure more bindings.]]>
+      </doc>
+    </method>
+    <method name="currentStage" return="com.google.inject.Stage"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the current stage.]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="java.lang.String"/>
+      <param name="arguments" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[Records an error message which will be presented to the user at a later
+ time. Unlike throwing an exception, this enable us to continue
+ configuring the Injector and discover more errors. Uses {@link
+ String#format(String, Object[])} to insert the arguments into the
+ message.]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="t" type="java.lang.Throwable"/>
+      <doc>
+      <![CDATA[Records an exception, the full details of which will be logged, and the
+ message of which will be presented to the user at a later
+ time. If your Module calls something that you worry may fail, you should
+ catch the exception and pass it into this.]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+      <doc>
+      <![CDATA[Records an error message to be presented to the user at a later time.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection key.
+ The returned provider will not be valid until the {@link Injector} has been
+ created. The provider will throw an {@code IllegalStateException} if you
+ try to use it beforehand.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="dependency" type="com.google.inject.spi.Dependency&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection key.
+ The returned provider will be attached to the injection point and will
+ follow the nullability specified in the dependency.
+ Additionally, the returned provider will not be valid until the {@link Injector} 
+ has been created. The provider will throw an {@code IllegalStateException} if you
+ try to use it beforehand.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection type.
+ The returned provider will not be valid until the {@link Injector} has been
+ created. The provider will throw an {@code IllegalStateException} if you
+ try to use it beforehand.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}. The returned members injector will not be valid until the main
+ {@link Injector} has been created. The members injector will throw an {@code
+ IllegalStateException} if you try to use it beforehand.
+
+ @param typeLiteral type to get members injector for
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}. The returned members injector will not be valid until the main
+ {@link Injector} has been created. The members injector will throw an {@code
+ IllegalStateException} if you try to use it beforehand.
+
+ @param type type to get members injector for
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="convertToTypes"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="converter" type="com.google.inject.spi.TypeConverter"/>
+      <doc>
+      <![CDATA[Binds a type converter. The injector will use the given converter to
+ convert string constants to matching types as needed.
+
+ @param typeMatcher matches types the converter can handle
+ @param converter converts values
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="listener" type="com.google.inject.spi.TypeListener"/>
+      <doc>
+      <![CDATA[Registers a listener for injectable types. Guice will notify the listener when it encounters
+ injectable types matched by the given type matcher.
+
+ @param typeMatcher that matches injectable types the listener should be notified of
+ @param listener for injectable types matched by typeMatcher
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bindingMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <param name="listeners" type="com.google.inject.spi.ProvisionListener[]"/>
+      <doc>
+      <![CDATA[Registers listeners for provisioned objects. Guice will notify the
+ listeners just before and after the object is provisioned. Provisioned
+ objects that are also injectable (everything except objects provided
+ through Providers) can also be notified through TypeListeners registered in
+ {@link #bindListener}.
+ 
+ @param bindingMatcher that matches bindings of provisioned objects the listener
+          should be notified of
+ @param listeners for provisioned objects matched by bindingMatcher 
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="withSource" return="com.google.inject.Binder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns a binder that uses {@code source} as the reference location for
+ configuration errors. This is typically a {@link StackTraceElement}
+ for {@code .java} source but it could any binding source, such as the
+ path to a {@code .properties} file.
+
+ @param source any object representing the source location and has a
+     concise {@link Object#toString() toString()} value
+ @return a binder that shares its configuration with this binder
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="skipSources" return="com.google.inject.Binder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="classesToSkip" type="java.lang.Class[]"/>
+      <doc>
+      <![CDATA[Returns a binder that skips {@code classesToSkip} when identify the
+ calling code. The caller's {@link StackTraceElement} is used to locate
+ the source of configuration errors.
+
+ @param classesToSkip library classes that create bindings on behalf of
+      their clients.
+ @return a binder that shares its configuration with this binder.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="newPrivateBinder" return="com.google.inject.PrivateBinder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Creates a new private child environment for bindings and other configuration. The returned
+ binder can be used to add and configuration information in this environment. See {@link
+ PrivateModule} for details.
+
+ @return a binder that inherits configuration from this binder. Only exposed configuration on
+      the returned binder will be visible to this binder.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="requireExplicitBindings"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Instructs the Injector that bindings must be listed in a Module in order to
+ be injected. Classes that are not explicitly bound in a module cannot be
+ injected. Bindings created through a linked binding
+ (<code>bind(Foo.class).to(FooImpl.class)</code>) are allowed, but the
+ implicit binding (<code>FooImpl</code>) cannot be directly injected unless
+ it is also explicitly bound (<code>bind(FooImpl.class)</code>).
+ <p>
+ Tools can still retrieve bindings for implicit bindings (bindings created
+ through a linked binding) if explicit bindings are required, however
+ {@link Binding#getProvider} will fail.
+ <p>
+ By default, explicit bindings are not required.
+ <p>
+ If a parent injector requires explicit bindings, then all child injectors
+ (and private modules within that injector) also require explicit bindings.
+ If a parent does not require explicit bindings, a child injector or private
+ module may optionally declare itself as requiring explicit bindings. If it
+ does, the behavior is limited only to that child or any grandchildren. No
+ siblings of the child will require explicit bindings.
+ <p>
+ In the absence of an explicit binding for the target, linked bindings in
+ child injectors create a binding for the target in the parent. Since this
+ behavior can be surprising, it causes an error instead if explicit bindings
+ are required. To avoid this error, add an explicit binding for the target,
+ either in the child or the parent.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="disableCircularProxies"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Prevents Guice from injecting dependencies that form a cycle, unless broken by a
+ {@link Provider}. By default, circular dependencies are not disabled.
+ <p>
+ If a parent injector disables circular dependencies, then all child injectors (and private
+ modules within that injector) also disable circular dependencies. If a parent does not disable
+ circular dependencies, a child injector or private module may optionally declare itself as
+ disabling circular dependencies. If it does, the behavior is limited only to that child or any
+ grandchildren. No siblings of the child will disable circular dependencies.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="requireAtInjectOnConstructors"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Requires that a {@literal @}{@link Inject} annotation exists on a constructor in order for
+ Guice to consider it an eligible injectable class. By default, Guice will inject classes that
+ have a no-args constructor if no {@literal @}{@link Inject} annotation exists on any
+ constructor.
+ <p>
+ If the class is bound using {@link LinkedBindingBuilder#toConstructor}, Guice will still inject
+ that constructor regardless of annotations.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="requireExactBindingAnnotations"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Requires that Guice finds an exactly matching binding annotation.  This disables the
+ error-prone feature in Guice where it can substitute a binding for
+ <code>{@literal @}Named Foo</code> when attempting to inject
+ <code>{@literal @}Named("foo") Foo</code>.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="scanModulesForAnnotatedMethods"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scanner" type="com.google.inject.spi.ModuleAnnotatedMethodScanner"/>
+      <doc>
+      <![CDATA[Adds a scanner that will look in all installed modules for annotations the scanner can parse,
+ and binds them like {@literal @}Provides methods. Scanners apply to all modules installed in
+ the injector. Scanners installed in child injectors or private modules do not impact modules in
+ siblings or parents, however scanners installed in parents do apply to all child injectors and
+ private modules.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Collects configuration information (primarily <i>bindings</i>) which will be
+ used to create an {@link Injector}. Guice provides this object to your
+ application's {@link Module} implementors so they may each contribute
+ their own bindings and other registrations.
+
+ <h3>The Guice Binding EDSL</h3>
+
+ Guice uses an <i>embedded domain-specific language</i>, or EDSL, to help you
+ create bindings simply and readably.  This approach is great for overall
+ usability, but it does come with a small cost: <b>it is difficult to
+ learn how to use the Binding EDSL by reading
+ method-level javadocs</b>.  Instead, you should consult the series of
+ examples below.  To save space, these examples omit the opening
+ {@code binder}, just as you will if your module extends
+ {@link AbstractModule}.
+
+ <pre>
+     bind(ServiceImpl.class);</pre>
+
+ This statement does essentially nothing; it "binds the {@code ServiceImpl}
+ class to itself" and does not change Guice's default behavior.  You may still
+ want to use this if you prefer your {@link Module} class to serve as an
+ explicit <i>manifest</i> for the services it provides.  Also, in rare cases,
+ Guice may be unable to validate a binding at injector creation time unless it
+ is given explicitly.
+
+ <pre>
+     bind(Service.class).to(ServiceImpl.class);</pre>
+
+ Specifies that a request for a {@code Service} instance with no binding
+ annotations should be treated as if it were a request for a
+ {@code ServiceImpl} instance. This <i>overrides</i> the function of any
+ {@link ImplementedBy @ImplementedBy} or {@link ProvidedBy @ProvidedBy}
+ annotations found on {@code Service}, since Guice will have already
+ "moved on" to {@code ServiceImpl} before it reaches the point when it starts
+ looking for these annotations.
+
+ <pre>
+     bind(Service.class).toProvider(ServiceProvider.class);</pre>
+
+ In this example, {@code ServiceProvider} must extend or implement
+ {@code Provider<Service>}. This binding specifies that Guice should resolve
+ an unannotated injection request for {@code Service} by first resolving an
+ instance of {@code ServiceProvider} in the regular way, then calling
+ {@link Provider#get get()} on the resulting Provider instance to obtain the
+ {@code Service} instance.
+
+ <p>The {@link Provider} you use here does not have to be a "factory"; that
+ is, a provider which always <i>creates</i> each instance it provides.
+ However, this is generally a good practice to follow.  You can then use
+ Guice's concept of {@link Scope scopes} to guide when creation should happen
+ -- "letting Guice work for you".
+
+ <pre>
+     bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);</pre>
+
+ Like the previous example, but only applies to injection requests that use
+ the binding annotation {@code @Red}.  If your module also includes bindings
+ for particular <i>values</i> of the {@code @Red} annotation (see below),
+ then this binding will serve as a "catch-all" for any values of {@code @Red}
+ that have no exact match in the bindings.
+ 
+ <pre>
+     bind(ServiceImpl.class).in(Singleton.class);
+     // or, alternatively
+     bind(ServiceImpl.class).in(Scopes.SINGLETON);</pre>
+
+ Either of these statements places the {@code ServiceImpl} class into
+ singleton scope.  Guice will create only one instance of {@code ServiceImpl}
+ and will reuse it for all injection requests of this type.  Note that it is
+ still possible to bind another instance of {@code ServiceImpl} if the second
+ binding is qualified by an annotation as in the previous example.  Guice is
+ not overly concerned with <i>preventing</i> you from creating multiple
+ instances of your "singletons", only with <i>enabling</i> your application to
+ share only one instance if that's all you tell Guice you need.
+
+ <p><b>Note:</b> a scope specified in this way <i>overrides</i> any scope that
+ was specified with an annotation on the {@code ServiceImpl} class.
+ 
+ <p>Besides {@link Singleton}/{@link Scopes#SINGLETON}, there are
+ servlet-specific scopes available in
+ {@code com.google.inject.servlet.ServletScopes}, and your Modules can
+ contribute their own custom scopes for use here as well.
+
+ <pre>
+     bind(new TypeLiteral&lt;PaymentService&lt;CreditCard>>() {})
+         .to(CreditCardPaymentService.class);</pre>
+
+ This admittedly odd construct is the way to bind a parameterized type. It
+ tells Guice how to honor an injection request for an element of type
+ {@code PaymentService<CreditCard>}. The class
+ {@code CreditCardPaymentService} must implement the
+ {@code PaymentService<CreditCard>} interface.  Guice cannot currently bind or
+ inject a generic type, such as {@code Set<E>}; all type parameters must be
+ fully specified.
+
+ <pre>
+     bind(Service.class).toInstance(new ServiceImpl());
+     // or, alternatively
+     bind(Service.class).toInstance(SomeLegacyRegistry.getService());</pre>
+
+ In this example, your module itself, <i>not Guice</i>, takes responsibility
+ for obtaining a {@code ServiceImpl} instance, then asks Guice to always use
+ this single instance to fulfill all {@code Service} injection requests.  When
+ the {@link Injector} is created, it will automatically perform field
+ and method injection for this instance, but any injectable constructor on
+ {@code ServiceImpl} is simply ignored.  Note that using this approach results
+ in "eager loading" behavior that you can't control.
+
+ <pre>
+     bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre>
+
+ Sets up a constant binding. Constant injections must always be annotated.
+ When a constant binding's value is a string, it is eligile for conversion to
+ all primitive types, to {@link Enum#valueOf(Class, String) all enums}, and to
+ {@link Class#forName class literals}. Conversions for other types can be
+ configured using {@link #convertToTypes(Matcher, TypeConverter)
+ convertToTypes()}.
+
+ <pre>
+   {@literal @}Color("red") Color red; // A member variable (field)
+    . . .
+     red = MyModule.class.getDeclaredField("red").getAnnotation(Color.class);
+     bind(Service.class).annotatedWith(red).to(RedService.class);</pre>
+
+ If your binding annotation has parameters you can apply different bindings to
+ different specific values of your annotation.  Getting your hands on the
+ right instance of the annotation is a bit of a pain -- one approach, shown
+ above, is to apply a prototype annotation to a field in your module class, so
+ that you can read this annotation instance and give it to Guice.
+
+ <pre>
+     bind(Service.class)
+         .annotatedWith(Names.named("blue"))
+         .to(BlueService.class);</pre>
+
+ Differentiating by names is a common enough use case that we provided a
+ standard annotation, {@link com.google.inject.name.Named @Named}.  Because of
+ Guice's library support, binding by name is quite easier than in the
+ arbitrary binding annotation case we just saw.  However, remember that these
+ names will live in a single flat namespace with all the other names used in
+ your application.
+
+ <pre>
+     Constructor<T> loneCtor = getLoneCtorFromServiceImplViaReflection();
+     bind(ServiceImpl.class)
+         .toConstructor(loneCtor);</pre>
+
+ In this example, we directly tell Guice which constructor to use in a concrete
+ class implementation. It means that we do not need to place {@literal @}Inject
+ on any of the constructors and that Guice treats the provided constructor as though
+ it were annotated so. It is useful for cases where you cannot modify existing
+ classes and is a bit simpler than using a {@link Provider}.
+
+ <p>The above list of examples is far from exhaustive.  If you can think of
+ how the concepts of one example might coexist with the concepts from another,
+ you can most likely weave the two together.  If the two concepts make no
+ sense with each other, you most likely won't be able to do it.  In a few
+ cases Guice will let something bogus slip by, and will then inform you of
+ the problems at runtime, as soon as you try to create your Injector.
+
+ <p>The other methods of Binder such as {@link #bindScope},
+ {@link #bindInterceptor}, {@link #install}, {@link #requestStaticInjection},
+ {@link #addError} and {@link #currentStage} are not part of the Binding EDSL;
+ you can learn how to use these in the usual way, from the method
+ documentation.
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)
+ @author kevinb@google.com (Kevin Bourrillion)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Binder -->
+  <!-- start interface com.google.inject.Binding -->
+  <interface name="Binding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key for this binding.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the scoped provider guice uses to fulfill requests for this
+ binding.
+
+ @throws UnsupportedOperationException when invoked on a {@link Binding}
+      created via {@link com.google.inject.spi.Elements#getElements}. This
+      method is only supported on {@link Binding}s returned from an injector.]]>
+      </doc>
+    </method>
+    <method name="acceptTargetVisitor" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.BindingTargetVisitor&lt;? super T, V&gt;"/>
+      <doc>
+      <![CDATA[Accepts a target visitor. Invokes the visitor method specific to this binding's target.
+
+ @param visitor to call back on
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="acceptScopingVisitor" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.BindingScopingVisitor&lt;V&gt;"/>
+      <doc>
+      <![CDATA[Accepts a scoping visitor. Invokes the visitor method specific to this binding's scoping.
+
+ @param visitor to call back on
+ @since 2.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A mapping from a key (type and optional annotation) to the strategy for getting instances of the
+ type. This interface is part of the introspection API and is intended primarily for use by 
+ tools.
+
+ <p>Bindings are created in several ways:
+ <ul>
+     <li>Explicitly in a module, via {@code bind()} and {@code bindConstant()}
+         statements:
+ <pre>
+     bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);
+     bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre></li>
+     <li>Implicitly by the Injector by following a type's {@link ImplementedBy
+         pointer} {@link ProvidedBy annotations} or by using its {@link Inject annotated} or
+         default constructor.</li>
+     <li>By converting a bound instance to a different type.</li>
+     <li>For {@link Provider providers}, by delegating to the binding for the provided type.</li>
+ </ul>
+
+
+ <p>They exist on both modules and on injectors, and their behaviour is different for each:
+ <ul>
+     <li><strong>Module bindings</strong> are incomplete and cannot be used to provide instances.
+         This is because the applicable scopes and interceptors may not be known until an injector
+         is created. From a tool's perspective, module bindings are like the injector's source
+         code. They can be inspected or rewritten, but this analysis must be done statically.</li>
+     <li><strong>Injector bindings</strong> are complete and valid and can be used to provide
+         instances. From a tools' perspective, injector bindings are like reflection for an
+         injector. They have full runtime information, including the complete graph of injections
+         necessary to satisfy a binding.</li>
+ </ul>
+
+ @param <T> the bound type. The injected is always assignable to this type.
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Binding -->
+  <!-- start class com.google.inject.BindingAnnotation -->
+  <class name="BindingAnnotation"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates annotations which are used for binding. Only one such annotation
+ may apply to a single injection point. You must also annotate binder
+ annotations with {@code @Retention(RUNTIME)}. For example:
+
+ <pre>
+   {@code @}Retention(RUNTIME)
+   {@code @}Target({ FIELD, PARAMETER, METHOD })
+   {@code @}BindingAnnotation
+   public {@code @}interface Transactional {}
+ </pre>
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.BindingAnnotation -->
+  <!-- start class com.google.inject.ConfigurationException -->
+  <class name="ConfigurationException" extends="java.lang.RuntimeException"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ConfigurationException" type="java.lang.Iterable&lt;com.google.inject.spi.Message&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Creates a ConfigurationException containing {@code messages}.]]>
+      </doc>
+    </constructor>
+    <method name="withPartialValue" return="com.google.inject.ConfigurationException"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="partialValue" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns a copy of this configuration exception with the specified partial value.]]>
+      </doc>
+    </method>
+    <method name="getErrorMessages" return="java.util.Collection&lt;com.google.inject.spi.Message&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns messages for the errors that caused this exception.]]>
+      </doc>
+    </method>
+    <method name="getPartialValue" return="E"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a value that was only partially computed due to this exception. The caller can use
+ this while collecting additional configuration problems.
+
+ @return the partial value, or {@code null} if none was set. The type of the partial value is
+      specified by the throwing method.]]>
+      </doc>
+    </method>
+    <method name="getMessage" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Thrown when a programming error such as a misplaced annotation, illegal binding, or unsupported
+ scope is found. Clients should catch this exception, log it, and stop execution.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.ConfigurationException -->
+  <!-- start class com.google.inject.CreationException -->
+  <class name="CreationException" extends="java.lang.RuntimeException"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="CreationException" type="java.util.Collection&lt;com.google.inject.spi.Message&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Creates a CreationException containing {@code messages}.]]>
+      </doc>
+    </constructor>
+    <method name="getErrorMessages" return="java.util.Collection&lt;com.google.inject.spi.Message&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns messages for the errors that caused this exception.]]>
+      </doc>
+    </method>
+    <method name="getMessage" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Thrown when errors occur while creating a {@link Injector}. Includes a list of encountered
+ errors. Clients should catch this exception, log it, and stop execution.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.CreationException -->
+  <!-- start class com.google.inject.Exposed -->
+  <class name="Exposed"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Acccompanies a {@literal @}{@link com.google.inject.Provides Provides} method annotation in a
+ private module to indicate that the provided binding is exposed.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Exposed -->
+  <!-- start class com.google.inject.Guice -->
+  <class name="Guice" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="createInjector" return="com.google.inject.Injector"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Creates an injector for the given set of modules. This is equivalent to
+ calling {@link #createInjector(Stage, Module...)} with Stage.DEVELOPMENT.
+
+ @throws CreationException if one or more errors occur during injector
+     construction]]>
+      </doc>
+    </method>
+    <method name="createInjector" return="com.google.inject.Injector"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Creates an injector for the given set of modules. This is equivalent to
+ calling {@link #createInjector(Stage, Iterable)} with Stage.DEVELOPMENT.
+
+ @throws CreationException if one or more errors occur during injector
+     creation]]>
+      </doc>
+    </method>
+    <method name="createInjector" return="com.google.inject.Injector"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="stage" type="com.google.inject.Stage"/>
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Creates an injector for the given set of modules, in a given development
+ stage.
+
+ @throws CreationException if one or more errors occur during injector
+     creation.]]>
+      </doc>
+    </method>
+    <method name="createInjector" return="com.google.inject.Injector"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="stage" type="com.google.inject.Stage"/>
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Creates an injector for the given set of modules, in a given development
+ stage.
+
+ @throws CreationException if one or more errors occur during injector
+     construction]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[The entry point to the Guice framework. Creates {@link Injector}s from
+ {@link Module}s.
+
+ <p>Guice supports a model of development that draws clear boundaries between
+ APIs, Implementations of these APIs, Modules which configure these
+ implementations, and finally Applications which consist of a collection of
+ Modules. It is the Application, which typically defines your {@code main()}
+ method, that bootstraps the Guice Injector using the {@code Guice} class, as
+ in this example:
+ <pre>
+     public class FooApplication {
+       public static void main(String[] args) {
+         Injector injector = Guice.createInjector(
+             new ModuleA(),
+             new ModuleB(),
+             . . .
+             new FooApplicationFlagsModule(args)
+         );
+
+         // Now just bootstrap the application and you're done
+         FooStarter starter = injector.getInstance(FooStarter.class);
+         starter.runApplication();
+       }
+     }
+ </pre>]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Guice -->
+  <!-- start class com.google.inject.ImplementedBy -->
+  <class name="ImplementedBy"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[A pointer to the default implementation of a type.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.ImplementedBy -->
+  <!-- start class com.google.inject.Inject -->
+  <class name="Inject"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates members of your implementation class (constructors, methods
+ and fields) into which the {@link Injector} should inject values.
+ The Injector fulfills injection requests for:
+
+ <ul>
+ <li>Every instance it constructs. The class being constructed must have
+ exactly one of its constructors marked with {@code @Inject} or must have a
+ constructor taking no parameters. The Injector then proceeds to perform
+ field and method injections.
+ 
+ <li>Pre-constructed instances passed to {@link Injector#injectMembers},
+ {@link com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and
+ {@link com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}.
+ In this case all constructors are, of course, ignored.
+
+ <li>Static fields and methods of classes which any {@link Module} has
+ specifically requested static injection for, using
+ {@link Binder#requestStaticInjection}.
+ </ul>
+
+ In all cases, a member can be injected regardless of its Java access
+ specifier (private, default, protected, public).
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Inject -->
+  <!-- start interface com.google.inject.Injector -->
+  <interface name="Injector"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="injectMembers"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
+ absence of an injectable constructor.
+
+ <p>Whenever Guice creates an instance, it performs this injection automatically (after first
+ performing constructor injection), so if you're able to let Guice create all your objects for
+ you, you'll never need to use this method.
+
+ @param instance to inject members on
+
+ @see Binder#getMembersInjector(Class) for a preferred alternative that supports checks before
+  run time]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}.
+
+ @param typeLiteral type to get members injector for
+ @see Binder#getMembersInjector(TypeLiteral) for an alternative that offers up front error
+  detection
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}. When feasible, use {@link Binder#getMembersInjector(TypeLiteral)}
+ instead to get increased up front error detection.
+
+ @param type type to get members injector for
+ @see Binder#getMembersInjector(Class) for an alternative that offers up front error
+  detection
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getBindings" return="java.util.Map&lt;com.google.inject.Key&lt;?&gt;, com.google.inject.Binding&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns this injector's <strong>explicit</strong> bindings.
+
+ <p>The returned map does not include bindings inherited from a {@link #getParent() parent
+ injector}, should one exist. The returned map is guaranteed to iterate (for example, with
+ its {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in
+ which bindings appear in user Modules.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.]]>
+      </doc>
+    </method>
+    <method name="getAllBindings" return="java.util.Map&lt;com.google.inject.Key&lt;?&gt;, com.google.inject.Binding&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a snapshot of this injector's bindings, <strong>both explicit and
+ just-in-time</strong>. The returned map is immutable; it contains only the bindings that were
+ present when {@code getAllBindings()} was invoked. Subsequent calls may return a map with
+ additional just-in-time bindings.
+
+ <p>The returned map does not include bindings inherited from a {@link #getParent() parent
+ injector}, should one exist.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="getBinding" return="com.google.inject.Binding&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the binding for the given injection key. This will be an explicit bindings if the key
+ was bound explicitly by a module, or an implicit binding otherwise. The implicit binding will
+ be created if necessary.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+
+ @throws ConfigurationException if this injector cannot find or create the binding.]]>
+      </doc>
+    </method>
+    <method name="getBinding" return="com.google.inject.Binding&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the binding for the given type. This will be an explicit bindings if the injection key
+ was bound explicitly by a module, or an implicit binding otherwise. The implicit binding will
+ be created if necessary.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+
+ @throws ConfigurationException if this injector cannot find or create the binding.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getExistingBinding" return="com.google.inject.Binding&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the binding if it already exists, or null if does not exist. Unlike
+ {@link #getBinding(Key)}, this does not attempt to create just-in-time bindings
+ for keys that aren't bound.
+ 
+ <p> This method is part of the Guice SPI and is intended for use by tools and extensions.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="findBindingsByType" return="java.util.List&lt;com.google.inject.Binding&lt;T&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns all explicit bindings for {@code type}.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection key. When feasible, avoid
+ using this method, in favor of having Guice inject your dependencies ahead of time.
+
+ @throws ConfigurationException if this injector cannot find or create the provider.
+ @see Binder#getProvider(Key) for an alternative that offers up front error detection]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given type. When feasible, avoid
+ using this method, in favor of having Guice inject your dependencies ahead of time.
+
+ @throws ConfigurationException if this injector cannot find or create the provider.
+ @see Binder#getProvider(Class) for an alternative that offers up front error detection]]>
+      </doc>
+    </method>
+    <method name="getInstance" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the appropriate instance for the given injection key; equivalent to {@code
+ getProvider(key).get()}. When feasible, avoid using this method, in favor of having Guice
+ inject your dependencies ahead of time.
+
+ @throws ConfigurationException if this injector cannot find or create the provider.
+ @throws ProvisionException if there was a runtime failure while providing an instance.]]>
+      </doc>
+    </method>
+    <method name="getInstance" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the appropriate instance for the given injection type; equivalent to {@code
+ getProvider(type).get()}. When feasible, avoid using this method, in favor of having Guice
+ inject your dependencies ahead of time.
+
+ @throws ConfigurationException if this injector cannot find or create the provider.
+ @throws ProvisionException if there was a runtime failure while providing an instance.]]>
+      </doc>
+    </method>
+    <method name="getParent" return="com.google.inject.Injector"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns this injector's parent, or {@code null} if this is a top-level injector.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="createChildInjector" return="com.google.inject.Injector"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injector that inherits all state from this injector. All bindings, scopes,
+ interceptors and type converters are inherited -- they are visible to the child injector.
+ Elements of the child injector are not visible to its parent.
+
+ <p>Just-in-time bindings created for child injectors will be created in an ancestor injector
+ whenever possible. This allows for scoped instances to be shared between injectors. Use
+ explicit bindings to prevent bindings from being shared with the parent injector.  Optional
+ injections in just-in-time bindings (created in the parent injector) may be silently
+ ignored if the optional dependencies are from the child injector.
+
+ <p>No key may be bound by both an injector and one of its ancestors. This includes just-in-time
+ bindings. The lone exception is the key for {@code Injector.class}, which is bound by each
+ injector to itself.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="createChildInjector" return="com.google.inject.Injector"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Returns a new injector that inherits all state from this injector. All bindings, scopes,
+ interceptors and type converters are inherited -- they are visible to the child injector.
+ Elements of the child injector are not visible to its parent.
+
+ <p>Just-in-time bindings created for child injectors will be created in an ancestor injector
+ whenever possible. This allows for scoped instances to be shared between injectors. Use
+ explicit bindings to prevent bindings from being shared with the parent injector.
+
+ <p>No key may be bound by both an injector and one of its ancestors. This includes just-in-time
+ bindings. The lone exception is the key for {@code Injector.class}, which is bound by each
+ injector to itself.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getScopeBindings" return="java.util.Map&lt;java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;, com.google.inject.Scope&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a map containing all scopes in the injector. The maps keys are scoping annotations
+ like {@code Singleton.class}, and the values are scope instances, such as {@code
+ Scopes.SINGLETON}. The returned map is immutable.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="getTypeConverterBindings" return="java.util.Set&lt;com.google.inject.spi.TypeConverterBinding&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a set containing all type converter bindings in the injector. The returned set is
+ immutable.
+
+ <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Builds the graphs of objects that make up your application. The injector tracks the dependencies
+ for each type and uses bindings to inject them. This is the core of Guice, although you rarely
+ interact with it directly. This "behind-the-scenes" operation is what distinguishes dependency
+ injection from its cousin, the service locator pattern.
+
+ <p>Contains several default bindings:
+
+ <ul>
+ <li>This {@link Injector} instance itself
+ <li>A {@code Provider<T>} for each binding of type {@code T}
+ <li>The {@link java.util.logging.Logger} for the class being injected
+ <li>The {@link Stage} in which the Injector was created
+ </ul>
+
+ Injectors are created using the facade class {@link Guice}.
+
+ <p>An injector can also {@link #injectMembers(Object) inject the dependencies} of
+ already-constructed instances. This can be used to interoperate with objects created by other
+ frameworks or services.
+
+ <p>Injectors can be {@link #createChildInjector(Iterable) hierarchical}. Child injectors inherit
+ the configuration of their parent injectors, but the converse does not hold.
+
+ <p>The injector's {@link #getBindings() internal bindings} are available for introspection. This
+ enables tools and extensions to operate on an injector reflectively.
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Injector -->
+  <!-- start class com.google.inject.Key -->
+  <class name="Key" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Key" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Constructs a new key. Derives the type from this class's type parameter.
+
+ <p>Clients create an empty anonymous subclass. Doing so embeds the type
+ parameter in the anonymous class's type hierarchy so we can reconstitute it
+ at runtime despite erasure.
+
+ <p>Example usage for a binding of type {@code Foo} annotated with
+ {@code @Bar}:
+
+ <p>{@code new Key<Foo>(Bar.class) {}}.]]>
+      </doc>
+    </constructor>
+    <constructor name="Key" type="java.lang.annotation.Annotation"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Constructs a new key. Derives the type from this class's type parameter.
+
+ <p>Clients create an empty anonymous subclass. Doing so embeds the type
+ parameter in the anonymous class's type hierarchy so we can reconstitute it
+ at runtime despite erasure.
+
+ <p>Example usage for a binding of type {@code Foo} annotated with
+ {@code @Bar}:
+
+ <p>{@code new Key<Foo>(new Bar()) {}}.]]>
+      </doc>
+    </constructor>
+    <constructor name="Key"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Constructs a new key. Derives the type from this class's type parameter.
+
+ <p>Clients create an empty anonymous subclass. Doing so embeds the type
+ parameter in the anonymous class's type hierarchy so we can reconstitute it
+ at runtime despite erasure.
+
+ <p>Example usage for a binding of type {@code Foo}:
+
+ <p>{@code new Key<Foo>() {}}.]]>
+      </doc>
+    </constructor>
+    <method name="getTypeLiteral" return="com.google.inject.TypeLiteral&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the key type.]]>
+      </doc>
+    </method>
+    <method name="getAnnotationType" return="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the annotation type.]]>
+      </doc>
+    </method>
+    <method name="getAnnotation" return="java.lang.annotation.Annotation"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the annotation.]]>
+      </doc>
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="o" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation type.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Gets a key for an injection type and an annotation.]]>
+      </doc>
+    </method>
+    <method name="ofType" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new key of the specified type with the same annotation as this
+ key.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="ofType" return="com.google.inject.Key&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a new key of the specified type with the same annotation as this
+ key.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="ofType" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new key of the specified type with the same annotation as this
+ key.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="hasAttributes" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if this key has annotation attributes.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="withoutAttributes" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns this key without annotation attributes, i.e. with only the
+ annotation type.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Binding key consisting of an injection type and an optional annotation.
+ Matches the type and annotation at a point of injection.
+
+ <p>For example, {@code Key.get(Service.class, Transactional.class)} will
+ match:
+
+ <pre>
+   {@literal @}Inject
+   public void setService({@literal @}Transactional Service service) {
+     ...
+   }
+ </pre>
+
+ <p>{@code Key} supports generic types via subclassing just like {@link
+ TypeLiteral}.
+
+ <p>Keys do not differentiate between primitive types (int, char, etc.) and
+ their corresponding wrapper types (Integer, Character, etc.). Primitive
+ types will be replaced with their wrapper types when keys are created.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Key -->
+  <!-- start interface com.google.inject.MembersInjector -->
+  <interface name="MembersInjector"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="injectMembers"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="T"/>
+      <doc>
+      <![CDATA[Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
+ absence of an injectable constructor.
+
+ <p>Whenever Guice creates an instance, it performs this injection automatically (after first
+ performing constructor injection), so if you're able to let Guice create all your objects for
+ you, you'll never need to use this method.
+
+ @param instance to inject members on. May be {@code null}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[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 crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.MembersInjector -->
+  <!-- start interface com.google.inject.Module -->
+  <interface name="Module"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="configure"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <doc>
+      <![CDATA[Contributes bindings and other configurations for this module to {@code binder}.
+
+ <p><strong>Do not invoke this method directly</strong> to install submodules. Instead use
+ {@link Binder#install(Module)}, which ensures that {@link Provides provider methods} are
+ discovered.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A module contributes configuration information, typically interface
+ bindings, which will be used to create an {@link Injector}. A Guice-based
+ application is ultimately composed of little more than a set of
+ {@code Module}s and some bootstrapping code.
+
+ <p>Your Module classes can use a more streamlined syntax by extending
+ {@link AbstractModule} rather than implementing this interface directly.
+
+ <p>In addition to the bindings configured via {@link #configure}, bindings
+ will be created for all methods annotated with {@literal @}{@link Provides}.
+ Use scope and binding annotations on these methods to configure the
+ bindings.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Module -->
+  <!-- start class com.google.inject.OutOfScopeException -->
+  <class name="OutOfScopeException" extends="java.lang.RuntimeException"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="OutOfScopeException" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="OutOfScopeException" type="java.lang.String, java.lang.Throwable"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="OutOfScopeException" type="java.lang.Throwable"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[Thrown from {@link Provider#get} when an attempt is made to access a scoped
+ object while the scope in question is not currently active.
+
+ @author kevinb@google.com (Kevin Bourrillion)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.OutOfScopeException -->
+  <!-- start interface com.google.inject.PrivateBinder -->
+  <interface name="PrivateBinder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binder"/>
+    <method name="expose"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Makes the binding for {@code key} available to the enclosing environment]]>
+      </doc>
+    </method>
+    <method name="expose" return="com.google.inject.binder.AnnotatedElementBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Makes a binding for {@code type} available to the enclosing environment. Use {@link
+ com.google.inject.binder.AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to expose {@code type} with a
+ binding annotation.]]>
+      </doc>
+    </method>
+    <method name="expose" return="com.google.inject.binder.AnnotatedElementBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Makes a binding for {@code type} available to the enclosing environment. Use {@link
+ AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to expose {@code type} with a
+ binding annotation.]]>
+      </doc>
+    </method>
+    <method name="withSource" return="com.google.inject.PrivateBinder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Object"/>
+    </method>
+    <method name="skipSources" return="com.google.inject.PrivateBinder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="classesToSkip" type="java.lang.Class[]"/>
+    </method>
+    <doc>
+    <![CDATA[Returns a binder whose configuration information is hidden from its environment by default. See
+ {@link com.google.inject.PrivateModule PrivateModule} for details.
+ 
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.PrivateBinder -->
+  <!-- start class com.google.inject.PrivateModule -->
+  <class name="PrivateModule" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Module"/>
+    <constructor name="PrivateModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="true"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="configure"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Creates bindings and other configurations private to this module. Use {@link #expose(Class)
+ expose()} to make the bindings in this module available externally.]]>
+      </doc>
+    </method>
+    <method name="expose"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Makes the binding for {@code key} available to other modules and the injector.]]>
+      </doc>
+    </method>
+    <method name="expose" return="com.google.inject.binder.AnnotatedElementBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Makes a binding for {@code type} available to other modules and the injector. Use {@link
+ AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to expose {@code type} with a
+ binding annotation.]]>
+      </doc>
+    </method>
+    <method name="expose" return="com.google.inject.binder.AnnotatedElementBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Makes a binding for {@code type} available to other modules and the injector. Use {@link
+ AnnotatedElementBuilder#annotatedWith(Class) annotatedWith()} to expose {@code type} with a
+ binding annotation.]]>
+      </doc>
+    </method>
+    <method name="binder" return="com.google.inject.PrivateBinder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the current binder.]]>
+      </doc>
+    </method>
+    <method name="bindScope"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="scope" type="com.google.inject.Scope"/>
+      <doc>
+      <![CDATA[@see Binder#bindScope(Class, Scope)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(Key)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(TypeLiteral)]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.binder.AnnotatedBindingBuilder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="clazz" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#bind(Class)]]>
+      </doc>
+    </method>
+    <method name="bindConstant" return="com.google.inject.binder.AnnotatedConstantBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@see Binder#bindConstant()]]>
+      </doc>
+    </method>
+    <method name="install"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="module" type="com.google.inject.Module"/>
+      <doc>
+      <![CDATA[@see Binder#install(Module)]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="message" type="java.lang.String"/>
+      <param name="arguments" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[@see Binder#addError(String, Object[])]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="t" type="java.lang.Throwable"/>
+      <doc>
+      <![CDATA[@see Binder#addError(Throwable)]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+      <doc>
+      <![CDATA[@see Binder#addError(Message)]]>
+      </doc>
+    </method>
+    <method name="requestInjection"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[@see Binder#requestInjection(Object)]]>
+      </doc>
+    </method>
+    <method name="requestStaticInjection"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="types" type="java.lang.Class[]"/>
+      <doc>
+      <![CDATA[@see Binder#requestStaticInjection(Class[])]]>
+      </doc>
+    </method>
+    <method name="bindInterceptor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="classMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.Class&lt;?&gt;&gt;"/>
+      <param name="methodMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.reflect.Method&gt;"/>
+      <param name="interceptors" type="org.aopalliance.intercept.MethodInterceptor[]"/>
+      <doc>
+      <![CDATA[@see Binder#bindInterceptor(com.google.inject.matcher.Matcher, com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])]]>
+      </doc>
+    </method>
+    <method name="requireBinding"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Instructs Guice to require a binding to the given key.]]>
+      </doc>
+    </method>
+    <method name="requireBinding"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Instructs Guice to require a binding to the given type.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getProvider(Key)]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getProvider(Class)]]>
+      </doc>
+    </method>
+    <method name="convertToTypes"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="converter" type="com.google.inject.spi.TypeConverter"/>
+      <doc>
+      <![CDATA[@see Binder#convertToTypes(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeConverter)]]>
+      </doc>
+    </method>
+    <method name="currentStage" return="com.google.inject.Stage"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@see Binder#currentStage()]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getMembersInjector(Class)]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@see Binder#getMembersInjector(TypeLiteral)]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="typeMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"/>
+      <param name="listener" type="com.google.inject.spi.TypeListener"/>
+      <doc>
+      <![CDATA[@see Binder#bindListener(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeListener)]]>
+      </doc>
+    </method>
+    <method name="bindListener"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="bindingMatcher" type="com.google.inject.matcher.Matcher&lt;? super com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <param name="listeners" type="com.google.inject.spi.ProvisionListener[]"/>
+      <doc>
+      <![CDATA[@see Binder#bindListener(Matcher, ProvisionListener...)
+ @since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A module whose configuration information is hidden from its environment by default. Only bindings
+ that are explicitly exposed will be available to other modules and to the users of the injector.
+ This module may expose the bindings it creates and the bindings of the modules it installs.
+
+ <p>A private module can be nested within a regular module or within another private module using
+ {@link Binder#install install()}.  Its bindings live in a new environment that inherits bindings,
+ type converters, scopes, and interceptors from the surrounding ("parent") environment.  When you
+ nest multiple private modules, the result is a tree of environments where the injector's
+ environment is the root.
+
+ <p>Guice EDSL bindings can be exposed with {@link #expose(Class) expose()}. {@literal @}{@link
+ com.google.inject.Provides Provides} bindings can be exposed with the {@literal @}{@link
+ Exposed} annotation:
+
+ <pre>
+ public class FooBarBazModule extends PrivateModule {
+   protected void configure() {
+     bind(Foo.class).to(RealFoo.class);
+     expose(Foo.class);
+
+     install(new TransactionalBarModule());
+     expose(Bar.class).annotatedWith(Transactional.class);
+
+     bind(SomeImplementationDetail.class);
+     install(new MoreImplementationDetailsModule());
+   }
+
+   {@literal @}Provides {@literal @}Exposed
+   public Baz provideBaz() {
+     return new SuperBaz();
+   }
+ }
+ </pre>
+
+ <p>Private modules are implemented using {@link Injector#createChildInjector(Module[]) parent
+ injectors}. When it can satisfy their dependencies, just-in-time bindings will be created in the
+ root environment. Such bindings are shared among all environments in the tree.
+ 
+ <p>The scope of a binding is constrained to its environment. A singleton bound in a private
+ module will be unique to its environment. But a binding for the same type in a different private
+ module will yield a different instance.
+
+ <p>A shared binding that injects the {@code Injector} gets the root injector, which only has
+ access to bindings in the root environment. An explicit binding that injects the {@code Injector}
+ gets access to all bindings in the child environment.
+
+ <p>To promote a just-in-time binding to an explicit binding, bind it:
+ <pre>
+   bind(FooImpl.class);
+ </pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.PrivateModule -->
+  <!-- start class com.google.inject.ProvidedBy -->
+  <class name="ProvidedBy"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[A pointer to the default provider type for a type.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.ProvidedBy -->
+  <!-- start interface com.google.inject.Provider -->
+  <interface name="Provider"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="javax.inject.Provider&lt;T&gt;"/>
+    <method name="get" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Provides an instance of {@code T}. Must never return {@code null}.
+
+ @throws OutOfScopeException when an attempt is made to access a scoped object while the scope
+     in question is not currently active
+ @throws ProvisionException if an instance cannot be provided. Such exceptions include messages
+     and throwables to describe why provision failed.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An object capable of providing instances of type {@code T}. Providers are used in numerous ways
+ by Guice:
+
+ <ul>
+ <li>When the default means for obtaining instances (an injectable or parameterless constructor)
+ is insufficient for a particular binding, the module can specify a custom {@code Provider}
+ instead, to control exactly how Guice creates or obtains instances for the binding.
+
+ <li>An implementation class may always choose to have a {@code Provider<T>} instance injected,
+ rather than having a {@code T} injected directly.  This may give you access to multiple
+ instances, instances you wish to safely mutate and discard, instances which are out of scope
+ (e.g. using a {@code @RequestScoped} object from within a {@code @SessionScoped} object), or
+ instances that will be initialized lazily.
+
+ <li>A custom {@link Scope} is implemented as a decorator of {@code Provider<T>}, which decides
+ when to delegate to the backing provider and when to provide the instance some other way.
+
+ <li>The {@link Injector} offers access to the {@code Provider<T>} it uses to fulfill requests
+ for a given key, via the {@link Injector#getProvider} methods.
+ </ul>
+
+ @param <T> the type of object this provides
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Provider -->
+  <!-- start class com.google.inject.Provides -->
+  <class name="Provides"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to create a provider method binding. The method's return
+ type is bound to its returned value. Guice will pass dependencies to the method as parameters.
+
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Provides -->
+  <!-- start class com.google.inject.ProvisionException -->
+  <class name="ProvisionException" extends="java.lang.RuntimeException"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ProvisionException" type="java.lang.Iterable&lt;com.google.inject.spi.Message&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Creates a ProvisionException containing {@code messages}.]]>
+      </doc>
+    </constructor>
+    <constructor name="ProvisionException" type="java.lang.String, java.lang.Throwable"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="ProvisionException" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getErrorMessages" return="java.util.Collection&lt;com.google.inject.spi.Message&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns messages for the errors that caused this exception.]]>
+      </doc>
+    </method>
+    <method name="getMessage" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Indicates that there was a runtime failure while providing an instance.
+
+ @author kevinb@google.com (Kevin Bourrillion)
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.ProvisionException -->
+  <!-- start interface com.google.inject.Scope -->
+  <interface name="Scope"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="scope" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <param name="unscoped" type="com.google.inject.Provider&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Scopes a provider. The returned provider returns objects from this scope.
+ If an object does not exist in this scope, the provider can use the given
+ unscoped provider to retrieve one.
+
+ <p>Scope implementations are strongly encouraged to override
+ {@link Object#toString} in the returned provider and include the backing
+ provider's {@code toString()} output.
+
+ @param key binding key
+ @param unscoped locates an instance when one doesn't already exist in this
+  scope.
+ @return a new provider which only delegates to the given unscoped provider
+  when an instance of the requested object doesn't already exist in this
+  scope]]>
+      </doc>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[A short but useful description of this scope.  For comparison, the standard
+ scopes that ship with guice use the descriptions
+ {@code "Scopes.SINGLETON"}, {@code "ServletScopes.SESSION"} and
+ {@code "ServletScopes.REQUEST"}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A scope is a level of visibility that instances provided by Guice may have.
+ By default, an instance created by the {@link Injector} has <i>no scope</i>,
+ meaning it has no state from the framework's perspective -- the
+ {@code Injector} creates it, injects it once into the class that required it,
+ and then immediately forgets it. Associating a scope with a particular
+ binding allows the created instance to be "remembered" and possibly used
+ again for other injections.
+
+ <p>An example of a scope is {@link Scopes#SINGLETON}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.Scope -->
+  <!-- start class com.google.inject.ScopeAnnotation -->
+  <class name="ScopeAnnotation"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates annotations which are used for scoping. Only one such annotation
+ may apply to a single implementation class. You must also annotate scope
+ annotations with {@code @Retention(RUNTIME)}. For example:
+
+ <pre>
+   {@code @}Retention(RUNTIME)
+   {@code @}Target(TYPE, METHOD)
+   {@code @}ScopeAnnotation
+   public {@code @}interface SessionScoped {}
+ </pre>
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.ScopeAnnotation -->
+  <!-- start class com.google.inject.Scopes -->
+  <class name="Scopes" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="isSingleton" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns true if {@code binding} is singleton-scoped. If the binding is a {@link
+ com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (ie. it
+ was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will
+ also true if the target binding is singleton-scoped.
+
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="isScoped" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;?&gt;"/>
+      <param name="scope" type="com.google.inject.Scope"/>
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns true if {@code binding} has the given scope. If the binding is a {@link
+ com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (ie. it
+ was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will
+ also true if the target binding has the given scope.
+
+ @param binding binding to check
+ @param scope scope implementation instance
+ @param scopeAnnotation scope annotation class
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="isCircularProxy" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="object" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns true if the object is a proxy for a circular dependency,
+ constructed by Guice because it encountered a circular dependency. Scope
+ implementations should be careful to <b>not cache circular proxies</b>,
+ because the proxies are not intended for general purpose use. (They are
+ designed just to fulfill the immediate injection, not all injections.
+ Caching them can lead to IllegalArgumentExceptions or ClassCastExceptions.)
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <field name="SINGLETON" type="com.google.inject.Scope"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[One instance per {@link Injector}. Also see {@code @}{@link Singleton}.]]>
+      </doc>
+    </field>
+    <field name="NO_SCOPE" type="com.google.inject.Scope"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[No scope; the same as not applying any scope at all.  Each time the
+ Injector obtains an instance of an object with "no scope", it injects this
+ instance then immediately forgets it.  When the next request for the same
+ binding arrives it will need to obtain the instance over again.
+
+ <p>This exists only in case a class has been annotated with a scope
+ annotation such as {@link Singleton @Singleton}, and you need to override
+ this to "no scope" in your binding.
+
+ @since 2.0]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[Built-in scope implementations.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Scopes -->
+  <!-- start class com.google.inject.Singleton -->
+  <class name="Singleton"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Apply this to implementation classes when you want only one instance
+ (per {@link Injector}) to be reused for all injections for that binding.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Singleton -->
+  <!-- start class com.google.inject.Stage -->
+  <class name="Stage" extends="java.lang.Enum&lt;com.google.inject.Stage&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.Stage[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.Stage"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[The stage we're running in.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.Stage -->
+  <!-- start class com.google.inject.TypeLiteral -->
+  <class name="TypeLiteral" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="TypeLiteral"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Constructs a new type literal. Derives represented class from type
+ parameter.
+
+ <p>Clients create an empty anonymous subclass. Doing so embeds the type
+ parameter in the anonymous class's type hierarchy so we can reconstitute it
+ at runtime despite erasure.]]>
+      </doc>
+    </constructor>
+    <method name="getRawType" return="java.lang.Class&lt;? super T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the raw (non-generic) type for this type.
+ 
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getType" return="java.lang.reflect.Type"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets underlying {@code Type} instance.]]>
+      </doc>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="o" type="java.lang.Object"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="get" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Gets type literal for the given {@code Type} instance.]]>
+      </doc>
+    </method>
+    <method name="get" return="com.google.inject.TypeLiteral&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Gets type literal for the given {@code Class} instance.]]>
+      </doc>
+    </method>
+    <method name="getSupertype" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="supertype" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns the generic form of {@code supertype}. For example, if this is {@code
+ ArrayList<String>}, this returns {@code Iterable<String>} given the input {@code
+ Iterable.class}.
+
+ @param supertype a superclass of, or interface implemented by, this.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getFieldType" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="field" type="java.lang.reflect.Field"/>
+      <doc>
+      <![CDATA[Returns the resolved generic type of {@code field}.
+
+ @param field a field defined by this or any superclass.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getParameterTypes" return="java.util.List&lt;com.google.inject.TypeLiteral&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="methodOrConstructor" type="java.lang.reflect.Member"/>
+      <doc>
+      <![CDATA[Returns the resolved generic parameter types of {@code methodOrConstructor}.
+
+ @param methodOrConstructor a method or constructor defined by this or any supertype.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getExceptionTypes" return="java.util.List&lt;com.google.inject.TypeLiteral&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="methodOrConstructor" type="java.lang.reflect.Member"/>
+      <doc>
+      <![CDATA[Returns the resolved generic exception types thrown by {@code constructor}.
+
+ @param methodOrConstructor a method or constructor defined by this or any supertype.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="getReturnType" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="method" type="java.lang.reflect.Method"/>
+      <doc>
+      <![CDATA[Returns the resolved generic return type of {@code method}.
+
+ @param method a method defined by this or any supertype.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Represents a generic type {@code T}. Java doesn't yet provide a way to
+ represent generic types, so this class does. Forces clients to create a
+ subclass of this class which enables retrieval the type information even at
+ runtime.
+
+ <p>For example, to create a type literal for {@code List<String>}, you can
+ create an empty anonymous inner class:
+
+ <p>
+ {@code TypeLiteral<List<String>> list = new TypeLiteral<List<String>>() {};}
+
+ <p>Along with modeling generic types, this class can resolve type parameters.
+ For example, to figure out what type {@code keySet()} returns on a {@code
+ Map<Integer, String>}, use this code:<pre>   {@code
+
+   TypeLiteral<Map<Integer, String>> mapType
+       = new TypeLiteral<Map<Integer, String>>() {};
+   TypeLiteral<?> keySetType
+       = mapType.getReturnType(Map.class.getMethod("keySet"));
+   System.out.println(keySetType); // prints "Set<Integer>"}</pre>
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.TypeLiteral -->
+</package>
+<package name="com.google.inject.assistedinject">
+  <!-- start class com.google.inject.assistedinject.Assisted -->
+  <class name="Assisted"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates an injected parameter or field whose value comes from an argument to a factory method.
+
+ @author jmourits@google.com (Jerome Mourits)
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.assistedinject.Assisted -->
+  <!-- start class com.google.inject.assistedinject.AssistedInject -->
+  <class name="AssistedInject"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[<p>
+ When used in tandem with {@link FactoryModuleBuilder}, constructors annotated with 
+ {@code @AssistedInject} indicate that multiple constructors can be injected, each with different
+ parameters. AssistedInject annotations should not be mixed with {@literal @}{@link Inject}
+ annotations. The assisted parameters must exactly match one corresponding factory method within
+ the factory interface, but the parameters do not need to be in the same order. Constructors
+ annotated with AssistedInject <b>are</b> created by Guice and receive all the benefits
+ (such as AOP).
+ 
+ <p>
+ <strong>Obsolete Usage:</strong> When used in tandem with {@link FactoryProvider}, constructors
+ annotated with {@code @AssistedInject} trigger a "backwards compatibility mode". The assisted
+ parameters must exactly match one corresponding factory method within the factory interface and
+ all must be in the same order as listed in the factory. In this backwards compatable mode,
+ constructors annotated with AssistedInject <b>are not</b> created by Guice and thus receive
+ none of the benefits.
+ 
+ <p>
+ Constructor parameters must be either supplied by the factory interface and marked with
+ <code>@Assisted</code>, or they must be injectable.
+ 
+ @author jmourits@google.com (Jerome Mourits)
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.assistedinject.AssistedInject -->
+  <!-- start interface com.google.inject.assistedinject.AssistedInjectBinding -->
+  <interface name="AssistedInjectBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the {@link Key} for the factory binding.]]>
+      </doc>
+    </method>
+    <method name="getAssistedMethods" return="java.util.Collection&lt;com.google.inject.assistedinject.AssistedMethod&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns an {@link AssistedMethod} for each method in the factory.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding for a factory created by FactoryModuleBuilder.
+ 
+ @param <T> The fully qualified type of the factory.
+  
+ @since 3.0
+ @author ramakrishna@google.com (Ramakrishna Rajanna)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.assistedinject.AssistedInjectBinding -->
+  <!-- start interface com.google.inject.assistedinject.AssistedInjectTargetVisitor -->
+  <interface name="AssistedInjectTargetVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingTargetVisitor&lt;T, V&gt;"/>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="assistedInjectBinding" type="com.google.inject.assistedinject.AssistedInjectBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits an {@link AssistedInjectBinding} created through {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A visitor for the AssistedInject extension.
+ <p>
+ If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ {@link FactoryModuleBuilder} will be visited through this interface.
+
+ @since 3.0
+ @author ramakrishna@google.com (Ramakrishna Rajanna)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.assistedinject.AssistedInjectTargetVisitor -->
+  <!-- start interface com.google.inject.assistedinject.AssistedMethod -->
+  <interface name="AssistedMethod"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getFactoryMethod" return="java.lang.reflect.Method"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the factory method that is being assisted.]]>
+      </doc>
+    </method>
+    <method name="getImplementationType" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the implementation type that will be created when the method is
+ used.]]>
+      </doc>
+    </method>
+    <method name="getImplementationConstructor" return="java.lang.reflect.Constructor&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the constructor that will be used to construct instances of the 
+ implementation.]]>
+      </doc>
+    </method>
+    <method name="getDependencies" return="java.util.Set&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns all non-assisted dependencies required to construct and inject
+ the implementation.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Details about how a method in an assisted inject factory will be assisted.
+ 
+ @since 3.0
+ @author ramakrishna@google.com (Ramakrishna Rajanna)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.assistedinject.AssistedMethod -->
+  <!-- start class com.google.inject.assistedinject.FactoryModuleBuilder -->
+  <class name="FactoryModuleBuilder" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="FactoryModuleBuilder"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.Key&lt;T&gt;"/>
+      <param name="target" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="implement" return="com.google.inject.assistedinject.FactoryModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="com.google.inject.Key&lt;T&gt;"/>
+      <param name="target" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="build" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="factoryInterface" type="java.lang.Class&lt;F&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="build" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="factoryInterface" type="com.google.inject.TypeLiteral&lt;F&gt;"/>
+      <doc>
+      <![CDATA[See the factory configuration examples at {@link FactoryModuleBuilder}.]]>
+      </doc>
+    </method>
+    <method name="build" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="factoryInterface" type="com.google.inject.Key&lt;F&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[Provides a factory that combines the caller's arguments with injector-supplied values to
+ construct objects.
+
+ <h3>Defining a factory</h3>
+ Create an interface whose methods return the constructed type, or any of its supertypes. The
+ method's parameters are the arguments required to build the constructed type.
+
+ <pre>public interface PaymentFactory {
+   Payment create(Date startDate, Money amount);
+ }</pre>
+
+ You can name your factory methods whatever you like, such as <i>create</i>, <i>createPayment</i>
+ or <i>newPayment</i>.
+
+ <h3>Creating a type that accepts factory parameters</h3>
+ {@code constructedType} is a concrete class with an {@literal @}{@link com.google.inject.Inject
+ Inject}-annotated constructor. In addition to injector-supplied parameters, the constructor
+ should have parameters that match each of the factory method's parameters. Each factory-supplied
+ parameter requires an {@literal @}{@link Assisted} annotation. This serves to document that the
+ parameter is not bound by your application's modules.
+
+ <pre>public class RealPayment implements Payment {
+   {@literal @}Inject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+      <strong>{@literal @}Assisted Date startDate</strong>,
+      <strong>{@literal @}Assisted Money amount</strong>) {
+     ...
+   }
+ }</pre>
+ 
+ <h3>Multiple factory methods for the same type</h3>
+ If the factory contains many methods that return the same type, you can create multiple
+ constructors in your concrete class, each constructor marked with with
+ {@literal @}{@link AssistedInject}, in order to match the different parameters types of the
+ factory methods. 
+ 
+ <pre>public interface PaymentFactory {
+    Payment create(Date startDate, Money amount);
+    Payment createWithoutDate(Money amount);
+ }
+ 
+ public class RealPayment implements Payment {
+  {@literal @}AssistedInject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+     <strong>{@literal @}Assisted Date startDate</strong>,
+     <strong>{@literal @}Assisted Money amount</strong>) {
+     ...
+   }
+   
+  {@literal @}AssistedInject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+     <strong>{@literal @}Assisted Money amount</strong>) {
+     ...
+   }   
+ }</pre> 
+
+ <h3>Configuring simple factories</h3>
+ In your {@link Module module}, install a {@code FactoryModuleBuilder} that creates the
+ factory:
+
+ <pre>install(new FactoryModuleBuilder()
+     .implement(Payment.class, RealPayment.class)
+     .build(PaymentFactory.class));</pre>
+
+ As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
+ factory cannot be used until the injector has been initialized.
+ 
+ <h3>Configuring complex factories</h3>
+ Factories can create an arbitrary number of objects, one per each method.  Each factory
+ method can be configured using <code>.implement</code>.
+
+ <pre>public interface OrderFactory {
+    Payment create(Date startDate, Money amount);
+    Shipment create(Customer customer, Item item);
+    Receipt create(Payment payment, Shipment shipment);
+ }
+ 
+ [...]
+ 
+ install(new FactoryModuleBuilder()
+     .implement(Payment.class, RealPayment.class)
+     // excluding .implement for Shipment means the implementation class
+     // will be 'Shipment' itself, which is legal if it's not an interface.
+     .implement(Receipt.class, RealReceipt.class)
+     .build(OrderFactory.class));</pre>
+ </pre>
+
+ <h3>Using the factory</h3>
+ Inject your factory into your application classes. When you use the factory, your arguments
+ will be combined with values from the injector to construct an instance.
+
+ <pre>public class PaymentAction {
+   {@literal @}Inject private PaymentFactory paymentFactory;
+
+   public void doPayment(Money amount) {
+     Payment payment = paymentFactory.create(new Date(), amount);
+     payment.apply();
+   }
+ }</pre>
+
+ <h3>Making parameter types distinct</h3>
+ The types of the factory method's parameters must be distinct. To use multiple parameters of
+ the same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the
+ parameters. The names must be applied to the factory method's parameters:
+
+ <pre>public interface PaymentFactory {
+   Payment create(
+       <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
+       <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
+       Money amount);
+ } </pre>
+
+ ...and to the concrete type's constructor parameters:
+
+ <pre>public class RealPayment implements Payment {
+   {@literal @}Inject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+      <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
+      <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
+      <strong>{@literal @}Assisted</strong> Money amount) {
+     ...
+   }
+ }</pre>
+
+ <h3>Values are created by Guice</h3>
+ Returned factories use child injectors to create values. The values are eligible for method
+ interception. In addition, {@literal @}{@literal Inject} members will be injected before they are
+ returned.
+
+ <h3>More configuration options</h3>
+ In addition to simply specifying an implementation class for any returned type, factories' return
+ values can be automatic or can be configured to use annotations:
+ <p/>
+ If you just want to return the types specified in the factory, do not configure any
+ implementations:
+
+ <pre>public interface FruitFactory {
+   Apple getApple(Color color);
+ }
+ ...
+ protected void configure() {
+   install(new FactoryModuleBuilder().build(FruitFactory.class));
+ }</pre>
+
+ Note that any type returned by the factory in this manner needs to be an implementation class.
+ <p/>
+ To return two different implementations for the same interface from your factory, use binding
+ annotations on your return types:
+
+ <pre>interface CarFactory {
+   {@literal @}Named("fast") Car getFastCar(Color color);
+   {@literal @}Named("clean") Car getCleanCar(Color color);
+ }
+ ...
+ protected void configure() {
+   install(new FactoryModuleBuilder()
+       .implement(Car.class, Names.named("fast"), Porsche.class)
+       .implement(Car.class, Names.named("clean"), Prius.class)
+       .build(CarFactory.class));
+ }</pre>
+ 
+ <h3>Implementation limitations</h3>
+ As a limitation of the implementation, it is prohibited to declare a factory method that
+ accepts a {@code Provider} as one of its arguments.
+
+ @since 3.0
+ @author schmitt@google.com (Peter Schmitt)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.assistedinject.FactoryModuleBuilder -->
+  <!-- start class com.google.inject.assistedinject.FactoryProvider -->
+  <class name="FactoryProvider" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="use {@link FactoryModuleBuilder} instead.">
+    <implements name="com.google.inject.Provider&lt;F&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="newFactory" return="com.google.inject.Provider&lt;F&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="factoryType" type="java.lang.Class&lt;F&gt;"/>
+      <param name="implementationType" type="java.lang.Class&lt;?&gt;"/>
+    </method>
+    <method name="newFactory" return="com.google.inject.Provider&lt;F&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="factoryType" type="com.google.inject.TypeLiteral&lt;F&gt;"/>
+      <param name="implementationType" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+    </method>
+    <method name="getDependencies" return="java.util.Set&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="get" return="F"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <doc>
+    <![CDATA[<strong>Obsolete.</strong> Prefer {@link FactoryModuleBuilder} for its more concise API and
+ additional capability.
+
+ <p>Provides a factory that combines the caller's arguments with injector-supplied values to
+ construct objects.
+
+ <h3>Defining a factory</h3>
+ Create an interface whose methods return the constructed type, or any of its supertypes. The
+ method's parameters are the arguments required to build the constructed type.
+ <pre>public interface PaymentFactory {
+   Payment create(Date startDate, Money amount);
+ }</pre>
+ You can name your factory methods whatever you like, such as <i>create</i>, <i>createPayment</i>
+ or <i>newPayment</i>.
+
+ <h3>Creating a type that accepts factory parameters</h3>
+ {@code constructedType} is a concrete class with an {@literal @}{@link Inject}-annotated
+ constructor. In addition to injector-supplied parameters, the constructor should have
+ parameters that match each of the factory method's parameters. Each factory-supplied parameter
+ requires an {@literal @}{@link Assisted} annotation. This serves to document that the parameter
+ is not bound by your application's modules.
+ <pre>public class RealPayment implements Payment {
+   {@literal @}Inject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+      <strong>{@literal @}Assisted Date startDate</strong>,
+      <strong>{@literal @}Assisted Money amount</strong>) {
+     ...
+   }
+ }</pre>
+ Any parameter that permits a null value should also be annotated {@code @Nullable}.
+
+ <h3>Configuring factories</h3>
+ In your {@link com.google.inject.Module module}, bind the factory interface to the returned
+ factory:
+ <pre>bind(PaymentFactory.class).toProvider(
+     FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));</pre>
+ As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
+ factory cannot be used until the injector has been initialized.
+
+ <h3>Using the factory</h3>
+ Inject your factory into your application classes. When you use the factory, your arguments
+ will be combined with values from the injector to construct an instance.
+ <pre>public class PaymentAction {
+   {@literal @}Inject private PaymentFactory paymentFactory;
+
+   public void doPayment(Money amount) {
+     Payment payment = paymentFactory.create(new Date(), amount);
+     payment.apply();
+   }
+ }</pre>
+
+ <h3>Making parameter types distinct</h3>
+ The types of the factory method's parameters must be distinct. To use multiple parameters of
+ the same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the
+ parameters. The names must be applied to the factory method's parameters:
+
+ <pre>public interface PaymentFactory {
+   Payment create(
+       <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
+       <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
+       Money amount);
+ } </pre>
+ ...and to the concrete type's constructor parameters:
+ <pre>public class RealPayment implements Payment {
+   {@literal @}Inject
+   public RealPayment(
+      CreditService creditService,
+      AuthService authService,
+      <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
+      <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
+      <strong>{@literal @}Assisted</strong> Money amount) {
+     ...
+   }
+ }</pre>
+
+ <h3>Values are created by Guice</h3>
+ Returned factories use child injectors to create values. The values are eligible for method
+ interception. In addition, {@literal @}{@literal Inject} members will be injected before they are
+ returned.
+
+ <h3>Backwards compatibility using {@literal @}AssistedInject</h3>
+ Instead of the {@literal @}Inject annotation, you may annotate the constructed classes with
+ {@literal @}{@link AssistedInject}. This triggers a limited backwards-compatability mode.
+
+ <p>Instead of matching factory method arguments to constructor parameters using their names, the
+ <strong>parameters are matched by their order</strong>. The first factory method argument is
+ used for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no
+ effect.
+
+ <p>Returned values are <strong>not created by Guice</strong>. These types are not eligible for
+ method interception. They do receive post-construction member injection.
+
+ @param <F> The factory interface
+
+ @author jmourits@google.com (Jerome Mourits)
+ @author jessewilson@google.com (Jesse Wilson)
+ @author dtm@google.com (Daniel Martin)
+ 
+ @deprecated use {@link FactoryModuleBuilder} instead.]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.assistedinject.FactoryProvider -->
+</package>
+<package name="com.google.inject.binder">
+  <!-- start interface com.google.inject.binder.AnnotatedBindingBuilder -->
+  <interface name="AnnotatedBindingBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"/>
+    <method name="annotatedWith" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="annotatedWith" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.AnnotatedBindingBuilder -->
+  <!-- start interface com.google.inject.binder.AnnotatedConstantBindingBuilder -->
+  <interface name="AnnotatedConstantBindingBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="annotatedWith" return="com.google.inject.binder.ConstantBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="annotatedWith" return="com.google.inject.binder.ConstantBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.AnnotatedConstantBindingBuilder -->
+  <!-- start interface com.google.inject.binder.AnnotatedElementBuilder -->
+  <interface name="AnnotatedElementBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="annotatedWith"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="annotatedWith"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.AnnotatedElementBuilder -->
+  <!-- start interface com.google.inject.binder.ConstantBindingBuilder -->
+  <interface name="ConstantBindingBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="int"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="long"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="boolean"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="double"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="float"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="short"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="char"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="byte"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <method name="to"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="E extends java.lang.Enum&lt;E&gt;"/>
+      <doc>
+      <![CDATA[Binds constant to the given value.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Binds to a constant value.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.ConstantBindingBuilder -->
+  <!-- start interface com.google.inject.binder.LinkedBindingBuilder -->
+  <interface name="LinkedBindingBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.binder.ScopedBindingBuilder"/>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="implementation" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="implementation" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="targetKey" type="com.google.inject.Key&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="toInstance"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="T"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @see com.google.inject.Injector#injectMembers]]>
+      </doc>
+    </method>
+    <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="provider" type="com.google.inject.Provider&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @see com.google.inject.Injector#injectMembers]]>
+      </doc>
+    </method>
+    <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="provider" type="javax.inject.Provider&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @see com.google.inject.Injector#injectMembers
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerType" type="java.lang.Class&lt;? extends javax.inject.Provider&lt;? extends T&gt;&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerType" type="com.google.inject.TypeLiteral&lt;? extends javax.inject.Provider&lt;? extends T&gt;&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="toProvider" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerKey" type="com.google.inject.Key&lt;? extends javax.inject.Provider&lt;? extends T&gt;&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="toConstructor" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="constructor" type="java.lang.reflect.Constructor&lt;S&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="toConstructor" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="constructor" type="java.lang.reflect.Constructor&lt;S&gt;"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;? extends S&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.LinkedBindingBuilder -->
+  <!-- start interface com.google.inject.binder.ScopedBindingBuilder -->
+  <interface name="ScopedBindingBuilder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="in"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="in"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scope" type="com.google.inject.Scope"/>
+      <doc>
+      <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <method name="asEagerSingleton"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Instructs the {@link com.google.inject.Injector} to eagerly initialize this
+ singleton-scoped binding upon creation. Useful for application
+ initialization logic.  See the EDSL examples at
+ {@link com.google.inject.Binder}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link com.google.inject.Binder}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.binder.ScopedBindingBuilder -->
+</package>
+<package name="com.google.inject.daggeradapter">
+  <!-- start class com.google.inject.daggeradapter.DaggerAdapter -->
+  <class name="DaggerAdapter" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="from" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="daggerModuleObjects" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[Returns a guice module from a dagger module.
+
+ <p>Note: At present, it does not honor {@code @Module(includes=...)} directives.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A utility to adapt classes annotated with {@link @dagger.Module} such that their
+ {@link @dagger.Provides} methods can be properly invoked by Guice to perform their
+ provision operations.
+
+ <p>Simple example: <pre>{@code
+   Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter()));
+ }</pre>
+
+ <p>Some notes on usage and compatibility.
+   <ul>
+     <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice.
+     <li>MapBindings are not yet implemented (pending).
+     <li>Be careful about stateful modules. In contrast to Dagger (where components are
+         expected to be recreated on-demand with new Module instances), Guice typically
+         has a single injector with a long lifetime, so your module instance will be used
+         throughout the lifetime of the entire app.
+     <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes
+         like per-request or per-activity.  Using modules written with Dagger 1.x usage
+         in mind may result in mis-scoped objects.
+     <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope
+         implementation must be registered in order to support the custom lifetime of that
+         annotation.
+   </ul>
+
+ @author cgruber@google.com (Christian Gruber)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.daggeradapter.DaggerAdapter -->
+</package>
+<package name="com.google.inject.grapher">
+  <!-- start class com.google.inject.grapher.AbstractInjectorGrapher -->
+  <class name="AbstractInjectorGrapher" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.grapher.InjectorGrapher"/>
+    <constructor name="AbstractInjectorGrapher"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="AbstractInjectorGrapher" type="com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="graph"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+      <exception name="IOException" type="java.io.IOException"/>
+    </method>
+    <method name="graph"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+      <param name="root" type="java.util.Set&lt;com.google.inject.Key&lt;?&gt;&gt;"/>
+      <exception name="IOException" type="java.io.IOException"/>
+    </method>
+    <method name="reset"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Resets the state of the grapher before rendering a new graph.]]>
+      </doc>
+    </method>
+    <method name="newInterfaceNode"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.InterfaceNode"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Adds a new interface node to the graph.]]>
+      </doc>
+    </method>
+    <method name="newImplementationNode"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.ImplementationNode"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Adds a new implementation node to the graph.]]>
+      </doc>
+    </method>
+    <method name="newInstanceNode"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.InstanceNode"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Adds a new instance node to the graph.]]>
+      </doc>
+    </method>
+    <method name="newDependencyEdge"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.DependencyEdge"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Adds a new dependency edge to the graph.]]>
+      </doc>
+    </method>
+    <method name="newBindingEdge"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.BindingEdge"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Adds a new binding edge to the graph.]]>
+      </doc>
+    </method>
+    <method name="postProcess"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Performs any post processing required after all nodes and edges have been added.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Abstract injector grapher that builds the dependency graph but doesn't render it.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.AbstractInjectorGrapher -->
+  <!-- start class com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters -->
+  <class name="AbstractInjectorGrapher.GrapherParameters" extends="java.lang.Object"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="GrapherParameters"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getRootKeySetCreator" return="com.google.inject.grapher.RootKeySetCreator"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setRootKeySetCreator" return="com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rootKeySetCreator" type="com.google.inject.grapher.RootKeySetCreator"/>
+    </method>
+    <method name="getAliasCreator" return="com.google.inject.grapher.AliasCreator"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setAliasCreator" return="com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="aliasCreator" type="com.google.inject.grapher.AliasCreator"/>
+    </method>
+    <method name="getNodeCreator" return="com.google.inject.grapher.NodeCreator"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setNodeCreator" return="com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="nodeCreator" type="com.google.inject.grapher.NodeCreator"/>
+    </method>
+    <method name="getEdgeCreator" return="com.google.inject.grapher.EdgeCreator"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setEdgeCreator" return="com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="edgeCreator" type="com.google.inject.grapher.EdgeCreator"/>
+    </method>
+    <doc>
+    <![CDATA[Parameters used to override default settings of the grapher.
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.AbstractInjectorGrapher.GrapherParameters -->
+  <!-- start class com.google.inject.grapher.Alias -->
+  <class name="Alias" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Alias" type="com.google.inject.grapher.NodeId, com.google.inject.grapher.NodeId"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getFromId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getToId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Alias between two nodes. Causes the 'from' node to be aliased with the 'to' node, which means
+ that the 'from' node is not rendered and all edges going to it instead go to the 'to' node.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.Alias -->
+  <!-- start interface com.google.inject.grapher.AliasCreator -->
+  <interface name="AliasCreator"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="createAliases" return="java.lang.Iterable&lt;com.google.inject.grapher.Alias&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bindings" type="java.lang.Iterable&lt;com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <doc>
+      <![CDATA[Returns aliases for the given dependency graph. The aliases do not need to be transitively
+ resolved, i.e. it is valid to return an alias (X to Y) and an alias (Y to Z). It is the
+ responsibility of the caller to resolve this to (X to Z) and (Y to Z).
+
+ @param bindings bindings that make up the dependency graph
+ @return aliases that should be applied on the graph]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Creator of node aliases. Used by dependency graphers to merge nodes in the internal Guice graph
+ into a single node on the rendered graph.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.AliasCreator -->
+  <!-- start class com.google.inject.grapher.BindingEdge -->
+  <class name="BindingEdge" extends="com.google.inject.grapher.Edge"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="BindingEdge" type="com.google.inject.grapher.NodeId, com.google.inject.grapher.NodeId, com.google.inject.grapher.BindingEdge.Type"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getType" return="com.google.inject.grapher.BindingEdge.Type"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Edge"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="fromId" type="com.google.inject.grapher.NodeId"/>
+      <param name="toId" type="com.google.inject.grapher.NodeId"/>
+    </method>
+    <doc>
+    <![CDATA[Edge that connects an interface to the type or instance that is bound to implement it.
+
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.BindingEdge -->
+  <!-- start class com.google.inject.grapher.BindingEdge.Type -->
+  <class name="BindingEdge.Type" extends="java.lang.Enum&lt;com.google.inject.grapher.BindingEdge.Type&gt;"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.BindingEdge.Type[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.BindingEdge.Type"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[Classification for what kind of binding this edge represents.]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.BindingEdge.Type -->
+  <!-- start class com.google.inject.grapher.DefaultRootKeySetCreator -->
+  <class name="DefaultRootKeySetCreator" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.grapher.RootKeySetCreator"/>
+    <constructor name="DefaultRootKeySetCreator"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getRootKeys" return="java.util.Set&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+    </method>
+    <doc>
+    <![CDATA[Root key set creator that starts with all types that are not Guice internal types or the
+ {@link Logger} type.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.DefaultRootKeySetCreator -->
+  <!-- start class com.google.inject.grapher.DependencyEdge -->
+  <class name="DependencyEdge" extends="com.google.inject.grapher.Edge"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="DependencyEdge" type="com.google.inject.grapher.NodeId, com.google.inject.grapher.NodeId, com.google.inject.spi.InjectionPoint"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getInjectionPoint" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Edge"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="fromId" type="com.google.inject.grapher.NodeId"/>
+      <param name="toId" type="com.google.inject.grapher.NodeId"/>
+    </method>
+    <doc>
+    <![CDATA[Edge from a class or {@link InjectionPoint} to the interface node that will satisfy the
+ dependency.
+
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.DependencyEdge -->
+  <!-- start class com.google.inject.grapher.Edge -->
+  <class name="Edge" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Edge" type="com.google.inject.grapher.NodeId, com.google.inject.grapher.NodeId"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getFromId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getToId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Edge"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="fromId" type="com.google.inject.grapher.NodeId"/>
+      <param name="toId" type="com.google.inject.grapher.NodeId"/>
+      <doc>
+      <![CDATA[Returns a copy of the edge with new node IDs.
+
+ @param fromId new ID of the 'from' node
+ @param toId new ID of the 'to' node
+ @return copy of the edge with the new node IDs]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Edge in a guice dependency graph.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.Edge -->
+  <!-- start interface com.google.inject.grapher.EdgeCreator -->
+  <interface name="EdgeCreator"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getEdges" return="java.lang.Iterable&lt;com.google.inject.grapher.Edge&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bindings" type="java.lang.Iterable&lt;com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <doc>
+      <![CDATA[Returns edges for the given dependency graph.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Creator of graph edges to render. All edges will be rendered on the graph after node aliasing is
+ performed.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.EdgeCreator -->
+  <!-- start class com.google.inject.grapher.ImplementationNode -->
+  <class name="ImplementationNode" extends="com.google.inject.grapher.Node"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ImplementationNode" type="com.google.inject.grapher.NodeId, java.lang.Object, java.util.Collection&lt;java.lang.reflect.Member&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getMembers" return="java.util.Collection&lt;java.lang.reflect.Member&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Node"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="id" type="com.google.inject.grapher.NodeId"/>
+    </method>
+    <doc>
+    <![CDATA[Node for types that have {@link com.google.inject.spi.Dependency}s and are
+ bound to {@link InterfaceNode}s. These nodes will often have fields for
+ {@link Member}s that are {@link com.google.inject.spi.InjectionPoint}s.
+
+ @see DependencyEdge
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.ImplementationNode -->
+  <!-- start interface com.google.inject.grapher.InjectorGrapher -->
+  <interface name="InjectorGrapher"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="graph"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Graphs the guice dependency graph for the given injector using default starting keys.]]>
+      </doc>
+    </method>
+    <method name="graph"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+      <param name="root" type="java.util.Set&lt;com.google.inject.Key&lt;?&gt;&gt;"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Graphs the guice dependency graph for the given injector using the given starting keys and
+ their transitive dependencies.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Guice injector grapher. Renders the guice dependency graph for an injector. It can render the
+ whole dependency graph or just transitive dependencies of a given set of nodes.
+
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as a concrete class with a different API)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.InjectorGrapher -->
+  <!-- start class com.google.inject.grapher.InstanceNode -->
+  <class name="InstanceNode" extends="com.google.inject.grapher.Node"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="InstanceNode" type="com.google.inject.grapher.NodeId, java.lang.Object, java.lang.Object, java.lang.Iterable&lt;java.lang.reflect.Member&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getInstance" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getMembers" return="java.lang.Iterable&lt;java.lang.reflect.Member&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Node"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="id" type="com.google.inject.grapher.NodeId"/>
+    </method>
+    <doc>
+    <![CDATA[Node for instances. Used when a type is bound to an instance.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.InstanceNode -->
+  <!-- start class com.google.inject.grapher.InterfaceNode -->
+  <class name="InterfaceNode" extends="com.google.inject.grapher.Node"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="InterfaceNode" type="com.google.inject.grapher.NodeId, java.lang.Object"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="copy" return="com.google.inject.grapher.Node"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="id" type="com.google.inject.grapher.NodeId"/>
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Node for an interface type that has been bound to an implementation class or instance.
+
+ @see BindingEdge
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0 (since 2.0 as an interface)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.InterfaceNode -->
+  <!-- start interface com.google.inject.grapher.NameFactory -->
+  <interface name="NameFactory"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getMemberName" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="member" type="java.lang.reflect.Member"/>
+    </method>
+    <method name="getClassName" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="getInstanceName" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+    </method>
+    <method name="getAnnotationName" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="getSourceName" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Object"/>
+    </method>
+    <doc>
+    <![CDATA[Interface for a service that provides nice {@link String}s that we can
+ display in the graph for the types that come up in
+ {@link com.google.inject.Binding}s.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.NameFactory -->
+  <!-- start class com.google.inject.grapher.Node -->
+  <class name="Node" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Node" type="com.google.inject.grapher.NodeId, java.lang.Object"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="copy" return="com.google.inject.grapher.Node"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="id" type="com.google.inject.grapher.NodeId"/>
+      <doc>
+      <![CDATA[Returns a copy of the node with a new ID.
+
+ @param id new ID of the node
+ @return copy of the node with a new ID]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Node in a guice dependency graph.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.Node -->
+  <!-- start interface com.google.inject.grapher.NodeCreator -->
+  <interface name="NodeCreator"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getNodes" return="java.lang.Iterable&lt;com.google.inject.grapher.Node&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bindings" type="java.lang.Iterable&lt;com.google.inject.Binding&lt;?&gt;&gt;"/>
+      <doc>
+      <![CDATA[Returns nodes for the given dependency graph.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Creator of graph nodes.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.NodeCreator -->
+  <!-- start class com.google.inject.grapher.NodeId -->
+  <class name="NodeId" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="newTypeId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="newInstanceId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="getKey" return="com.google.inject.Key&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="obj" type="java.lang.Object"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[ID of a node in the graph. An ID is given by a {@link Key} and a node type, which is used to
+ distinguish instances and implementation classes for the same key. For example
+ {@code bind(Integer.class).toInstance(42)} produces two nodes: an
+ interface node with the key of {@code Key<Integer>} and an instance node with the same
+ {@link Key} and value of 42.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.NodeId -->
+  <!-- start class com.google.inject.grapher.NodeId.NodeType -->
+  <class name="NodeId.NodeType" extends="java.lang.Enum&lt;com.google.inject.grapher.NodeId.NodeType&gt;"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.NodeId.NodeType[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.NodeId.NodeType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[Type of node.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.NodeId.NodeType -->
+  <!-- start interface com.google.inject.grapher.RootKeySetCreator -->
+  <interface name="RootKeySetCreator"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getRootKeys" return="java.util.Set&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injector" type="com.google.inject.Injector"/>
+      <doc>
+      <![CDATA[Returns the set of starting keys to graph.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Creator of the default starting set of keys to graph. These keys and their transitive
+ dependencies will be graphed.
+
+ @author bojand@google.com (Bojan Djordjevic)
+ @since 4.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.RootKeySetCreator -->
+  <!-- start class com.google.inject.grapher.ShortNameFactory -->
+  <class name="ShortNameFactory" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.grapher.NameFactory"/>
+    <constructor name="ShortNameFactory"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getMemberName" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="member" type="java.lang.reflect.Member"/>
+    </method>
+    <method name="getAnnotationName" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="getClassName" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+    </method>
+    <method name="getInstanceName" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+    </method>
+    <method name="getSourceName" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="source" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns a name for a Guice "source" object. This will typically be either
+ a {@link StackTraceElement} for when the binding is made to the instance,
+ or a {@link Method} when a provider method is used.]]>
+      </doc>
+    </method>
+    <method name="getFileString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="stackTraceElement" type="java.lang.StackTraceElement"/>
+    </method>
+    <method name="getMethodString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="method" type="java.lang.reflect.Method"/>
+    </method>
+    <doc>
+    <![CDATA[Reasonable implementation for {@link NameFactory}. Mostly takes various
+ {@link Object#toString()}s and strips package names out of them so that
+ they'll fit on the graph.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.ShortNameFactory -->
+  <!-- start class com.google.inject.grapher.TransitiveDependencyVisitor -->
+  <class name="TransitiveDependencyVisitor" extends="com.google.inject.spi.DefaultBindingTargetVisitor&lt;java.lang.Object, java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;&gt;"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="TransitiveDependencyVisitor"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ConstructorBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ConvertedConstantBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.InstanceBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.LinkedKeyBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderInstanceBinding&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderKeyBinding&lt;?&gt;"/>
+    </method>
+    <method name="visitOther" return="java.util.Collection&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;?&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[{@link com.google.inject.spi.BindingTargetVisitor} that returns a
+ {@link Collection} of the {@link Key}s of each {@link Binding}'s
+ dependencies. Used by {@link InjectorGrapher} to walk the dependency graph
+ from a starting set of {@link Binding}s.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.TransitiveDependencyVisitor -->
+</package>
+<package name="com.google.inject.grapher.graphviz">
+  <!-- start class com.google.inject.grapher.graphviz.ArrowType -->
+  <class name="ArrowType" extends="java.lang.Enum&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.graphviz.ArrowType[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.graphviz.ArrowType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Arrow symbols that are available from Graphviz. These can be composed by
+ concatenation to make double arrows and such.
+ <p>
+ See: http://www.graphviz.org/doc/info/arrows.html
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.ArrowType -->
+  <!-- start class com.google.inject.grapher.graphviz.CompassPoint -->
+  <class name="CompassPoint" extends="java.lang.Enum&lt;com.google.inject.grapher.graphviz.CompassPoint&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.graphviz.CompassPoint[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.graphviz.CompassPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Enum for the "compass point" values used to control where edge
+ end points appear on the graph.
+ <p>
+ See: http://www.graphviz.org/doc/info/attrs.html#k:portPos
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.CompassPoint -->
+  <!-- start class com.google.inject.grapher.graphviz.EdgeStyle -->
+  <class name="EdgeStyle" extends="java.lang.Enum&lt;com.google.inject.grapher.graphviz.EdgeStyle&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.graphviz.EdgeStyle[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.graphviz.EdgeStyle"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Styles for edges.
+ <p>
+ See: http://www.graphviz.org/doc/info/attrs.html#k:style
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.EdgeStyle -->
+  <!-- start class com.google.inject.grapher.graphviz.GraphvizEdge -->
+  <class name="GraphvizEdge" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="GraphvizEdge" type="com.google.inject.grapher.NodeId, com.google.inject.grapher.NodeId"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getHeadNodeId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="getHeadPortId" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setHeadPortId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="headPortId" type="java.lang.String"/>
+    </method>
+    <method name="getHeadCompassPoint" return="com.google.inject.grapher.graphviz.CompassPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setHeadCompassPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="headCompassPoint" type="com.google.inject.grapher.graphviz.CompassPoint"/>
+    </method>
+    <method name="getArrowHead" return="java.util.List&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setArrowHead"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="arrowHead" type="java.util.List&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"/>
+    </method>
+    <method name="getTailNodeId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="getTailPortId" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setTailPortId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="tailPortId" type="java.lang.String"/>
+    </method>
+    <method name="getTailCompassPoint" return="com.google.inject.grapher.graphviz.CompassPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setTailCompassPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="tailCompassPoint" type="com.google.inject.grapher.graphviz.CompassPoint"/>
+    </method>
+    <method name="getArrowTail" return="java.util.List&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setArrowTail"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="arrowTail" type="java.util.List&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"/>
+    </method>
+    <method name="getStyle" return="com.google.inject.grapher.graphviz.EdgeStyle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setStyle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="style" type="com.google.inject.grapher.graphviz.EdgeStyle"/>
+    </method>
+    <doc>
+    <![CDATA[Data object to encapsulate the attributes of Graphviz edges that we're
+ interested in drawing.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.GraphvizEdge -->
+  <!-- start class com.google.inject.grapher.graphviz.GraphvizGrapher -->
+  <class name="GraphvizGrapher" extends="com.google.inject.grapher.AbstractInjectorGrapher"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="reset"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="setOut"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="out" type="java.io.PrintWriter"/>
+    </method>
+    <method name="setRankdir"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rankdir" type="java.lang.String"/>
+    </method>
+    <method name="postProcess"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="getGraphAttributes" return="java.util.Map&lt;java.lang.String, java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="start"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="finish"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="renderNode"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.graphviz.GraphvizNode"/>
+    </method>
+    <method name="getNodeAttributes" return="java.util.Map&lt;java.lang.String, java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.graphviz.GraphvizNode"/>
+    </method>
+    <method name="getNodeLabel" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.graphviz.GraphvizNode"/>
+      <doc>
+      <![CDATA[Creates the "label" for a node. This is a string of HTML that defines a
+ table with a heading at the top and (in the case of
+ {@link ImplementationNode}s) rows for each of the member fields.]]>
+      </doc>
+    </method>
+    <method name="renderEdge"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.graphviz.GraphvizEdge"/>
+    </method>
+    <method name="getEdgeAttributes" return="java.util.Map&lt;java.lang.String, java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.graphviz.GraphvizEdge"/>
+    </method>
+    <method name="getArrowString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="arrows" type="java.util.List&lt;com.google.inject.grapher.graphviz.ArrowType&gt;"/>
+      <doc>
+      <![CDATA[Turns a {@link List} of {@link ArrowType}s into a {@link String} that
+ represents combining them. With Graphviz, that just means concatenating
+ them.]]>
+      </doc>
+    </method>
+    <method name="getEdgeEndPoint" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="nodeId" type="java.lang.String"/>
+      <param name="portId" type="java.lang.String"/>
+      <param name="compassPoint" type="com.google.inject.grapher.graphviz.CompassPoint"/>
+    </method>
+    <method name="htmlEscape" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="str" type="java.lang.String"/>
+    </method>
+    <method name="htmlEscape" return="java.util.List&lt;java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="elements" type="java.util.List&lt;java.lang.String&gt;"/>
+    </method>
+    <method name="newInterfaceNode"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.InterfaceNode"/>
+    </method>
+    <method name="newImplementationNode"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.ImplementationNode"/>
+    </method>
+    <method name="newInstanceNode"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="node" type="com.google.inject.grapher.InstanceNode"/>
+    </method>
+    <method name="newDependencyEdge"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.DependencyEdge"/>
+    </method>
+    <method name="newBindingEdge"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="edge" type="com.google.inject.grapher.BindingEdge"/>
+    </method>
+    <doc>
+    <![CDATA[{@link com.google.inject.grapher.InjectorGrapher} implementation that writes out a Graphviz DOT
+ file of the graph. Dependencies are bound in {@link GraphvizModule}.
+ <p>
+ Specify the {@link PrintWriter} to output to with {@link #setOut(PrintWriter)}.
+
+ @author phopkins@gmail.com (Pete Hopkins)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.GraphvizGrapher -->
+  <!-- start class com.google.inject.grapher.graphviz.GraphvizModule -->
+  <class name="GraphvizModule" extends="com.google.inject.AbstractModule"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="GraphvizModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Module that provides classes needed by {@link GraphvizGrapher}.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.GraphvizModule -->
+  <!-- start class com.google.inject.grapher.graphviz.GraphvizNode -->
+  <class name="GraphvizNode" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="GraphvizNode" type="com.google.inject.grapher.NodeId"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </constructor>
+    <method name="getNodeId" return="com.google.inject.grapher.NodeId"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="getShape" return="com.google.inject.grapher.graphviz.NodeShape"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setShape"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="shape" type="com.google.inject.grapher.graphviz.NodeShape"/>
+    </method>
+    <method name="getStyle" return="com.google.inject.grapher.graphviz.NodeStyle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setStyle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="style" type="com.google.inject.grapher.graphviz.NodeStyle"/>
+    </method>
+    <method name="getTitle" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setTitle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="title" type="java.lang.String"/>
+    </method>
+    <method name="getSubtitles" return="java.util.List&lt;java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="addSubtitle"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="position" type="int"/>
+      <param name="subtitle" type="java.lang.String"/>
+    </method>
+    <method name="getHeaderTextColor" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setHeaderTextColor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="headerTextColor" type="java.lang.String"/>
+    </method>
+    <method name="getHeaderBackgroundColor" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="setHeaderBackgroundColor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="headerBackgroundColor" type="java.lang.String"/>
+    </method>
+    <method name="addField"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="portId" type="java.lang.String"/>
+      <param name="title" type="java.lang.String"/>
+    </method>
+    <method name="getFields" return="java.util.Map&lt;java.lang.String, java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getIdentifier" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="setIdentifier"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="identifier" type="java.lang.String"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Data object to encapsulate the attributes of Graphviz nodes that we're
+ interested in drawing.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.GraphvizNode -->
+  <!-- start class com.google.inject.grapher.graphviz.NodeShape -->
+  <class name="NodeShape" extends="java.lang.Enum&lt;com.google.inject.grapher.graphviz.NodeShape&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.graphviz.NodeShape[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.graphviz.NodeShape"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Enum for the shapes that are most interesting for Guice graphing.
+ <p>
+ See: http://www.graphviz.org/doc/info/shapes.html
+ 
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.NodeShape -->
+  <!-- start class com.google.inject.grapher.graphviz.NodeStyle -->
+  <class name="NodeStyle" extends="java.lang.Enum&lt;com.google.inject.grapher.graphviz.NodeStyle&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.grapher.graphviz.NodeStyle[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.grapher.graphviz.NodeStyle"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Styles for nodes. Similar to {@link EdgeStyle} but with a few more options.
+ <p>
+ See: http://www.graphviz.org/doc/info/attrs.html#k:style
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.NodeStyle -->
+  <!-- start interface com.google.inject.grapher.graphviz.PortIdFactory -->
+  <interface name="PortIdFactory"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getPortId" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="member" type="java.lang.reflect.Member"/>
+    </method>
+    <doc>
+    <![CDATA[Interface for a service that returns Graphviz port IDs, used for naming the
+ rows in {@link com.google.inject.grapher.ImplementationNode}-displaying {@link GraphvizNode}s.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.grapher.graphviz.PortIdFactory -->
+  <!-- start class com.google.inject.grapher.graphviz.PortIdFactoryImpl -->
+  <class name="PortIdFactoryImpl" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.grapher.graphviz.PortIdFactory"/>
+    <constructor name="PortIdFactoryImpl"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getPortId" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="member" type="java.lang.reflect.Member"/>
+    </method>
+    <doc>
+    <![CDATA[Implementation of {@link PortIdFactory}. Bound in {@link GraphvizModule}.
+
+ @author phopkins@gmail.com (Pete Hopkins)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.grapher.graphviz.PortIdFactoryImpl -->
+</package>
+<package name="com.google.inject.jndi">
+  <!-- start class com.google.inject.jndi.JndiIntegration -->
+  <class name="JndiIntegration" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="fromJndi" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="name" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Creates a provider which looks up objects in JNDI using the given name.
+ Example usage:
+
+ <pre>
+ bind(DataSource.class).toProvider(fromJndi(DataSource.class, "java:..."));
+ </pre>]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Integrates Guice with JNDI. Requires a binding to 
+ {@link javax.naming.Context}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.jndi.JndiIntegration -->
+</package>
+<package name="com.google.inject.matcher">
+  <!-- start class com.google.inject.matcher.AbstractMatcher -->
+  <class name="AbstractMatcher" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.matcher.Matcher&lt;T&gt;"/>
+    <constructor name="AbstractMatcher"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="and" return="com.google.inject.matcher.Matcher&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="other" type="com.google.inject.matcher.Matcher&lt;? super T&gt;"/>
+    </method>
+    <method name="or" return="com.google.inject.matcher.Matcher&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="other" type="com.google.inject.matcher.Matcher&lt;? super T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[Implements {@code and()} and {@code or()}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.matcher.AbstractMatcher -->
+  <!-- start interface com.google.inject.matcher.Matcher -->
+  <interface name="Matcher"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="matches" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="t" type="T"/>
+      <doc>
+      <![CDATA[Returns {@code true} if this matches {@code t}, {@code false} otherwise.]]>
+      </doc>
+    </method>
+    <method name="and" return="com.google.inject.matcher.Matcher&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="other" type="com.google.inject.matcher.Matcher&lt;? super T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new matcher which returns {@code true} if both this and the
+ given matcher return {@code true}.]]>
+      </doc>
+    </method>
+    <method name="or" return="com.google.inject.matcher.Matcher&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="other" type="com.google.inject.matcher.Matcher&lt;? super T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new matcher which returns {@code true} if either this or the
+ given matcher return {@code true}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Returns {@code true} or {@code false} for a given input.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.matcher.Matcher -->
+  <!-- start class com.google.inject.matcher.Matchers -->
+  <class name="Matchers" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="any" return="com.google.inject.matcher.Matcher&lt;java.lang.Object&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a matcher which matches any input.]]>
+      </doc>
+    </method>
+    <method name="not" return="com.google.inject.matcher.Matcher&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="p" type="com.google.inject.matcher.Matcher&lt;? super T&gt;"/>
+      <doc>
+      <![CDATA[Inverts the given matcher.]]>
+      </doc>
+    </method>
+    <method name="annotatedWith" return="com.google.inject.matcher.Matcher&lt;java.lang.reflect.AnnotatedElement&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches elements (methods, classes, etc.)
+ with a given annotation.]]>
+      </doc>
+    </method>
+    <method name="annotatedWith" return="com.google.inject.matcher.Matcher&lt;java.lang.reflect.AnnotatedElement&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches elements (methods, classes, etc.)
+ with a given annotation.]]>
+      </doc>
+    </method>
+    <method name="subclassesOf" return="com.google.inject.matcher.Matcher&lt;java.lang.Class&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="superclass" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches subclasses of the given type (as well as
+ the given type).]]>
+      </doc>
+    </method>
+    <method name="only" return="com.google.inject.matcher.Matcher&lt;java.lang.Object&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches objects equal to the given object.]]>
+      </doc>
+    </method>
+    <method name="identicalTo" return="com.google.inject.matcher.Matcher&lt;java.lang.Object&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches only the given object.]]>
+      </doc>
+    </method>
+    <method name="inPackage" return="com.google.inject.matcher.Matcher&lt;java.lang.Class&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="targetPackage" type="java.lang.Package"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches classes in the given package. Packages are specific to their
+ classloader, so classes with the same package name may not have the same package at runtime.]]>
+      </doc>
+    </method>
+    <method name="inSubpackage" return="com.google.inject.matcher.Matcher&lt;java.lang.Class&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="targetPackageName" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches classes in the given package and its subpackages. Unlike
+ {@link #inPackage(Package) inPackage()}, this matches classes from any classloader.
+ 
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="returns" return="com.google.inject.matcher.Matcher&lt;java.lang.reflect.Method&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="returnType" type="com.google.inject.matcher.Matcher&lt;? super java.lang.Class&lt;?&gt;&gt;"/>
+      <doc>
+      <![CDATA[Returns a matcher which matches methods with matching return types.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Matcher implementations. Supports matching classes and methods.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.matcher.Matchers -->
+</package>
+<package name="com.google.inject.multibindings">
+  <!-- start class com.google.inject.multibindings.ClassMapKey -->
+  <class name="ClassMapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows {@literal @}{@link ProvidesIntoMap} to specify a class map key.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ClassMapKey -->
+  <!-- start class com.google.inject.multibindings.MapBinder -->
+  <class name="MapBinder" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="com.google.inject.TypeLiteral&lt;K&gt;"/>
+      <param name="valueType" type="com.google.inject.TypeLiteral&lt;V&gt;"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with no binding annotation.]]>
+      </doc>
+    </method>
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="java.lang.Class&lt;K&gt;"/>
+      <param name="valueType" type="java.lang.Class&lt;V&gt;"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with no binding annotation.]]>
+      </doc>
+    </method>
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="com.google.inject.TypeLiteral&lt;K&gt;"/>
+      <param name="valueType" type="com.google.inject.TypeLiteral&lt;V&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with {@code annotation}.]]>
+      </doc>
+    </method>
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="java.lang.Class&lt;K&gt;"/>
+      <param name="valueType" type="java.lang.Class&lt;V&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with {@code annotation}.]]>
+      </doc>
+    </method>
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="com.google.inject.TypeLiteral&lt;K&gt;"/>
+      <param name="valueType" type="com.google.inject.TypeLiteral&lt;V&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with {@code annotationType}.]]>
+      </doc>
+    </method>
+    <method name="newMapBinder" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="keyType" type="java.lang.Class&lt;K&gt;"/>
+      <param name="valueType" type="java.lang.Class&lt;V&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
+ {@link Map} that is itself bound with {@code annotationType}.]]>
+      </doc>
+    </method>
+    <method name="permitDuplicates" return="com.google.inject.multibindings.MapBinder&lt;K, V&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Configures the {@code MapBinder} to handle duplicate entries.
+ <p>When multiple equal keys are bound, the value that gets included in the map is
+ arbitrary.
+ <p>In addition to the {@code Map<K, V>} and {@code Map<K, Provider<V>>}
+ maps that are normally bound, a {@code Map<K, Set<V>>} and
+ {@code Map<K, Set<Provider<V>>>} are <em>also</em> bound, which contain
+ all values bound to each key.
+ <p>
+ When multiple modules contribute elements to the map, this configuration
+ option impacts all of them.
+
+ @return this map binder
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="addBinding" return="com.google.inject.binder.LinkedBindingBuilder&lt;V&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="K"/>
+      <doc>
+      <![CDATA[Returns a binding builder used to add a new entry in the map. Each
+ key must be distinct (and non-null). Bound providers will be evaluated each
+ time the map is injected.
+
+ <p>It is an error to call this method without also calling one of the
+ {@code to} methods on the returned binding builder.
+
+ <p>Scoping elements independently is supported. Use the {@code in} method
+ to specify a binding scope.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An API to bind multiple map entries separately, only to later inject them as
+ a complete map. MapBinder is intended for use in your application's module:
+ <pre><code>
+ public class SnacksModule extends AbstractModule {
+   protected void configure() {
+     MapBinder&lt;String, Snack&gt; mapbinder
+         = MapBinder.newMapBinder(binder(), String.class, Snack.class);
+     mapbinder.addBinding("twix").toInstance(new Twix());
+     mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
+     mapbinder.addBinding("skittles").to(Skittles.class);
+   }
+ }</code></pre>
+
+ <p>With this binding, a {@link Map}{@code <String, Snack>} can now be
+ injected:
+ <pre><code>
+ class SnackMachine {
+   {@literal @}Inject
+   public SnackMachine(Map&lt;String, Snack&gt; snacks) { ... }
+ }</code></pre>
+
+ <p>In addition to binding {@code Map<K, V>}, a mapbinder will also bind
+ {@code Map<K, Provider<V>>} for lazy value provision:
+ <pre><code>
+ class SnackMachine {
+   {@literal @}Inject
+   public SnackMachine(Map&lt;String, Provider&lt;Snack&gt;&gt; snackProviders) { ... }
+ }</code></pre>
+
+ <p>Contributing mapbindings from different modules is supported. For example,
+ it is okay to have both {@code CandyModule} and {@code ChipsModule} both
+ create their own {@code MapBinder<String, Snack>}, and to each contribute
+ bindings to the snacks map. When that map is injected, it will contain
+ entries from both modules.
+
+ <p>The map's iteration order is consistent with the binding order. This is
+ convenient when multiple elements are contributed by the same module because
+ that module can order its bindings appropriately. Avoid relying on the
+ iteration order of elements contributed by different modules, since there is
+ no equivalent mechanism to order modules.
+
+ <p>The map is unmodifiable.  Elements can only be added to the map by
+ configuring the MapBinder.  Elements can never be removed from the map.
+
+ <p>Values are resolved at map injection time. If a value is bound to a
+ provider, that provider's get method will be called each time the map is
+ injected (unless the binding is also scoped, or a map of providers is injected).
+
+ <p>Annotations are used to create different maps of the same key/value
+ type. Each distinct annotation gets its own independent map.
+
+ <p><strong>Keys must be distinct.</strong> If the same key is bound more than
+ once, map injection will fail. However, use {@link #permitDuplicates()} in
+ order to allow duplicate keys; extra bindings to {@code Map<K, Set<V>>} and
+ {@code Map<K, Set<Provider<V>>} will be added.
+
+ <p><strong>Keys must be non-null.</strong> {@code addBinding(null)} will
+ throw an unchecked exception.
+
+ <p><strong>Values must be non-null to use map injection.</strong> If any
+ value is null, map injection will fail (although injecting a map of providers
+ will not).
+
+ @author dpb@google.com (David P. Baker)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.MapBinder -->
+  <!-- start interface com.google.inject.multibindings.MapBinderBinding -->
+  <interface name="MapBinderBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getMapKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the {@link Key} for the map.]]>
+      </doc>
+    </method>
+    <method name="getKeyTypeLiteral" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the TypeLiteral describing the keys of the map.
+ <p>
+ The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
+ returns a key of <code>Map&lt;String, Snack></code>, then this will always return a
+ <code>TypeLiteral&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="getValueTypeLiteral" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the TypeLiteral describing the values of the map.
+ <p>
+ The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
+ returns a key of <code>Map&lt;String, Snack></code>, then this will always return a
+ <code>TypeLiteral&lt;Snack></code>.]]>
+      </doc>
+    </method>
+    <method name="getEntries" return="java.util.List&lt;java.util.Map.Entry&lt;?, com.google.inject.Binding&lt;?&gt;&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns all entries in the Map. The returned list of Map.Entries contains the key and a binding
+ to the value. Duplicate keys or values will exist as separate Map.Entries in the returned list.
+ This is only supported on bindings returned from an injector. This will throw
+ {@link UnsupportedOperationException} if it is called on an element retrieved from
+ {@link Elements#getElements}.
+ <p>
+ The elements will always match the type Map's generic type. For example, if getMapKey returns a
+ key of <code>Map&lt;String, Snack></code>, then this will always return a list of type
+ <code>List&lt;Map.Entry&lt;String, Binding&lt;Snack>>></code>.]]>
+      </doc>
+    </method>
+    <method name="permitsDuplicates" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if the MapBinder permits duplicates. This is only supported on bindings returned
+ from an injector. This will throw {@link UnsupportedOperationException} if it is called on a
+ MapBinderBinding retrieved from {@link Elements#getElements}.]]>
+      </doc>
+    </method>
+    <method name="containsElement" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="element" type="com.google.inject.spi.Element"/>
+      <doc>
+      <![CDATA[Returns true if this MapBinder contains the given Element in order to build the map or uses the
+ given Element in order to support building and injecting the map. This will work for
+ MapBinderBindings retrieved from an injector and {@link Elements#getElements}. Usually this is
+ only necessary if you are working with elements retrieved from modules (without an Injector),
+ otherwise {@link #getEntries} and {@link #permitsDuplicates} are better options.
+ <p>
+ If you need to introspect the details of the map, such as the keys, values or if it permits
+ duplicates, it is necessary to pass the elements through an Injector and use
+ {@link #getEntries()} and {@link #permitsDuplicates()}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding for a MapBinder.
+ <p>
+ Although MapBinders may be injected through a variety of generic types (Map&lt;K, V>, Map
+ &lt;K, Provider&lt;V>>, Map&lt;K, Set&lt;V>>, Map<K, Set&lt;
+ Provider&lt;V>>, and even Set&lt;Map.Entry&lt;K, Provider&lt;V>>), a
+ MapBinderBinding exists only on the Binding associated with the Map&lt;K, V> key. Other
+ bindings can be validated to be derived from this MapBinderBinding using
+ {@link #containsElement(Element)}.
+ 
+ @param <T> The fully qualified type of the map, including Map. For example:
+          <code>MapBinderBinding&lt;Map&lt;String, Snack>></code>
+ 
+ @since 3.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.multibindings.MapBinderBinding -->
+  <!-- start class com.google.inject.multibindings.MapKey -->
+  <class name="MapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows users define customized key type annotations for map bindings by annotating an annotation
+ of a {@code Map}'s key type. The custom key annotation can be applied to methods also annotated
+ with {@literal @}{@link ProvidesIntoMap}.
+ 
+ <p>A {@link StringMapKey} and {@link ClassMapKey} are provided for convenience with maps whose
+ keys are strings or classes. For maps with enums or primitive types as keys, you must provide
+ your own MapKey annotation, such as this one for an enum:
+
+ <pre>
+ {@literal @}MapKey(unwrapValue = true)
+ {@literal @}Retention(RUNTIME)
+ public {@literal @}interface MyCustomEnumKey {
+   MyCustomEnum value();
+ }
+ </pre>
+
+ You can also use the whole annotation as the key, if {@code unwrapValue=false}.
+ When unwrapValue is false, the annotation type will be the key type for the injected map and
+ the annotation instances will be the key values. If {@code unwrapValue=true}, the value() type
+ will be the key type for injected map and the value() instances will be the keys values.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.MapKey -->
+  <!-- start class com.google.inject.multibindings.Multibinder -->
+  <class name="Multibinder" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with no binding annotation.]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with no binding annotation.]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with {@code annotation}.]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with {@code annotation}.]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with {@code annotationType}.]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of the key's type in a {@link Set} that is
+ itself bound with the annotation (if any) of the key.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="newSetBinder" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is
+ itself bound with {@code annotationType}.]]>
+      </doc>
+    </method>
+    <method name="permitDuplicates" return="com.google.inject.multibindings.Multibinder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Configures the bound set to silently discard duplicate elements. When multiple equal values are
+ bound, the one that gets included is arbitrary. When multiple modules contribute elements to
+ the set, this configuration option impacts all of them.
+
+ @return this multibinder
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="addBinding" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a binding builder used to add a new element in the set. Each
+ bound element must have a distinct value. Bound providers will be
+ evaluated each time the set is injected.
+
+ <p>It is an error to call this method without also calling one of the
+ {@code to} methods on the returned binding builder.
+
+ <p>Scoping elements independently is supported. Use the {@code in} method
+ to specify a binding scope.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An API to bind multiple values separately, only to later inject them as a
+ complete collection. Multibinder is intended for use in your application's
+ module:
+ <pre><code>
+ public class SnacksModule extends AbstractModule {
+   protected void configure() {
+     Multibinder&lt;Snack&gt; multibinder
+         = Multibinder.newSetBinder(binder(), Snack.class);
+     multibinder.addBinding().toInstance(new Twix());
+     multibinder.addBinding().toProvider(SnickersProvider.class);
+     multibinder.addBinding().to(Skittles.class);
+   }
+ }</code></pre>
+
+ <p>With this binding, a {@link Set}{@code <Snack>} can now be injected:
+ <pre><code>
+ class SnackMachine {
+   {@literal @}Inject
+   public SnackMachine(Set&lt;Snack&gt; snacks) { ... }
+ }</code></pre>
+
+ If desired, {@link Collection}{@code <Provider<Snack>>} can also be injected.
+
+ <p>Contributing multibindings from different modules is supported. For
+ example, it is okay for both {@code CandyModule} and {@code ChipsModule}
+ to create their own {@code Multibinder<Snack>}, and to each contribute
+ bindings to the set of snacks. When that set is injected, it will contain
+ elements from both modules.
+
+ <p>The set's iteration order is consistent with the binding order. This is
+ convenient when multiple elements are contributed by the same module because
+ that module can order its bindings appropriately. Avoid relying on the
+ iteration order of elements contributed by different modules, since there is
+ no equivalent mechanism to order modules.
+
+ <p>The set is unmodifiable.  Elements can only be added to the set by
+ configuring the multibinder.  Elements can never be removed from the set.
+
+ <p>Elements are resolved at set injection time. If an element is bound to a
+ provider, that provider's get method will be called each time the set is
+ injected (unless the binding is also scoped).
+
+ <p>Annotations are be used to create different sets of the same element
+ type. Each distinct annotation gets its own independent collection of
+ elements.
+
+ <p><strong>Elements must be distinct.</strong> If multiple bound elements
+ have the same value, set injection will fail.
+
+ <p><strong>Elements must be non-null.</strong> If any set element is null,
+ set injection will fail.
+
+ @author jessewilson@google.com (Jesse Wilson)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.Multibinder -->
+  <!-- start interface com.google.inject.multibindings.MultibinderBinding -->
+  <interface name="MultibinderBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getSetKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key for the set.]]>
+      </doc>
+    </method>
+    <method name="getElementTypeLiteral" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the TypeLiteral that describes the type of elements in the set.
+ <p>
+ The elements will always match the type Set's generic type. For example, if getSetKey returns a
+ key of <code>Set&lt;String></code>, then this will always return a
+ <code>TypeLiteral&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.Binding&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns all bindings that make up the set. This is only supported on bindings returned from an
+ injector. This will throw {@link UnsupportedOperationException} if it is called on an element
+ retrieved from {@link Elements#getElements}.
+ <p>
+ The elements will always match the type Set's generic type. For example, if getSetKey returns a
+ key of <code>Set&lt;String></code>, then this will always return a list of type
+ <code>List&lt;Binding&lt;String>></code>.]]>
+      </doc>
+    </method>
+    <method name="permitsDuplicates" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if the multibinder permits duplicates. This is only supported on bindings returned
+ from an injector. This will throw {@link UnsupportedOperationException} if it is called on a
+ MultibinderBinding retrieved from {@link Elements#getElements}.]]>
+      </doc>
+    </method>
+    <method name="containsElement" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="element" type="com.google.inject.spi.Element"/>
+      <doc>
+      <![CDATA[Returns true if this Multibinder uses the given Element. This will be true for bindings that
+ derive the elements of the set and other bindings that Multibinder uses internally. This will
+ work for MultibinderBindings retrieved from an injector and {@link Elements#getElements}.
+ Usually this is only necessary if you are working with elements retrieved from modules (without
+ an Injector), otherwise {@link #getElements} and {@link #permitsDuplicates} are better options.
+ <p>
+ If you need to introspect the details of the set, such as the values or if it permits
+ duplicates, it is necessary to pass the elements through an Injector and use
+ {@link #getElements()} and {@link #permitsDuplicates()}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding for a Multibinder.
+ 
+ @param <T> The fully qualified type of the set, including Set. For example:
+          <code>MultibinderBinding&lt;Set&lt;Boolean>></code>
+ 
+ @since 3.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.multibindings.MultibinderBinding -->
+  <!-- start class com.google.inject.multibindings.MultibindingsScanner -->
+  <class name="MultibindingsScanner" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="asModule" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a module that, when installed, will scan all modules for methods with the annotations
+ {@literal @}{@link ProvidesIntoMap}, {@literal @}{@link ProvidesIntoSet}, and
+ {@literal @}{@link ProvidesIntoOptional}.
+ 
+ <p>This is a convenience method, equivalent to doing
+ {@code binder().scanModulesForAnnotatedMethods(MultibindingsScanner.scanner())}.]]>
+      </doc>
+    </method>
+    <method name="scanner" return="com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a {@link ModuleAnnotatedMethodScanner} that, when bound, will scan all modules for
+ methods with the annotations {@literal @}{@link ProvidesIntoMap},
+ {@literal @}{@link ProvidesIntoSet}, and {@literal @}{@link ProvidesIntoOptional}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Scans a module for annotations that signal multibindings, mapbindings, and optional bindings.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.MultibindingsScanner -->
+  <!-- start interface com.google.inject.multibindings.MultibindingsTargetVisitor -->
+  <interface name="MultibindingsTargetVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingTargetVisitor&lt;T, V&gt;"/>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="multibinding" type="com.google.inject.multibindings.MultibinderBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits a binding created through {@link Multibinder}.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="mapbinding" type="com.google.inject.multibindings.MapBinderBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits a binding created through {@link MapBinder}.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="optionalbinding" type="com.google.inject.multibindings.OptionalBinderBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits a binding created through {@link OptionalBinder}.
+ 
+ @since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A visitor for the multibinder extension.
+ <p>
+ If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ {@link Multibinder}, {@link MapBinder} or {@link OptionalBinderBinding} will be visited through
+ this interface.
+
+ @since 3.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.multibindings.MultibindingsTargetVisitor -->
+  <!-- start class com.google.inject.multibindings.OptionalBinder -->
+  <class name="OptionalBinder" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+    </method>
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+    </method>
+    <method name="newOptionalBinder" return="com.google.inject.multibindings.OptionalBinder&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="type" type="com.google.inject.Key&lt;T&gt;"/>
+    </method>
+    <method name="setDefault" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a binding builder used to set the default value that will be injected.
+ The binding set by this method will be ignored if {@link #setBinding} is called.
+ 
+ <p>It is an error to call this method without also calling one of the {@code to}
+ methods on the returned binding builder.]]>
+      </doc>
+    </method>
+    <method name="setBinding" return="com.google.inject.binder.LinkedBindingBuilder&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a binding builder used to set the actual value that will be injected.
+ This overrides any binding set by {@link #setDefault}.
+ 
+ <p>It is an error to call this method without also calling one of the {@code to}
+ methods on the returned binding builder.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An API to bind optional values, optionally with a default value.
+ OptionalBinder fulfills two roles: <ol>
+ <li>It allows a framework to define an injection point that may or
+     may not be bound by users.
+ <li>It allows a framework to supply a default value that can be changed
+     by users.
+ </ol>
+ 
+ <p>When an OptionalBinder is added, it will always supply the bindings:
+ {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
+ {@link #setBinding} or {@link #setDefault} are called, it will also
+ bind {@code T}.
+ 
+ <p>{@code setDefault} is intended for use by frameworks that need a default
+ value.  User code can call {@code setBinding} to override the default.
+ <b>Warning: Even if setBinding is called, the default binding
+ will still exist in the object graph.  If it is a singleton, it will be
+ instantiated in {@code Stage.PRODUCTION}.</b>
+ 
+ <p>If setDefault or setBinding are linked to Providers, the Provider may return
+ {@code null}.  If it does, the Optional bindings will be absent.  Binding
+ setBinding to a Provider that returns null will not cause OptionalBinder
+ to fall back to the setDefault binding.
+ 
+ <p>If neither setDefault nor setBinding are called, it will try to link to a
+ user-supplied binding of the same type.  If no binding exists, the optionals
+ will be absent.  Otherwise, if a user-supplied binding of that type exists,
+ or if setBinding or setDefault are called, the optionals will return present
+ if they are bound to a non-null value.
+
+ <p>Values are resolved at injection time. If a value is bound to a
+ provider, that provider's get method will be called each time the optional
+ is injected (unless the binding is also scoped, or an optional of provider is
+ injected).
+ 
+ <p>Annotations are used to create different optionals of the same key/value
+ type. Each distinct annotation gets its own independent binding.
+  
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
+   }
+ }</code></pre>
+
+ <p>With this module, an {@link Optional}{@code <Renamer>} can now be
+ injected.  With no other bindings, the optional will be absent.
+ Users can specify bindings in one of two ways:
+ 
+ <p>Option 1:
+ <pre><code>
+ public class UserRenamerModule extends AbstractModule {
+   protected void configure() {
+     bind(Renamer.class).to(ReplacingRenamer.class);
+   }
+ }</code></pre>
+ 
+ <p>or Option 2:
+ <pre><code>
+ public class UserRenamerModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
+         .setBinding().to(ReplacingRenamer.class);
+   }
+ }</code></pre>
+ With both options, the {@code Optional<Renamer>} will be present and supply the
+ ReplacingRenamer. 
+ 
+ <p>Default values can be supplied using:
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+   }
+ }</code></pre>
+ With the above module, code can inject an {@code @LookupUrl String} and it
+ will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
+ <pre><code>
+ public class UserLookupModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
+   }
+ }</code></pre>
+ ... which will override the default value.
+ 
+ <p>If one module uses setDefault the only way to override the default is to use setBinding.
+ It is an error for a user to specify the binding without using OptionalBinder if
+ setDefault or setBinding are called.  For example, 
+ <pre><code>
+ public class FrameworkModule extends AbstractModule {
+   protected void configure() {
+     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
+         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
+   }
+ }
+ public class UserLookupModule extends AbstractModule {
+   protected void configure() {
+     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
+   } 
+ }</code></pre>
+ ... would generate an error, because both the framework and the user are trying to bind
+ {@code @LookupUrl String}. 
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.OptionalBinder -->
+  <!-- start interface com.google.inject.multibindings.OptionalBinderBinding -->
+  <interface name="OptionalBinderBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the {@link Key} for this binding.]]>
+      </doc>
+    </method>
+    <method name="getDefaultBinding" return="com.google.inject.Binding&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the default binding (set by {@link OptionalBinder#setDefault}) if one exists or null
+ if no default binding is set. This will throw {@link UnsupportedOperationException} if it is
+ called on an element retrieved from {@link Elements#getElements}.
+ <p>
+ The Binding's type will always match the type Optional's generic type. For example, if getKey
+ returns a key of <code>Optional&lt;String></code>, then this will always return a
+ <code>Binding&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="getActualBinding" return="com.google.inject.Binding&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the actual binding (set by {@link OptionalBinder#setBinding}) or null if not set.
+ This will throw {@link UnsupportedOperationException} if it is called on an element retrieved
+ from {@link Elements#getElements}.
+ <p>
+ The Binding's type will always match the type Optional's generic type. For example, if getKey
+ returns a key of <code>Optional&lt;String></code>, then this will always return a
+ <code>Binding&lt;String></code>.]]>
+      </doc>
+    </method>
+    <method name="containsElement" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="element" type="com.google.inject.spi.Element"/>
+      <doc>
+      <![CDATA[Returns true if this OptionalBinder contains the given Element in order to build the optional
+ binding or uses the given Element in order to support building and injecting its data. This
+ will work for OptionalBinderBinding retrieved from an injector and
+ {@link Elements#getElements}. Usually this is only necessary if you are working with elements
+ retrieved from modules (without an Injector), otherwise {@link #getDefaultBinding} and
+ {@link #getActualBinding} are better options.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding for a OptionalBinder.
+ 
+ <p>Although OptionalBinders may be injected through a variety of types
+ {@code T}, {@code Optional<T>}, {@code Optional<Provider<T>>}, etc..), an
+ OptionalBinderBinding exists only on the Binding associated with the
+ {@code Optional<T>} key.  Other bindings can be validated to be derived from this
+ OptionalBinderBinding using {@link #containsElement}.
+ 
+ @param <T> The fully qualified type of the optional binding, including Optional.
+        For example: {@code Optional<String>}.
+ 
+ @since 4.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.multibindings.OptionalBinderBinding -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoMap -->
+  <class name="ProvidesIntoMap"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link MapBinder}.
+ The method's return type, binding annotation and additional key annotation determines
+ what Map this will contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoMap
+ {@literal @}StringMapKey("Foo")
+ {@literal @}Named("plugins")
+ Plugin provideFooUrl(FooManager fm) { return fm.getPlugin(); }
+
+ {@literal @}ProvidesIntoMap
+ {@literal @}StringMapKey("Bar")
+ {@literal @}Named("urls")
+ Plugin provideBarUrl(BarManager bm) { return bm.getPlugin(); }
+ </pre>
+
+ will add two items to the {@code @Named("urls") Map<String, Plugin>} map. The key 'Foo'
+ will map to the provideFooUrl method, and the key 'Bar' will map to the provideBarUrl method.
+ The values are bound as providers and will be evaluated at injection time.
+
+ <p>Because the key is specified as an annotation, only Strings, Classes, enums, primitive
+ types and annotation instances are supported as keys.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoMap -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoOptional -->
+  <class name="ProvidesIntoOptional"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
+ The method's return type and binding annotation determines what Optional this will
+ contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoOptional(DEFAULT)
+ {@literal @}Named("url")
+ String provideFooUrl(FooManager fm) { returm fm.getUrl(); }
+
+ {@literal @}ProvidesIntoOptional(ACTUAL)
+ {@literal @}Named("url")
+ String provideBarUrl(BarManager bm) { return bm.getUrl(); }
+ </pre>
+
+ will set the default value of {@code @Named("url") Optional<String>} to foo's URL,
+ and then override it to bar's URL.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoOptional -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoOptional.Type -->
+  <class name="ProvidesIntoOptional.Type" extends="java.lang.Enum&lt;com.google.inject.multibindings.ProvidesIntoOptional.Type&gt;"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.multibindings.ProvidesIntoOptional.Type[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.multibindings.ProvidesIntoOptional.Type"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[@since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoOptional.Type -->
+  <!-- start class com.google.inject.multibindings.ProvidesIntoSet -->
+  <class name="ProvidesIntoSet"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link Module} to add items to a {@link Multibinder}.
+ The method's return type and binding annotation determines what Set this will
+ contribute to. For example,
+
+ <pre>
+ {@literal @}ProvidesIntoSet
+ {@literal @}Named("urls")
+ String provideFooUrl(FooManager fm) { returm fm.getUrl(); }
+
+ {@literal @}ProvidesIntoSet
+ {@literal @}Named("urls")
+ String provideBarUrl(BarManager bm) { return bm.getUrl(); }
+ </pre>
+
+ will add two items to the {@code @Named("urls") Set<String>} set. The items are bound as
+ providers and will be evaluated at injection time.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.ProvidesIntoSet -->
+  <!-- start class com.google.inject.multibindings.StringMapKey -->
+  <class name="StringMapKey"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Allows {@literal @}{@link ProvidesIntoMap} to specify a string map key.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.multibindings.StringMapKey -->
+</package>
+<package name="com.google.inject.name">
+  <!-- start class com.google.inject.name.Named -->
+  <class name="Named"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates named things.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.name.Named -->
+  <!-- start class com.google.inject.name.Names -->
+  <class name="Names" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="named" return="com.google.inject.name.Named"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Creates a {@link Named} annotation with {@code name} as the value.]]>
+      </doc>
+    </method>
+    <method name="bindProperties"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="properties" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[Creates a constant binding to {@code @Named(key)} for each entry in
+ {@code properties}.]]>
+      </doc>
+    </method>
+    <method name="bindProperties"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="properties" type="java.util.Properties"/>
+      <doc>
+      <![CDATA[Creates a constant binding to {@code @Named(key)} for each property. This
+ method binds all properties including those inherited from 
+ {@link Properties#defaults defaults}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Utility methods for use with {@code @}{@link Named}.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.name.Names -->
+</package>
+<package name="com.google.inject.persist">
+  <!-- start class com.google.inject.persist.PersistFilter -->
+  <class name="PersistFilter" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="javax.servlet.Filter"/>
+    <constructor name="PersistFilter" type="com.google.inject.persist.UnitOfWork, com.google.inject.persist.PersistService"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="init"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterConfig" type="javax.servlet.FilterConfig"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
+    </method>
+    <method name="destroy"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="doFilter"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletRequest" type="javax.servlet.ServletRequest"/>
+      <param name="servletResponse" type="javax.servlet.ServletResponse"/>
+      <param name="filterChain" type="javax.servlet.FilterChain"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
+    </method>
+    <doc>
+    <![CDATA[Apply this filter to enable the HTTP Request unit of work and to have
+ guice-persist manage the lifecycle of active units of work.
+ The filter automatically starts and stops the relevant {@link PersistService}
+ upon {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and
+ {@link javax.servlet.Filter#destroy()} respectively.
+
+ <p> To be able to use the open session-in-view pattern (i.e. work per request),
+ register this filter <b>once</b> in your Guice {@code ServletModule}. It is
+ important that you register this filter before any other filter.
+
+ For multiple providers, you should register this filter once per provider, inside
+ a private module for each persist module installed (this must be the same private
+ module where the specific persist module is itself installed).
+
+ <p>
+ Example configuration:
+ <pre>{@code
+  public class MyModule extends ServletModule {
+    public void configureServlets() {
+      filter("/*").through(PersistFilter.class);
+
+      serve("/index.html").with(MyHtmlServlet.class);
+      // Etc.
+    }
+  }
+ }</pre>
+ <p>
+ This filter is thread safe and allows you to create injectors concurrently
+ and deploy multiple guice-persist modules within the same injector, or even
+ multiple injectors with persist modules withing the same JVM or web app.
+ <p>
+ This filter requires the Guice Servlet extension.
+
+ @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.PersistFilter -->
+  <!-- start class com.google.inject.persist.PersistModule -->
+  <class name="PersistModule" extends="com.google.inject.AbstractModule"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="PersistModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="configurePersistence"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="getTransactionInterceptor" return="org.aopalliance.intercept.MethodInterceptor"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Install this module to add guice-persist library support for JPA persistence
+ providers.
+
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.PersistModule -->
+  <!-- start interface com.google.inject.persist.PersistService -->
+  <interface name="PersistService"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="start"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Starts the underlying persistence engine and makes guice-persist ready for
+ use. For instance, with JPA, it creates an EntityManagerFactory and may
+ open connection pools. This method must be called by your code prior to
+ using any guice-persist or JPA artifacts. If already started,
+ calling this method does nothing, if already stopped, it also does
+ nothing.]]>
+      </doc>
+    </method>
+    <method name="stop"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Stops the underlying persistence engine. For instance, with JPA, it
+ closes the {@code EntityManagerFactory}. If already stopped, calling this
+ method does nothing. If not yet started, it also does nothing.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Persistence provider service. Use this to manage the overall
+ startup and stop of the persistence module(s).
+
+ TODO(dhanji): Integrate with Service API when appropriate.
+
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.persist.PersistService -->
+  <!-- start class com.google.inject.persist.Transactional -->
+  <class name="Transactional"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[<p> Any method or class marked with this annotation will be considered for transactionality.
+ Consult the documentation on https://github.com/google/guice/wiki/GuicePersist for detailed
+ semantics.
+ Marking a method {@code @Transactional} will start a new transaction before the method
+ executes and commit it after the method returns.
+ <p>
+ If the method throws an exception, the transaction will be rolled back <em>unless</em>
+ you have specifically requested not to in the {@link #ignore()} clause.
+ <p>
+ Similarly, the set of exceptions that will trigger a rollback can be defined in
+ the {@link #rollbackOn()} clause. By default, only unchecked exceptions trigger a
+ rollback.
+
+ @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.Transactional -->
+  <!-- start interface com.google.inject.persist.UnitOfWork -->
+  <interface name="UnitOfWork"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="begin"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Starts a Unit Of Work. Underneath, causes a session to the data layer to be opened. If there
+ is already one open, the invocation will do nothing. In this way, you can define arbitrary
+ units-of-work that nest within one another safely.
+
+ Transaction semantics are not affected.]]>
+      </doc>
+    </method>
+    <method name="end"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Declares an end to the current Unit of Work. Underneath, causes any open session to the data
+ layer to close. If there is no Unit of work open, then the call returns silently. You can
+ safely invoke end() repeatedly.
+ <p>
+ Transaction semantics are not affected.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[This interface is used to gain manual control over the unit of work. This is mostly to do
+ work in non-request, non-transactional threads. Or where more fine-grained control over the unit
+ of work is required. Starting and ending a unit of work directly corresponds to opening and
+ closing a {@code Session}, {@code EntityManager} or {@code ObjectContainer} respectively.
+ <p> The
+ Unit of Work referred to by UnitOfWork will always be local to the calling thread. Be careful to
+ end() in a finally block. Neither JPA, nor Hibernate supports threadsafe sessions (reasoning
+ behind thread-locality of Unit of Work semantics).
+
+ <ul>
+   <li>Using UnitOfWork with the PersistFilter inside a request is not recommended.</li>
+   <li>Using UnitOfWork with session-per-txn strategy is not terribly clever either.</li>
+   <li>Using UnitOfWork with session-per-request strategy but *outside* a request (i.e. in a
+       background or bootstrap thread) is probably a good use case.</li>
+  </ul>
+
+ @author Dhanji R. Prasanna (dhanji@gmail com)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.persist.UnitOfWork -->
+</package>
+<package name="com.google.inject.persist.finder">
+  <!-- start class com.google.inject.persist.finder.DynamicFinder -->
+  <class name="DynamicFinder" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="DynamicFinder" type="java.lang.reflect.Method"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="from" return="com.google.inject.persist.finder.DynamicFinder"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="method" type="java.lang.reflect.Method"/>
+      <doc>
+      <![CDATA[Returns some metadata if the method is annotated {@code @Finder} or null.
+
+ @param method a method you want to test as a dynamic finder]]>
+      </doc>
+    </method>
+    <method name="metadata" return="com.google.inject.persist.finder.Finder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Utility that helps you introspect dynamic finder methods.
+
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.finder.DynamicFinder -->
+  <!-- start class com.google.inject.persist.finder.Finder -->
+  <class name="Finder"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Marks a method stub as a dynamic finder. The method is intercepted and replaced with the
+ specified JPAQL query. Provides result auto-boxing and automatic parameter binding.
+
+ @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.finder.Finder -->
+  <!-- start class com.google.inject.persist.finder.FirstResult -->
+  <class name="FirstResult"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotate any dynamic finder method's integer argument with this to pass in
+ the index of the first result in the result set you are interested in.
+ Useful for paging result sets. Complemented by {@link MaxResults}.
+
+ @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.finder.FirstResult -->
+  <!-- start class com.google.inject.persist.finder.MaxResults -->
+  <class name="MaxResults"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotate any dynamic finder method's integer argument with this to pass in
+ the maximum size of returned result window. Usefule for paging result sets.
+ Complement of {@link FirstResult}.
+
+ @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.finder.MaxResults -->
+</package>
+<package name="com.google.inject.persist.jpa">
+  <!-- start class com.google.inject.persist.jpa.JpaPersistModule -->
+  <class name="JpaPersistModule" extends="com.google.inject.persist.PersistModule"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="JpaPersistModule" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configurePersistence"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="getTransactionInterceptor" return="org.aopalliance.intercept.MethodInterceptor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="properties" return="com.google.inject.persist.jpa.JpaPersistModule"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="properties" type="java.util.Map&lt;?, ?&gt;"/>
+      <doc>
+      <![CDATA[Configures the JPA persistence provider with a set of properties.
+ 
+ @param properties A set of name value pairs that configure a JPA persistence
+     provider as per the specification.
+ @since 4.0 (since 3.0 with a parameter type of {@code java.util.Properties})]]>
+      </doc>
+    </method>
+    <method name="addFinder" return="com.google.inject.persist.jpa.JpaPersistModule"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="iface" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Adds an interface to this module to use as a dynamic finder.
+
+ @param iface Any interface type whose methods are all dynamic finders.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[JPA provider for guice persist.
+
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.persist.jpa.JpaPersistModule -->
+</package>
+<package name="com.google.inject.servlet">
+  <!-- start class com.google.inject.servlet.GuiceFilter -->
+  <class name="GuiceFilter" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="javax.servlet.Filter"/>
+    <constructor name="GuiceFilter"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="doFilter"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletRequest" type="javax.servlet.ServletRequest"/>
+      <param name="servletResponse" type="javax.servlet.ServletResponse"/>
+      <param name="filterChain" type="javax.servlet.FilterChain"/>
+      <exception name="IOException" type="java.io.IOException"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
+    </method>
+    <method name="init"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterConfig" type="javax.servlet.FilterConfig"/>
+      <exception name="ServletException" type="javax.servlet.ServletException"/>
+    </method>
+    <method name="destroy"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[<p>
+ Apply this filter in web.xml above all other filters (typically), to all requests where you plan
+  to use servlet scopes. This is also needed in order to dispatch requests to injectable filters
+  and servlets:
+  <pre>
+  &lt;filter&gt;
+    &lt;filter-name&gt;guiceFilter&lt;/filter-name&gt;
+    &lt;filter-class&gt;<b>com.google.inject.servlet.GuiceFilter</b>&lt;/filter-class&gt;
+  &lt;/filter&gt;
+
+  &lt;filter-mapping&gt;
+    &lt;filter-name&gt;guiceFilter&lt;/filter-name&gt;
+    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+  &lt;/filter-mapping&gt;
+  </pre>
+
+ This filter must appear before every filter that makes use of Guice injection or servlet
+ scopes functionality. Typically, you will only register this filter in web.xml and register
+ any other filters (and servlets) using a {@link ServletModule}.
+
+ @author crazybob@google.com (Bob Lee)
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.GuiceFilter -->
+  <!-- start class com.google.inject.servlet.GuiceServletContextListener -->
+  <class name="GuiceServletContextListener" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="javax.servlet.ServletContextListener"/>
+    <constructor name="GuiceServletContextListener"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="contextInitialized"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletContextEvent" type="javax.servlet.ServletContextEvent"/>
+    </method>
+    <method name="contextDestroyed"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletContextEvent" type="javax.servlet.ServletContextEvent"/>
+    </method>
+    <method name="getInjector" return="com.google.inject.Injector"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Override this method to create (or otherwise obtain a reference to) your
+ injector.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[As of Guice 2.0 you can still use (your subclasses of) {@code GuiceServletContextListener}
+ class as a logical place to create and configure your injector. This will ensure the injector
+ is created when the web application is deployed.
+ 
+ @author Kevin Bourrillion (kevinb@google.com)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.GuiceServletContextListener -->
+  <!-- start interface com.google.inject.servlet.InstanceFilterBinding -->
+  <interface name="InstanceFilterBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.servlet.ServletModuleBinding"/>
+    <method name="getFilterInstance" return="javax.servlet.Filter"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the filter instance that will be used.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a single instance of a filter. 
+
+ @author sameb@google.com
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.InstanceFilterBinding -->
+  <!-- start interface com.google.inject.servlet.InstanceServletBinding -->
+  <interface name="InstanceServletBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.servlet.ServletModuleBinding"/>
+    <method name="getServletInstance" return="javax.servlet.http.HttpServlet"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the servlet instance that will be used.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a single instance of a servlet. 
+
+ @author sameb@google.com
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.InstanceServletBinding -->
+  <!-- start interface com.google.inject.servlet.LinkedFilterBinding -->
+  <interface name="LinkedFilterBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.servlet.ServletModuleBinding"/>
+    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key used to lookup the filter instance.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A linked binding to a filter. 
+
+ @author sameb@google.com
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.LinkedFilterBinding -->
+  <!-- start interface com.google.inject.servlet.LinkedServletBinding -->
+  <interface name="LinkedServletBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.servlet.ServletModuleBinding"/>
+    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key used to lookup the servlet instance.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A linked binding to a servlet. 
+
+ @author sameb@google.com
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.LinkedServletBinding -->
+  <!-- start class com.google.inject.servlet.RequestParameters -->
+  <class name="RequestParameters"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Apply this to field or parameters of type {@code Map<String, String[]>}
+ when you want the HTTP request parameter map to be injected.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.RequestParameters -->
+  <!-- start class com.google.inject.servlet.RequestScoped -->
+  <class name="RequestScoped"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Apply this to implementation classes when you want one instance per request.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.RequestScoped -->
+  <!-- start interface com.google.inject.servlet.RequestScoper -->
+  <interface name="RequestScoper"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="open" return="com.google.inject.servlet.RequestScoper.CloseableScope"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Opens up the request scope until the returned object is closed.
+ Implementations should ensure (e.g. by blocking) that multiple threads
+ cannot open the same request scope concurrently. It is allowable to open
+ the same request scope on the same thread, as long as open/close calls are
+ correctly nested.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Object that can be used to apply a request scope to a block of code.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.RequestScoper -->
+  <!-- start interface com.google.inject.servlet.RequestScoper.CloseableScope -->
+  <interface name="RequestScoper.CloseableScope"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.io.Closeable"/>
+    <method name="close"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Closeable subclass that does not throw any exceptions from close.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.RequestScoper.CloseableScope -->
+  <!-- start class com.google.inject.servlet.ScopingException -->
+  <class name="ScopingException" extends="java.lang.IllegalStateException"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ScopingException" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[Exception thrown when there was a failure entering request scope.
+
+ @author Chris Nokleberg
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.ScopingException -->
+  <!-- start class com.google.inject.servlet.ScopingOnly -->
+  <class name="ScopingOnly"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates a {@link GuiceFilter} that provides scope functionality, but
+ doesn't dispatch to {@link ServletModule} bound servlets or filters.
+
+ @author iqshum@google.com (Isaac Shum)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.ScopingOnly -->
+  <!-- start class com.google.inject.servlet.ServletModule -->
+  <class name="ServletModule" extends="com.google.inject.AbstractModule"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ServletModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <method name="configureServlets"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[<h3>Servlet Mapping EDSL</h3>
+
+ <p> Part of the EDSL builder language for configuring servlets
+ and filters with guice-servlet. Think of this as an in-code replacement for web.xml.
+ Filters and servlets are configured here using simple java method calls. Here is a typical
+ example of registering a filter when creating your Guice injector:
+
+ <pre>
+   Guice.createInjector(..., new ServletModule() {
+
+     {@literal @}Override
+     protected void configureServlets() {
+       <b>serve("*.html").with(MyServlet.class)</b>
+     }
+   }
+ </pre>
+
+ This registers a servlet (subclass of {@code HttpServlet}) called {@code MyServlet} to service
+ any web pages ending in {@code .html}. You can also use a path-style syntax to register
+ servlets:
+
+ <pre>
+       <b>serve("/my/*").with(MyServlet.class)</b>
+ </pre>
+
+ Every servlet (or filter) is required to be a singleton. If you cannot annotate the class
+ directly, you should add a separate {@code bind(..).in(Singleton.class)} rule elsewhere in
+ your module. Mapping a servlet that is bound under any other scope is an error.
+
+ <p>
+ <h4>Dispatch Order</h4>
+ You are free to register as many servlets and filters as you like this way. They will
+ be compared and dispatched in the order in which the filter methods are called:
+
+ <pre>
+
+   Guice.createInjector(..., new ServletModule() {
+
+     {@literal @}Override
+     protected void configureServlets() {
+       filter("/*").through(MyFilter.class);
+       filter("*.css").through(MyCssFilter.class);
+       filter("*.jpg").through(new MyJpgFilter());
+       // etc..
+
+       serve("*.html").with(MyServlet.class);
+       serve("/my/*").with(MyServlet.class);
+       serve("*.jpg").with(new MyServlet());
+       // etc..
+      }
+    }
+ </pre>
+ This will traverse down the list of rules in lexical order. For example, a url
+  "{@code /my/file.js}" (after it runs through the matching filters) will first
+  be compared against the servlet mapping:
+ 
+ <pre>
+       serve("*.html").with(MyServlet.class);
+ </pre>
+ And failing that, it will descend to the next servlet mapping:
+
+ <pre>
+       serve("/my/*").with(MyServlet.class);
+ </pre>
+
+ Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These
+ two mapping rules can also be written in more compact form using varargs syntax:
+
+ <pre>
+       serve(<b>"*.html", "/my/*"</b>).with(MyServlet.class);
+ </pre>
+ 
+ This way you can map several URI patterns to the same servlet. A similar syntax is
+ also available for filter mappings.
+
+ <p>
+ <h4>Regular Expressions</h4>
+ You can also map servlets (or filters) to URIs using regular expressions:
+ <pre>
+    <b>serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)</b>
+ </pre>
+
+ This will map any URI containing the text "ajax" in it to {@code MyAjaxServlet}. Such as:
+ <ul>
+ <li>http://www.google.com/ajax.html</li>
+ <li>http://www.google.com/content/ajax/index</li>
+ <li>http://www.google.com/it/is_totally_ajaxian</li>
+ </ul>
+
+
+ <h3>Initialization Parameters</h3>
+
+ Servlets (and filters) allow you to pass in init params
+ using the {@code <init-param>} tag in web.xml. You can similarly pass in parameters to
+ Servlets and filters registered in Guice-servlet using a {@link java.util.Map} of parameter
+ name/value pairs. For example, to initialize {@code MyServlet} with two parameters
+ ({@code name="Dhanji", site="google.com"}) you could write:
+
+ <pre>
+  Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
+  params.put("name", "Dhanji");
+  params.put("site", "google.com");
+
+  ...
+      serve("/*").with(MyServlet.class, <b>params</b>)
+ </pre>
+
+ <p>
+ <h3>Binding Keys</h3>
+
+ You can also bind keys rather than classes. This lets you hide
+ implementations with package-local visbility and expose them using
+ only a Guice module and an annotation:
+
+ <pre>
+  ...
+      filter("/*").through(<b>Key.get(Filter.class, Fave.class)</b>);
+ </pre>
+
+ Where {@code Filter.class} refers to the Servlet API interface and {@code Fave.class} is a
+ custom binding annotation. Elsewhere (in one of your own modules) you can bind this
+ filter's implementation:
+
+ <pre>
+   bind(Filter.class)<b>.annotatedWith(Fave.class)</b>.to(MyFilterImpl.class);
+ </pre>
+
+ See {@link com.google.inject.Binder} for more information on binding syntax.
+
+ <p>
+ <h3>Multiple Modules</h3>
+
+ It is sometimes useful to capture servlet and filter mappings from multiple different
+ modules. This is essential if you want to package and offer drop-in Guice plugins that
+ provide servlet functionality.
+
+ <p>
+ Guice Servlet allows you to register several instances of {@code ServletModule} to your
+ injector. The order in which these modules are installed determines the dispatch order
+ of filters and the precedence order of servlets. For example, if you had two servlet modules,
+ {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped
+ to the same URI pattern, {@code "/*"}:
+
+ <p>
+ In {@code RpcModule}:
+ <pre>
+     filter("/*").through(RpcFilter.class);
+ </pre>
+
+ In {@code WebServiceModule}:
+ <pre>
+     filter("/*").through(WebServiceFilter.class);
+ </pre>
+
+ Then the order in which these filters are dispatched is determined by the order in which
+ the modules are installed:
+
+ <pre>
+   <b>install(new WebServiceModule());</b>
+   install(new RpcModule());
+ </pre>
+
+ In the case shown above {@code WebServiceFilter} will run first.
+ 
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="filter" return="com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="urlPattern" type="java.lang.String"/>
+      <param name="morePatterns" type="java.lang.String[]"/>
+      <doc>
+      <![CDATA[@param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="filter" return="com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="urlPatterns" type="java.lang.Iterable&lt;java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@param urlPatterns Any Servlet-style patterns. examples: /*, /html/*, *.html, etc.
+ @since 4.1]]>
+      </doc>
+    </method>
+    <method name="filterRegex" return="com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="regex" type="java.lang.String"/>
+      <param name="regexes" type="java.lang.String[]"/>
+      <doc>
+      <![CDATA[@param regex Any Java-style regular expression.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="filterRegex" return="com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="regexes" type="java.lang.Iterable&lt;java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@param regexes Any Java-style regular expressions.
+ @since 4.1]]>
+      </doc>
+    </method>
+    <method name="serve" return="com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="urlPattern" type="java.lang.String"/>
+      <param name="morePatterns" type="java.lang.String[]"/>
+      <doc>
+      <![CDATA[@param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="serve" return="com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="urlPatterns" type="java.lang.Iterable&lt;java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@param urlPatterns Any Servlet-style patterns. examples: /*, /html/*, *.html, etc.
+ @since 4.1]]>
+      </doc>
+    </method>
+    <method name="serveRegex" return="com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="regex" type="java.lang.String"/>
+      <param name="regexes" type="java.lang.String[]"/>
+      <doc>
+      <![CDATA[@param regex Any Java-style regular expression.
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="serveRegex" return="com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <param name="regexes" type="java.lang.Iterable&lt;java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@param regexes Any Java-style regular expressions.
+ @since 4.1]]>
+      </doc>
+    </method>
+    <method name="getServletContext" return="javax.servlet.ServletContext"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="true" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This method only works if you are using the {@linkplain GuiceServletContextListener} to
+ create your injector. Otherwise, it returns null.
+ @return The current servlet context.
+ @since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Configures the servlet scopes and creates bindings for the servlet API
+ objects so you can inject the request, response, session, etc.
+
+ <p>
+ You should subclass this module to register servlets and
+ filters in the {@link #configureServlets()} method.
+
+ @author crazybob@google.com (Bob Lee)
+ @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.ServletModule -->
+  <!-- start interface com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder -->
+  <interface name="ServletModule.FilterKeyBindingBuilder"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterKey" type="java.lang.Class&lt;? extends javax.servlet.Filter&gt;"/>
+    </method>
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterKey" type="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"/>
+    </method>
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filter" type="javax.servlet.Filter"/>
+      <doc>
+      <![CDATA[@since 3.0]]>
+      </doc>
+    </method>
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterKey" type="java.lang.Class&lt;? extends javax.servlet.Filter&gt;"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+    </method>
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filterKey" type="com.google.inject.Key&lt;? extends javax.servlet.Filter&gt;"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+    </method>
+    <method name="through"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="filter" type="javax.servlet.Filter"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link ServletModule#configureServlets()}
+
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.ServletModule.FilterKeyBindingBuilder -->
+  <!-- start interface com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder -->
+  <interface name="ServletModule.ServletKeyBindingBuilder"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletKey" type="java.lang.Class&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
+    </method>
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletKey" type="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
+    </method>
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servlet" type="javax.servlet.http.HttpServlet"/>
+      <doc>
+      <![CDATA[@since 3.0]]>
+      </doc>
+    </method>
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletKey" type="java.lang.Class&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+    </method>
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servletKey" type="com.google.inject.Key&lt;? extends javax.servlet.http.HttpServlet&gt;"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+    </method>
+    <method name="with"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="servlet" type="javax.servlet.http.HttpServlet"/>
+      <param name="initParams" type="java.util.Map&lt;java.lang.String, java.lang.String&gt;"/>
+      <doc>
+      <![CDATA[@since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL examples at {@link ServletModule#configureServlets()}
+
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.ServletModule.ServletKeyBindingBuilder -->
+  <!-- start interface com.google.inject.servlet.ServletModuleBinding -->
+  <interface name="ServletModuleBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getUriPatternType" return="com.google.inject.servlet.UriPatternType"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the pattern type that this binding was created with.]]>
+      </doc>
+    </method>
+    <method name="getPattern" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the pattern used to match against the binding.]]>
+      </doc>
+    </method>
+    <method name="getInitParams" return="java.util.Map&lt;java.lang.String, java.lang.String&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns any context params supplied when creating the binding.]]>
+      </doc>
+    </method>
+    <method name="matchesUri" return="boolean"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="uri" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Returns true if the given URI will match this binding.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding created by {@link ServletModule}.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.ServletModuleBinding -->
+  <!-- start interface com.google.inject.servlet.ServletModuleTargetVisitor -->
+  <interface name="ServletModuleTargetVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingTargetVisitor&lt;T, V&gt;"/>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.servlet.LinkedFilterBinding"/>
+      <doc>
+      <![CDATA[Visits a filter binding created by {@link ServletModule#filter}, where
+ {@link FilterKeyBindingBuilder#through} is called with a Class or Key.
+ 
+ If multiple patterns were specified, this will be called multiple times.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.servlet.InstanceFilterBinding"/>
+      <doc>
+      <![CDATA[Visits a filter binding created by {@link ServletModule#filter} where
+ {@link FilterKeyBindingBuilder#through} is called with a {@link Filter}.
+ 
+ If multiple patterns were specified, this will be called multiple times.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.servlet.LinkedServletBinding"/>
+      <doc>
+      <![CDATA[Visits a servlet binding created by {@link ServletModule#serve} where
+ {@link ServletKeyBindingBuilder#with}, is called with a Class or Key.
+ 
+ If multiple patterns were specified, this will be called multiple times.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.servlet.InstanceServletBinding"/>
+      <doc>
+      <![CDATA[Visits a servlet binding created by {@link ServletModule#serve} where 
+ {@link ServletKeyBindingBuilder#with}, is called with an {@link HttpServlet}.
+ 
+ If multiple patterns were specified, this will be called multiple times.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A visitor for the servlet extension.
+ 
+ If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ {@link ServletModule} will be visited through this interface.
+ 
+ @since 3.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.servlet.ServletModuleTargetVisitor -->
+  <!-- start class com.google.inject.servlet.ServletScopes -->
+  <class name="ServletScopes" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="continueRequest" return="java.util.concurrent.Callable&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="You probably want to use {@code transferRequest} instead">
+      <param name="callable" type="java.util.concurrent.Callable&lt;T&gt;"/>
+      <param name="seedMap" type="java.util.Map&lt;com.google.inject.Key&lt;?&gt;, java.lang.Object&gt;"/>
+      <doc>
+      <![CDATA[Wraps the given callable in a contextual callable that "continues" the
+ HTTP request in another thread. This acts as a way of transporting
+ request context data from the request processing thread to to worker
+ threads.
+ <p>
+ There are some limitations:
+ <ul>
+   <li>Derived objects (i.e. anything marked @RequestScoped will not be
+      transported.</li>
+   <li>State changes to the HttpServletRequest after this method is called
+      will not be seen in the continued thread.</li>
+   <li>Only the HttpServletRequest, ServletContext and request parameter
+      map are available in the continued thread. The response and session
+      are not available.</li>
+ </ul>
+
+ <p>The returned callable will throw a {@link ScopingException} when called
+ if the HTTP request scope is still active on the current thread.
+
+ @param callable code to be executed in another thread, which depends on
+     the request scope.
+ @param seedMap the initial set of scoped instances for Guice to seed the
+     request scope with.  To seed a key with null, use {@code null} as
+     the value.
+ @return a callable that will invoke the given callable, making the request
+     context available to it.
+ @throws OutOfScopeException if this method is called from a non-request
+     thread, or if the request has completed.
+ 
+ @since 3.0
+ @deprecated You probably want to use {@code transferRequest} instead]]>
+      </doc>
+    </method>
+    <method name="transferRequest" return="java.util.concurrent.Callable&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="callable" type="java.util.concurrent.Callable&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Wraps the given callable in a contextual callable that "transfers" the
+ request to another thread. This acts as a way of transporting
+ request context data from the current thread to a future thread.
+
+ <p>As opposed to {@link #continueRequest}, this method propagates all
+ existing scoped objects. The primary use case is in server implementations
+ where you can detach the request processing thread while waiting for data,
+ and reattach to a different thread to finish processing at a later time.
+
+ <p>Because request-scoped objects are not typically thread-safe, the
+ callable returned by this method must not be run on a different thread
+ until the current request scope has terminated. The returned callable will
+ block until the current thread has released the request scope.
+
+ @param callable code to be executed in another thread, which depends on
+     the request scope.
+ @return a callable that will invoke the given callable, making the request
+     context available to it.
+ @throws OutOfScopeException if this method is called from a non-request
+     thread, or if the request has completed.
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="transferRequest" return="com.google.inject.servlet.RequestScoper"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns an object that "transfers" the request to another thread. This acts
+ as a way of transporting request context data from the current thread to a
+ future thread. The transferred scope is the one active for the thread that
+ calls this method. A later call to {@code open()} activates the transferred
+ the scope, including propagating any objects scoped at that time.
+
+ <p>As opposed to {@link #continueRequest}, this method propagates all
+ existing scoped objects. The primary use case is in server implementations
+ where you can detach the request processing thread while waiting for data,
+ and reattach to a different thread to finish processing at a later time.
+
+ <p>Because request-scoped objects are not typically thread-safe, it is
+ important to avoid applying the same request scope concurrently. The
+ returned Scoper will block on open until the current thread has released
+ the request scope.
+
+ @return an object that when opened will initiate the request scope
+ @throws OutOfScopeException if this method is called from a non-request
+     thread, or if the request has completed.
+ @since 4.1]]>
+      </doc>
+    </method>
+    <method name="isRequestScoped" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns true if {@code binding} is request-scoped. If the binding is a
+ {@link com.google.inject.spi.LinkedKeyBinding linked key binding} and
+ belongs to an injector (i. e. it was retrieved via
+ {@link Injector#getBinding Injector.getBinding()}), then this method will
+ also return true if the target binding is request-scoped.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="scopeRequest" return="java.util.concurrent.Callable&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="callable" type="java.util.concurrent.Callable&lt;T&gt;"/>
+      <param name="seedMap" type="java.util.Map&lt;com.google.inject.Key&lt;?&gt;, java.lang.Object&gt;"/>
+      <doc>
+      <![CDATA[Scopes the given callable inside a request scope. This is not the same
+ as the HTTP request scope, but is used if no HTTP request scope is in
+ progress. In this way, keys can be scoped as @RequestScoped and exist
+ in non-HTTP requests (for example: RPC requests) as well as in HTTP
+ request threads.
+
+ <p>The returned callable will throw a {@link ScopingException} when called
+ if there is a request scope already active on the current thread.
+
+ @param callable code to be executed which depends on the request scope.
+     Typically in another thread, but not necessarily so.
+ @param seedMap the initial set of scoped instances for Guice to seed the
+     request scope with.  To seed a key with null, use {@code null} as
+     the value.
+ @return a callable that when called will run inside the a request scope
+     that exposes the instances in the {@code seedMap} as scoped keys.
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="scopeRequest" return="com.google.inject.servlet.RequestScoper"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="seedMap" type="java.util.Map&lt;com.google.inject.Key&lt;?&gt;, java.lang.Object&gt;"/>
+      <doc>
+      <![CDATA[Returns an object that will apply request scope to a block of code. This is
+ not the same as the HTTP request scope, but is used if no HTTP request
+ scope is in progress. In this way, keys can be scoped as @RequestScoped and
+ exist in non-HTTP requests (for example: RPC requests) as well as in HTTP
+ request threads.
+
+ <p>The returned object will throw a {@link ScopingException} when opened
+ if there is a request scope already active on the current thread.
+
+ @param seedMap the initial set of scoped instances for Guice to seed the
+     request scope with.  To seed a key with null, use {@code null} as
+     the value.
+ @return an object that when opened will initiate the request scope
+ @since 4.1]]>
+      </doc>
+    </method>
+    <field name="REQUEST" type="com.google.inject.Scope"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[HTTP servlet request scope.]]>
+      </doc>
+    </field>
+    <field name="SESSION" type="com.google.inject.Scope"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[HTTP session scope.]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[Servlet scopes.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.ServletScopes -->
+  <!-- start class com.google.inject.servlet.SessionScoped -->
+  <class name="SessionScoped"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Apply this to implementation classes when you want one instance per session.
+
+ @see com.google.inject.Scopes#SINGLETON
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.SessionScoped -->
+  <!-- start class com.google.inject.servlet.UriPatternType -->
+  <class name="UriPatternType" extends="java.lang.Enum&lt;com.google.inject.servlet.UriPatternType&gt;"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="com.google.inject.servlet.UriPatternType[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="com.google.inject.servlet.UriPatternType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <doc>
+    <![CDATA[An enumeration of the available URI-pattern matching styles
+ 
+ @since 3.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.servlet.UriPatternType -->
+</package>
+<package name="com.google.inject.spi">
+  <!-- start interface com.google.inject.spi.BindingScopingVisitor -->
+  <interface name="BindingScopingVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="visitEagerSingleton" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Visit an eager singleton or single instance. This scope strategy is found on both module and
+ injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visitScope" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scope" type="com.google.inject.Scope"/>
+      <doc>
+      <![CDATA[Visit a scope instance. This scope strategy is found on both module and injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visitScopeAnnotation" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+      <doc>
+      <![CDATA[Visit a scope annotation. This scope strategy is found only on module bindings. The instance
+ that implements this scope is registered by {@link com.google.inject.Binder#bindScope(Class,
+ Scope) Binder.bindScope()}.]]>
+      </doc>
+    </method>
+    <method name="visitNoScoping" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Visit an unspecified or unscoped strategy. On a module, this strategy indicates that the
+ injector should use scoping annotations to find a scope. On an injector, it indicates that
+ no scope is applied to the binding. An unscoped binding will behave like a scoped one when it
+ is linked to a scoped binding.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Visits each of the strategies used to scope an injection.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.BindingScopingVisitor -->
+  <!-- start interface com.google.inject.spi.BindingTargetVisitor -->
+  <interface name="BindingTargetVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.InstanceBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a instance binding. The same instance is returned for every injection. This target is
+ found in both module and injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderInstanceBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a provider instance binding. The provider's {@code get} method is invoked to resolve
+ injections. This target is found in both module and injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderKeyBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a provider key binding. To resolve injections, the provider key is first resolved, then
+ that provider's {@code get} method is invoked. This target is found in both module and injector
+ bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.LinkedKeyBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a linked key binding. The other key's binding is used to resolve injections. This
+ target is found in both module and injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ExposedBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a binding to a key exposed from an enclosed private environment. This target is only
+ found in injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.UntargettedBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit an untargetted binding. This target is found only on module bindings. It indicates
+ that the injector should use its implicit binding strategies to resolve injections.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ConstructorBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a constructor binding. To resolve injections, an instance is instantiated by invoking
+ {@code constructor}. This target is found only on injector bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ConvertedConstantBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a binding created from converting a bound instance to a new type. The source binding
+ has the same binding annotation but a different type. This target is found only on injector
+ bindings.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProviderBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visit a binding to a {@link com.google.inject.Provider} that delegates to the binding for the
+ provided type. This target is found only on injector bindings.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Visits each of the strategies used to find an instance to satisfy an injection.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.BindingTargetVisitor -->
+  <!-- start interface com.google.inject.spi.ConstructorBinding -->
+  <interface name="ConstructorBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getConstructor" return="com.google.inject.spi.InjectionPoint"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the constructor this binding injects.]]>
+      </doc>
+    </method>
+    <method name="getInjectableMembers" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns all instance method and field injection points on {@code type}.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.]]>
+      </doc>
+    </method>
+    <method name="getMethodInterceptors" return="java.util.Map&lt;java.lang.reflect.Method, java.util.List&lt;org.aopalliance.intercept.MethodInterceptor&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the interceptors applied to each method, in the order that they will be applied.
+
+ @return a possibly empty map]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to the constructor of a concrete clss. To resolve injections, an instance is
+ instantiated by invoking the constructor.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ConstructorBinding -->
+  <!-- start interface com.google.inject.spi.ConvertedConstantBinding -->
+  <interface name="ConvertedConstantBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getValue" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the converted value.]]>
+      </doc>
+    </method>
+    <method name="getTypeConverterBinding" return="com.google.inject.spi.TypeConverterBinding"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the type converter binding used to convert the constant.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="getSourceKey" return="com.google.inject.Key&lt;java.lang.String&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key for the source binding. That binding can be retrieved from an injector using
+ {@link com.google.inject.Injector#getBinding(Key) Injector.getBinding(key)}.]]>
+      </doc>
+    </method>
+    <method name="getDependencies" return="java.util.Set&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a singleton set containing only the converted key.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding created from converting a bound instance to a new type. The source binding has the same
+ binding annotation but a different type.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ConvertedConstantBinding -->
+  <!-- start class com.google.inject.spi.DefaultBindingScopingVisitor -->
+  <class name="DefaultBindingScopingVisitor" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingScopingVisitor&lt;V&gt;"/>
+    <constructor name="DefaultBindingScopingVisitor"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="visitOther" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Default visit implementation. Returns {@code null}.]]>
+      </doc>
+    </method>
+    <method name="visitEagerSingleton" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="visitScope" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scope" type="com.google.inject.Scope"/>
+    </method>
+    <method name="visitScopeAnnotation" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeAnnotation" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+    </method>
+    <method name="visitNoScoping" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[No-op visitor for subclassing. All interface methods simply delegate to
+ {@link #visitOther()}, returning its result.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+ 
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.DefaultBindingScopingVisitor -->
+  <!-- start class com.google.inject.spi.DefaultBindingTargetVisitor -->
+  <class name="DefaultBindingTargetVisitor" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingTargetVisitor&lt;T, V&gt;"/>
+    <constructor name="DefaultBindingTargetVisitor"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="visitOther" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Default visit implementation. Returns {@code null}.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instanceBinding" type="com.google.inject.spi.InstanceBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerInstanceBinding" type="com.google.inject.spi.ProviderInstanceBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerKeyBinding" type="com.google.inject.spi.ProviderKeyBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="linkedKeyBinding" type="com.google.inject.spi.LinkedKeyBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="exposedBinding" type="com.google.inject.spi.ExposedBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="untargettedBinding" type="com.google.inject.spi.UntargettedBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="constructorBinding" type="com.google.inject.spi.ConstructorBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="convertedConstantBinding" type="com.google.inject.spi.ConvertedConstantBinding&lt;? extends T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerBinding" type="com.google.inject.spi.ProviderBinding&lt;? extends T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[No-op visitor for subclassing. All interface methods simply delegate to {@link
+ #visitOther(Binding)}, returning its result.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.DefaultBindingTargetVisitor -->
+  <!-- start class com.google.inject.spi.DefaultElementVisitor -->
+  <class name="DefaultElementVisitor" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.ElementVisitor&lt;V&gt;"/>
+    <constructor name="DefaultElementVisitor"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="visitOther" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+      <param name="element" type="com.google.inject.spi.Element"/>
+      <doc>
+      <![CDATA[Default visit implementation. Returns {@code null}.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="interceptorBinding" type="com.google.inject.spi.InterceptorBinding"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeBinding" type="com.google.inject.spi.ScopeBinding"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeConverterBinding" type="com.google.inject.spi.TypeConverterBinding"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providerLookup" type="com.google.inject.spi.ProviderLookup&lt;T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injectionRequest" type="com.google.inject.spi.InjectionRequest&lt;?&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="staticInjectionRequest" type="com.google.inject.spi.StaticInjectionRequest"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="privateElements" type="com.google.inject.spi.PrivateElements"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="lookup" type="com.google.inject.spi.MembersInjectorLookup&lt;T&gt;"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.TypeListenerBinding"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProvisionListenerBinding"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.DisableCircularProxiesOption"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireExplicitBindingsOption"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireAtInjectOnConstructorsOption"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireExactBindingAnnotationsOption"/>
+    </method>
+    <method name="visit" return="V"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ModuleAnnotatedMethodScannerBinding"/>
+    </method>
+    <doc>
+    <![CDATA[No-op visitor for subclassing. All interface methods simply delegate to
+ {@link #visitOther(Element)}, returning its result.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+
+ @author sberlin@gmail.com (Sam Berlin)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.DefaultElementVisitor -->
+  <!-- start class com.google.inject.spi.Dependency -->
+  <class name="Dependency" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="get" return="com.google.inject.spi.Dependency&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new dependency that is not attached to an injection point. The returned dependency is
+ nullable.]]>
+      </doc>
+    </method>
+    <method name="forInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injectionPoints" type="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"/>
+      <doc>
+      <![CDATA[Returns the dependencies from the given injection points.]]>
+      </doc>
+    </method>
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key to the binding that satisfies this dependency.]]>
+      </doc>
+    </method>
+    <method name="isNullable" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if null is a legal value for this dependency.]]>
+      </doc>
+    </method>
+    <method name="getInjectionPoint" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the injection point to which this dependency belongs, or null if this dependency isn't
+ attached to a particular injection point.]]>
+      </doc>
+    </method>
+    <method name="getParameterIndex" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the index of this dependency in the injection point's parameter list, or {@code -1} if
+ this dependency does not belong to a parameter list. Only method and constuctor dependencies
+ are elements in a parameter list.]]>
+      </doc>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="o" type="java.lang.Object"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[A variable that can be resolved by an injector.
+
+ <p>Use {@link #get} to build a freestanding dependency, or {@link InjectionPoint} to build one
+ that's attached to a constructor, method or field.
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.Dependency -->
+  <!-- start class com.google.inject.spi.DependencyAndSource -->
+  <class name="DependencyAndSource" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="DependencyAndSource" type="com.google.inject.spi.Dependency&lt;?&gt;, java.lang.Object"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getDependency" return="com.google.inject.spi.Dependency&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the Dependency, if one exists. For anything that can be referenced
+ by {@link Injector#getBinding}, a dependency exists. A dependency will not
+ exist (and this will return null) for types initialized with
+ {@link Binder#requestInjection} or {@link Injector#injectMembers(Object)},
+ nor will it exist for objects injected into Providers bound with
+ LinkedBindingBuilder#toProvider(Provider).]]>
+      </doc>
+    </method>
+    <method name="getBindingSource" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a string describing where this dependency was bound. If the binding
+ was just-in-time, there is no valid binding source, so this describes the
+ class in question.]]>
+      </doc>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[A combination of a {@link Dependency} and the {@link Binding#getSource()
+ source} where the dependency was bound.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.DependencyAndSource -->
+  <!-- start class com.google.inject.spi.DisableCircularProxiesOption -->
+  <class name="DisableCircularProxiesOption" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[A request to disable circular proxies.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 3.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.DisableCircularProxiesOption -->
+  <!-- start interface com.google.inject.spi.Element -->
+  <interface name="Element"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getSource" return="java.lang.Object"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns an arbitrary object containing information about the "place" where this element was
+ configured. Used by Guice in the production of descriptive error messages.
+
+ <p>Tools might specially handle types they know about; {@code StackTraceElement} is a good
+ example. Tools should simply call {@code toString()} on the source object if the type is
+ unfamiliar.]]>
+      </doc>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Accepts an element visitor. Invokes the visitor method specific to this element's type.
+
+ @param visitor to call back on]]>
+      </doc>
+    </method>
+    <method name="applyTo"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <doc>
+      <![CDATA[Writes this module element to the given binder (optional operation).
+
+ @param binder to apply configuration element to
+ @throws UnsupportedOperationException if the {@code applyTo} method is not supported by this
+     element.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A core component of a module or injector.
+
+ <p>The elements of a module can be inspected, validated and rewritten. Use {@link
+ Elements#getElements(com.google.inject.Module[]) Elements.getElements()} to read the elements
+ from a module, and {@link Elements#getModule(Iterable) Elements.getModule()} to rewrite them.
+ This can be used for static analysis and generation of Guice modules.
+
+ <p>The elements of an injector can be inspected and exercised. Use {@link
+ com.google.inject.Injector#getBindings Injector.getBindings()} to reflect on Guice injectors.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.Element -->
+  <!-- start class com.google.inject.spi.Elements -->
+  <class name="Elements" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Elements"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.spi.Element&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Records the elements executed by {@code modules}.]]>
+      </doc>
+    </method>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.spi.Element&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="stage" type="com.google.inject.Stage"/>
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Records the elements executed by {@code modules}.]]>
+      </doc>
+    </method>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.spi.Element&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Records the elements executed by {@code modules}.]]>
+      </doc>
+    </method>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.spi.Element&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="stage" type="com.google.inject.Stage"/>
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Records the elements executed by {@code modules}.]]>
+      </doc>
+    </method>
+    <method name="getModule" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="elements" type="java.lang.Iterable&lt;? extends com.google.inject.spi.Element&gt;"/>
+      <doc>
+      <![CDATA[Returns the module composed of {@code elements}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Exposes elements of a module so they can be inspected, validated or {@link
+ Element#applyTo(Binder) rewritten}.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.Elements -->
+  <!-- start class com.google.inject.spi.ElementSource -->
+  <class name="ElementSource" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="getOriginalElementSource" return="com.google.inject.spi.ElementSource"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the {@link ElementSource} of the element this was created or copied from. If this was
+ not created or copied from another element, returns {@code null}.]]>
+      </doc>
+    </method>
+    <method name="getDeclaringSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns a single location in source code that defines the element. It can be any object
+ such as {@link java.lang.reflect.Constructor}, {@link java.lang.reflect.Method},
+ {@link java.lang.reflect.Field}, {@link StackTraceElement}, etc. For
+ example, if the element is created from a method annotated by {@literal @Provides}, the
+ declaring source of element would be the method itself.]]>
+      </doc>
+    </method>
+    <method name="getModuleClassNames" return="java.util.List&lt;java.lang.String&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the class names of modules involved in creating this {@link Element}. The first
+ element (index 0) is the class name of module that defined the element, and the last element
+ is the class name of root module.]]>
+      </doc>
+    </method>
+    <method name="getModuleConfigurePositionsInStackTrace" return="java.util.List&lt;java.lang.Integer&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the position of {@link com.google.inject.Module#configure configure(Binder)} method
+ call in the {@link #getStackTrace stack trace} for modules that their classes returned by
+ {@link #getModuleClassNames}. For example, if the stack trace looks like the following:
+ <p>
+ {@code
+  0 - Binder.bind(),
+  1 - ModuleTwo.configure(),
+  2 - Binder.install(),
+  3 - ModuleOne.configure(),
+  4 - theRest(). 
+ }
+ <p>
+ 1 and 3 are returned.
+ <p>
+ In the cases where stack trace is not available (i.e., the stack trace was not collected),
+ it returns -1 for all module positions.]]>
+      </doc>
+    </method>
+    <method name="getStackTrace" return="java.lang.StackTraceElement[]"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the sequence of method calls that ends at one of {@link com.google.inject.Binder}
+ {@code bindXXX()} methods and eventually defines the element. Note that
+ {@link #getStackTrace} lists {@link StackTraceElement StackTraceElements} in reverse
+ chronological order. The first element (index zero) is the last method call and the last
+ element is the first method invocation. In the cases where stack trace is not available
+ (i.e.,the stack trace was not collected), it returns an empty array.]]>
+      </doc>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns {@code getDeclaringSource().toString()} value.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Contains information about where and how an {@link Element element} was
+ bound.
+ <p>
+ The {@link #getDeclaringSource() declaring source} refers to a location in
+ source code that defines the Guice {@link Element element}. For example, if
+ the element is created from a method annotated by {@literal @Provides}, the
+ declaring source of element would be the method itself.
+ <p>
+ The {@link #getStackTrace()} refers to the sequence of calls ends at one of
+ {@link com.google.inject.Binder} {@code bindXXX()} methods and eventually
+ defines the element. Note that {@link #getStackTrace()} lists
+ {@link StackTraceElement StackTraceElements} in reverse chronological order.
+ The first element (index zero) is the last method call and the last element
+ is the first method invocation. By default, the stack trace is not collected.
+ The default behavior can be changed by setting the
+ {@code guice_include_stack_traces} flag value. The value can be either
+ {@code OFF}, {@code ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that
+ collecting stack traces for every binding can cause a performance hit when
+ the injector is created.
+ <p>
+ The sequence of class names of {@link com.google.inject.Module modules}
+ involved in the element creation can be retrieved by
+ {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the
+ order is reverse chronological. The first module (index 0) is the module that
+ installs the {@link Element element}. The last module is the root module.
+ <p>
+ In order to support the cases where a Guice {@link Element element} is
+ created from another Guice {@link Element element} (original) (e.g., by
+ {@link Element#applyTo}), it also provides a reference to the original
+ element source ({@link #getOriginalElementSource()}).
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ElementSource -->
+  <!-- start interface com.google.inject.spi.ElementVisitor -->
+  <interface name="ElementVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.Binding&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Visit a mapping from a key (type and optional annotation) to the strategy for getting
+ instances of the type.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.InterceptorBinding"/>
+      <doc>
+      <![CDATA[Visit a registration of interceptors for matching methods of matching classes.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ScopeBinding"/>
+      <doc>
+      <![CDATA[Visit a registration of a scope annotation with the scope that implements it.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.TypeConverterBinding"/>
+      <doc>
+      <![CDATA[Visit a registration of type converters for matching target types.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="request" type="com.google.inject.spi.InjectionRequest&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Visit a request to inject the instance fields and methods of an instance.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="request" type="com.google.inject.spi.StaticInjectionRequest"/>
+      <doc>
+      <![CDATA[Visit a request to inject the static fields and methods of type.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="lookup" type="com.google.inject.spi.ProviderLookup&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Visit a lookup of the provider for a type.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="lookup" type="com.google.inject.spi.MembersInjectorLookup&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Visit a lookup of the members injector.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+      <doc>
+      <![CDATA[Visit an error message and the context in which it occured.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="elements" type="com.google.inject.spi.PrivateElements"/>
+      <doc>
+      <![CDATA[Visit a collection of configuration elements for a {@linkplain com.google.inject.PrivateBinder
+ private binder}.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.TypeListenerBinding"/>
+      <doc>
+      <![CDATA[Visit an injectable type listener binding.]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ProvisionListenerBinding"/>
+      <doc>
+      <![CDATA[Visit a provision listener binding.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireExplicitBindingsOption"/>
+      <doc>
+      <![CDATA[Visit a require explicit bindings command.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.DisableCircularProxiesOption"/>
+      <doc>
+      <![CDATA[Visit a disable circular proxies command.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireAtInjectOnConstructorsOption"/>
+      <doc>
+      <![CDATA[Visit a require explicit {@literal @}{@link Inject} command.
+ 
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="option" type="com.google.inject.spi.RequireExactBindingAnnotationsOption"/>
+      <doc>
+      <![CDATA[Visit a require exact binding annotations command.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binding" type="com.google.inject.spi.ModuleAnnotatedMethodScannerBinding"/>
+      <doc>
+      <![CDATA[Visits a {@link Binder#scanModulesForAnnotatedMethods} command.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Visit elements.
+
+ @param <V> any type to be returned by the visit method. Use {@link Void} with
+     {@code return null} if no return type is needed.
+ 
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ElementVisitor -->
+  <!-- start interface com.google.inject.spi.ExposedBinding -->
+  <interface name="ExposedBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getPrivateElements" return="com.google.inject.spi.PrivateElements"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the enclosed environment that holds the original binding.]]>
+      </doc>
+    </method>
+    <method name="applyTo"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <doc>
+      <![CDATA[Unsupported. Always throws {@link UnsupportedOperationException}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a key exposed from an enclosed private environment.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ExposedBinding -->
+  <!-- start interface com.google.inject.spi.HasDependencies -->
+  <interface name="HasDependencies"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getDependencies" return="java.util.Set&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the known dependencies for this type. If this has dependencies whose values are not
+ known statically, a dependency for the {@link com.google.inject.Injector Injector} will be
+ included in the returned set.
+ 
+ @return a possibly empty set]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Implemented by {@link com.google.inject.Binding bindings}, {@link com.google.inject.Provider
+ providers} and instances that expose their dependencies explicitly.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.HasDependencies -->
+  <!-- start interface com.google.inject.spi.InjectionListener -->
+  <interface name="InjectionListener"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="afterInjection"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="injectee" type="I"/>
+      <doc>
+      <![CDATA[Invoked by Guice after it injects the fields and methods of instance.
+
+ @param injectee instance that Guice injected dependencies into]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Listens for injections into instances of type {@code I}. Useful for performing further
+ injections, post-injection initialization, and more.
+
+ @author crazybob@google.com (Bob Lee)
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.InjectionListener -->
+  <!-- start class com.google.inject.spi.InjectionPoint -->
+  <class name="InjectionPoint" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="getMember" return="java.lang.reflect.Member"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the injected constructor, field, or method.]]>
+      </doc>
+    </method>
+    <method name="getDependencies" return="java.util.List&lt;com.google.inject.spi.Dependency&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the dependencies for this injection point. If the injection point is for a method or
+ constructor, the dependencies will correspond to that member's parameters. Field injection
+ points always have a single dependency for the field itself.
+
+ @return a possibly-empty list]]>
+      </doc>
+    </method>
+    <method name="isOptional" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if this injection point shall be skipped if the injector cannot resolve bindings
+ for all required dependencies. Both explicit bindings (as specified in a module), and implicit
+ bindings ({@literal @}{@link com.google.inject.ImplementedBy ImplementedBy}, default
+ constructors etc.) may be used to satisfy optional injection points.]]>
+      </doc>
+    </method>
+    <method name="isToolable" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns true if the element is annotated with {@literal @}{@link Toolable}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="getDeclaringType" return="com.google.inject.TypeLiteral&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the generic type that defines this injection point. If the member exists on a
+ parameterized type, the result will include more type information than the member's {@link
+ Member#getDeclaringClass() raw declaring class}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="o" type="java.lang.Object"/>
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="forConstructor" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="constructor" type="java.lang.reflect.Constructor&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the specified constructor. If the declaring type of {@code
+ constructor} is parameterized (such as {@code List<T>}), prefer the overload that includes a
+ type literal.
+
+ @param constructor any single constructor present on {@code type}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="forConstructor" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="constructor" type="java.lang.reflect.Constructor&lt;T&gt;"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the specified constructor of {@code type}.
+
+ @param constructor any single constructor present on {@code type}.
+ @param type the concrete type that defines {@code constructor}.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="forConstructorOf" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the injectable constructor of {@code type}.
+
+ @param type a concrete type with exactly one constructor annotated {@literal @}{@link Inject},
+     or a no-arguments constructor that is not private.
+ @throws ConfigurationException if there is no injectable constructor, more than one injectable
+     constructor, or if parameters of the injectable constructor are malformed, such as a
+     parameter with multiple binding annotations.]]>
+      </doc>
+    </method>
+    <method name="forConstructorOf" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the injectable constructor of {@code type}.
+
+ @param type a concrete type with exactly one constructor annotated {@literal @}{@link Inject},
+     or a no-arguments constructor that is not private.
+ @throws ConfigurationException if there is no injectable constructor, more than one injectable
+     constructor, or if parameters of the injectable constructor are malformed, such as a
+     parameter with multiple binding annotations.]]>
+      </doc>
+    </method>
+    <method name="forMethod" return="com.google.inject.spi.InjectionPoint"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="method" type="java.lang.reflect.Method"/>
+      <param name="type" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a new injection point for the specified method of {@code type}.
+ This is useful for extensions that need to build dependency graphs from
+ arbitrary methods.
+
+ @param method any single method present on {@code type}.
+ @param type the concrete type that defines {@code method}.
+
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="forStaticMethodsAndFields" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns all static method and field injection points on {@code type}.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+      a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <method name="forStaticMethodsAndFields" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns all static method and field injection points on {@code type}.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+      a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <method name="forInstanceMethodsAndFields" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns all instance method and field injection points on {@code type}.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+      a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <method name="forInstanceMethodsAndFields" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns all instance method and field injection points on {@code type}.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+      a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A constructor, field or method that can receive injections. Typically this is a member with the
+ {@literal @}{@link Inject} annotation. For non-private, no argument constructors, the member may
+ omit the annotation.
+
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.InjectionPoint -->
+  <!-- start class com.google.inject.spi.InjectionRequest -->
+  <class name="InjectionRequest" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="InjectionRequest" type="java.lang.Object, com.google.inject.TypeLiteral&lt;T&gt;, T"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getInstance" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getType" return="com.google.inject.TypeLiteral&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="ConfigurationException" type="com.google.inject.ConfigurationException"/>
+      <doc>
+      <![CDATA[Returns the instance methods and fields of {@code instance} that will be injected to fulfill
+ this request.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on the class of {@code
+      instance}, such as a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <method name="acceptVisitor" return="R"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;R&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[A request to inject the instance fields and methods of an instance. Requests are created
+ explicitly in a module using {@link com.google.inject.Binder#requestInjection(Object)
+ requestInjection()} statements:
+ <pre>
+     requestInjection(serviceInstance);</pre>
+
+ @author mikeward@google.com (Mike Ward)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.InjectionRequest -->
+  <!-- start interface com.google.inject.spi.InstanceBinding -->
+  <interface name="InstanceBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getInstance" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the user-supplied instance.]]>
+      </doc>
+    </method>
+    <method name="getInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the field and method injection points of the instance, injected at injector-creation
+ time only.
+
+ @return a possibly empty set]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a single instance. The same instance is returned for every injection.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.InstanceBinding -->
+  <!-- start class com.google.inject.spi.InterceptorBinding -->
+  <class name="InterceptorBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getClassMatcher" return="com.google.inject.matcher.Matcher&lt;? super java.lang.Class&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getMethodMatcher" return="com.google.inject.matcher.Matcher&lt;? super java.lang.reflect.Method&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getInterceptors" return="java.util.List&lt;org.aopalliance.intercept.MethodInterceptor&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Registration of interceptors for matching methods of matching classes. Instances are created
+ explicitly in a module using {@link com.google.inject.Binder#bindInterceptor(
+ Matcher, Matcher, MethodInterceptor[]) bindInterceptor()} statements:
+ <pre>
+     bindInterceptor(Matchers.subclassesOf(MyAction.class),
+         Matchers.annotatedWith(Transactional.class),
+         new MyTransactionInterceptor());</pre>
+
+ or from an injectable type listener using {@link TypeEncounter#bindInterceptor(Matcher,
+ org.aopalliance.intercept.MethodInterceptor[]) TypeEncounter.bindInterceptor()}.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.InterceptorBinding -->
+  <!-- start interface com.google.inject.spi.LinkedKeyBinding -->
+  <interface name="LinkedKeyBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <method name="getLinkedKey" return="com.google.inject.Key&lt;? extends T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the linked key used to resolve injections. That binding can be retrieved from an
+ injector using {@link com.google.inject.Injector#getBinding(Key) Injector.getBinding(key)}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a linked key. The other key's binding is used to resolve injections.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.LinkedKeyBinding -->
+  <!-- start class com.google.inject.spi.MembersInjectorLookup -->
+  <class name="MembersInjectorLookup" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="MembersInjectorLookup" type="java.lang.Object, com.google.inject.TypeLiteral&lt;T&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getType" return="com.google.inject.TypeLiteral&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the type containing the members to be injected.]]>
+      </doc>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="initializeDelegate"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="delegate" type="com.google.inject.MembersInjector&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Sets the actual members injector.
+
+ @throws IllegalStateException if the delegate is already set]]>
+      </doc>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="getDelegate" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the delegate members injector, or {@code null} if it has not yet been initialized.
+ The delegate will be initialized when this element is processed, or otherwise used to create
+ an injector.]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the looked up members injector. The result is not valid until this lookup has been
+ initialized, which usually happens when the injector is created. The members injector will
+ throw an {@code IllegalStateException} if you try to use it beforehand.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A lookup of the members injector for a type. Lookups are created explicitly in a module using
+ {@link com.google.inject.Binder#getMembersInjector(Class) getMembersInjector()} statements:
+ <pre>
+     MembersInjector&lt;PaymentService&gt; membersInjector
+         = getMembersInjector(PaymentService.class);</pre>
+
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.MembersInjectorLookup -->
+  <!-- start class com.google.inject.spi.Message -->
+  <class name="Message" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.io.Serializable"/>
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="Message" type="java.util.List&lt;java.lang.Object&gt;, java.lang.String, java.lang.Throwable"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 2.0]]>
+      </doc>
+    </constructor>
+    <constructor name="Message" type="java.lang.String, java.lang.Throwable"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </constructor>
+    <constructor name="Message" type="java.lang.Object, java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="Message" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getSource" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getSources" return="java.util.List&lt;java.lang.Object&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 2.0]]>
+      </doc>
+    </method>
+    <method name="getMessage" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the error message text.]]>
+      </doc>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@since 2.0]]>
+      </doc>
+    </method>
+    <method name="getCause" return="java.lang.Throwable"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the throwable that caused this message, or {@code null} if this
+ message was not caused by a throwable.
+
+ @since 2.0]]>
+      </doc>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="hashCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="equals" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="o" type="java.lang.Object"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <doc>
+      <![CDATA[@since 2.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An error message and the context in which it occured. Messages are usually created internally by
+ Guice and its extensions. Messages can be created explicitly in a module using {@link
+ com.google.inject.Binder#addError(Throwable) addError()} statements:
+ <pre>
+     try {
+       bindPropertiesFromFile();
+     } catch (IOException e) {
+       addError(e);
+     }</pre>
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.Message -->
+  <!-- start class com.google.inject.spi.ModuleAnnotatedMethodScanner -->
+  <class name="ModuleAnnotatedMethodScanner" extends="java.lang.Object"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ModuleAnnotatedMethodScanner"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="annotationClasses" return="java.util.Set&lt;? extends java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the annotations this should scan for. Every method in the module that has one of these
+ annotations will create a Provider binding, with the return value of the binding being what's
+ provided and the parameters of the method being dependencies of the provider.]]>
+      </doc>
+    </method>
+    <method name="prepareMethod" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <param name="injectionPoint" type="com.google.inject.spi.InjectionPoint"/>
+      <doc>
+      <![CDATA[Prepares a method for binding. This {@code key} parameter is the key discovered from looking at
+ the binding annotation and return value of the method. Implementations can modify the key to
+ instead bind to another key. For example, Multibinder may want to change
+ {@code @SetProvides String provideFoo()} to bind into a unique Key within the multibinder
+ instead of binding {@code String}.
+
+ <p>The injection point and annotation are provided in case the implementation wants to set the
+ key based on the property of the annotation or if any additional preparation is needed for any
+ of the dependencies. The annotation is guaranteed to be an instance of one the classes returned
+ by {@link #annotationClasses}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Allows extensions to scan modules for annotated methods and bind those methods
+ as providers, similar to {@code @Provides} methods.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ModuleAnnotatedMethodScanner -->
+  <!-- start class com.google.inject.spi.ModuleAnnotatedMethodScannerBinding -->
+  <class name="ModuleAnnotatedMethodScannerBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="ModuleAnnotatedMethodScannerBinding" type="java.lang.Object, com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getScanner" return="com.google.inject.spi.ModuleAnnotatedMethodScanner"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Represents a call to {@link Binder#scanModulesForAnnotatedMethods} in a module.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ModuleAnnotatedMethodScannerBinding -->
+  <!-- start interface com.google.inject.spi.PrivateElements -->
+  <interface name="PrivateElements"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getElements" return="java.util.List&lt;com.google.inject.spi.Element&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the configuration information in this private environment.]]>
+      </doc>
+    </method>
+    <method name="getInjector" return="com.google.inject.Injector"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the child injector that hosts these private elements, or null if the elements haven't
+ been used to create an injector.]]>
+      </doc>
+    </method>
+    <method name="getExposedKeys" return="java.util.Set&lt;com.google.inject.Key&lt;?&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the unique exposed keys for these private elements.]]>
+      </doc>
+    </method>
+    <method name="getExposedSource" return="java.lang.Object"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Returns an arbitrary object containing information about the "place" where this key was
+ exposed. Used by Guice in the production of descriptive error messages.
+
+ <p>Tools might specially handle types they know about; {@code StackTraceElement} is a good
+ example. Tools should simply call {@code toString()} on the source object if the type is
+ unfamiliar.
+
+ @param key one of the keys exposed by this module.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A private collection of elements that are hidden from the enclosing injector or module by
+ default. See {@link com.google.inject.PrivateModule PrivateModule} for details.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.PrivateElements -->
+  <!-- start interface com.google.inject.spi.ProviderBinding -->
+  <interface name="ProviderBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <method name="getProvidedKey" return="com.google.inject.Key&lt;?&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key whose binding is used to {@link Provider#get provide instances}. That binding
+ can be retrieved from an injector using {@link com.google.inject.Injector#getBinding(Key)
+ Injector.getBinding(providedKey)}]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a {@link Provider} that delegates to the binding for the provided type. This binding
+ is used whenever a {@code Provider<T>} is injected (as opposed to injecting {@code T} directly).
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProviderBinding -->
+  <!-- start interface com.google.inject.spi.ProviderInstanceBinding -->
+  <interface name="ProviderInstanceBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getProviderInstance" return="com.google.inject.Provider&lt;? extends T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="Use {@link #getUserSuppliedProvider} instead.">
+      <doc>
+      <![CDATA[If the user supplied a JSR330 binding, then this will wrap that one. To always return the
+ user-supplied provider, use {@link #getUserSuppliedProvider}.
+ 
+ @deprecated Use {@link #getUserSuppliedProvider} instead.]]>
+      </doc>
+    </method>
+    <method name="getUserSuppliedProvider" return="javax.inject.Provider&lt;? extends T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the user-supplied, unscoped provider.
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="getInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the field and method injection points of the provider, injected at injector-creation
+ time only.
+
+ @return a possibly empty set]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a provider instance. The provider's {@code get} method is invoked to resolve
+ injections.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProviderInstanceBinding -->
+  <!-- start interface com.google.inject.spi.ProviderKeyBinding -->
+  <interface name="ProviderKeyBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <method name="getProviderKey" return="com.google.inject.Key&lt;? extends javax.inject.Provider&lt;? extends T&gt;&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key used to resolve the provider's binding. That binding can be retrieved from an
+ injector using {@link com.google.inject.Injector#getBinding(Key)
+ Injector.getBinding(providerKey)}]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A binding to a provider key. To resolve injections, the provider key is first resolved, then that
+ provider's {@code get} method is invoked.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProviderKeyBinding -->
+  <!-- start class com.google.inject.spi.ProviderLookup -->
+  <class name="ProviderLookup" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="ProviderLookup" type="java.lang.Object, com.google.inject.Key&lt;T&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <constructor name="ProviderLookup" type="java.lang.Object, com.google.inject.spi.Dependency&lt;T&gt;"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getDependency" return="com.google.inject.spi.Dependency&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="initializeDelegate"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="delegate" type="com.google.inject.Provider&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Sets the actual provider.
+
+ @throws IllegalStateException if the delegate is already set]]>
+      </doc>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="getDelegate" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the delegate provider, or {@code null} if it has not yet been initialized. The delegate
+ will be initialized when this element is processed, or otherwise used to create an injector.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the looked up provider. The result is not valid until this lookup has been initialized,
+ which usually happens when the injector is created. The provider will throw an {@code
+ IllegalStateException} if you try to use it beforehand.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A lookup of the provider for a type. Lookups are created explicitly in a module using
+ {@link com.google.inject.Binder#getProvider(Class) getProvider()} statements:
+ <pre>
+     Provider&lt;PaymentService&gt; paymentServiceProvider
+         = getProvider(PaymentService.class);</pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ProviderLookup -->
+  <!-- start interface com.google.inject.spi.ProviderWithDependencies -->
+  <interface name="ProviderWithDependencies"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Provider&lt;T&gt;"/>
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <doc>
+    <![CDATA[A provider with dependencies on other injected types. If a {@link Provider} has dependencies that
+ aren't specified in injections, this interface should be used to expose all dependencies.
+
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProviderWithDependencies -->
+  <!-- start interface com.google.inject.spi.ProviderWithExtensionVisitor -->
+  <interface name="ProviderWithExtensionVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Provider&lt;T&gt;"/>
+    <method name="acceptExtensionVisitor" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.BindingTargetVisitor&lt;B, V&gt;"/>
+      <param name="binding" type="com.google.inject.spi.ProviderInstanceBinding&lt;? extends B&gt;"/>
+      <doc>
+      <![CDATA[Instructs the extension determine if the visitor is an instance of a custom
+ extension visitor, and if so, visit it using that method. If the visitor is
+ not an instance of the custom extension visitor, this method <b>MUST</b>
+ call visitor.visit(binding).
+ <p> 
+ Due to issues with generics, the type parameters of this method do not
+ relate to the type of the provider. In practice, the 'B' type will always
+ be a supertype of 'T'.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A Provider that is part of an extension which supports a custom
+ BindingTargetVisitor.
+ <p> 
+ When an extension binds a provider instance, the provider can implement this
+ interface to allow users using the
+ {@link Binding#acceptTargetVisitor(BindingTargetVisitor)} method to visit a
+ custom visitor designed for that extension. A typical implementation within
+ the extension would look like
+ <pre> 
+ &lt;V, B> V acceptExtensionVisitor(BindingTargetVisitor&lt;B, V> visitor, ProviderInstanceBinding&lt;? extends B> binding) {
+   if(visitor instanceof MyCustomExtensionVisitor) {
+     return ((MyCustomExtensionVisitor&lt;B, V>)visitor).visitCustomExtension(customProperties, binding);
+   } else {
+     return visitor.visit(binding);
+   }
+ }</pre> 
+ 'MyCustomExtensionVisitor' in the example above would be an interface the
+ extension provides that users can implement in order to be notified of custom
+ extension information. These visitor interfaces must extend from
+ BindingTargetVisitor.
+
+ @since 3.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProviderWithExtensionVisitor -->
+  <!-- start interface com.google.inject.spi.ProvidesMethodBinding -->
+  <interface name="ProvidesMethodBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.HasDependencies"/>
+    <method name="getMethod" return="java.lang.reflect.Method"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the method this binding uses.]]>
+      </doc>
+    </method>
+    <method name="getEnclosingInstance" return="java.lang.Object"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the instance of the object the method is defined in.]]>
+      </doc>
+    </method>
+    <method name="getKey" return="com.google.inject.Key&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the key of the binding.]]>
+      </doc>
+    </method>
+    <method name="getAnnotation" return="java.lang.annotation.Annotation"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the annotation that caused this binding to be created. For {@code @Provides} methods,
+ this is an instance of the {@code @Provides} annotation. For bindings from
+ {@link ModuleAnnotatedMethodScanner}, this is the annotation that caused the scanner to produce
+ the binding.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[An {@literal @}{@link Provides} binding or binding produced by a
+ {@link ModuleAnnotatedMethodScanner}.
+
+ @since 4.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProvidesMethodBinding -->
+  <!-- start interface com.google.inject.spi.ProvidesMethodTargetVisitor -->
+  <interface name="ProvidesMethodTargetVisitor"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.BindingTargetVisitor&lt;T, V&gt;"/>
+    <method name="visit" return="V"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providesMethodBinding" type="com.google.inject.spi.ProvidesMethodBinding&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[Visits an {@link ProvidesMethodBinding} created with an {@literal @}{@link Provides} method.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A visitor for the {@literal @}{@link Provides} bindings.
+ <p>
+ If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ {@code @Provides} will be visited through this interface.
+
+ @since 4.0
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProvidesMethodTargetVisitor -->
+  <!-- start interface com.google.inject.spi.ProvisionListener -->
+  <interface name="ProvisionListener"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="onProvision"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="provision" type="com.google.inject.spi.ProvisionListener.ProvisionInvocation&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Invoked by Guice when an object requires provisioning. Provisioning occurs
+ when Guice locates and injects the dependencies for a binding. For types
+ bound to a Provider, provisioning encapsulates the {@link Provider#get}
+ method. For toInstance or constant bindings, provisioning encapsulates
+ the injecting of {@literal @}{@code Inject}ed fields or methods.
+ For other types, provisioning encapsulates the construction of the
+ object. If a type is bound within a {@link Scope}, provisioning depends on
+ the scope. Types bound in Singleton scope will only be provisioned once.
+ Types bound in no scope will be provisioned every time they are injected.
+ Other scopes define their own behavior for provisioning.
+ <p>
+ To perform the provision, call {@link ProvisionInvocation#provision()}.
+ If you do not explicitly call provision, it will be automatically done after
+ this method returns.  It is an error to call provision more than once.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Listens for provisioning of objects. Useful for gathering timing information
+ about provisioning, post-provision initialization, and more.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.ProvisionListener -->
+  <!-- start class com.google.inject.spi.ProvisionListener.ProvisionInvocation -->
+  <class name="ProvisionListener.ProvisionInvocation" extends="java.lang.Object"
+    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ProvisionInvocation"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getBinding" return="com.google.inject.Binding&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the Binding this is provisioning.
+ <p>
+ You must not call {@link Provider#get()} on the provider returned by
+ {@link Binding#getProvider}, otherwise you will get confusing error messages.]]>
+      </doc>
+    </method>
+    <method name="provision" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Performs the provision, returning the object provisioned.]]>
+      </doc>
+    </method>
+    <method name="getDependencyChain" return="java.util.List&lt;com.google.inject.spi.DependencyAndSource&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the dependency chain that led to this object being provisioned.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Encapsulates a single act of provisioning.
+
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ProvisionListener.ProvisionInvocation -->
+  <!-- start class com.google.inject.spi.ProvisionListenerBinding -->
+  <class name="ProvisionListenerBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getListeners" return="java.util.List&lt;com.google.inject.spi.ProvisionListener&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the registered listeners.]]>
+      </doc>
+    </method>
+    <method name="getBindingMatcher" return="com.google.inject.matcher.Matcher&lt;? super com.google.inject.Binding&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the binding matcher which chooses which bindings the listener should be notified of.]]>
+      </doc>
+    </method>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="R"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;R&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Binds keys (picked using a Matcher) to a provision listener. Listeners are created explicitly in
+ a module using {@link Binder#bindListener(Matcher, ProvisionListener...)} statements:
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ProvisionListenerBinding -->
+  <!-- start class com.google.inject.spi.RequireAtInjectOnConstructorsOption -->
+  <class name="RequireAtInjectOnConstructorsOption" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[A request to require explicit {@literal @}{@link Inject} annotations on constructors.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.RequireAtInjectOnConstructorsOption -->
+  <!-- start class com.google.inject.spi.RequireExactBindingAnnotationsOption -->
+  <class name="RequireExactBindingAnnotationsOption" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[A request to require exact binding annotations.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.RequireExactBindingAnnotationsOption -->
+  <!-- start class com.google.inject.spi.RequireExplicitBindingsOption -->
+  <class name="RequireExplicitBindingsOption" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[A request to require explicit bindings.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 3.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.RequireExplicitBindingsOption -->
+  <!-- start class com.google.inject.spi.ScopeBinding -->
+  <class name="ScopeBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getAnnotationType" return="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getScope" return="com.google.inject.Scope"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Registration of a scope annotation with the scope that implements it. Instances are created
+ explicitly in a module using {@link com.google.inject.Binder#bindScope(Class, Scope) bindScope()}
+ statements:
+ <pre>
+     Scope recordScope = new RecordScope();
+     bindScope(RecordScoped.class, new RecordScope());</pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.ScopeBinding -->
+  <!-- start class com.google.inject.spi.StaticInjectionRequest -->
+  <class name="StaticInjectionRequest" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getType" return="java.lang.Class&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getInjectionPoints" return="java.util.Set&lt;com.google.inject.spi.InjectionPoint&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="ConfigurationException" type="com.google.inject.ConfigurationException"/>
+      <doc>
+      <![CDATA[Returns the static methods and fields of {@code type} that will be injected to fulfill this
+ request.
+
+ @return a possibly empty set of injection points. The set has a specified iteration order. All
+      fields are returned and then all methods. Within the fields, supertype fields are returned
+      before subtype fields. Similarly, supertype methods are returned before subtype methods.
+ @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+      a field with multiple binding annotations. The exception's {@link
+      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+      of the valid injection points.]]>
+      </doc>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <doc>
+    <![CDATA[A request to inject the static fields and methods of a type. Requests are created
+ explicitly in a module using {@link com.google.inject.Binder#requestStaticInjection(Class[])
+ requestStaticInjection()} statements:
+ <pre>
+     requestStaticInjection(MyLegacyService.class);</pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.StaticInjectionRequest -->
+  <!-- start class com.google.inject.spi.Toolable -->
+  <class name="Toolable"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Instructs an {@link Injector} running in {@link Stage#TOOL} that a method should be injected.
+ This is typically useful for for extensions to Guice that perform additional validation in an
+ injected method or field.  This only applies to objects that are already constructed when
+ bindings are created (ie., something bound using {@link
+ com.google.inject.binder.LinkedBindingBuilder#toProvider toProvider}, {@link
+ com.google.inject.binder.LinkedBindingBuilder#toInstance toInstance}, or {@link
+ com.google.inject.Binder#requestInjection requestInjection}.
+ 
+ @author sberlin@gmail.com (Sam Berlin)
+ @since 3.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.Toolable -->
+  <!-- start interface com.google.inject.spi.TypeConverter -->
+  <interface name="TypeConverter"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="convert" return="java.lang.Object"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="value" type="java.lang.String"/>
+      <param name="toType" type="com.google.inject.TypeLiteral&lt;?&gt;"/>
+      <doc>
+      <![CDATA[Converts a string value. Throws an exception if a conversion error occurs.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Converts constant string values to a different type.
+
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.TypeConverter -->
+  <!-- start class com.google.inject.spi.TypeConverterBinding -->
+  <class name="TypeConverterBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <constructor name="TypeConverterBinding" type="java.lang.Object, com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;, com.google.inject.spi.TypeConverter"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[@since 3.0]]>
+      </doc>
+    </constructor>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getTypeMatcher" return="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getTypeConverter" return="com.google.inject.spi.TypeConverter"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Registration of type converters for matching target types. Instances are created
+ explicitly in a module using {@link com.google.inject.Binder#convertToTypes(Matcher,
+ TypeConverter) convertToTypes()} statements:
+ <pre>
+     convertToTypes(Matchers.only(TypeLiteral.get(DateTime.class)), new DateTimeConverter());</pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.TypeConverterBinding -->
+  <!-- start interface com.google.inject.spi.TypeEncounter -->
+  <interface name="TypeEncounter"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="java.lang.String"/>
+      <param name="arguments" type="java.lang.Object[]"/>
+      <doc>
+      <![CDATA[Records an error message for type {@code I} which will be presented to the user at a later
+ time. Unlike throwing an exception, this enable us to continue configuring the Injector and
+ discover more errors. Uses {@link String#format(String, Object[])} to insert the arguments
+ into the message.]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="t" type="java.lang.Throwable"/>
+      <doc>
+      <![CDATA[Records an exception for type {@code I}, the full details of which will be logged, and the
+ message of which will be presented to the user at a later time. If your type listener calls
+ something that you worry may fail, you should catch the exception and pass it to this method.]]>
+      </doc>
+    </method>
+    <method name="addError"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="message" type="com.google.inject.spi.Message"/>
+      <doc>
+      <![CDATA[Records an error message to be presented to the user at a later time.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="key" type="com.google.inject.Key&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection key. The returned
+ provider will not be valid until the injector has been created. The provider will throw an
+ {@code IllegalStateException} if you try to use it beforehand.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the provider used to obtain instances for the given injection type. The returned
+ provider will not be valid until the injector has been created. The provider will throw an
+ {@code IllegalStateException} if you try to use it beforehand.]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}. The returned members injector will not be valid until the main
+ injector has been created. The members injector will throw an {@code IllegalStateException}
+ if you try to use it beforehand.
+
+ @param typeLiteral type to get members injector for]]>
+      </doc>
+    </method>
+    <method name="getMembersInjector" return="com.google.inject.MembersInjector&lt;T&gt;"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns the members injector used to inject dependencies into methods and fields on instances
+ of the given type {@code T}. The returned members injector will not be valid until the main
+ injector has been created. The members injector will throw an {@code IllegalStateException}
+ if you try to use it beforehand.
+
+ @param type type to get members injector for]]>
+      </doc>
+    </method>
+    <method name="register"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="membersInjector" type="com.google.inject.MembersInjector&lt;? super I&gt;"/>
+      <doc>
+      <![CDATA[Registers a members injector for type {@code I}. Guice will use the members injector after its
+ performed its own injections on an instance of {@code I}.]]>
+      </doc>
+    </method>
+    <method name="register"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="listener" type="com.google.inject.spi.InjectionListener&lt;? super I&gt;"/>
+      <doc>
+      <![CDATA[Registers an injection listener for type {@code I}. Guice will notify the listener after all
+ injections have been performed on an instance of {@code I}.]]>
+      </doc>
+    </method>
+    <method name="bindInterceptor"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="methodMatcher" type="com.google.inject.matcher.Matcher&lt;? super java.lang.reflect.Method&gt;"/>
+      <param name="interceptors" type="org.aopalliance.intercept.MethodInterceptor[]"/>
+      <doc>
+      <![CDATA[Binds method interceptor[s] to methods matched in type {@code I} and its supertypes. A
+ method is eligible for interception if:
+
+ <ul>
+  <li>Guice created the instance the method is on</li>
+  <li>Neither the enclosing type nor the method is final</li>
+  <li>And the method is package-private or more accessible</li>
+ </ul>
+
+ @param methodMatcher matches methods the interceptor should apply to. For
+     example: {@code annotatedWith(Transactional.class)}.
+ @param interceptors to bind]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Context of an injectable type encounter. Enables reporting errors, registering injection
+ listeners and binding method interceptors for injectable type {@code I}. It is an error to use
+ an encounter after the {@link TypeListener#hear(TypeLiteral, TypeEncounter) hear()} method has
+ returned.
+
+ @param <I> the injectable type encountered
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.TypeEncounter -->
+  <!-- start interface com.google.inject.spi.TypeListener -->
+  <interface name="TypeListener"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="hear"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="com.google.inject.TypeLiteral&lt;I&gt;"/>
+      <param name="encounter" type="com.google.inject.spi.TypeEncounter&lt;I&gt;"/>
+      <doc>
+      <![CDATA[Invoked when Guice encounters a new type eligible for constructor or members injection.
+ Called during injector creation (or afterwards if Guice encounters a type at run time and
+ creates a JIT binding).
+
+ @param type encountered by Guice
+ @param encounter context of this encounter, enables reporting errors, registering injection
+     listeners and binding method interceptors for {@code type}.
+
+ @param <I> the injectable type]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Listens for Guice to encounter injectable types. If a given type has its constructor injected in
+ one situation but only its methods and fields injected in another, Guice will notify this
+ listener once.
+
+ <p>Useful for extra type checking, {@linkplain TypeEncounter#register(InjectionListener)
+ registering injection listeners}, and {@linkplain TypeEncounter#bindInterceptor(
+ com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
+ binding method interceptors}.
+ 
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.TypeListener -->
+  <!-- start class com.google.inject.spi.TypeListenerBinding -->
+  <class name="TypeListenerBinding" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.spi.Element"/>
+    <method name="getListener" return="com.google.inject.spi.TypeListener"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the registered listener.]]>
+      </doc>
+    </method>
+    <method name="getTypeMatcher" return="com.google.inject.matcher.Matcher&lt;? super com.google.inject.TypeLiteral&lt;?&gt;&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Returns the type matcher which chooses which types the listener should be notified of.]]>
+      </doc>
+    </method>
+    <method name="getSource" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="acceptVisitor" return="T"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="visitor" type="com.google.inject.spi.ElementVisitor&lt;T&gt;"/>
+    </method>
+    <method name="applyTo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Binds types (picked using a Matcher) to an type listener. Registrations are created explicitly in
+ a module using {@link com.google.inject.Binder#bindListener(Matcher, TypeListener)} statements:
+
+ <pre>
+     register(only(new TypeLiteral&lt;PaymentService&lt;CreditCard>>() {}), listener);</pre>
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spi.TypeListenerBinding -->
+  <!-- start interface com.google.inject.spi.UntargettedBinding -->
+  <interface name="UntargettedBinding"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Binding&lt;T&gt;"/>
+    <doc>
+    <![CDATA[An untargetted binding. This binding indicates that the injector should use its implicit binding
+ strategies to resolve injections.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.spi.UntargettedBinding -->
+</package>
+<package name="com.google.inject.spring">
+  <!-- start class com.google.inject.spring.SpringIntegration -->
+  <class name="SpringIntegration" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="fromSpring" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.Class&lt;T&gt;"/>
+      <param name="name" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Creates a provider which looks up objects from Spring using the given name.
+ Expects a binding to {@link
+ org.springframework.beans.factory.BeanFactory}. Example usage:
+
+ <pre>
+ bind(DataSource.class)
+   .toProvider(fromSpring(DataSource.class, "dataSource"));
+ </pre>]]>
+      </doc>
+    </method>
+    <method name="bindAll"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+      <param name="beanFactory" type="org.springframework.beans.factory.ListableBeanFactory"/>
+      <doc>
+      <![CDATA[Binds all Spring beans from the given factory by name. For a Spring bean
+ named "foo", this method creates a binding to the bean's type and
+ {@code @Named("foo")}.
+
+ @see com.google.inject.name.Named
+ @see com.google.inject.name.Names#named(String)]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Integrates Guice with Spring.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.spring.SpringIntegration -->
+</package>
+<package name="com.google.inject.struts2">
+  <!-- start class com.google.inject.struts2.GuiceObjectFactory -->
+  <class name="GuiceObjectFactory" extends="com.opensymphony.xwork2.ObjectFactory"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="Use {@link com.google.inject.struts2.Struts2Factory} instead.">
+    <constructor name="GuiceObjectFactory"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="isNoArgConstructorRequired" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getClassInstance" return="java.lang.Class"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+      <exception name="ClassNotFoundException" type="java.lang.ClassNotFoundException"/>
+    </method>
+    <method name="buildBean" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="clazz" type="java.lang.Class"/>
+      <param name="extraContext" type="java.util.Map"/>
+    </method>
+    <method name="buildInterceptor" return="com.opensymphony.xwork2.interceptor.Interceptor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="interceptorConfig" type="com.opensymphony.xwork2.config.entities.InterceptorConfig"/>
+      <param name="interceptorRefParams" type="java.util.Map"/>
+      <exception name="ConfigurationException" type="com.opensymphony.xwork2.config.ConfigurationException"/>
+    </method>
+    <doc>
+    <![CDATA[@deprecated Use {@link com.google.inject.struts2.Struts2Factory} instead.]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.struts2.GuiceObjectFactory -->
+  <!-- start class com.google.inject.struts2.Struts2Factory -->
+  <class name="Struts2Factory" extends="com.opensymphony.xwork2.ObjectFactory"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Struts2Factory"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="isNoArgConstructorRequired" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getClassInstance" return="java.lang.Class&lt;?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+      <exception name="ClassNotFoundException" type="java.lang.ClassNotFoundException"/>
+    </method>
+    <method name="buildBean" return="java.lang.Object"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="clazz" type="java.lang.Class"/>
+      <param name="extraContext" type="java.util.Map&lt;java.lang.String, java.lang.Object&gt;"/>
+    </method>
+    <method name="buildInterceptor" return="com.opensymphony.xwork2.interceptor.Interceptor"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="interceptorConfig" type="com.opensymphony.xwork2.config.entities.InterceptorConfig"/>
+      <param name="interceptorRefParams" type="java.util.Map"/>
+      <exception name="ConfigurationException" type="com.opensymphony.xwork2.config.ConfigurationException"/>
+    </method>
+    <doc>
+    <![CDATA[Cleanup up version from Bob's GuiceObjectFactory. Now works properly with
+ GS2 and fixes several bugs.
+
+ @author dhanji@gmail.com
+ @author benmccann.com]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.struts2.Struts2Factory -->
+  <!-- start class com.google.inject.struts2.Struts2GuicePluginModule -->
+  <class name="Struts2GuicePluginModule" extends="com.google.inject.AbstractModule"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Struts2GuicePluginModule"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="protected"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[Initializes the Struts 2 Guice Plugin. Must be added to the injector returned
+ by {@link com.google.inject.servlet.GuiceServletContextListener#getInjector}.
+
+ @author benmccann.com]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.struts2.Struts2GuicePluginModule -->
+</package>
+<package name="com.google.inject.testing.fieldbinder">
+  <!-- start class com.google.inject.testing.fieldbinder.Bind -->
+  <class name="Bind"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotation used by {@link BoundFieldModule} to indicate that a field should be bound to its
+ value using Guice.
+
+ <p>Binding to {@code null} is only allowed for fields that are annotated {@code @Nullable}. See
+ <a href="https://github.com/google/guice/wiki/UseNullable">https://github.com/google/guice/wiki/UseNullable</a>
+
+ @see BoundFieldModule
+ @author eatnumber1@google.com (Russ Harmon)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.testing.fieldbinder.Bind -->
+  <!-- start class com.google.inject.testing.fieldbinder.BoundFieldModule -->
+  <class name="BoundFieldModule" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="com.google.inject.Module"/>
+    <method name="of" return="com.google.inject.testing.fieldbinder.BoundFieldModule"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[Create a BoundFieldModule which binds the {@link Bind} annotated fields of {@code instance}.
+
+ @param instance the instance whose fields will be bound.
+ @return a module which will bind the {@link Bind} annotated fields of {@code instance}.]]>
+      </doc>
+    </method>
+    <method name="configure"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <doc>
+    <![CDATA[Automatically creates Guice bindings for fields in an object annotated with {@link Bind}.
+
+ <p>This module is intended for use in tests to reduce the code needed to bind local fields
+ (usually mocks) for injection.
+
+ <p>The following rules are followed in determining how fields are bound using this module:
+
+ <ul>
+ <li>
+ For each {@link Bind} annotated field of an object and its superclasses, this module will bind
+ that field's type to that field's value at injector creation time. This includes both instance
+ and static fields.
+ </li>
+ <li>
+ If {@link Bind#to} is specified, the field's value will be bound to the class specified by
+ {@link Bind#to} instead of the field's actual type.
+ </li>
+ <li>
+ If a {@link BindingAnnotation} or {@link javax.inject.Qualifier} is present on the field,
+ that field will be bound using that annotation via {@link AnnotatedBindingBuilder#annotatedWith}.
+ For example, {@code bind(Foo.class).annotatedWith(BarAnnotation.class).toInstance(theValue)}.
+ It is an error to supply more than one {@link BindingAnnotation} or
+ {@link javax.inject.Qualifier}.
+ </li>
+ <li>
+ If the field is of type {@link Provider}, the field's value will be bound as a {@link Provider}
+ using {@link LinkedBindingBuilder#toProvider} to the provider's parameterized type. For example,
+ {@code Provider<Integer>} binds to {@link Integer}. Attempting to bind a non-parameterized
+ {@link Provider} without a {@link Bind#to} clause is an error.
+ </li>
+ </ul>
+
+ <p>Example use:
+ <pre><code>
+ public class TestFoo {
+   // bind(new TypeLiteral{@code <List<Object>>}() {}).toInstance(listOfObjects);
+   {@literal @}Bind private List{@code <Object>} listOfObjects = Lists.of();
+
+   // bind(String.class).toProvider(new Provider() { public String get() { return userName; }});
+   {@literal @}Bind(lazy = true) private String userName;
+
+   // bind(SuperClass.class).toInstance(aSubClass);
+   {@literal @}Bind(to = SuperClass.class) private SubClass aSubClass = new SubClass();
+
+   // bind(String.class).annotatedWith(MyBindingAnnotation.class).toInstance(myString);
+   {@literal @}Bind
+   {@literal @}MyBindingAnnotation
+   private String myString = "hello";
+
+   // bind(Object.class).toProvider(myProvider);
+   {@literal @}Bind private Provider{@code <Object>} myProvider = getProvider();
+
+   {@literal @}Before public void setUp() {
+     Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
+   }
+ }
+ </code></pre>
+
+ @see Bind
+ @author eatnumber1@google.com (Russ Harmon)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.testing.fieldbinder.BoundFieldModule -->
+</package>
+<package name="com.google.inject.throwingproviders">
+  <!-- start interface com.google.inject.throwingproviders.CheckedProvider -->
+  <interface name="CheckedProvider"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="get" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="Exception" type="java.lang.Exception"/>
+    </method>
+    <doc>
+    <![CDATA[Alternative to the Guice {@link com.google.inject.Provider} that throws
+ a checked Exception. Users may not inject {@code T} directly.
+
+ <p>This interface must be extended to use application-specific exception types.
+ Such subinterfaces may not define new methods, but may narrow the exception type.
+ <pre>
+ public interface RemoteProvider&lt;T&gt; extends CheckedProvider&lt;T&gt; { 
+   T get() throws CustomExceptionOne, CustomExceptionTwo;
+ }
+ </pre>
+
+ <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned
+ or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get}
+ will invoked at most once within each scope.
+ 
+ @since 3.0]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.throwingproviders.CheckedProvider -->
+  <!-- start class com.google.inject.throwingproviders.CheckedProvides -->
+  <class name="CheckedProvides"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[Annotates methods of a {@link com.google.inject.Module} to create a
+ {@link CheckedProvider} method binding that can throw exceptions. The
+ method's return type is bound to a {@link CheckedProvider} that can be
+ injected. Guice will pass dependencies to the method as parameters. Install
+ {@literal @}CheckedProvides methods by using
+ {@link ThrowingProviderBinder#forModule(com.google.inject.Module)} on the
+ module where the methods are declared.
+ 
+ @author sameb@google.com (Sam Berlin)
+ @since 3.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.throwingproviders.CheckedProvides -->
+  <!-- start class com.google.inject.throwingproviders.ThrowingInject -->
+  <class name="ThrowingInject"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="java.lang.annotation.Annotation"/>
+    <doc>
+    <![CDATA[A version of {@literal @}{@link Inject} designed for ThrowingProviders.  Use by:
+ <pre><code>ThrowingProviderBinder.create(binder())
+    .bind(RemoteProvider.class, Customer.class)
+    .providing(CustomerImpl.class);
+ </code></pre>
+ where CustomerImpl has a constructor annotated with ThrowingInject.
+
+ @author sameb@google.com (Sam Berlin)
+ @since 4.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.throwingproviders.ThrowingInject -->
+  <!-- start interface com.google.inject.throwingproviders.ThrowingProvider -->
+  <interface name="ThrowingProvider"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="use {@link CheckedProvider} instead.">
+    <implements name="com.google.inject.throwingproviders.CheckedProvider&lt;T&gt;"/>
+    <method name="get" return="T"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="Exception" type="java.lang.Exception"/>
+    </method>
+    <doc>
+    <![CDATA[Alternative to the Guice {@link com.google.inject.Provider} that throws
+ a checked Exception. Users may not inject {@code T} directly.
+
+ <p>This interface must be extended to use application-specific exception types.
+ Such subinterfaces may not define new methods:
+ <pre>
+ public interface RemoteProvider&lt;T&gt; extends ThrowingProvider&lt;T, RemoteException&gt; { }
+ </pre>
+
+ <p>When this type is bound using {@link ThrowingProviderBinder}, the value returned
+ or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get}
+ will invoked at most once within each scope.
+
+ @author jmourits@google.com (Jerome Mourits)
+ @author jessewilson@google.com (Jesse Wilson)
+ @deprecated use {@link CheckedProvider} instead.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.throwingproviders.ThrowingProvider -->
+  <!-- start class com.google.inject.throwingproviders.ThrowingProviderBinder -->
+  <class name="ThrowingProviderBinder" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="create" return="com.google.inject.throwingproviders.ThrowingProviderBinder"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="binder" type="com.google.inject.Binder"/>
+    </method>
+    <method name="forModule" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="module" type="com.google.inject.Module"/>
+      <doc>
+      <![CDATA[Returns a module that installs {@literal @}{@link CheckedProvides} methods.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, ?&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="Use {@link #bind(Class, Class)} or {@link #bind(Class, TypeLiteral)} instead.">
+      <param name="interfaceType" type="java.lang.Class&lt;P&gt;"/>
+      <param name="clazz" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[@deprecated Use {@link #bind(Class, Class)} or {@link #bind(Class, TypeLiteral)} instead.]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="interfaceType" type="java.lang.Class&lt;P&gt;"/>
+      <param name="clazz" type="java.lang.Class&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="bind" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="interfaceType" type="java.lang.Class&lt;P&gt;"/>
+      <param name="typeLiteral" type="com.google.inject.TypeLiteral&lt;T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[<p>Builds a binding for a {@link CheckedProvider}.
+ 
+ <p>You can use a fluent API and custom providers:
+ <pre><code>ThrowingProviderBinder.create(binder())
+    .bind(RemoteProvider.class, Customer.class)
+    .to(RemoteCustomerProvider.class)
+    .in(RequestScope.class);
+ </code></pre>
+ or, you can use throwing provider methods:
+ <pre><code>class MyModule extends AbstractModule {
+   configure() {
+     ThrowingProviderBinder.install(this, binder());
+   }
+   
+   {@literal @}CheckedProvides(RemoteProvider.class)
+   {@literal @}RequestScope
+   Customer provideCustomer(FlakyCustomerCreator creator) throws RemoteException {
+     return creator.getCustomerOrThrow();
+   }
+ }
+ </code></pre>
+ You also can declare that a CheckedProvider construct
+ a particular class whose constructor throws an exception:
+ <pre><code>ThrowingProviderBinder.create(binder())
+    .bind(RemoteProvider.class, Customer.class)
+    .providing(CustomerImpl.class)
+    .in(RequestScope.class);
+ </code></pre>
+ 
+ @author jmourits@google.com (Jerome Mourits)
+ @author jessewilson@google.com (Jesse Wilson)
+ @author sameb@google.com (Sam Berlin)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.throwingproviders.ThrowingProviderBinder -->
+  <!-- start class com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder -->
+  <class name="ThrowingProviderBinder.SecondaryBinder" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="SecondaryBinder" type="java.lang.Class&lt;P&gt;, java.lang.reflect.Type"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="annotatedWith" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotationType" type="java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;"/>
+    </method>
+    <method name="annotatedWith" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="annotation" type="java.lang.annotation.Annotation"/>
+    </method>
+    <method name="scopeExceptions" return="com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder&lt;P, T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scopeExceptions" type="boolean"/>
+      <doc>
+      <![CDATA[Determines if exceptions should be scoped. By default exceptions are scoped.
+
+ @param scopeExceptions whether exceptions should be scoped.
+ @since 4.0]]>
+      </doc>
+    </method>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="target" type="P extends com.google.inject.throwingproviders.CheckedProvider"/>
+    </method>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="targetType" type="java.lang.Class&lt;? extends P&gt;"/>
+    </method>
+    <method name="providing" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="cxtorClass" type="java.lang.Class&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="providing" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="cxtorLiteral" type="com.google.inject.TypeLiteral&lt;? extends T&gt;"/>
+      <doc>
+      <![CDATA[@since 4.0]]>
+      </doc>
+    </method>
+    <method name="to" return="com.google.inject.binder.ScopedBindingBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="targetKey" type="com.google.inject.Key&lt;? extends P&gt;"/>
+    </method>
+  </class>
+  <!-- end class com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder -->
+</package>
+<package name="com.google.inject.tools.jmx">
+  <!-- start interface com.google.inject.tools.jmx.ManagedBindingMBean -->
+  <interface name="ManagedBindingMBean"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="getSource" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the source of this binding.]]>
+      </doc>
+    </method>
+    <method name="getProvider" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the provider to which this binding is bound.]]>
+      </doc>
+    </method>
+    <method name="getKey" return="java.lang.String"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Gets the binding key.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[JMX interface to bindings.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.tools.jmx.ManagedBindingMBean -->
+  <!-- start class com.google.inject.tools.jmx.Manager -->
+  <class name="Manager" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Manager"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="manage"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="domain" type="java.lang.String"/>
+      <param name="injector" type="com.google.inject.Injector"/>
+      <doc>
+      <![CDATA[Registers all the bindings of an Injector with the platform MBean server.
+ Consider using the name of your root {@link Module} class as the domain.]]>
+      </doc>
+    </method>
+    <method name="manage"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="server" type="javax.management.MBeanServer"/>
+      <param name="domain" type="java.lang.String"/>
+      <param name="injector" type="com.google.inject.Injector"/>
+      <doc>
+      <![CDATA[Registers all the bindings of an Injector with the given MBean server.
+ Consider using the name of your root {@link Module} class as the domain.]]>
+      </doc>
+    </method>
+    <method name="main"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="args" type="java.lang.String[]"/>
+      <exception name="Exception" type="java.lang.Exception"/>
+      <doc>
+      <![CDATA[Run with no arguments for usage instructions.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Provides a JMX interface to Guice.
+
+ @author crazybob@google.com (Bob Lee)]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.tools.jmx.Manager -->
+</package>
+<package name="com.google.inject.util">
+  <!-- start class com.google.inject.util.Modules -->
+  <class name="Modules" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="override" return="com.google.inject.util.Modules.OverriddenModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Returns a builder that creates a module that overlays override modules over the given
+ modules. If a key is bound in both sets of modules, only the binding from the override modules
+ is kept. If a single {@link PrivateModule} is supplied or all elements are from
+ a single {@link PrivateBinder}, then this will overwrite the private bindings.
+ Otherwise, private bindings will not be overwritten unless they are exposed. 
+ This can be used to replace the bindings of a production module with test bindings:
+ <pre>
+ Module functionalTestModule
+     = Modules.override(new ProductionModule()).with(new TestModule());
+ </pre>
+
+ <p>Prefer to write smaller modules that can be reused and tested without overrides.
+
+ @param modules the modules whose bindings are open to be overridden]]>
+      </doc>
+    </method>
+    <method name="override" return="com.google.inject.util.Modules.OverriddenModuleBuilder"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Returns a builder that creates a module that overlays override modules over the given
+ modules. If a key is bound in both sets of modules, only the binding from the override modules
+ is kept. If a single {@link PrivateModule} is supplied or all elements are from
+ a single {@link PrivateBinder}, then this will overwrite the private bindings.
+ Otherwise, private bindings will not be overwritten unless they are exposed. 
+ This can be used to replace the bindings of a production module with test bindings:
+ <pre>
+ Module functionalTestModule
+     = Modules.override(getProductionModules()).with(getTestModules());
+ </pre>
+
+ <p>Prefer to write smaller modules that can be reused and tested without overrides.
+
+ @param modules the modules whose bindings are open to be overridden]]>
+      </doc>
+    </method>
+    <method name="combine" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[Returns a new module that installs all of {@code modules}.]]>
+      </doc>
+    </method>
+    <method name="combine" return="com.google.inject.Module"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="modules" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[Returns a new module that installs all of {@code modules}.]]>
+      </doc>
+    </method>
+    <field name="EMPTY_MODULE" type="com.google.inject.Module"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <doc>
+    <![CDATA[Static utility methods for creating and working with instances of {@link Module}.
+
+ @author jessewilson@google.com (Jesse Wilson)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.util.Modules -->
+  <!-- start interface com.google.inject.util.Modules.OverriddenModuleBuilder -->
+  <interface name="Modules.OverriddenModuleBuilder"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="with" return="com.google.inject.Module"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="overrides" type="com.google.inject.Module[]"/>
+      <doc>
+      <![CDATA[See the EDSL example at {@link Modules#override(Module[]) override()}.]]>
+      </doc>
+    </method>
+    <method name="with" return="com.google.inject.Module"
+      abstract="true" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="overrides" type="java.lang.Iterable&lt;? extends com.google.inject.Module&gt;"/>
+      <doc>
+      <![CDATA[See the EDSL example at {@link Modules#override(Module[]) override()}.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[See the EDSL example at {@link Modules#override(Module[]) override()}.]]>
+    </doc>
+  </interface>
+  <!-- end interface com.google.inject.util.Modules.OverriddenModuleBuilder -->
+  <!-- start class com.google.inject.util.Providers -->
+  <class name="Providers" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="of" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="instance" type="T"/>
+      <doc>
+      <![CDATA[Returns a provider which always provides {@code instance}.  This should not
+ be necessary to use in your application, but is helpful for several types
+ of unit tests.
+
+ @param instance the instance that should always be provided.  This is also
+     permitted to be null, to enable aggressive testing, although in real
+     life a Guice-supplied Provider will never return null.]]>
+      </doc>
+    </method>
+    <method name="guicify" return="com.google.inject.Provider&lt;T&gt;"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="provider" type="javax.inject.Provider&lt;T&gt;"/>
+      <doc>
+      <![CDATA[Returns a Guice-friendly {@code com.google.inject.Provider} for the given
+ JSR-330 {@code javax.inject.Provider}. The converse method is unnecessary,
+ since Guice providers directly implement the JSR-330 interface.
+ 
+ @since 3.0]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Static utility methods for creating and working with instances of
+ {@link Provider}.
+
+ @author Kevin Bourrillion (kevinb9n@gmail.com)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.util.Providers -->
+  <!-- start class com.google.inject.util.Types -->
+  <class name="Types" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="newParameterizedType" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rawType" type="java.lang.reflect.Type"/>
+      <param name="typeArguments" type="java.lang.reflect.Type[]"/>
+      <doc>
+      <![CDATA[Returns a new parameterized type, applying {@code typeArguments} to
+ {@code rawType}. The returned type does not have an owner type.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="newParameterizedTypeWithOwner" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="ownerType" type="java.lang.reflect.Type"/>
+      <param name="rawType" type="java.lang.reflect.Type"/>
+      <param name="typeArguments" type="java.lang.reflect.Type[]"/>
+      <doc>
+      <![CDATA[Returns a new parameterized type, applying {@code typeArguments} to
+ {@code rawType} and enclosed by {@code ownerType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="arrayOf" return="java.lang.reflect.GenericArrayType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="componentType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns an array type whose elements are all instances of
+ {@code componentType}.
+
+ @return a {@link java.io.Serializable serializable} generic array type.]]>
+      </doc>
+    </method>
+    <method name="subtypeOf" return="java.lang.reflect.WildcardType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bound" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type that represents an unknown type that extends {@code bound}.
+ For example, if {@code bound} is {@code CharSequence.class}, this returns
+ {@code ? extends CharSequence}. If {@code bound} is {@code Object.class},
+ this returns {@code ?}, which is shorthand for {@code ? extends Object}.]]>
+      </doc>
+    </method>
+    <method name="supertypeOf" return="java.lang.reflect.WildcardType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bound" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type that represents an unknown supertype of {@code bound}. For
+ example, if {@code bound} is {@code String.class}, this returns {@code ?
+ super String}.]]>
+      </doc>
+    </method>
+    <method name="listOf" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="elementType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link List} whose elements are of type
+ {@code elementType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="collectionOf" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="elementType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link Collection} whose elements are of type
+ {@code elementType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="setOf" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="elementType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link Set} whose elements are of type
+ {@code elementType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="mapOf" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="keyType" type="java.lang.reflect.Type"/>
+      <param name="valueType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link Map} whose keys are of type
+ {@code keyType} and whose values are of type {@code valueType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="providerOf" return="java.lang.reflect.ParameterizedType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="providedType" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link Provider} that provides elements of type
+ {@code elementType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <method name="javaxProviderOf" return="java.lang.reflect.Type"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="type" type="java.lang.reflect.Type"/>
+      <doc>
+      <![CDATA[Returns a type modelling a {@link javax.inject.Provider} that provides elements of type
+ {@code elementType}.
+
+ @return a {@link java.io.Serializable serializable} parameterized type.]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[Static methods for working with types.
+
+ @author crazybob@google.com (Bob Lee)
+ @since 2.0]]>
+    </doc>
+  </class>
+  <!-- end class com.google.inject.util.Types -->
+</package>
+
+</api>
diff --git a/lib/build/asm-5.0.3.jar b/lib/build/asm-5.0.3.jar
deleted file mode 100644
index 573535b..0000000
--- a/lib/build/asm-5.0.3.jar
+++ /dev/null
Binary files differ
diff --git a/lib/build/asm-6.0.jar b/lib/build/asm-6.0.jar
new file mode 100644
index 0000000..8730f3d
--- /dev/null
+++ b/lib/build/asm-6.0.jar
Binary files differ
diff --git a/lib/build/cglib-3.1.jar b/lib/build/cglib-3.1.jar
deleted file mode 100644
index 25a5df1..0000000
--- a/lib/build/cglib-3.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/build/cglib-3.2.6.jar b/lib/build/cglib-3.2.6.jar
new file mode 100644
index 0000000..600a475
--- /dev/null
+++ b/lib/build/cglib-3.2.6.jar
Binary files differ
diff --git a/lib/build/guava-testlib-16.0.1.jar b/lib/build/guava-testlib-16.0.1.jar
deleted file mode 100644
index 59150aa..0000000
--- a/lib/build/guava-testlib-16.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/build/guava-testlib-19.0.jar b/lib/build/guava-testlib-19.0.jar
new file mode 100644
index 0000000..e0b8c89
--- /dev/null
+++ b/lib/build/guava-testlib-19.0.jar
Binary files differ
diff --git a/lib/build/jdiff/Null.java b/lib/build/jdiff/Null.java
index 019b718..e34b592 100644
--- a/lib/build/jdiff/Null.java
+++ b/lib/build/jdiff/Null.java
@@ -1,9 +1,7 @@
-/** 
- * This class is used only as a "null" argument for Javadoc when comparing
- * two API files. Javadoc has to have a package, .java or .class file as an 
- * argument, even though JDiff doesn't use it.
+/**
+ * This class is used only as a "null" argument for Javadoc when comparing two API files. Javadoc
+ * has to have a package, .java or .class file as an argument, even though JDiff doesn't use it.
  */
 public class Null {
-    public Null() {
-    }
+  public Null() {}
 }
diff --git a/lib/build/truth-0.36.jar b/lib/build/truth-0.36.jar
new file mode 100644
index 0000000..8174e4a
--- /dev/null
+++ b/lib/build/truth-0.36.jar
Binary files differ
diff --git a/lib/guava-16.0.1.jar b/lib/guava-16.0.1.jar
deleted file mode 100644
index 2c8127d..0000000
--- a/lib/guava-16.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/guava-19.0.jar b/lib/guava-19.0.jar
new file mode 100644
index 0000000..b175ca8
--- /dev/null
+++ b/lib/guava-19.0.jar
Binary files differ
diff --git a/pom.xml b/pom.xml
index 9cdc793..988ecba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
 
   <groupId>com.google.inject</groupId>
   <artifactId>guice-parent</artifactId>
-  <version>4.0</version>
+  <version>4.2.0</version>
 
   <name>Google Guice</name>
 
@@ -67,7 +67,7 @@
   </scm>
 
   <issueManagement>
-    <system>Google Code</system>
+    <system>Github</system>
     <url>https://github.com/google/guice/issues/</url>
   </issueManagement>
 
@@ -144,22 +144,39 @@
       <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
-        <version>16.0.1</version>
+        <version>23.6-android</version>
       </dependency>
       <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava-testlib</artifactId>
-        <version>16.0.1</version>
+        <version>23.6-android</version>
       </dependency>
       <dependency>
         <groupId>org.ow2.asm</groupId>
         <artifactId>asm</artifactId>
-        <version>5.0.3</version>
+        <version>6.0</version>
       </dependency>
       <dependency>
         <groupId>cglib</groupId>
         <artifactId>cglib</artifactId>
-        <version>3.1</version>
+        <version>3.2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.11</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.google.truth</groupId>
+        <artifactId>truth</artifactId>
+        <version>0.36</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.google.code.findbugs</groupId>
+        <artifactId>jsr305</artifactId>
+        <version>3.0.1</version>
       </dependency>
     </dependencies>
   </dependencyManagement>
@@ -168,8 +185,6 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.11</version>
-      <scope>test</scope>
     </dependency>
   </dependencies>
 
@@ -250,30 +265,30 @@
           </executions>
         </plugin>
         <!--
-         | Make sure we only use Java6 methods
+         | Make sure we only use Java7 methods
         -->
         <plugin>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>2.3.2</version>
           <configuration>
-            <source>1.6</source>
-            <target>1.6</target>
+            <source>1.7</source>
+            <target>1.7</target>
           </configuration>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>animal-sniffer-maven-plugin</artifactId>
-          <version>1.10</version>
+          <version>1.16</version>
           <configuration>
             <signature>
               <groupId>org.codehaus.mojo.signature</groupId>
-              <artifactId>java16</artifactId>
+              <artifactId>java17</artifactId>
               <version>1.0</version>
             </signature>
           </configuration>
           <executions>
             <execution>
-              <id>check-java-1.6-compat</id>
+              <id>check-java-1.7-compat</id>
               <phase>process-classes</phase>
               <goals>
                 <goal>check</goal>
@@ -321,7 +336,7 @@
         <plugin>
           <groupId>org.apache.felix</groupId>
           <artifactId>maven-bundle-plugin</artifactId>
-          <version>2.1.0</version>
+          <version>3.5.0</version>
           <configuration>
             <instructions>
               <module>com.google.inject</module>
@@ -377,7 +392,7 @@
         </plugin>
         <plugin>
           <artifactId>maven-javadoc-plugin</artifactId>
-          <version>2.7</version>
+          <version>3.0.0</version>
           <executions>
             <execution>
               <phase>package</phase>
@@ -448,7 +463,9 @@
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-javadoc-plugin</artifactId>
             <configuration>
-              <additionalparam>-Xdoclint:none</additionalparam>
+              <additionalOptions>
+                <additionalOption>-Xdoclint:none</additionalOption>
+              </additionalOptions>
             </configuration>
           </plugin>
         </plugins>
@@ -459,7 +476,9 @@
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-javadoc-plugin</artifactId>
             <configuration>
-              <additionalparam>-Xdoclint:none</additionalparam>
+              <additionalOptions>
+                <additionalOption>-Xdoclint:none</additionalOption>
+              </additionalOptions>
             </configuration>
           </plugin>
         </plugins>
diff --git a/util/generate-latest-docs.sh b/util/generate-latest-docs.sh
index 683c5fd..4dec42f 100755
--- a/util/generate-latest-docs.sh
+++ b/util/generate-latest-docs.sh
@@ -23,7 +23,7 @@
   cp -rf $HOME/api-diffs-latest api-docs/latest/api-diffs
   cp -rf $HOME/javadoc-latest api-docs/latest/javadoc
   git add -f .
-  git commit -m "Lastest javadoc & api-diffs on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
+  git commit -m "Latest javadoc & api-diffs on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
   git push -fq origin gh-pages > /dev/null
 
   echo -e "Published Javadoc & JDiff to gh-pages.\n"