Adopt latest google collections snapshot (partially); some style cleanup

git-svn-id: https://google-guice.googlecode.com/svn/trunk@504 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/build.xml b/build.xml
index a5097a3..28620b7 100644
--- a/build.xml
+++ b/build.xml
@@ -19,9 +19,11 @@
       <fileset dir="${build.dir}/classes"/>
       <zipfileset src="lib/build/cglib-2.2.jar"/>
       <zipfileset src="lib/build/asm-3.1.jar"/>
-      <keep pattern="com.google.**"/>
+      <zipfileset src="lib/build/google-collect-snapshot-20080530.jar"/>
+      <rule pattern="com.google.common.**" result="com.google.inject.internal.@1"/>
       <rule pattern="net.sf.cglib.**" result="com.google.inject.cglib.@1"/>
       <rule pattern="org.objectweb.asm.**" result="com.google.inject.asm.@1"/>
+      <keep pattern="com.google.**"/>
     </jarjar>
   </target>
 
diff --git a/extensions/commands/src/com/google/inject/commands/intercepting/InterceptingInjectorBuilder.java b/extensions/commands/src/com/google/inject/commands/intercepting/InterceptingInjectorBuilder.java
index e805da9..2c0a31a 100644
--- a/extensions/commands/src/com/google/inject/commands/intercepting/InterceptingInjectorBuilder.java
+++ b/extensions/commands/src/com/google/inject/commands/intercepting/InterceptingInjectorBuilder.java
@@ -20,9 +20,9 @@
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
 import com.google.inject.commands.*;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.internal.UniqueAnnotations;
 import com.google.inject.name.Names;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.*;
 
@@ -194,15 +194,15 @@
 
     @Inject void initialize(Injector injector,
         Provider<ProvisionInterceptor> injectionInterceptorProvider) {
-      this.injectionInterceptorProvider = nonNull(
-          injectionInterceptorProvider, "injectionInterceptorProvider");
-      this.delegateProvider = nonNull(
-          injector.getProvider(anonymousKey), "delegateProvider");
+      this.injectionInterceptorProvider
+          = checkNotNull(injectionInterceptorProvider, "injectionInterceptorProvider");
+      this.delegateProvider
+          = checkNotNull(injector.getProvider(anonymousKey), "delegateProvider");
     }
 
     public T get() {
-      nonNull(injectionInterceptorProvider, "injectionInterceptorProvider");
-      nonNull(delegateProvider, "delegateProvider");
+      checkNotNull(injectionInterceptorProvider, "injectionInterceptorProvider");
+      checkNotNull(delegateProvider, "delegateProvider");
       return injectionInterceptorProvider.get().intercept(key, delegateProvider);
     }
   }
diff --git a/extensions/compiletime/src/com/google/inject/CodeGenReflectionFactory.java b/extensions/compiletime/src/com/google/inject/CodeGenReflectionFactory.java
index a378f27..7709102 100644
--- a/extensions/compiletime/src/com/google/inject/CodeGenReflectionFactory.java
+++ b/extensions/compiletime/src/com/google/inject/CodeGenReflectionFactory.java
@@ -18,7 +18,7 @@
 package com.google.inject;
 
 import com.google.inject.internal.*;
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.File;
 import java.io.IOException;
@@ -78,7 +78,7 @@
     private final Reflection delegate;
 
     private CodeGenReflection(Reflection delegate) {
-      this.delegate = nonNull(delegate, "delegate");
+      this.delegate = checkNotNull(delegate, "delegate");
     }
 
     public <T> ConstructionProxy<T> getConstructionProxy(Class<T> implementation) {
diff --git a/extensions/compiletime/src/com/google/inject/CompileTimeGuice.java b/extensions/compiletime/src/com/google/inject/CompileTimeGuice.java
index 08b55ce..a8194fe 100644
--- a/extensions/compiletime/src/com/google/inject/CompileTimeGuice.java
+++ b/extensions/compiletime/src/com/google/inject/CompileTimeGuice.java
@@ -17,11 +17,10 @@
 
 package com.google.inject;
 
-import static com.google.inject.internal.Objects.nonNull;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.Set;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * <strong>Unsupported.</strong> Currently compile-time Guice code still
@@ -47,8 +46,8 @@
    * @param modules the modules used to build the injector.
    */
   public CompileTimeGuice(String name, Set<? extends Module> modules) {
-    this.name = nonNull(name, "name");
-    this.modules = nonNull(modules, "modules");
+    this.name = checkNotNull(name, "name");
+    this.modules = checkNotNull(modules, "modules");
   }
 
   /**
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
index 63cb57e..01d2729 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
@@ -18,10 +18,10 @@
 
 import com.google.inject.*;
 import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.internal.Objects;
 import com.google.inject.internal.Types;
 import com.google.inject.multibindings.Multibinder.RealMultibinder;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -218,7 +218,7 @@
      * and another for {@code V}.
      */
     @Override public LinkedBindingBuilder<V> addBinding(K key) {
-      Objects.nonNull(key, "key");
+      checkNotNull(key, "key");
       if (isInitialized()) {
         throw new IllegalStateException("MapBinder was already initialized");
       }
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
index 0df1ed7..2aef6b2 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
@@ -18,9 +18,9 @@
 
 import com.google.inject.*;
 import com.google.inject.binder.LinkedBindingBuilder;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.internal.Types;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -164,10 +164,10 @@
 
     private RealMultibinder(Binder binder, Type elementType,
         String setName, Key<Set<T>> setKey) {
-      this.binder = nonNull(binder, "binder");
-      this.elementType = nonNull(elementType, "elementType");
-      this.setName = nonNull(setName, "setName");
-      this.setKey = nonNull(setKey, "setKey");
+      this.binder = checkNotNull(binder, "binder");
+      this.elementType = checkNotNull(elementType, "elementType");
+      this.setName = checkNotNull(setName, "setName");
+      this.setKey = checkNotNull(setKey, "setKey");
     }
 
     @SuppressWarnings("unchecked")
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
index 12e06da..1a49a8d 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
@@ -18,8 +18,8 @@
 
 import com.google.inject.*;
 import com.google.inject.binder.ScopedBindingBuilder;
-import com.google.inject.internal.Objects;
 import com.google.inject.internal.UniqueAnnotations;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.*;
@@ -60,8 +60,8 @@
     private final Class<?> exceptionType;
 
     public SecondaryBinder(Class<P> interfaceType, Type valueType) {
-      this.interfaceType = Objects.nonNull(interfaceType, "interfaceType");
-      this.valueType = Objects.nonNull(valueType, "valueType");
+      this.interfaceType = checkNotNull(interfaceType, "interfaceType");
+      this.valueType = checkNotNull(valueType, "valueType");
       checkInterface();
       this.exceptionType = getExceptionType(interfaceType);
     }
@@ -93,7 +93,7 @@
     }
 
     public ScopedBindingBuilder to(final Key<? extends P> targetKey) {
-      Objects.nonNull(targetKey, "targetKey");
+      checkNotNull(targetKey, "targetKey");
       final Key<Result> resultKey = Key.get(Result.class, UniqueAnnotations.create());
       final Key<P> key = createKey();
 
diff --git a/guice.iml b/guice.iml
index 3fc4d87..f4d0954 100644
--- a/guice.iml
+++ b/guice.iml
@@ -69,21 +69,14 @@
     <orderEntry type="module-library">
       <library>
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/build/asm-3.1.jar!/" />
+          <root url="file://$MODULE_DIR$/lib/build" />
         </CLASSES>
         <JAVADOC />
         <SOURCES />
+        <jarDirectory url="file://$MODULE_DIR$/lib/build" recursive="false" />
       </library>
     </orderEntry>
-    <orderEntry type="module-library">
-      <library>
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/build/cglib-2.2.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES />
-      </library>
-    </orderEntry>
+    <orderEntry type="library" exported="" name="collect" level="project" />
     <orderEntryProperties />
   </component>
 </module>
diff --git a/guice.ipr b/guice.ipr
index 04f02db..56a6b4c 100644
--- a/guice.ipr
+++ b/guice.ipr
@@ -49,7 +49,7 @@
         <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
         <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
         <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
-        <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+        <option name="BLANK_LINES_BEFORE_PACKAGE" value="1" />
         <option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
         <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
         <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
@@ -63,7 +63,9 @@
             <package name="" withSubpackages="true" />
           </value>
         </option>
-        <option name="RIGHT_MARGIN" value="80" />
+        <option name="OPTIMIZE_IMPORTS_ON_THE_FLY" value="true" />
+        <option name="ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY" value="true" />
+        <option name="RIGHT_MARGIN" value="100" />
         <option name="CALL_PARAMETERS_WRAP" value="1" />
         <option name="METHOD_PARAMETERS_WRAP" value="1" />
         <option name="EXTENDS_LIST_WRAP" value="1" />
@@ -89,6 +91,7 @@
         <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
         <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
         <option name="JD_P_AT_EMPTY_LINES" value="false" />
+        <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
         <option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
         <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
         <option name="JD_KEEP_EMPTY_RETURN" value="false" />
@@ -98,7 +101,7 @@
         <option name="PARAMETER_ANNOTATION_WRAP" value="1" />
         <option name="VARIABLE_ANNOTATION_WRAP" value="1" />
         <option name="ENUM_CONSTANTS_WRAP" value="1" />
-        <ADDITIONAL_INDENT_OPTIONS fileType="js">
+        <ADDITIONAL_INDENT_OPTIONS fileType="">
           <option name="INDENT_SIZE" value="4" />
           <option name="CONTINUATION_INDENT_SIZE" value="8" />
           <option name="TAB_SIZE" value="4" />
@@ -109,7 +112,7 @@
         </ADDITIONAL_INDENT_OPTIONS>
       </value>
     </option>
-    <option name="USE_PER_PROJECT_SETTINGS" value="false" />
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
   </component>
   <component name="CompilerConfiguration">
     <option name="DEFAULT_COMPILER" value="Javac" />
@@ -157,15 +160,124 @@
   <component name="IdProvider" IDEtalkID="0FACE31A44579D2420BBAE592490FBFA" />
   <component name="InspectionProjectProfileManager">
     <option name="PROJECT_PROFILE" value="Project Default" />
-    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="true" />
     <scopes />
     <profiles>
       <profile version="1.0" is_locked="false">
         <option name="myName" value="Project Default" />
         <option name="myLocal" value="false" />
+        <inspection_tool class="SSBasedInspection" level="WARNING" enabled="true">
+          <replaceConfiguration name="use Lists.newArrayList" text="java.util.List&lt;$T$&gt; $var$ = new java.util.ArrayList&lt;$T$&gt;();" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.List&lt;$T$&gt; $var$ = com.google.common.collect.Lists.newArrayList();">
+            <constraint name="var" />
+            <constraint name="T" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Lists.newArrayList (iterable)" text="java.util.List&lt;$T$&gt; $var$ = new java.util.ArrayList&lt;$T$&gt;($iterable$);" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.List&lt;$T$&gt; $var$ = com.google.common.collect.Lists.newArrayList($iterable$);">
+            <constraint name="var" />
+            <constraint name="T" />
+            <constraint name="iterable" nameOfExprType="java.lang.Iterable" exprTypeWithinHierarchy="true" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Lists.newLinkedList" text="java.util.List&lt;$T$&gt; $var$ = new java.util.LinkedList&lt;$T$&gt;();" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.List&lt;$T$&gt; $var$ = com.google.common.collect.Lists.newLinkedList();">
+            <constraint name="var" />
+            <constraint name="T" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Lists.newLinkedList (iterable)" text="java.util.List&lt;$T$&gt; $var$ = new java.util.LinkedList&lt;$T$&gt;($iterable$);" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.List&lt;$T$&gt; $var$ = com.google.common.collect.Lists.newLinkedList($iterable$);">
+            <constraint name="var" />
+            <constraint name="iterable" nameOfExprType="java.lang.Iterable" exprTypeWithinHierarchy="true" />
+            <constraint name="T" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Sets.newHashSet" text="java.util.Set&lt;$T$&gt; $var$ = new java.util.HashSet&lt;$T$&gt;();" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.Set&lt;$T$&gt; $var$ = com.google.common.collect.Sets.newHashSet();">
+            <constraint name="var" />
+            <constraint name="T" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Sets.newHashSet (iterable)" text="java.util.Set&lt;$T$&gt; $var$ = new HashSet&lt;$T$&gt;($iterable$);" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.Set&lt;$T$&gt; $var$ = com.google.common.collect.Sets.newHashSet($iterable$);">
+            <constraint name="var" />
+            <constraint name="T" />
+            <constraint name="iterable" nameOfExprType="java.lang.Iterable" exprTypeWithinHierarchy="true" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Maps.newHashMap" text="java.util.Map&lt;$K$, $V$&gt; $var$ = new java.util.HashMap&lt;$K$, $V$&gt;();" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="java.util.Map&lt;$K$, $V$&gt; $var$ = com.google.common.collect.Maps.newHashMap();">
+            <constraint name="var" />
+            <constraint name="K" />
+            <constraint name="V" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Multimap&lt;K, V&gt; instead of Map&lt;K, List&lt;V&gt;&gt;" text="java.util.Map&lt;$K$, java.util.List&lt;$V$&gt;&gt; $var$ = $expr$;" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Multimap&lt;$K$, $V$&gt; $var$ = $expr$;">
+            <constraint name="K" />
+            <constraint name="V" />
+            <constraint name="var" />
+            <constraint name="expr" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Multimap&lt;K, V&gt; instead of Map&lt;K, Set&lt;V&gt;&gt;" text="java.util.Map&lt;$K$, java.util.Set&lt;$V$&gt;&gt; $var$ = $expr$;" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Multimap&lt;$K$, $V$&gt; $var$ = $expr$;">
+            <constraint name="K" />
+            <constraint name="V" />
+            <constraint name="var" />
+            <constraint name="expr" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkState" text="if ($condition$) {&#10;  throw new IllegalStateException($message$);&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkState(!($condition$), $message$);">
+            <constraint name="condition" />
+            <constraint name="message" nameOfExprType="java.lang.String" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkArgument" text="if ($argumentCondition$) {&#10;  throw new IllegalArgumentException($message$);&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkArgument(!($argumentCondition$), $message$);">
+            <constraint name="message" nameOfExprType="java.lang.String" />
+            <constraint name="argumentCondition" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkNotNull" text="if ($var$ == null) {&#10;  throw new NullPointerException($message$);&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkNotNull($var$, $message$);">
+            <constraint name="var" />
+            <constraint name="message" nameOfExprType="java.lang.String" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.max" text="$a$.compareTo($b$) &gt; 0 ? $a$ : $b$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.max($b$, $a$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.max for &gt;=" text="$a$.compareTo($b$) &gt;= 0 ? $a$ : $b$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.max($a$, $b$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.min" text="$a$.compareTo($b$) &lt; 0 ? $a$ : $b$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.min($b$, $a$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.min for &lt;=" text="$a$.compareTo($b$) &lt;= 0 ? $a$ : $b$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.min($a$, $b$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.min (2)" text="$a$.compareTo($b$) &gt; 0 ? $b$ : $a$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.min($a$, $b$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.min (2, &gt;=)" text="$a$.compareTo($b$) &gt;= 0 ? $b$ : $a$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.min($b$, $a$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.max (2)" text="$a$.compareTo($b$) &lt; 0 ? $b$ : $a$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.max($a$, $b$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Comparators.max (2, &lt;=)" text="$a$.compareTo($b$) &lt;= 0 ? $b$ : $a$" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.collect.Comparators.max($b$, $a$)">
+            <constraint name="a" />
+            <constraint name="b" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkState()" text="if ($condition$) {&#10;  throw new IllegalStateException();&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkState(!($condition$));">
+            <constraint name="condition" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkArgument()" text="if ($condition$) {&#10;  throw new IllegalArgumentException();&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkArgument(!($condition$));">
+            <constraint name="condition" />
+          </replaceConfiguration>
+          <replaceConfiguration name="use Preconditions.checkNotNull()" text="if ($var$ == null) {&#10;  throw new NullPointerException();&#10;}" recursive="false" caseInsensitive="true" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.google.common.base.Preconditions.checkNotNull($var$);">
+            <constraint name="reference" />
+            <constraint name="var" />
+          </replaceConfiguration>
+        </inspection_tool>
+        <inspection_tool class="UnnecessaryLocalVariable" level="WARNING" enabled="true">
+          <option name="m_ignoreImmediatelyReturnedVariables" value="false" />
+          <option name="m_ignoreAnnotatedVariables" value="true" />
+        </inspection_tool>
       </profile>
     </profiles>
-    <list size="0" />
+    <list size="4">
+      <item index="0" class="java.lang.String" itemvalue="SERVER PROBLEM" />
+      <item index="1" class="java.lang.String" itemvalue="INFO" />
+      <item index="2" class="java.lang.String" itemvalue="WARNING" />
+      <item index="3" class="java.lang.String" itemvalue="ERROR" />
+    </list>
   </component>
   <component name="JavacSettings">
     <option name="DEBUGGING_INFO" value="true" />
@@ -341,7 +453,7 @@
       <module fileurl="file://$PROJECT_DIR$/extensions/throwingproviders/throwingproviders.iml" filepath="$PROJECT_DIR$/extensions/throwingproviders/throwingproviders.iml" />
     </modules>
   </component>
-  <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="java version &quot;1.5.0_06&quot;" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/classes" />
   </component>
   <component name="ResourceManagerContainer">
@@ -389,5 +501,14 @@
       </value>
     </option>
   </component>
+  <component name="libraryTable">
+    <library name="collect">
+      <CLASSES>
+        <root url="jar://$PROJECT_DIR$/lib/build/google-collect-snapshot-20080530.jar!/" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES />
+    </library>
+  </component>
 </project>
 
diff --git a/lib/build/google-collect-snapshot-20080530.jar b/lib/build/google-collect-snapshot-20080530.jar
new file mode 100644
index 0000000..fe0ea12
--- /dev/null
+++ b/lib/build/google-collect-snapshot-20080530.jar
Binary files differ
diff --git a/spring/src/com/google/inject/spring/SpringIntegration.java b/spring/src/com/google/inject/spring/SpringIntegration.java
index 2ea2b4e..a74ccee 100644
--- a/spring/src/com/google/inject/spring/SpringIntegration.java
+++ b/spring/src/com/google/inject/spring/SpringIntegration.java
@@ -19,9 +19,9 @@
 import com.google.inject.Binder;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.name.Names;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.ListableBeanFactory;
 
@@ -92,8 +92,8 @@
     final String name;
 
     public SpringProvider(Class<T> type, String name) {
-      this.type = nonNull(type, "type");
-      this.name = nonNull(name, "name");
+      this.type = checkNotNull(type, "type");
+      this.name = checkNotNull(name, "name");
     }
 
     static <T> SpringProvider<T> newInstance(Class<T> type, String name) {
diff --git a/src/com/google/inject/AbstractModule.java b/src/com/google/inject/AbstractModule.java
index cc29e51..b1a34c1 100644
--- a/src/com/google/inject/AbstractModule.java
+++ b/src/com/google/inject/AbstractModule.java
@@ -19,10 +19,10 @@
 import com.google.inject.binder.AnnotatedBindingBuilder;
 import com.google.inject.binder.AnnotatedConstantBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.internal.Objects;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.spi.SourceProviders;
 import com.google.inject.spi.TypeConverter;
+import static com.google.common.base.Preconditions.checkNotNull;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import org.aopalliance.intercept.MethodInterceptor;
@@ -61,7 +61,7 @@
       if (this.binder != null) {
         throw new IllegalStateException("Re-entry is not allowed.");
       }
-      this.binder = Objects.nonNull(builder, "builder");
+      this.binder = checkNotNull(builder, "builder");
 
       configure();
 
diff --git a/src/com/google/inject/BindCommandProcessor.java b/src/com/google/inject/BindCommandProcessor.java
index e94fb05..6dec2a6 100644
--- a/src/com/google/inject/BindCommandProcessor.java
+++ b/src/com/google/inject/BindCommandProcessor.java
@@ -16,18 +16,22 @@
 
 package com.google.inject;
 
+import com.google.common.collect.Lists;
 import com.google.inject.commands.BindCommand;
 import com.google.inject.commands.BindConstantCommand;
-import com.google.inject.commands.BindScoping;
+import com.google.inject.commands.BindScoping.Visitor;
 import com.google.inject.commands.BindTarget;
 import com.google.inject.internal.Annotations;
 import com.google.inject.internal.ErrorMessages;
 import com.google.inject.internal.ResolveFailedException;
 import com.google.inject.internal.StackTraceElements;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Handles {@link Binder#bind} and {@link Binder#bindConstant} commands.
@@ -39,16 +43,15 @@
 
   private final InjectorImpl injector;
   private final Map<Class<? extends Annotation>, Scope> scopes;
-  private final List<CreationListener> creationListeners
-      = new ArrayList<CreationListener>();
+  private final List<CreationListener> creationListeners = Lists.newArrayList();
   private final Map<Key<?>, BindingImpl<?>> bindings;
-  private final Map<Object, Void> outstandingInjections;
-  private final List<Runnable> untargettedBindings = new ArrayList<Runnable>();
+  private final Set<Object> outstandingInjections;
+  private final List<Runnable> untargettedBindings = Lists.newArrayList();
 
   BindCommandProcessor(InjectorImpl injector,
       Map<Class<? extends Annotation>, Scope> scopes,
       Map<Key<?>, BindingImpl<?>> bindings,
-      Map<Object, Void> outstandingInjections) {
+      Set<Object> outstandingInjections) {
     super(injector.errorHandler);
     this.injector = injector;
     this.scopes = scopes;
@@ -72,7 +75,7 @@
     final LoadStrategy loadStrategy = command.getScoping().isEagerSingleton()
         ? LoadStrategy.EAGER
         : LoadStrategy.LAZY;
-    final Scope scope = command.getScoping().acceptVisitor(new BindScoping.Visitor<Scope>() {
+    final Scope scope = command.getScoping().acceptVisitor(new Visitor<Scope>() {
       public Scope visitEagerSingleton() {
         return Scopes.SINGLETON;
       }
@@ -100,7 +103,7 @@
     command.getTarget().acceptVisitor(new BindTarget.Visitor<T, Void>() {
       public Void visitToInstance(T instance) {
         ConstantFactory<? extends T> factory = new ConstantFactory<T>(instance);
-        outstandingInjections.put(instance, null);
+        outstandingInjections.add(instance);
         InternalFactory<? extends T> scopedFactory
             = Scopes.scope(key, injector, factory, scope);
         putBinding(new InstanceBindingImpl<T>(
@@ -111,7 +114,7 @@
       public Void visitToProvider(Provider<? extends T> provider) {
         InternalFactoryToProviderAdapter<? extends T> factory
             = new InternalFactoryToProviderAdapter<T>(provider, source);
-        outstandingInjections.put(provider, null);
+        outstandingInjections.add(provider);
         InternalFactory<? extends T> scopedFactory
             = Scopes.scope(key, injector, factory, scope);
         putBinding(new ProviderInstanceBindingImpl<T>(
diff --git a/src/com/google/inject/InjectionPoint.java b/src/com/google/inject/InjectionPoint.java
index 7e363da..7baad95 100644
--- a/src/com/google/inject/InjectionPoint.java
+++ b/src/com/google/inject/InjectionPoint.java
@@ -17,9 +17,9 @@
 package com.google.inject;
 
 import com.google.inject.internal.ErrorMessages;
-import com.google.inject.internal.Objects;
 import com.google.inject.internal.ToStringBuilder;
 import com.google.inject.spi.Dependency;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
@@ -41,7 +41,7 @@
       Nullability nullability, Key<T> key, InjectorImpl injector) {
     this.member = member;
     this.parameterIndex = paramterIndex;
-    this.nullability = Objects.nonNull(nullability, "nullability");
+    this.nullability = checkNotNull(nullability, "nullability");
     this.key = key;
     this.injector = injector;
   }
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index 5d72349..01db577 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -16,15 +16,14 @@
 
 package com.google.inject;
 
+import com.google.common.collect.Iterables;
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.inject.Scopes.SINGLETON;
 import com.google.inject.commands.Command;
 import com.google.inject.commands.CommandRecorder;
 import com.google.inject.commands.FutureInjector;
-import static com.google.inject.internal.GoogleCollections.concat;
-import com.google.inject.internal.Objects;
 import com.google.inject.internal.Stopwatch;
 import com.google.inject.spi.SourceProviders;
-
 import java.lang.reflect.Member;
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -195,7 +194,7 @@
   public void loadEagerSingletons() {
     // load eager singletons, or all singletons if we're in Stage.PRODUCTION.
     for (final BindingImpl<?> binding
-        : concat(injector.explicitBindings.values(), injector.jitBindings.values())) {
+        : Iterables.concat(injector.explicitBindings.values(), injector.jitBindings.values())) {
       if ((stage == Stage.PRODUCTION && binding.getScope() == Scopes.SINGLETON)
           || binding.getLoadStrategy() == LoadStrategy.EAGER) {
         injector.callInContext(new ContextualCallable<Void>() {
@@ -223,8 +222,8 @@
     final Stage stage;
 
     private BuiltInModule(Injector injector, Stage stage) {
-      this.injector = Objects.nonNull(injector, "injector");
-      this.stage = Objects.nonNull(stage, "stage");
+      this.injector = checkNotNull(injector, "injector");
+      this.stage = checkNotNull(stage, "stage");
     }
 
     protected void configure() {
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 82e3cc4..d2a8c14 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -16,16 +16,49 @@
 
 package com.google.inject;
 
-import com.google.inject.internal.*;
-import com.google.inject.spi.*;
+import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.ReferenceType;
+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.internal.Classes;
+import com.google.inject.internal.ErrorHandler;
+import com.google.inject.internal.ErrorMessages;
+import com.google.inject.internal.GuiceFastClass;
+import com.google.inject.internal.Keys;
+import com.google.inject.internal.MatcherAndConverter;
+import com.google.inject.internal.ReferenceCache;
+import com.google.inject.internal.ResolveFailedException;
+import com.google.inject.internal.ResolvingCallable;
+import com.google.inject.internal.StackTraceElements;
+import com.google.inject.internal.ToStringBuilder;
+import com.google.inject.spi.BindingVisitor;
+import com.google.inject.spi.ConvertedConstantBinding;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.ProviderBinding;
+import com.google.inject.spi.SourceProviders;
 import com.google.inject.util.Providers;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import net.sf.cglib.reflect.FastClass;
 import net.sf.cglib.reflect.FastMethod;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.*;
-import java.util.*;
-
 /**
  * Default {@link Injector} implementation.
  *
@@ -33,20 +66,13 @@
  * @see InjectorBuilder
  */
 class InjectorImpl implements Injector {
-
   final Injector parentInjector;
-  final Map<Key<?>, BindingImpl<?>> explicitBindings
-      = new HashMap<Key<?>, BindingImpl<?>>();
+  final Map<Key<?>, BindingImpl<?>> explicitBindings = Maps.newHashMap();
   final BindingsMultimap bindingsMultimap = new BindingsMultimap();
-  final Map<Class<? extends Annotation>, Scope> scopes
-      = new HashMap<Class<? extends Annotation>, Scope>();
-  final List<MatcherAndConverter<?>> converters
-      = new ArrayList<MatcherAndConverter<?>>();
-  final Map<Key<?>, BindingImpl<?>> parentBindings
-      = new HashMap<Key<?>, BindingImpl<?>>();
-  final Map<Object, Void> outstandingInjections
-      = new IdentityHashMap<Object, Void>();
-
+  final Map<Class<? extends Annotation>, Scope> scopes = Maps.newHashMap();
+  final List<MatcherAndConverter<?>> converters = Lists.newArrayList();
+  final Map<Key<?>, BindingImpl<?>> parentBindings = Maps.newHashMap();
+  final Set<Object> outstandingInjections = Sets.newIdentityHashSet(ReferenceType.STRONG);
   final ErrorHandler errorHandler;
   Reflection reflection;
 
@@ -56,26 +82,24 @@
   }
 
   void validateOustandingInjections() {
-    for (Object toInject : outstandingInjections.keySet()) {
+    for (Object toInject : outstandingInjections) {
       injectors.get(toInject.getClass());
     }
   }
 
   /**
-   * Performs creation-time injections on all objects that require it. Whenever
-   * fulfilling an injection depends on another object that requires injection,
-   * we use {@link InternalContext#ensureMemberInjected} to inject that member
-   * first.
+   * Performs creation-time injections on all objects that require it. Whenever fulfilling an
+   * injection depends on another object that requires injection, we use {@link
+   * InternalContext#ensureMemberInjected} to inject that member first.
    *
-   * <p>If the two objects are codependent (directly or transitively), ordering
-   * of injection is arbitrary.
+   * <p>If the two objects are codependent (directly or transitively), ordering of injection is
+   * arbitrary.
    */
   void fulfillOutstandingInjections() {
     callInContext(new ContextualCallable<Void>() {
       public Void call(InternalContext context) {
-        // loop over a defensive copy, since ensureMemberInjected() mutates the
-        // outstandingInjections set
-        for (Object toInject : new ArrayList<Object>(outstandingInjections.keySet())) {
+        // loop over a defensive copy, since ensureMemberInjected() mutates the set
+        for (Object toInject : Lists.newArrayList(outstandingInjections)) {
           context.ensureMemberInjected(toInject);
         }
         return null;
@@ -83,13 +107,11 @@
     });
 
     if (!outstandingInjections.isEmpty()) {
-      throw new IllegalStateException("failed to satisfy " + outstandingInjections);
+      throw new AssertionError("failed to satisfy " + outstandingInjections);
     }
   }
 
-  /**
-   * Indexes bindings by type.
-   */
+  /** Indexes bindings by type. */
   void index() {
     for (BindingImpl<?> binding : explicitBindings.values()) {
       index(binding);
@@ -102,48 +124,40 @@
 
   // not test-covered
   public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
-    return Collections.<Binding<T>>unmodifiableList(
-        bindingsMultimap.getAll(type));
+    return Collections.<Binding<T>>unmodifiableList(bindingsMultimap.getAll(type));
   }
 
   // not test-covered
   <T> List<String> getNamesOfBindingAnnotations(TypeLiteral<T> type) {
-    List<String> names = new ArrayList<String>();
+    List<String> names = Lists.newArrayList();
     for (Binding<T> binding : findBindingsByType(type)) {
       Key<T> key = binding.getKey();
-      if (!key.hasAnnotationType()) {
-        names.add("[no annotation]");
-      } else {
-        names.add(key.getAnnotationName());
-      }
+      names.add(key.hasAnnotationType() ? key.getAnnotationName() : "[no annotation]");
     }
     return names;
   }
 
-  /**
-   * This is only used during Injector building.
-   */
+  /** This is only used during Injector building. */
   void withDefaultSource(Object defaultSource, Runnable runnable) {
+    // TODO: inline/get rid of?
     SourceProviders.withDefault(defaultSource, runnable);
   }
 
-  /**
-   * Returns the binding for {@code key}, or {@code null} if that binding
-   * cannot be resolved.
-   */
+  /** Returns the binding for {@code key}, or {@code null} if that binding cannot be resolved. */
   public <T> BindingImpl<T> getBinding(Key<T> key) {
     try {
       return getBindingOrThrow(key);
-    } catch(ResolveFailedException e) {
+    }
+    catch (ResolveFailedException e) {
       return null;
     }
   }
 
   /**
-   * 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.
+   * 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.
    */
   public <T> BindingImpl<T> getBindingOrThrow(Key<T> key) throws ResolveFailedException {
     if (parentInjector != null) {
@@ -163,62 +177,58 @@
     return getJitBindingImpl(key);
   }
 
-
   /**
-   * Checks the parent injector for a scoped binding, and if available, creates
-   * an appropriate binding local to this injector and remembers it.
+   * Checks the parent injector for a scoped binding, and if available, creates an appropriate
+   * binding local to this injector and remembers it.
+   *
+   * TODO: think about this wrt parent jit bindings
    */
   @SuppressWarnings("unchecked")
   private <T> BindingImpl<T> getParentBinding(Key<T> key) {
-    BindingImpl<T> bindingImpl;
-    synchronized(parentBindings) {
+    synchronized (parentBindings) {
       // null values will mean that the parent doesn't have this binding
-      if (!parentBindings.containsKey(key)) {
-        Binding<T> binding = null;
-        try {
-          binding = parentInjector.getBinding(key);
-        } catch (ConfigurationException e) {
-          // if this happens, the parent can't create this key, and we ignore it
-        }
-        if (binding != null
-            && binding.getScope() != null
-            && !binding.getScope().equals(Scopes.NO_SCOPE)) {
-          bindingImpl = new ProviderInstanceBindingImpl(
-              this,
-              key,
-              binding.getSource(),
-              new InternalFactoryToProviderAdapter(binding.getProvider(),
-                  binding.getSource()),
-              Scopes.NO_SCOPE,
-              binding.getProvider(),
-              LoadStrategy.LAZY);
-        } else {
-          bindingImpl = null;
-        }
-        parentBindings.put(key, bindingImpl);
-      } else {
-        bindingImpl = (BindingImpl<T>) parentBindings.get(key);
+      Binding<T> binding = (Binding<T>) parentBindings.get(key);
+      if (binding != null) {
+        return (BindingImpl<T>) binding;
       }
+      try {
+        binding = parentInjector.getBinding(key);
+      }
+      catch (ConfigurationException e) {
+        // if this happens, the parent can't create this key, and we ignore it
+      }
+
+      BindingImpl<T> bindingImpl = null;
+      if (binding != null
+          && binding.getScope() != null
+          && !binding.getScope().equals(Scopes.NO_SCOPE)) {
+        bindingImpl = new ProviderInstanceBindingImpl(
+            this,
+            key,
+            binding.getSource(),
+            new InternalFactoryToProviderAdapter(binding.getProvider(), binding.getSource()),
+            Scopes.NO_SCOPE,
+            binding.getProvider(),
+            LoadStrategy.LAZY);
+      }
+      parentBindings.put(key, bindingImpl); // this kinda scares me
+      return bindingImpl;
     }
-    return bindingImpl;
   }
 
   public <T> Binding<T> getBinding(Class<T> type) {
     return getBinding(Key.get(type));
   }
 
-  /**
-   * Gets a binding which was specified explicitly in a module.
-   */
+  /** Gets a binding which was specified explicitly in a module. */
   @SuppressWarnings("unchecked")
   <T> BindingImpl<T> getExplicitBindingImpl(Key<T> key) {
     return (BindingImpl<T>) explicitBindings.get(key);
   }
 
-  /**
-   * Gets a just-in-time binding. This could be an injectable class (including
-   * those with @ImplementedBy), an automatically converted constant, a
-   * Provider<X> binding, etc.
+  /*
+   * Gets a just-in-time binding. This could be an injectable class (including those with
+   * @ImplementedBy), an automatically converted constant, a Provider<X> binding, etc.
    */
   @SuppressWarnings("unchecked")
   <T> BindingImpl<T> getJitBindingImpl(Key<T> key) throws ResolveFailedException {
@@ -228,28 +238,22 @@
         BindingImpl<T> binding = createBindingJustInTime(key);
         jitBindings.put(key, binding);
         return binding;
-      } else {
+      }
+      else {
         return (BindingImpl<T>) jitBindings.get(key);
       }
     }
   }
 
   /** Just-in-time binding cache. */
-  final Map<Key<?>, BindingImpl<?>> jitBindings
-      = new HashMap<Key<?>, BindingImpl<?>>();
+  final Map<Key<?>, BindingImpl<?>> jitBindings = Maps.newHashMap();
 
-  /**
-   * Returns true if the key type is Provider<?> (but not a subclass of
-   * Provider<?>).
-   */
+  /* Returns true if the key type is Provider<?> (but not a subclass of Provider<?>). */
   static boolean isProvider(Key<?> key) {
     return key.getTypeLiteral().getRawType().equals(Provider.class);
   }
 
-  /**
-   * Creates a synthetic binding to Provider<T>, i.e. a binding to the provider
-   * from Binding<T>.
-   */
+  /** Creates a synthetic binding to Provider<T>, i.e. a binding to the provider from Binding<T>. */
   private <T> BindingImpl<Provider<T>> createProviderBinding(
       Key<Provider<T>> key, LoadStrategy loadStrategy) throws ResolveFailedException {
     Type providerType = key.getTypeLiteral().getType();
@@ -259,11 +263,9 @@
       throw new ResolveFailedException(ErrorMessages.CANNOT_INJECT_RAW_PROVIDER);
     }
 
-    Type entryType
-        = ((ParameterizedType) providerType).getActualTypeArguments()[0];
+    Type entryType = ((ParameterizedType) providerType).getActualTypeArguments()[0];
 
-    // This cast is safe. 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("unchecked") // safe because T came from Key<Provider<T>>
     Key<T> providedKey = (Key<T>) key.ofType(entryType);
 
     return new ProviderBindingImpl<T>(this, key, getBindingOrThrow(providedKey), loadStrategy);
@@ -280,8 +282,7 @@
       errorHandler.handle(source, ErrorMessages.MISSING_BINDING, key);
     }
     else {
-      errorHandler.handle(source,
-          ErrorMessages.MISSING_BINDING_BUT_OTHERS_EXIST, key, otherNames);
+      errorHandler.handle(source, ErrorMessages.MISSING_BINDING_BUT_OTHERS_EXIST, key, otherNames);
     }
   }
 
@@ -290,19 +291,25 @@
 
     final Binding<T> providedBinding;
 
-    ProviderBindingImpl(InjectorImpl injector, Key<Provider<T>> key,
-        Binding<T> providedBinding, LoadStrategy loadStrategy) {
-      super(injector, key, SourceProviders.UNKNOWN_SOURCE,
-          createInternalFactory(providedBinding), Scopes.NO_SCOPE, loadStrategy);
+    ProviderBindingImpl(
+        InjectorImpl injector,
+        Key<Provider<T>> key,
+        Binding<T> providedBinding,
+        LoadStrategy loadStrategy) {
+      super(
+          injector,
+          key,
+          SourceProviders.UNKNOWN_SOURCE,
+          createInternalFactory(providedBinding),
+          Scopes.NO_SCOPE,
+          loadStrategy);
       this.providedBinding = providedBinding;
     }
 
-    static <T> InternalFactory<Provider<T>> createInternalFactory(
-        Binding<T> providedBinding) {
+    static <T> InternalFactory<Provider<T>> createInternalFactory(Binding<T> providedBinding) {
       final Provider<T> provider = providedBinding.getProvider();
       return new InternalFactory<Provider<T>>() {
-        public Provider<T> get(InternalContext context,
-            InjectionPoint injectionPoint) {
+        public Provider<T> get(InternalContext context, InjectionPoint injectionPoint) {
           return provider;
         }
       };
@@ -322,18 +329,17 @@
   }
 
   <T> BindingImpl<T> invalidBinding(Key<T> key) {
-    return new InvalidBindingImpl<T>(
-        this, key, SourceProviders.defaultSource());
+    return new InvalidBindingImpl<T>(this, key, SourceProviders.defaultSource());
   }
 
   /**
    * Converts a constant string binding to the required type.
    *
-   * <p>If the required type is eligible for conversion and a constant string
-   * binding is found but the actual conversion fails, an error is generated.
+   * <p>If the required type is eligible for conversion and a constant string binding is found but
+   * the actual conversion fails, an error is generated.
    *
-   * <p>If the type is not eligible for conversion or a constant string
-   * binding is not found, this method returns null.
+   * <p>If the type is not eligible for conversion or a constant string binding is not found, this
+   * method returns null.
    */
   private <T> BindingImpl<T> convertConstantStringBinding(Key<T> key)
       throws ResolveFailedException {
@@ -341,7 +347,6 @@
     Key<String> stringKey = key.ofType(String.class);
     BindingImpl<String> stringBinding = getExplicitBindingImpl(stringKey);
     if (stringBinding == null || !stringBinding.isConstant()) {
-      // No constant string binding found.
       return null;
     }
 
@@ -356,7 +361,6 @@
           throw new ResolveFailedException(ErrorMessages.AMBIGUOUS_TYPE_CONVERSION,
               stringValue, type, matchingConverter, converter);
         }
-
         matchingConverter = converter;
       }
     }
@@ -368,8 +372,7 @@
 
     // Try to convert the string. A failed conversion results in an error.
     try {
-      // This cast is safe because we double check below.
-      @SuppressWarnings("unchecked")
+      @SuppressWarnings("unchecked") // This cast is safe because we double check below.
       T converted = (T) matchingConverter.getTypeConverter()
           .convert(stringValue, key.getTypeLiteral());
 
@@ -377,18 +380,17 @@
         throw new ResolveFailedException(ErrorMessages.CONVERTER_RETURNED_NULL);
       }
 
-      // We have to filter out primitive types because an Integer is not an
-      // instance of int, and we provide converters for all the primitive types
-      // and know that they work anyway.
+      // We have to filter out primitive types because an Integer is not an instance of int, and we
+      // provide converters for all the primitive types and know that they work anyway.
       if (!type.getRawType().isInstance(converted)) {
         throw new ResolveFailedException(ErrorMessages.CONVERSION_TYPE_ERROR, converted, type);
       }
-
-      return new ConvertedConstantBindingImpl<T>(
-          this, key, converted, stringBinding);
-    } catch (ResolveFailedException e) {
+      return new ConvertedConstantBindingImpl<T>(this, key, converted, stringBinding);
+    }
+    catch (ResolveFailedException e) {
       throw e;
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       throw new ResolveFailedException(ErrorMessages.CONVERSION_ERROR, stringValue,
           stringBinding.getSource(), type, matchingConverter, e.getMessage());
     }
@@ -396,23 +398,21 @@
 
   private static class ConvertedConstantBindingImpl<T> extends BindingImpl<T>
       implements ConvertedConstantBinding<T> {
-
     final T value;
     final Provider<T> provider;
     final Binding<String> originalBinding;
 
-    ConvertedConstantBindingImpl(InjectorImpl injector, Key<T> key, T value,
-        Binding<String> originalBinding) {
-      super(injector, key, SourceProviders.UNKNOWN_SOURCE,
-          new ConstantFactory<T>(value), Scopes.NO_SCOPE, LoadStrategy.LAZY);
+    ConvertedConstantBindingImpl(
+        InjectorImpl injector, Key<T> key, T value, Binding<String> originalBinding) {
+      super(injector, key, SourceProviders.UNKNOWN_SOURCE, new ConstantFactory<T>(value),
+          Scopes.NO_SCOPE, LoadStrategy.LAZY);
       this.value = value;
-      this.provider = Providers.of(value);
+      provider = Providers.of(value);
       this.originalBinding = originalBinding;
     }
 
-    @Override
-    public Provider<T> getProvider() {
-      return this.provider;
+    @Override public Provider<T> getProvider() {
+      return provider;
     }
 
     public void accept(BindingVisitor<? super T> bindingVisitor) {
@@ -420,15 +420,14 @@
     }
 
     public T getValue() {
-      return this.value;
+      return value;
     }
 
     public Binding<String> getOriginal() {
-      return this.originalBinding;
+      return originalBinding;
     }
 
-    @Override
-    public String toString() {
+    @Override public String toString() {
       return new ToStringBuilder(ConvertedConstantBinding.class)
           .add("key", key)
           .add("value", value)
@@ -439,18 +438,16 @@
 
   <T> BindingImpl<T> createBindingFromType(Class<T> type, LoadStrategy loadStrategy)
       throws ResolveFailedException {
-    BindingImpl<T> binding = createUnitializedBinding(
-        type, null, SourceProviders.defaultSource(), loadStrategy);
+    BindingImpl<T> binding
+        = createUnitializedBinding(type, null, SourceProviders.defaultSource(), loadStrategy);
     initializeBinding(binding);
     return binding;
   }
 
   <T> void initializeBinding(BindingImpl<T> binding) throws ResolveFailedException {
-    // Put the partially constructed binding in the map a little early. This
-    // enables us to handle circular dependencies.
-    // Example: FooImpl -> BarImpl -> FooImpl.
-    // Note: We don't need to synchronize on jitBindings during injector
-    // creation.
+    // Put the partially constructed binding in the map a little early. This enables us to handle
+    // circular dependencies. Example: FooImpl -> BarImpl -> FooImpl.
+    // Note: We don't need to synchronize on jitBindings during injector creation.
     if (binding instanceof ClassBindingImpl<?>) {
       Key<T> key = binding.getKey();
       jitBindings.put(key, binding);
@@ -458,7 +455,8 @@
       try {
         binding.initialize(this);
         successful = true;
-      } finally {
+      }
+      finally {
         if (!successful) {
           jitBindings.remove(key);
         }
@@ -467,11 +465,12 @@
   }
 
   /**
-   * Creates a binding for an injectable type with the given scope. Looks for
-   * a scope on the type if none is specified.
+   * 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> createUnitializedBinding(Class<T> type,
-      Scope scope, Object source, LoadStrategy loadStrategy) throws ResolveFailedException {
+  <T> BindingImpl<T> createUnitializedBinding(
+      Class<T> type, Scope scope, Object source, LoadStrategy loadStrategy)
+      throws ResolveFailedException {
     // Don't try to inject arrays, or enums.
     if (type.isArray() || type.isEnum()) {
       throw new ResolveFailedException(ErrorMessages.MISSING_BINDING, type);
@@ -512,39 +511,30 @@
     LateBoundConstructor<T> lateBoundConstructor = new LateBoundConstructor<T>();
     InternalFactory<? extends T> scopedFactory
         = Scopes.scope(key, this, lateBoundConstructor, scope);
-
-    return new ClassBindingImpl<T>(this, key, source, scopedFactory, scope, lateBoundConstructor,
-        loadStrategy);
+    return new ClassBindingImpl<T>(
+        this, key, source, scopedFactory, scope, lateBoundConstructor, loadStrategy);
   }
 
   static class LateBoundConstructor<T> implements InternalFactory<T> {
-
     ConstructorInjector<T> constructorInjector;
 
-    void bind(InjectorImpl injector, Class<T> implementation)
-        throws ResolveFailedException {
-      this.constructorInjector = injector.getConstructor(implementation);
+    void bind(InjectorImpl injector, Class<T> implementation) throws ResolveFailedException {
+      constructorInjector = injector.getConstructor(implementation);
     }
 
     @SuppressWarnings("unchecked")
     public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
-      if (constructorInjector == null) {
-        throw new IllegalStateException("Construct before bind, " + constructorInjector);
-      }
+      checkState(constructorInjector != null, "Construct before bind, " + constructorInjector);
 
-      // 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(
-          context, injectionPoint.getKey().getRawType());
+      // 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(context, injectionPoint.getKey().getRawType());
     }
   }
 
-  /**
-   * Creates a binding for a type annotated with @ProvidedBy.
-   */
-  <T> BindingImpl<T> createProvidedByBinding(final Class<T> type,
-      ProvidedBy providedBy, LoadStrategy loadStrategy) throws ResolveFailedException {
+  /** Creates a binding for a type annotated with @ProvidedBy. */
+  <T> BindingImpl<T> createProvidedByBinding(final Class<T> type, ProvidedBy providedBy,
+      LoadStrategy loadStrategy) throws ResolveFailedException {
     final Class<? extends Provider<?>> providerType = providedBy.value();
 
     // Make sure it's not the same type. TODO: Can we check for deeper loops?
@@ -552,45 +542,44 @@
       throw new ResolveFailedException(ErrorMessages.RECURSIVE_PROVIDER_TYPE);
     }
 
-    // TODO: Make sure the provided type extends type. We at least check
-    // the type at runtime below.
+    // TODO: Make sure the provided type extends type. We at least check the type at runtime below.
 
-    // Assume the provider provides an appropriate type. We double check at
-    // runtime.
+    // Assume the provider provides an appropriate type. We double check at runtime.
     @SuppressWarnings("unchecked")
-    Key<? extends Provider<T>> providerKey
-        = (Key<? extends Provider<T>>) Key.get(providerType);
-    final BindingImpl<? extends Provider<?>> providerBinding
-        = getBindingOrThrow(providerKey);
+    Key<? extends Provider<T>> providerKey = (Key<? extends Provider<T>>) Key.get(providerType);
+    final BindingImpl<? extends Provider<?>> providerBinding = getBindingOrThrow(providerKey);
 
     InternalFactory<T> internalFactory = new InternalFactory<T>() {
       public T get(InternalContext context, InjectionPoint injectionPoint) {
-        Provider<?> provider
-            = providerBinding.internalFactory.get(context, injectionPoint);
+        Provider<?> provider = providerBinding.internalFactory.get(context, injectionPoint);
         Object o = provider.get();
-        try {
-          return type.cast(o);
-        } catch (ClassCastException e) {
-          errorHandler.handle(StackTraceElements.forType(type),
-              ErrorMessages.SUBTYPE_NOT_PROVIDED, providerType, type);
+        if (o != null && !type.isInstance(o)) {
+          errorHandler.handle(StackTraceElements.forType(type), ErrorMessages.SUBTYPE_NOT_PROVIDED,
+              providerType, type);
           throw new AssertionError();
         }
+
+        @SuppressWarnings("unchecked") // protected by isInstance() check above
+        T t = (T) o;
+        return t;
       }
     };
 
-    return new LinkedProviderBindingImpl<T>(this, Key.get(type),
-        StackTraceElements.forType(type), internalFactory, Scopes.NO_SCOPE,
-        providerKey, loadStrategy);
+    return new LinkedProviderBindingImpl<T>(
+        this,
+        Key.get(type),
+        StackTraceElements.forType(type),
+        internalFactory,
+        Scopes.NO_SCOPE,
+        providerKey,
+        loadStrategy);
   }
 
-  /**
-   * Creates a binding for a type annotated with @ImplementedBy.
-   */
-  <T> BindingImpl<T> createImplementedByBinding(Class<T> type,
-      ImplementedBy implementedBy, LoadStrategy loadStrategy) throws ResolveFailedException {
-    // TODO: Use scope annotation on type if present. Right now, we always
-    // use NO_SCOPE.
-
+  /** Creates a binding for a type annotated with @ImplementedBy. */
+  <T> BindingImpl<T> createImplementedByBinding(
+      Class<T> type, ImplementedBy implementedBy, LoadStrategy loadStrategy)
+      throws ResolveFailedException {
+    // TODO: Use scope annotation on type if present. Right now, we always use NO_SCOPE.
     Class<?> implementationType = implementedBy.value();
 
     // Make sure it's not the same type. TODO: Can we check for deeper cycles?
@@ -608,8 +597,7 @@
     Class<? extends T> subclass = (Class<? extends T>) implementationType;
 
     // Look up the target binding.
-    final BindingImpl<? extends T> targetBinding
-        = getBindingOrThrow(Key.get(subclass));
+    final BindingImpl<? extends T> targetBinding = getBindingOrThrow(Key.get(subclass));
 
     InternalFactory<T> internalFactory = new InternalFactory<T>() {
       public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
@@ -617,20 +605,23 @@
       }
     };
 
-    return new LinkedBindingImpl<T>(this, Key.get(type), 
-        StackTraceElements.forType(type), internalFactory, Scopes.NO_SCOPE,
-        Key.get(subclass), loadStrategy);
+    return new LinkedBindingImpl<T>(
+        this,
+        Key.get(type),
+        StackTraceElements.forType(type),
+        internalFactory,
+        Scopes.NO_SCOPE,
+        Key.get(subclass),
+        loadStrategy);
   }
 
   <T> BindingImpl<T> createBindingJustInTime(Key<T> key) throws ResolveFailedException {
     // Handle cases where T is a Provider<?>.
     if (isProvider(key)) {
-      // These casts are safe. We know T extends Provider<X> and that given
-      // Key<Provider<X>>, createProviderBinding() will return
-      // BindingImpl<Provider<X>>.
-      @SuppressWarnings({ "UnnecessaryLocalVariable", "unchecked" })
-      BindingImpl<T> binding
-          = (BindingImpl<T>) createProviderBinding((Key) key, LoadStrategy.LAZY);
+      // These casts are safe. We know T extends Provider<X> and that given Key<Provider<X>>,
+      // createProviderBinding() will return BindingImpl<Provider<X>>.
+      @SuppressWarnings("unchecked")
+      BindingImpl<T> binding = (BindingImpl<T>) createProviderBinding((Key) key, LoadStrategy.LAZY);
       return binding;
     }
 
@@ -646,7 +637,8 @@
       if (key.hasAttributes()) {
         try {
           return getBindingOrThrow(key.withoutAttributes());
-        } catch (ResolveFailedException ignored) {
+        }
+        catch (ResolveFailedException ignored) {
           // throw with a more appropriate message below
         }
       }
@@ -659,27 +651,23 @@
     return createBindingFromType(clazz, LoadStrategy.LAZY);
   }
 
-  <T> InternalFactory<? extends T> getInternalFactory(Key<T> key)
-      throws ResolveFailedException {
+  <T> InternalFactory<? extends T> getInternalFactory(Key<T> key) throws ResolveFailedException {
     return getBindingOrThrow(key).internalFactory;
   }
 
-  /**
-   * Field and method injectors.
-   */
+  /** Field and method injectors. */
   final Map<Class<?>, List<SingleMemberInjector>> injectors
       = new ReferenceCache<Class<?>, List<SingleMemberInjector>>() {
     protected List<SingleMemberInjector> create(Class<?> key) {
-      List<SingleMemberInjector> injectors
-          = new ArrayList<SingleMemberInjector>();
+      List<SingleMemberInjector> injectors = Lists.newArrayList();
       addInjectors(key, injectors);
       return injectors;
     }
   };
 
   /**
-   * Recursively adds injectors for fields and methods from the given class to
-   * the given list. Injects parent classes before sub classes.
+   * Recursively adds injectors for fields and methods from the given class to the given list.
+   * Injects parent classes before sub classes.
    */
   void addInjectors(Class clazz, List<SingleMemberInjector> injectors) {
     if (clazz == Object.class) {
@@ -698,8 +686,8 @@
       List<SingleMemberInjector> injectors) {
     addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
         new SingleInjectorFactory<Method>() {
-          public SingleMemberInjector create(InjectorImpl injector,
-              Method method) throws ResolveFailedException {
+          public SingleMemberInjector create(InjectorImpl injector, Method method)
+              throws ResolveFailedException {
             return new SingleMethodInjector(injector, method);
           }
         });
@@ -709,15 +697,15 @@
       List<SingleMemberInjector> injectors) {
     addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
         new SingleInjectorFactory<Field>() {
-          public SingleMemberInjector create(InjectorImpl injector,
-              Field field) throws ResolveFailedException {
+          public SingleMemberInjector create(InjectorImpl injector, Field field)
+              throws ResolveFailedException {
             return new SingleFieldInjector(injector, field);
           }
         });
   }
 
-  <M extends Member & AnnotatedElement> void addInjectorsForMembers(
-      List<M> members, boolean statics, List<SingleMemberInjector> injectors,
+  <M extends Member & AnnotatedElement> void addInjectorsForMembers(List<M> members,
+      boolean statics, List<SingleMemberInjector> injectors,
       SingleInjectorFactory<M> injectorFactory) {
     for (M member : members) {
       if (isStatic(member) == statics) {
@@ -747,8 +735,7 @@
   }
 
   interface SingleInjectorFactory<M extends Member & AnnotatedElement> {
-    SingleMemberInjector create(InjectorImpl injector, M member)
-        throws ResolveFailedException;
+    SingleMemberInjector create(InjectorImpl injector, M member) throws ResolveFailedException;
   }
 
   private boolean isStatic(Member member) {
@@ -756,33 +743,20 @@
   }
 
   private static class BindingsMultimap {
-    private final Map<TypeLiteral<?>, List<? extends BindingImpl<?>>> map
-        = new HashMap<TypeLiteral<?>, List<? extends BindingImpl<?>>>();
+    final Multimap<TypeLiteral<?>, Binding<?>> multimap = Multimaps.newArrayListMultimap();
 
-    public <T> void put(TypeLiteral<T> type, BindingImpl<T> binding) {
-      List<BindingImpl<T>> bindingsForThisType = getFromMap(type);
-      if (bindingsForThisType == null) {
-        bindingsForThisType = new ArrayList<BindingImpl<T>>();
-        // We only put matching entries into the map
-        map.put(type, bindingsForThisType);
-      }
-      bindingsForThisType.add(binding);
-    }
-
-    public <T> List<BindingImpl<T>> getAll(TypeLiteral<T> type) {
-      List<BindingImpl<T>> list = getFromMap(type);
-      return list == null ? Collections.<BindingImpl<T>>emptyList() : list;
+    <T> void put(TypeLiteral<T> type, BindingImpl<T> binding) {
+      multimap.put(type, binding);
     }
 
     // safe because we only put matching entries into the map
     @SuppressWarnings("unchecked")
-    private <T> List<BindingImpl<T>> getFromMap(TypeLiteral<T> type) {
-      return (List<BindingImpl<T>>) map.get(type);
+    <T> List<Binding<T>> getAll(TypeLiteral<T> type) {
+      return (List<Binding<T>>) (List) multimap.get(type);
     }
   }
 
   class SingleFieldInjector implements SingleMemberInjector {
-
     final Field field;
     final InternalFactory<?> factory;
     final InjectionPoint<?> injectionPoint;
@@ -794,16 +768,16 @@
       // Ewwwww...
       field.setAccessible(true);
 
-      final Key<?> key = Keys.get(
-          field.getGenericType(), field, field.getAnnotations(), errorHandler);
+      final Key<?> key
+          = Keys.get(field.getGenericType(), field, field.getAnnotations(), errorHandler);
       factory = new ResolvingCallable<InternalFactory<?>>() {
-          public InternalFactory<?> call() throws ResolveFailedException {
-            return injector.getInternalFactory(key);
-          }
-        }.runWithDefaultSource(StackTraceElements.forMember(field));
+        public InternalFactory<?> call() throws ResolveFailedException {
+          return injector.getInternalFactory(key);
+        }
+      }.runWithDefaultSource(StackTraceElements.forMember(field));
 
-      this.injectionPoint = InjectionPoint.newInstance(field,
-          Nullability.forAnnotations(field.getAnnotations()), key, injector);
+      injectionPoint = InjectionPoint.newInstance(
+          field, Nullability.forAnnotations(field.getAnnotations()), key, injector);
     }
 
     public Collection<Dependency<?>> getDependencies() {
@@ -827,8 +801,7 @@
         throw provisionException;
       }
       catch (RuntimeException runtimeException) {
-        throw new ProvisionException(runtimeException,
-            ErrorMessages.ERROR_INJECTING_FIELD);
+        throw new ProvisionException(runtimeException, ErrorMessages.ERROR_INJECTING_FIELD);
       }
       finally {
         context.setInjectionPoint(null);
@@ -842,8 +815,7 @@
    * @param member to which the parameters belong
    * @return injections
    */
-  SingleParameterInjector<?>[] getParametersInjectors(Member member,
-      List<Parameter<?>> parameters)
+  SingleParameterInjector<?>[] getParametersInjectors(Member member, List<Parameter<?>> parameters)
       throws ResolveFailedException {
     SingleParameterInjector<?>[] parameterInjectors
         = new SingleParameterInjector<?>[parameters.size()];
@@ -856,13 +828,11 @@
   }
 
   <T> SingleParameterInjector<T> createParameterInjector(
-      final Parameter<T> parameter, Member member)
-      throws ResolveFailedException {
-    InternalFactory<? extends T> factory
-        = new ResolvingCallable<InternalFactory<? extends T>>() {
-          public InternalFactory<? extends T> call() throws ResolveFailedException {
-            return getInternalFactory(parameter.getKey());
-          }
+      final Parameter<T> parameter, Member member) throws ResolveFailedException {
+    InternalFactory<? extends T> factory = new ResolvingCallable<InternalFactory<? extends T>>() {
+      public InternalFactory<? extends T> call() throws ResolveFailedException {
+        return getInternalFactory(parameter.getKey());
+      }
     }.runWithDefaultSource(StackTraceElements.forMember(member));
 
     InjectionPoint<T> injectionPoint = InjectionPoint.newInstance(
@@ -871,19 +841,18 @@
   }
 
   static class SingleMethodInjector implements SingleMemberInjector {
-
     final MethodInvoker methodInvoker;
     final SingleParameterInjector<?>[] parameterInjectors;
 
     public SingleMethodInjector(InjectorImpl injector, final Method method)
         throws ResolveFailedException {
       // We can't use FastMethod if the method is private.
-      if (Modifier.isPrivate(method.getModifiers())
-          || Modifier.isProtected(method.getModifiers())) {
+      if (Modifier.isPrivate(method.getModifiers()) || Modifier.isProtected(method.getModifiers()))
+      {
         method.setAccessible(true);
-        this.methodInvoker = new MethodInvoker() {
-          public Object invoke(Object target, Object... parameters) throws
-              IllegalAccessException, InvocationTargetException {
+        methodInvoker = new MethodInvoker() {
+          public Object invoke(Object target, Object... parameters)
+              throws IllegalAccessException, InvocationTargetException {
             return method.invoke(target, parameters);
           }
         };
@@ -892,18 +861,17 @@
         FastClass fastClass = GuiceFastClass.create(method.getDeclaringClass());
         final FastMethod fastMethod = fastClass.getMethod(method);
 
-        this.methodInvoker = new MethodInvoker() {
+        methodInvoker = new MethodInvoker() {
           public Object invoke(Object target, Object... parameters)
-          throws IllegalAccessException, InvocationTargetException {
+              throws IllegalAccessException, InvocationTargetException {
             return fastMethod.invoke(target, parameters);
           }
         };
       }
 
-      Type[] parameterTypes = method.getGenericParameterTypes();
-      parameterInjectors = parameterTypes.length > 0
-          ? injector.getParametersInjectors(method,
-              Parameter.forMethod(injector.errorHandler, method))
+      parameterInjectors = method.getGenericParameterTypes().length > 0
+          ? injector.getParametersInjectors(
+              method, Parameter.forMethod(injector.errorHandler, method))
           : null;
     }
 
@@ -916,13 +884,12 @@
       }
       catch (InvocationTargetException e) {
         Throwable cause = e.getCause() != null ? e.getCause() : e;
-        throw new ProvisionException(cause,
-            ErrorMessages.ERROR_INJECTING_METHOD);
+        throw new ProvisionException(cause, ErrorMessages.ERROR_INJECTING_METHOD);
       }
     }
 
     public Collection<Dependency<?>> getDependencies() {
-      List<Dependency<?>> dependencies = new ArrayList<Dependency<?>>();
+      List<Dependency<?>> dependencies = new ArrayList<Dependency<?>>(parameterInjectors.length);
       for (SingleParameterInjector<?> parameterInjector : parameterInjectors) {
         dependencies.add(parameterInjector.injectionPoint);
       }
@@ -930,16 +897,13 @@
     }
   }
 
-  /**
-   * Invokes a method.
-   */
+  /** Invokes a method. */
   interface MethodInvoker {
-    Object invoke(Object target, Object... parameters) throws
-        IllegalAccessException, InvocationTargetException;
+    Object invoke(Object target, Object... parameters)
+        throws IllegalAccessException, InvocationTargetException;
   }
 
-  final Map<Class<?>, Object> constructors
-      = new ReferenceCache<Class<?>, Object>() {
+  final Map<Class<?>, Object> constructors = new ReferenceCache<Class<?>, Object>() {
     @SuppressWarnings("unchecked")
     protected Object create(Class<?> implementation) {
       if (!Classes.isConcrete(implementation)) {
@@ -947,15 +911,14 @@
             ErrorMessages.CANNOT_INJECT_ABSTRACT_TYPE, implementation);
       }
       if (Classes.isInnerClass(implementation)) {
-        return new ResolveFailedException(ErrorMessages.CANNOT_INJECT_INNER_CLASS, implementation);
+        return new ResolveFailedException(
+            ErrorMessages.CANNOT_INJECT_INNER_CLASS, implementation);
       }
-
       return new ConstructorInjector(InjectorImpl.this, implementation);
     }
   };
 
   static class SingleParameterInjector<T> {
-
     final InjectionPoint<T> injectionPoint;
     final InternalFactory<? extends T> factory;
 
@@ -978,8 +941,7 @@
         throw provisionException;
       }
       catch (RuntimeException runtimeException) {
-        throw new ProvisionException(runtimeException,
-            ErrorMessages.ERROR_INJECTING_METHOD);
+        throw new ProvisionException(runtimeException, ErrorMessages.ERROR_INJECTING_METHOD);
       }
       finally {
         context.setInjectionPoint(injectionPoint);
@@ -987,12 +949,9 @@
     }
   }
 
-  /**
-   * Iterates over parameter injectors and creates an array of parameter
-   * values.
-   */
-  static Object[] getParameters(InternalContext context,
-      SingleParameterInjector[] parameterInjectors) {
+  /** Iterates over parameter injectors and creates an array of parameter values. */
+  static Object[] getParameters(
+      InternalContext context, SingleParameterInjector[] parameterInjectors) {
     if (parameterInjectors == null) {
       return null;
     }
@@ -1008,7 +967,6 @@
     if (o == null) {
       return;
     }
-
     List<SingleMemberInjector> injectorsForClass = injectors.get(o.getClass());
     for (SingleMemberInjector injector : injectorsForClass) {
       injector.inject(context, o);
@@ -1036,13 +994,12 @@
       public T get() {
         return callInContext(new ContextualCallable<T>() {
           public T call(InternalContext context) {
-            InjectionPoint<T> injectionPoint
-                = InjectionPoint.newInstance(key, InjectorImpl.this);
+            InjectionPoint<T> injectionPoint = InjectionPoint.newInstance(key, InjectorImpl.this);
             context.setInjectionPoint(injectionPoint);
             try {
               return factory.get(context, injectionPoint);
             }
-            catch(ProvisionException provisionException) {
+            catch (ProvisionException provisionException) {
               provisionException.addContext(injectionPoint);
               throw provisionException;
             }
@@ -1062,7 +1019,8 @@
   public <T> Provider<T> getProvider(final Key<T> key) {
     try {
       return getProviderOrThrow(key);
-    } catch (ResolveFailedException e) {
+    }
+    catch (ResolveFailedException e) {
       throw new ConfigurationException(
           "Missing binding to " + ErrorMessages.convert(key) + ": " + e.getMessage());
     }
@@ -1076,17 +1034,13 @@
     return getProvider(type).get();
   }
 
-  final ThreadLocal<InternalContext[]> localContext
-      = new ThreadLocal<InternalContext[]>() {
+  final ThreadLocal<InternalContext[]> localContext = new ThreadLocal<InternalContext[]>() {
     protected InternalContext[] initialValue() {
       return new InternalContext[1];
     }
   };
 
-  /**
-   * Looks up thread local context. Creates (and removes) a new context if
-   * necessary.
-   */
+  /** Looks up thread local context. Creates (and removes) a new context if necessary. */
   <T> T callInContext(ContextualCallable<T> callable) {
     InternalContext[] reference = localContext.get();
     if (reference[0] == null) {
@@ -1105,34 +1059,30 @@
     }
   }
 
-  /**
-   * Gets a constructor function for a given implementation class.
-   */
+  /** Gets a constructor function for a given implementation class. */
   @SuppressWarnings("unchecked")
-  <T> ConstructorInjector<T> getConstructor(Class<T> implementation)
-      throws ResolveFailedException {
+  <T> ConstructorInjector<T> getConstructor(Class<T> implementation) throws ResolveFailedException {
     Object o = constructors.get(implementation);
     if (o instanceof ResolveFailedException) {
       throw (ResolveFailedException) o;
-    } else if (o instanceof ConstructorInjector<?>) {
+    }
+    else if (o instanceof ConstructorInjector<?>) {
       return (ConstructorInjector<T>) o;
-    } else {
+    }
+    else {
       throw new AssertionError();
     }
   }
 
-  /**
-   * Injects a field or method in a given object.
-   */
+  /** Injects a field or method in a given object. */
   public interface SingleMemberInjector {
     void inject(InternalContext context, Object o);
     Collection<Dependency<?>> getDependencies();
   }
 
-  List<Dependency<?>> getModifiableFieldAndMethodDependenciesFor(
-      Class<?> clazz) {
+  List<Dependency<?>> getModifiableFieldAndMethodDependenciesFor(Class<?> clazz) {
     List<SingleMemberInjector> injectors = this.injectors.get(clazz);
-    List<Dependency<?>> dependencies = new ArrayList<Dependency<?>>();
+    List<Dependency<?>> dependencies = Lists.newArrayList();
     for (SingleMemberInjector singleMemberInjector : injectors) {
       dependencies.addAll(singleMemberInjector.getDependencies());
     }
@@ -1140,8 +1090,7 @@
   }
 
   Collection<Dependency<?>> getFieldAndMethodDependenciesFor(Class<?> clazz) {
-    return Collections.unmodifiableList(
-        getModifiableFieldAndMethodDependenciesFor(clazz));
+    return Collections.unmodifiableList(getModifiableFieldAndMethodDependenciesFor(clazz));
   }
 
   public String toString() {
diff --git a/src/com/google/inject/InternalContext.java b/src/com/google/inject/InternalContext.java
index 3e035e4..d7c83eb 100644
--- a/src/com/google/inject/InternalContext.java
+++ b/src/com/google/inject/InternalContext.java
@@ -71,7 +71,7 @@
    * been injected before its use.
    */
   public void ensureMemberInjected(Object toInject) {
-    if (!injector.outstandingInjections.keySet().remove(toInject)) {
+    if (!injector.outstandingInjections.remove(toInject)) {
       return;
     }
 
diff --git a/src/com/google/inject/InternalFactoryToProviderAdapter.java b/src/com/google/inject/InternalFactoryToProviderAdapter.java
index 6b5fa95..6a21b40 100644
--- a/src/com/google/inject/InternalFactoryToProviderAdapter.java
+++ b/src/com/google/inject/InternalFactoryToProviderAdapter.java
@@ -17,8 +17,8 @@
 package com.google.inject;
 
 import com.google.inject.internal.ErrorMessages;
-import com.google.inject.internal.Objects;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * @author crazybob@google.com (Bob Lee)
@@ -34,8 +34,8 @@
 
   public InternalFactoryToProviderAdapter(
       Provider<? extends T> provider, Object source) {
-    this.provider = Objects.nonNull(provider, "provider");
-    this.source = Objects.nonNull(source, "source");
+    this.provider = checkNotNull(provider, "provider");
+    this.source = checkNotNull(source, "source");
   }
 
   public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
diff --git a/src/com/google/inject/Key.java b/src/com/google/inject/Key.java
index 56ba71b..3c2aa7c 100644
--- a/src/com/google/inject/Key.java
+++ b/src/com/google/inject/Key.java
@@ -17,9 +17,9 @@
 package com.google.inject;
 
 import com.google.inject.internal.Annotations;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.internal.ToStringBuilder;
 import com.google.inject.internal.Types;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
@@ -339,7 +339,7 @@
    * Gets the strategy for an annotation.
    */
   static AnnotationStrategy strategyFor(Annotation annotation) {
-    nonNull(annotation, "annotation");
+    checkNotNull(annotation, "annotation");
     Class<? extends Annotation> annotationType = annotation.annotationType();
     ensureRetainedAtRuntime(annotationType);
     ensureIsBindingAnnotation(annotationType);
@@ -354,9 +354,8 @@
   /**
    * Gets the strategy for an annotation type.
    */
-  static AnnotationStrategy strategyFor(
-      Class<? extends Annotation> annotationType) {
-    nonNull(annotationType, "annotation type");
+  static AnnotationStrategy strategyFor(Class<? extends Annotation> annotationType) {
+    checkNotNull(annotationType, "annotation type");
     ensureRetainedAtRuntime(annotationType);
     ensureIsBindingAnnotation(annotationType);
     return new AnnotationTypeStrategy(annotationType, null);
@@ -410,7 +409,7 @@
     final Annotation annotation;
 
     AnnotationInstanceStrategy(Annotation annotation) {
-      this.annotation = nonNull(annotation, "annotation");
+      this.annotation = checkNotNull(annotation, "annotation");
     }
 
     public boolean hasAttributes() {
@@ -458,7 +457,7 @@
 
     AnnotationTypeStrategy(Class<? extends Annotation> annotationType,
         Annotation annotation) {
-      this.annotationType = nonNull(annotationType, "annotation type");
+      this.annotationType = checkNotNull(annotationType, "annotation type");
       this.annotation = annotation;
     }
 
diff --git a/src/com/google/inject/MethodAspect.java b/src/com/google/inject/MethodAspect.java
index 26e0e75..30515cc 100644
--- a/src/com/google/inject/MethodAspect.java
+++ b/src/com/google/inject/MethodAspect.java
@@ -16,13 +16,10 @@
 
 package com.google.inject;
 
-import com.google.inject.internal.Objects;
 import com.google.inject.matcher.Matcher;
+import static com.google.common.base.Preconditions.checkNotNull;
 import java.lang.reflect.Method;
-import java.util.Arrays;
 import java.util.List;
-import java.util.Collection;
-import java.util.ArrayList;
 
 import org.aopalliance.intercept.MethodInterceptor;
 
@@ -39,9 +36,9 @@
 
   MethodAspect(Matcher<? super Class<?>> classMatcher,
       Matcher<? super Method> methodMatcher, List<MethodInterceptor> interceptors) {
-    this.classMatcher = Objects.nonNull(classMatcher, "class matcher");
-    this.methodMatcher = Objects.nonNull(methodMatcher, "method matcher");
-    this.interceptors = Objects.nonNull(interceptors, "interceptors");
+    this.classMatcher = checkNotNull(classMatcher, "class matcher");
+    this.methodMatcher = checkNotNull(methodMatcher, "method matcher");
+    this.interceptors = checkNotNull(interceptors, "interceptors");
   }
 
   boolean matches(Class<?> clazz) {
diff --git a/src/com/google/inject/RuntimeReflectionFactory.java b/src/com/google/inject/RuntimeReflectionFactory.java
index 0bd7b2b..f7ba25e 100644
--- a/src/com/google/inject/RuntimeReflectionFactory.java
+++ b/src/com/google/inject/RuntimeReflectionFactory.java
@@ -18,7 +18,7 @@
 package com.google.inject;
 
 import com.google.inject.internal.*;
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.reflect.Constructor;
 
@@ -37,8 +37,8 @@
 
     private RuntimeReflection(ErrorHandler errorHandler,
         ConstructionProxyFactory constructionProxyFactory) {
-      this.errorHandler = nonNull(errorHandler, "errorHandler");
-      this.constructionProxyFactory = nonNull(constructionProxyFactory, "constructionProxyFatory");
+      this.errorHandler = checkNotNull(errorHandler, "errorHandler");
+      this.constructionProxyFactory = checkNotNull(constructionProxyFactory, "constructionProxyFatory");
     }
 
     public <T> ConstructionProxy<T> getConstructionProxy(Class<T> implementation) {
diff --git a/src/com/google/inject/ScopesCommandProcessor.java b/src/com/google/inject/ScopesCommandProcessor.java
index a19fd05..87c0ce7 100644
--- a/src/com/google/inject/ScopesCommandProcessor.java
+++ b/src/com/google/inject/ScopesCommandProcessor.java
@@ -20,8 +20,8 @@
 import com.google.inject.internal.Annotations;
 import com.google.inject.internal.ErrorHandler;
 import com.google.inject.internal.ErrorMessages;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.internal.StackTraceElements;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 import java.util.Map;
@@ -58,12 +58,12 @@
       // Go ahead and bind anyway so we don't get collateral errors.
     }
 
-    Scope existing = scopes.get(nonNull(annotationType, "annotation type"));
+    Scope existing = scopes.get(checkNotNull(annotationType, "annotation type"));
     if (existing != null) {
       addError(command.getSource(), ErrorMessages.DUPLICATE_SCOPES, existing,
           annotationType, scope);
     } else {
-      scopes.put(annotationType, nonNull(scope, "scope"));
+      scopes.put(annotationType, checkNotNull(scope, "scope"));
     }
 
     return true;
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
index 932950d..6d4a450 100644
--- a/src/com/google/inject/TypeLiteral.java
+++ b/src/com/google/inject/TypeLiteral.java
@@ -16,9 +16,9 @@
 
 package com.google.inject;
 
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.internal.Types;
 import static com.google.inject.internal.Types.canonicalize;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.Serializable;
 import java.lang.reflect.ParameterizedType;
@@ -67,7 +67,7 @@
    */
   @SuppressWarnings("unchecked")
   TypeLiteral(Type type) {
-    this.type = canonicalize(nonNull(type, "type"));
+    this.type = canonicalize(checkNotNull(type, "type"));
     this.rawType = (Class<? super T>) Types.getRawType(this.type);
     this.hashCode = Types.hashCode(this.type);
   }
diff --git a/src/com/google/inject/commands/AddMessageErrorCommand.java b/src/com/google/inject/commands/AddMessageErrorCommand.java
index 2e336cd..cd4a8cf 100644
--- a/src/com/google/inject/commands/AddMessageErrorCommand.java
+++ b/src/com/google/inject/commands/AddMessageErrorCommand.java
@@ -16,11 +16,11 @@
 
 package com.google.inject.commands;
 
-import static com.google.inject.internal.Objects.nonNull;
 
 import java.util.Arrays;
 import static java.util.Collections.unmodifiableList;
 import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Immutable snapshot of a request to add a string message.
@@ -33,8 +33,8 @@
   private final List<Object> arguments;
 
   AddMessageErrorCommand(Object source, String message, Object[] arguments) {
-    this.source = nonNull(source, "source");
-    this.message = nonNull(message, "message");
+    this.source = checkNotNull(source, "source");
+    this.message = checkNotNull(message, "message");
     this.arguments = unmodifiableList(Arrays.asList(arguments.clone()));
   }
 
diff --git a/src/com/google/inject/commands/AddThrowableErrorCommand.java b/src/com/google/inject/commands/AddThrowableErrorCommand.java
index fb28038..456af93 100644
--- a/src/com/google/inject/commands/AddThrowableErrorCommand.java
+++ b/src/com/google/inject/commands/AddThrowableErrorCommand.java
@@ -16,7 +16,7 @@
 
 package com.google.inject.commands;
 
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Immutable snapshot of a request to add a throwable message.
@@ -28,8 +28,8 @@
   private final Throwable throwable;
 
   AddThrowableErrorCommand(Object source, Throwable throwable) {
-    this.source = nonNull(source, "source");
-    this.throwable = nonNull(throwable, "throwable");
+    this.source = checkNotNull(source, "source");
+    this.throwable = checkNotNull(throwable, "throwable");
   }
 
   public Object getSource() {
diff --git a/src/com/google/inject/commands/BindCommand.java b/src/com/google/inject/commands/BindCommand.java
index 83ae5c6..e012873 100644
--- a/src/com/google/inject/commands/BindCommand.java
+++ b/src/com/google/inject/commands/BindCommand.java
@@ -22,8 +22,8 @@
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
 import com.google.inject.internal.ErrorMessages;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 
@@ -58,13 +58,14 @@
 
   private final Object source;
   private Key<T> key;
-  @SuppressWarnings({"unchecked"})
+
+  @SuppressWarnings("unchecked")
   private BindTarget<T> bindTarget = (BindTarget<T>) EMPTY_BIND_TARGET;
   private BindScoping bindScoping = EMPTY_SCOPING;
 
   BindCommand(Object source, Key<T> key) {
-    this.source = nonNull(source, "source");
-    this.key = nonNull(key, "key");
+    this.source = checkNotNull(source, "source");
+    this.key = checkNotNull(key, "key");
   }
 
   public Object getSource() {
@@ -139,14 +140,14 @@
 
     public LinkedBindingBuilder<T> annotatedWith(
         Class<? extends Annotation> annotationType) {
-      nonNull(annotationType, "annotationType");
+      checkNotNull(annotationType, "annotationType");
       checkNotAnnotated();
       key = Key.get(key.getTypeLiteral(), annotationType);
       return this;
     }
 
     public LinkedBindingBuilder<T> annotatedWith(Annotation annotation) {
-      nonNull(annotation, "annotation");
+      checkNotNull(annotation, "annotation");
       checkNotAnnotated();
       key = Key.get(key.getTypeLiteral(), annotation);
       return this;
@@ -162,7 +163,7 @@
     }
 
     public ScopedBindingBuilder to(final Key<? extends T> targetKey) {
-      nonNull(targetKey, "targetKey");
+      checkNotNull(targetKey, "targetKey");
       checkNotTargetted();
       bindTarget = new AbstractTarget<T>() {
         public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) {
@@ -182,7 +183,7 @@
     }
 
     public void toInstance(final T instance) {
-      nonNull(instance, ErrorMessages.CANNOT_BIND_TO_NULL_INSTANCE);
+      checkNotNull(instance, ErrorMessages.CANNOT_BIND_TO_NULL_INSTANCE);
 
       checkNotTargetted();
       bindTarget = new AbstractTarget<T>() {
@@ -203,7 +204,7 @@
     }
 
     public ScopedBindingBuilder toProvider(final Provider<? extends T> provider) {
-      nonNull(provider, "provider");
+      checkNotNull(provider, "provider");
       checkNotTargetted();
       bindTarget = new AbstractTarget<T>() {
         public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) {
@@ -229,7 +230,7 @@
 
     public ScopedBindingBuilder toProvider(
         final Key<? extends Provider<? extends T>> providerKey) {
-      nonNull(providerKey, "providerKey");
+      checkNotNull(providerKey, "providerKey");
       checkNotTargetted();
       bindTarget = new AbstractTarget<T>() {
         public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) {
@@ -249,7 +250,7 @@
     }
 
     public void in(final Class<? extends Annotation> scopeAnnotation) {
-      nonNull(scopeAnnotation, "scopeAnnotation");
+      checkNotNull(scopeAnnotation, "scopeAnnotation");
       checkNotScoped();
 
       bindScoping = new AbstractScoping() {
@@ -269,7 +270,7 @@
     }
 
     public void in(final Scope scope) {
-      nonNull(scope, "scope");
+      checkNotNull(scope, "scope");
       checkNotScoped();
       bindScoping = new AbstractScoping() {
 
diff --git a/src/com/google/inject/commands/BindConstantCommand.java b/src/com/google/inject/commands/BindConstantCommand.java
index 11164fb..7e28458 100644
--- a/src/com/google/inject/commands/BindConstantCommand.java
+++ b/src/com/google/inject/commands/BindConstantCommand.java
@@ -23,9 +23,8 @@
 import com.google.inject.binder.ConstantBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
-import com.google.inject.internal.Objects;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 
@@ -44,7 +43,7 @@
   private ConstantTarget<?> target;
 
   BindConstantCommand(Object source) {
-    this.source = nonNull(source, "source");
+    this.source = checkNotNull(source, "source");
   }
 
   public Object getSource() {
@@ -118,7 +117,7 @@
     }
 
     public ConstantBindingBuilder annotatedWith(final Class<? extends Annotation> annotationType) {
-      nonNull(annotationType, "annotationType");
+      checkNotNull(annotationType, "annotationType");
       assertNoBindingAnnotation();
 
       bindingAnnotation = new BindingAnnotation() {
@@ -134,7 +133,7 @@
     }
 
     public ConstantBindingBuilder annotatedWith(final Annotation annotation) {
-      nonNull(annotation, "annotation");
+      checkNotNull(annotation, "annotation");
       assertNoBindingAnnotation();
 
       bindingAnnotation = new BindingAnnotation() {
@@ -150,7 +149,7 @@
     }
 
     public void to(final String value) {
-      nonNull(value, "value");
+      checkNotNull(value, "value");
       assertNoTarget();
 
       BindConstantCommand.this.target = new ConstantTarget() {
@@ -303,7 +302,7 @@
     }
 
     public void to(final Class<?> value) {
-      nonNull(value, "value");
+      checkNotNull(value, "value");
       assertNoTarget();
 
       BindConstantCommand.this.target = new ConstantTarget() {
@@ -323,7 +322,7 @@
     }
 
     public <E extends Enum<E>> void to(final E value) {
-      Objects.nonNull(value, "value");
+      checkNotNull(value, "value");
       assertNoTarget();
 
       BindConstantCommand.this.target = new ConstantTarget() {
diff --git a/src/com/google/inject/commands/BindInterceptorCommand.java b/src/com/google/inject/commands/BindInterceptorCommand.java
index 7485346..b7e0fa4 100644
--- a/src/com/google/inject/commands/BindInterceptorCommand.java
+++ b/src/com/google/inject/commands/BindInterceptorCommand.java
@@ -17,7 +17,7 @@
 package com.google.inject.commands;
 
 import com.google.inject.matcher.Matcher;
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 import org.aopalliance.intercept.MethodInterceptor;
 
 import java.lang.reflect.Method;
@@ -41,9 +41,9 @@
       Matcher<? super Class<?>> classMatcher,
       Matcher<? super Method> methodMatcher,
       MethodInterceptor[] interceptors) {
-    this.source = nonNull(source, "source");
-    this.classMatcher = nonNull(classMatcher, "classMatcher");
-    this.methodMatcher = nonNull(methodMatcher, "methodMatcher");
+    this.source = checkNotNull(source, "source");
+    this.classMatcher = checkNotNull(classMatcher, "classMatcher");
+    this.methodMatcher = checkNotNull(methodMatcher, "methodMatcher");
     this.interceptors = unmodifiableList(Arrays.asList(interceptors.clone()));
   }
 
diff --git a/src/com/google/inject/commands/BindScopeCommand.java b/src/com/google/inject/commands/BindScopeCommand.java
index 1c0e9f8..a8019e7 100644
--- a/src/com/google/inject/commands/BindScopeCommand.java
+++ b/src/com/google/inject/commands/BindScopeCommand.java
@@ -17,7 +17,7 @@
 package com.google.inject.commands;
 
 import com.google.inject.Scope;
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.annotation.Annotation;
 
@@ -32,9 +32,9 @@
   private final Scope scope;
 
   BindScopeCommand(Object source, Class<? extends Annotation> annotationType, Scope scope) {
-    this.source = nonNull(source, "source");
-    this.annotationType = nonNull(annotationType, "annotationType");
-    this.scope = nonNull(scope, "scope");
+    this.source = checkNotNull(source, "source");
+    this.annotationType = checkNotNull(annotationType, "annotationType");
+    this.scope = checkNotNull(scope, "scope");
   }
 
   public Object getSource() {
diff --git a/src/com/google/inject/commands/CommandReplayer.java b/src/com/google/inject/commands/CommandReplayer.java
index f1a1b28..96f3f7a 100644
--- a/src/com/google/inject/commands/CommandReplayer.java
+++ b/src/com/google/inject/commands/CommandReplayer.java
@@ -23,8 +23,8 @@
 import com.google.inject.binder.ConstantBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
-import com.google.inject.internal.Objects;
 import com.google.inject.spi.SourceProviders;
+import static com.google.common.base.Preconditions.checkNotNull;
 import org.aopalliance.intercept.MethodInterceptor;
 
 import java.util.List;
@@ -52,8 +52,8 @@
    * Replays {@code commands} against {@code binder}.
    */
   public final void replay(final Binder binder, Iterable<Command> commands) {
-    Objects.nonNull(binder, "binder");
-    Objects.nonNull(commands, "commands");
+    checkNotNull(binder, "binder");
+    checkNotNull(commands, "commands");
 
     Command.Visitor<Void> visitor = new Command.Visitor<Void>() {
       public Void visitAddMessageError(AddMessageErrorCommand command) {
diff --git a/src/com/google/inject/commands/ConvertToTypesCommand.java b/src/com/google/inject/commands/ConvertToTypesCommand.java
index ba7a6e8..775d5fe 100644
--- a/src/com/google/inject/commands/ConvertToTypesCommand.java
+++ b/src/com/google/inject/commands/ConvertToTypesCommand.java
@@ -17,10 +17,9 @@
 package com.google.inject.commands;
 
 import com.google.inject.TypeLiteral;
-import static com.google.inject.internal.Objects.nonNull;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.spi.TypeConverter;
-
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Immutable snapshot of a request to convert binder types.
@@ -34,9 +33,9 @@
 
   ConvertToTypesCommand(Object source, Matcher<? super TypeLiteral<?>> typeMatcher,
       TypeConverter typeConverter) {
-    this.source = nonNull(source, "source");
-    this.typeMatcher = nonNull(typeMatcher, "typeMatcher");
-    this.typeConverter = nonNull(typeConverter, "typeConverter");
+    this.source = checkNotNull(source, "source");
+    this.typeMatcher = checkNotNull(typeMatcher, "typeMatcher");
+    this.typeConverter = checkNotNull(typeConverter, "typeConverter");
   }
 
   public Object getSource() {
diff --git a/src/com/google/inject/commands/GetProviderCommand.java b/src/com/google/inject/commands/GetProviderCommand.java
index 0839f2c..f1b6abf 100644
--- a/src/com/google/inject/commands/GetProviderCommand.java
+++ b/src/com/google/inject/commands/GetProviderCommand.java
@@ -17,7 +17,7 @@
 package com.google.inject.commands;
 
 import com.google.inject.Key;
-import static com.google.inject.internal.Objects.nonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Immutable snapshot of a request for a provider.
@@ -30,7 +30,7 @@
   private final EarlyRequestsProvider earlyRequestsProvider;
 
   GetProviderCommand(Object source, Key<T> key, EarlyRequestsProvider earlyRequestsProvider) {
-    this.source = nonNull(source, "source");
+    this.source = checkNotNull(source, "source");
     this.key = key;
     this.earlyRequestsProvider = earlyRequestsProvider;
   }
diff --git a/src/com/google/inject/commands/RequestStaticInjectionCommand.java b/src/com/google/inject/commands/RequestStaticInjectionCommand.java
index dbf3a1c..564eead 100644
--- a/src/com/google/inject/commands/RequestStaticInjectionCommand.java
+++ b/src/com/google/inject/commands/RequestStaticInjectionCommand.java
@@ -16,11 +16,11 @@
 
 package com.google.inject.commands;
 
-import static com.google.inject.internal.Objects.nonNull;
 
 import java.util.Arrays;
 import static java.util.Collections.unmodifiableList;
 import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Immutable snapshot of a request for static injection.
@@ -32,7 +32,7 @@
   private final List<Class> types;
 
   RequestStaticInjectionCommand(Object source, Class[] types) {
-    this.source = nonNull(source, "source");
+    this.source = checkNotNull(source, "source");
     this.types = unmodifiableList(Arrays.asList(types.clone()));
   }
 
diff --git a/src/com/google/inject/internal/GoogleCollections.java b/src/com/google/inject/internal/GoogleCollections.java
deleted file mode 100644
index 1a5f29d..0000000
--- a/src/com/google/inject/internal/GoogleCollections.java
+++ /dev/null
@@ -1,66 +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.internal;
-
-import java.util.Iterator;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.NoSuchElementException;
-
-/**
- * A tiny subset of handy methods copied from the Google Collections library.
- * We should consider adding that .jar to our build dependencies so this class
- * is no longer necessary.
- *
- * @author jessewilson@google.com (Jesse Wilson)
- */
-public class GoogleCollections {
-  private GoogleCollections() {}
-
-  public static <T> Iterable<T> concat(
-      final Iterable<? extends T> a, final Iterable<? extends T> b) {
-    return new Iterable<T>() {
-      public Iterator<T> iterator() {
-        return concat(Arrays.asList(a.iterator(), b.iterator()).iterator());
-      }
-    };
-  }
-
-  public static <T> Iterator<T> concat(
-      final Iterator<Iterator<? extends T>> inputs) {
-    return new Iterator<T>() {
-      Iterator<? extends T> current = Collections.<T>emptySet().iterator();
-
-      public boolean hasNext() {
-        while (!current.hasNext() && inputs.hasNext()) {
-          current = inputs.next();
-        }
-        return current.hasNext();
-      }
-      public T next() {
-        if (!hasNext()) {
-          throw new NoSuchElementException();
-        }
-        return current.next();
-      }
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    };
-  }
-}
diff --git a/src/com/google/inject/internal/MatcherAndConverter.java b/src/com/google/inject/internal/MatcherAndConverter.java
index 4be445d..103e0e1 100644
--- a/src/com/google/inject/internal/MatcherAndConverter.java
+++ b/src/com/google/inject/internal/MatcherAndConverter.java
@@ -19,8 +19,8 @@
 import com.google.inject.matcher.Matcher;
 import com.google.inject.spi.TypeConverter;
 import com.google.inject.spi.SourceProviders;
-import com.google.inject.internal.Objects;
 import com.google.inject.TypeLiteral;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  *
@@ -38,15 +38,15 @@
 
   MatcherAndConverter(Matcher<? super TypeLiteral<?>> typeMatcher,
       TypeConverter typeConverter, Object source) {
-    this.typeMatcher = Objects.nonNull(typeMatcher, "type matcher");
-    this.typeConverter = Objects.nonNull(typeConverter, "converter");
+    this.typeMatcher = checkNotNull(typeMatcher, "type matcher");
+    this.typeConverter = checkNotNull(typeConverter, "converter");
     this.source = source;
   }
 
   MatcherAndConverter(Matcher<? super TypeLiteral<?>> typeMatcher,
       TypeConverter typeConverter) {
-    this.typeMatcher = Objects.nonNull(typeMatcher, "type matcher");
-    this.typeConverter = Objects.nonNull(typeConverter, "converter");
+    this.typeMatcher = checkNotNull(typeMatcher, "type matcher");
+    this.typeConverter = checkNotNull(typeConverter, "converter");
     this.source = SourceProviders.defaultSource();
   }
 
diff --git a/src/com/google/inject/internal/Objects.java b/src/com/google/inject/internal/Objects.java
deleted file mode 100644
index 1b383ca..0000000
--- a/src/com/google/inject/internal/Objects.java
+++ /dev/null
@@ -1,61 +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;
-
-/**
- * Object utilities.
- *
- * @author crazybob@google.com (Bob Lee)
- */
-public class Objects {
-
-  /**
-   * Detects null values.
-   *
-   * @param t value
-   * @param message to display in the event of a null
-   * @return t
-   */
-  public static <T> T nonNull(T t, String message) {
-    if (t == null) {
-      throw new NullPointerException(message);
-    }
-    return t;
-  }
-
-  /**
-   * {@code null}-aware equals.
-   */
-  public static boolean equal(Object a, Object b) {
-    if (a == b) {
-      return true;
-    }
-
-    if (a == null || b == null) {
-      return false;
-    }
-
-    return a.equals(b);
-  }
-
-  /**
-   * {@code null}-aware hashCode.
-   */
-  public static int hashCode(Object o) {
-    return o != null ? o.hashCode() : 0;
-  }
-}
diff --git a/src/com/google/inject/internal/ReferenceCache.java b/src/com/google/inject/internal/ReferenceCache.java
index 44bfc2f..ad8293c 100644
--- a/src/com/google/inject/internal/ReferenceCache.java
+++ b/src/com/google/inject/internal/ReferenceCache.java
@@ -17,6 +17,7 @@
 package com.google.inject.internal;
 
 import static com.google.inject.internal.ReferenceType.STRONG;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Extends {@link ReferenceMap} to support lazy loading values by overriding
@@ -61,7 +62,7 @@
       ReferenceType keyReferenceType,
       ReferenceType valueReferenceType,
       final Function<? super K, ? extends V> function) {
-    Objects.nonNull(function, "function");
+    checkNotNull(function, "function");
     return new ReferenceCache<K, V>(keyReferenceType, valueReferenceType) {
       protected V create(K key) {
         return function.apply(key);
diff --git a/src/com/google/inject/internal/ReferenceMap.java b/src/com/google/inject/internal/ReferenceMap.java
index 1fa17c4..4185a3b 100644
--- a/src/com/google/inject/internal/ReferenceMap.java
+++ b/src/com/google/inject/internal/ReferenceMap.java
@@ -17,6 +17,7 @@
 package com.google.inject.internal;
 
 import static com.google.inject.internal.ReferenceType.STRONG;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -78,7 +79,7 @@
   }
 
   public V get(final Object key) {
-    Objects.nonNull(key, "key");
+    checkNotNull(key, "key");
     return internalGet((K) key);
   }
 
@@ -95,7 +96,7 @@
   }
 
   public V remove(Object key) {
-    Objects.nonNull(key, "key");
+    checkNotNull(key, "key");
     Object referenceAwareKey = makeKeyReferenceAware(key);
     Object valueReference = delegate.remove(referenceAwareKey);
     return dereferenceValue(valueReference);
@@ -110,13 +111,13 @@
   }
 
   public boolean containsKey(Object key) {
-    Objects.nonNull(key, "key");
+    checkNotNull(key, "key");
     Object referenceAwareKey = makeKeyReferenceAware(key);
     return delegate.containsKey(referenceAwareKey);
   }
 
   public boolean containsValue(Object value) {
-    Objects.nonNull(value, "value");
+    checkNotNull(value, "value");
     for (Object valueReference : delegate.values()) {
       if (value.equals(dereferenceValue(valueReference))) {
         return true;
diff --git a/src/com/google/inject/internal/Types.java b/src/com/google/inject/internal/Types.java
index e0d6af7..9ca7a6b 100644
--- a/src/com/google/inject/internal/Types.java
+++ b/src/com/google/inject/internal/Types.java
@@ -17,15 +17,14 @@
 
 package com.google.inject.internal;
 
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
 import com.google.inject.TypeLiteral;
-
 import java.io.Serializable;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -34,20 +33,18 @@
 public class Types {
   private Types() {}
 
-  private static final Map<TypeLiteral<?>, TypeLiteral<?>> PRIMITIVE_TO_WRAPPER;
-  static {
-    Map<TypeLiteral<?>, TypeLiteral<?>> m = new HashMap<TypeLiteral<?>, TypeLiteral<?>>();
-    m.put(TypeLiteral.get(boolean.class), TypeLiteral.get(Boolean.class));
-    m.put(TypeLiteral.get(byte.class), TypeLiteral.get(Byte.class));
-    m.put(TypeLiteral.get(short.class), TypeLiteral.get(Short.class));
-    m.put(TypeLiteral.get(int.class), TypeLiteral.get(Integer.class));
-    m.put(TypeLiteral.get(long.class), TypeLiteral.get(Long.class));
-    m.put(TypeLiteral.get(float.class), TypeLiteral.get(Float.class));
-    m.put(TypeLiteral.get(double.class), TypeLiteral.get(Double.class));
-    m.put(TypeLiteral.get(char.class), TypeLiteral.get(Character.class));
-    m.put(TypeLiteral.get(void.class), TypeLiteral.get(Void.class));
-    PRIMITIVE_TO_WRAPPER = Collections.unmodifiableMap(m);
-  }
+  private static final Map<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))
+          .put(TypeLiteral.get(int.class), TypeLiteral.get(Integer.class))
+          .put(TypeLiteral.get(long.class), TypeLiteral.get(Long.class))
+          .put(TypeLiteral.get(float.class), TypeLiteral.get(Float.class))
+          .put(TypeLiteral.get(double.class), TypeLiteral.get(Double.class))
+          .put(TypeLiteral.get(char.class), TypeLiteral.get(Character.class))
+          .put(TypeLiteral.get(void.class), TypeLiteral.get(Void.class))
+          .build();
 
   /**
    * Returns an equivalent (but not necessarily equal) type literal that is
@@ -189,18 +186,21 @@
       ParameterizedType p = (ParameterizedType) type;
       return Arrays.hashCode(p.getActualTypeArguments())
           ^ p.getRawType().hashCode()
-          ^ Objects.hashCode(p.getOwnerType());
+          ^ hashCodeOrZero(p.getOwnerType());
 
     } else if (type instanceof GenericArrayType) {
       return hashCode(((GenericArrayType) type).getGenericComponentType());
 
     } else {
-      // This isn't a type we support. Could be a generic array type, wildcard
-      // type, etc.
-      return Objects.hashCode(type);
+      // This isn't a type we support. Could be a generic array type, wildcard type, etc.
+      return hashCodeOrZero(type);
     }
   }
 
+  private static int hashCodeOrZero(Object o) {
+    return o != null ? o.hashCode() : 0;
+  }
+
   public static String toString(Type type) {
     if (type instanceof Class<?>) {
       return ((Class) type).getName();
@@ -239,7 +239,7 @@
       this.rawType = canonicalize(rawType);
       this.typeArguments = typeArguments.clone();
       for (int t = 0; t < this.typeArguments.length; t++) {
-        if (this.typeArguments[t] instanceof Class<?> 
+        if (this.typeArguments[t] instanceof Class<?>
             && ((Class) this.typeArguments[t]).isPrimitive()) {
           throw new IllegalArgumentException(
               "Parameterized types may not have primitive arguments: " + this.typeArguments[t]);
diff --git a/src/com/google/inject/matcher/Matchers.java b/src/com/google/inject/matcher/Matchers.java
index a9f4ff4..d4643ea 100644
--- a/src/com/google/inject/matcher/Matchers.java
+++ b/src/com/google/inject/matcher/Matchers.java
@@ -16,14 +16,13 @@
 
 package com.google.inject.matcher;
 
-import com.google.inject.internal.Objects;
-
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Matcher implementations. Supports matching classes and methods.
@@ -67,7 +66,7 @@
     final Matcher<? super T> delegate;
 
     private Not(Matcher<? super T> delegate) {
-      this.delegate = Objects.nonNull(delegate, "delegate");
+      this.delegate = checkNotNull(delegate, "delegate");
     }
 
     public boolean matches(T t) {
@@ -111,7 +110,7 @@
     private final Class<? extends Annotation> annotationType;
 
     public AnnotatedWithType(Class<? extends Annotation> annotationType) {
-      this.annotationType = Objects.nonNull(annotationType, "annotation type");
+      this.annotationType = checkNotNull(annotationType, "annotation type");
       checkForRuntimeRetention(annotationType);
     }
 
@@ -147,7 +146,7 @@
     private final Annotation annotation;
 
     public AnnotatedWith(Annotation annotation) {
-      this.annotation = Objects.nonNull(annotation, "annotation");
+      this.annotation = checkNotNull(annotation, "annotation");
       checkForRuntimeRetention(annotation.annotationType());
     }
 
@@ -183,7 +182,7 @@
     private final Class<?> superclass;
 
     public SubclassesOf(Class<?> superclass) {
-      this.superclass = Objects.nonNull(superclass, "superclass");
+      this.superclass = checkNotNull(superclass, "superclass");
     }
 
     public boolean matches(Class subclass) {
@@ -216,7 +215,7 @@
     private final Object value;
 
     public Only(Object value) {
-      this.value = Objects.nonNull(value, "value");
+      this.value = checkNotNull(value, "value");
     }
 
     public boolean matches(Object other) {
@@ -249,7 +248,7 @@
     private final Object value;
 
     public IdenticalTo(Object value) {
-      this.value = Objects.nonNull(value, "value");
+      this.value = checkNotNull(value, "value");
     }
 
     public boolean matches(Object other) {
@@ -282,7 +281,7 @@
     private final String packageName;
 
     public InPackage(Package targetPackage) {
-      this.targetPackage = Objects.nonNull(targetPackage, "package");
+      this.targetPackage = checkNotNull(targetPackage, "package");
       this.packageName = targetPackage.getName();
     }
 
@@ -320,7 +319,7 @@
     private final Matcher<? super Class<?>> returnType;
 
     public Returns(Matcher<? super Class<?>> returnType) {
-      this.returnType = Objects.nonNull(returnType, "return type matcher");
+      this.returnType = checkNotNull(returnType, "return type matcher");
     }
 
     public boolean matches(Method m) {
diff --git a/src/com/google/inject/name/NamedImpl.java b/src/com/google/inject/name/NamedImpl.java
index eb5d82e..7253e29 100644
--- a/src/com/google/inject/name/NamedImpl.java
+++ b/src/com/google/inject/name/NamedImpl.java
@@ -16,17 +16,16 @@
 
 package com.google.inject.name;
 
-import com.google.inject.internal.Objects;
-
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 class NamedImpl implements Named, Serializable {
 
   private final String value;
 
   public NamedImpl(String value) {
-    this.value = Objects.nonNull(value, "name");
+    this.value = checkNotNull(value, "name");
   }
 
   public String value() {
diff --git a/src/com/google/inject/spi/Message.java b/src/com/google/inject/spi/Message.java
index 1bf78f5..d537dff 100644
--- a/src/com/google/inject/spi/Message.java
+++ b/src/com/google/inject/spi/Message.java
@@ -16,9 +16,8 @@
 
 package com.google.inject.spi;
 
-import static com.google.inject.internal.Objects.nonNull;
-
 import java.io.Serializable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * A message. Contains a source pointing to the code which resulted
@@ -32,8 +31,8 @@
   private final String message;
 
   public Message(Object source, String message) {
-    this.source = nonNull(source, "source").toString();
-    this.message = nonNull(message, "message");
+    this.source = checkNotNull(source, "source").toString();
+    this.message = checkNotNull(message, "message");
   }
 
   public Message(String message) {