Introduced ToStringBuilder. Pulled up ConstructorInjector. Introduced ConstructionProxy.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@59 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/guice.iws b/guice.iws
index 1e37412..1f758c4 100644
--- a/guice.iws
+++ b/guice.iws
@@ -18,24 +18,24 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" name="Default" comment="">
-      <change type="DELETED" beforePath="$PROJECT_DIR$/test/com/google/inject/QueryTest.java" afterPath="" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractModule.java" afterPath="$PROJECT_DIR$/src/com/google/inject/AbstractModule.java" />
-      <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/Query.java" afterPath="" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Query.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept" />
-      <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/Queries.java" afterPath="" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/PredicatesTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/PredicatesTest.java" />
-      <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractQuery.java" afterPath="" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Predicate.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Predicate.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" afterPath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Binding.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Binding.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iws" afterPath="$PROJECT_DIR$/guice.iws" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractPredicate.java" afterPath="$PROJECT_DIR$/src/com/google/inject/AbstractPredicate.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Predicates.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Predicates.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java" afterPath="$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/package-info.java" afterPath="$PROJECT_DIR$/src/com/google/inject/package-info.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java" afterPath="$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java" />
     </list>
   </component>
   <component name="ChangeListSynchronizer" />
@@ -205,22 +205,119 @@
   </component>
   <component name="FileEditorManager">
     <leaf>
-      <file leaf-file-name="Queries.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+      <file leaf-file-name="ErrorHandlingTest.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/test/com/google/inject/ErrorHandlingTest.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="31" column="0" selection-start="625" selection-end="625" vertical-scroll-proportion="0.7496063">
+            <state line="57" column="0" selection-start="1419" selection-end="1419" vertical-scroll-proportion="1.5487288">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="QueryTest.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java">
+      <file leaf-file-name="Container.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Container.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="35" column="7" selection-start="1001" selection-end="1001" vertical-scroll-proportion="0.28346458">
-              <folding>
-                <element signature="imports" expanded="true" />
-              </folding>
+            <state line="68" column="17" selection-start="1987" selection-end="1987" vertical-scroll-proportion="0.99364406">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ConstructionProxy.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="12" column="17" selection-start="292" selection-end="292" vertical-scroll-proportion="0.43220338">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ConstructionProxyFactory.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="11" column="17" selection-start="240" selection-end="240" vertical-scroll-proportion="0.39618644">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="TypeLiteral.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="32" column="8" selection-start="1141" selection-end="1141" vertical-scroll-proportion="0.03601695">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Binding.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Binding.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="25" column="13" selection-start="808" selection-end="808" vertical-scroll-proportion="0.03601695">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ContainerBuilder.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="130" column="36" selection-start="4273" selection-end="4273" vertical-scroll-proportion="1.0529661">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ConstantFactory.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="38" column="14" selection-start="1098" selection-end="1098" vertical-scroll-proportion="0.8283898">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ContainerScope.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerScope.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="50" column="15" selection-start="1625" selection-end="1625" vertical-scroll-proportion="1.2966101">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Queries.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="8" column="0" selection-start="213" selection-end="213" vertical-scroll-proportion="0.03601695">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="package-info.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/package-info.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="18" column="3" selection-start="647" selection-end="647" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ContainerImpl.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="51" column="6" selection-start="1627" selection-end="1627" vertical-scroll-proportion="0.43220338">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ConstructorInjector.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="0" column="18" selection-start="18" selection-end="18" vertical-scroll-proportion="0.0">
+              <folding />
             </state>
           </provider>
         </entry>
@@ -228,39 +325,95 @@
       <file leaf-file-name="AllTests.java" pinned="false" current="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/test/com/google/inject/AllTests.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="40" column="18" selection-start="1350" selection-end="1350" vertical-scroll-proportion="0.5086614">
+            <state line="30" column="13" selection-start="1010" selection-end="1010" vertical-scroll-proportion="0.32415253">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="AbstractModule.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractModule.java">
+      <file leaf-file-name="ProxyFactory.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="36" column="6" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.5086614">
+            <state line="7" column="17" selection-start="156" selection-end="156" vertical-scroll-proportion="0.25211865">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="Query.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Query.java">
+      <file leaf-file-name="ProxyFactoryBuilder.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="9" column="17" selection-start="219" selection-end="219" vertical-scroll-proportion="0.24094488">
+            <state line="7" column="13" selection-start="152" selection-end="152" vertical-scroll-proportion="0.25211865">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="AbstractQuery.java" pinned="false" current="true" current-in-tab="true">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java">
+      <file leaf-file-name="InternalContext.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/InternalContext.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="18" column="0" selection-start="441" selection-end="441" vertical-scroll-proportion="0.48188975">
+            <state line="71" column="1" selection-start="2161" selection-end="2161" vertical-scroll-proportion="2.0169492">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
+      <file leaf-file-name="PerformanceComparison.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="149" column="37" selection-start="5048" selection-end="5048" vertical-scroll-proportion="3.1694915">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="NumberFormat.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="jar:///usr/local/src.zip!/java/text/NumberFormat.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="509" column="9" selection-start="19846" selection-end="19846" vertical-scroll-proportion="0.36864406">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ConstructionContext.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="30" column="6" selection-start="973" selection-end="973" vertical-scroll-proportion="-1.4194915">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ToStringCreator.class" pinned="false" current="false" current-in-tab="false">
+        <entry file="jar://$PROJECT_DIR$/lib/build/spring-core.jar!/org/springframework/core/style/ToStringCreator.class">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="5" column="13" selection-start="168" selection-end="168" vertical-scroll-proportion="0.1440678">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ToStringBuilder.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="0" column="16" selection-start="16" selection-end="16" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="DefaultConstructionProxyFactory.java" pinned="false" current="true" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="0" column="10" selection-start="10" selection-end="10" vertical-scroll-proportion="0.0">
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
     </leaf>
   </component>
   <component name="FindManager">
@@ -316,6 +469,26 @@
           <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
         </PATH_ELEMENT>
         <PATH_ELEMENT>
+          <option name="myItemId" value="com.google.inject.spi" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
+        </PATH_ELEMENT>
+      </PATH>
+      <PATH>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="guice.ipr" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
+        </PATH_ELEMENT>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="com.google.inject.intercept" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
+        </PATH_ELEMENT>
+      </PATH>
+      <PATH>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="guice.ipr" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
+        </PATH_ELEMENT>
+        <PATH_ELEMENT>
           <option name="myItemId" value="com.google.inject" />
           <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
         </PATH_ELEMENT>
@@ -441,7 +614,7 @@
       <showLibraryContents PackagesPane="false" />
       <hideEmptyPackages />
       <abbreviatePackageNames />
-      <showStructure Favorites="false" PackagesPane="false" Scope="false" ProjectPane="false" />
+      <showStructure Scope="false" ProjectPane="false" PackagesPane="false" Favorites="false" />
       <autoscrollToSource />
       <autoscrollFromSource />
       <sortByType />
@@ -449,17 +622,17 @@
   </component>
   <component name="PropertiesComponent">
     <property name="MemberChooser.copyJavadoc" value="false" />
-    <property name="cvs_file_history_treeWidth0" value="458" />
-    <property name="cvs_file_history_flatWidth2" value="458" />
+    <property name="cvs_file_history_treeWidth0" value="457" />
+    <property name="cvs_file_history_flatWidth2" value="457" />
     <property name="cvs_file_history_treeOrder1" value="1" />
     <property name="GoToFile.includeJavaFiles" value="false" />
     <property name="cvs_file_history_flatOrder1" value="1" />
-    <property name="cvs_file_history_flatWidth1" value="457" />
-    <property name="cvs_file_history_treeWidth1" value="457" />
+    <property name="cvs_file_history_flatWidth1" value="456" />
+    <property name="cvs_file_history_treeWidth1" value="456" />
     <property name="GoToClass.includeLibraries" value="false" />
     <property name="cvs_file_history_flatOrder2" value="2" />
     <property name="MemberChooser.showClasses" value="true" />
-    <property name="cvs_file_history_treeWidth2" value="458" />
+    <property name="cvs_file_history_treeWidth2" value="457" />
     <property name="GoToClass.toSaveIncludeLibraries" value="false" />
     <property name="cvs_file_history_flatOrder3" value="3" />
     <property name="RunManagerConfig.showSettingsBeforeRunnig" value="false" />
@@ -469,9 +642,9 @@
     <property name="cvs_file_history_treeOrder3" value="3" />
     <property name="last_opened_file_path" value="/usr/local/client/2/google3/java/com/google/inject" />
     <property name="cvs_file_history_treeOrder2" value="2" />
-    <property name="cvs_file_history_treeWidth3" value="457" />
-    <property name="cvs_file_history_flatWidth0" value="458" />
-    <property name="cvs_file_history_flatWidth3" value="457" />
+    <property name="cvs_file_history_treeWidth3" value="456" />
+    <property name="cvs_file_history_flatWidth0" value="457" />
+    <property name="cvs_file_history_flatWidth3" value="456" />
     <property name="cvs_file_history_treeOrder0" value="0" />
   </component>
   <component name="ReadonlyStatusHandler">
@@ -522,7 +695,17 @@
       <RunnerSettings RunnerId="Run" />
       <ConfigurationWrapper RunnerId="Debug" />
       <ConfigurationWrapper RunnerId="Run" />
+      <method>
+        <option name="Make" value="true" />
+      </method>
     </tempConfiguration>
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+    </configuration>
     <configuration default="true" type="Applet" factoryName="Applet">
       <module name="" />
       <option name="MAIN_CLASS_NAME" />
@@ -548,13 +731,6 @@
         <option name="Make" value="true" />
       </method>
     </configuration>
-    <configuration default="true" type="Remote" factoryName="Remote">
-      <option name="USE_SOCKET_TRANSPORT" value="true" />
-      <option name="SERVER_MODE" value="false" />
-      <option name="SHMEM_ADDRESS" value="javadebug" />
-      <option name="HOST" value="localhost" />
-      <option name="PORT" value="5005" />
-    </configuration>
     <configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
       <module name="" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -576,7 +752,7 @@
     </configuration>
     <configuration default="false" name="PerformanceComparison" type="Application" factoryName="Application" enabled="false" merge="false">
       <option name="MAIN_CLASS_NAME" value="com.google.inject.PerformanceComparison" />
-      <option name="VM_PARAMETERS" value="" />
+      <option name="VM_PARAMETERS" value="-server" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -593,6 +769,21 @@
         <option name="Make" value="true" />
       </method>
     </configuration>
+    <configuration default="false" name="ErrorHandlingTest" type="Application" factoryName="Application" enabled="false" merge="false">
+      <option name="MAIN_CLASS_NAME" value="com.google.inject.ErrorHandlingTest" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <module name="guice" />
+      <RunnerSettings RunnerId="Run" />
+      <ConfigurationWrapper RunnerId="Run" />
+      <method>
+        <option name="Make" value="true" />
+      </method>
+    </configuration>
     <configuration default="false" name="AllTests" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
       <pattern value="com.google.inject.*" />
       <module name="guice" />
@@ -615,46 +806,6 @@
         <option name="Make" value="true" />
       </method>
     </configuration>
-    <configuration default="false" name="ErrorHandlingTest" type="Application" factoryName="Application" enabled="false" merge="false">
-      <option name="MAIN_CLASS_NAME" value="com.google.inject.ErrorHandlingTest" />
-      <option name="VM_PARAMETERS" />
-      <option name="PROGRAM_PARAMETERS" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
-      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-      <option name="ALTERNATIVE_JRE_PATH" />
-      <option name="ENABLE_SWING_INSPECTOR" value="false" />
-      <module name="guice" />
-      <RunnerSettings RunnerId="Run" />
-      <ConfigurationWrapper RunnerId="Run" />
-      <method>
-        <option name="Make" value="true" />
-      </method>
-    </configuration>
-    <configuration default="false" name="QueryTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
-      <pattern value="com.google.inject.*" />
-      <module name="guice" />
-      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-      <option name="ALTERNATIVE_JRE_PATH" />
-      <option name="PACKAGE_NAME" value="com.google.inject.intercept" />
-      <option name="MAIN_CLASS_NAME" value="com.google.inject.intercept.QueryTest" />
-      <option name="METHOD_NAME" />
-      <option name="TEST_OBJECT" value="class" />
-      <option name="VM_PARAMETERS" />
-      <option name="PARAMETERS" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
-      <option name="ADDITIONAL_CLASS_PATH" />
-      <option name="TEST_SEARCH_SCOPE">
-        <value defaultName="wholeProject" />
-      </option>
-      <RunnerSettings RunnerId="Debug">
-        <option name="DEBUG_PORT" value="41735" />
-        <option name="TRANSPORT" value="0" />
-        <option name="LOCAL" value="true" />
-      </RunnerSettings>
-      <RunnerSettings RunnerId="Run" />
-      <ConfigurationWrapper RunnerId="Debug" />
-      <ConfigurationWrapper RunnerId="Run" />
-    </configuration>
   </component>
   <component name="ScopeViewComponent">
     <subPane subId="Project">
@@ -754,7 +905,7 @@
       <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
       <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.14623655" order="1" />
       <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3282876" order="8" />
-      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.38315988" order="2" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.5373699" order="2" />
       <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
       <window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="6" />
       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39978448" order="0" />
@@ -853,113 +1004,113 @@
     <option name="myLastEditedConfigurable" value="Default" />
   </component>
   <component name="editorHistoryManager">
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="159" column="27" selection-start="4053" selection-end="4053" vertical-scroll-proportion="0.33700788">
+        <state line="0" column="16" selection-start="16" selection-end="16" vertical-scroll-proportion="0.0">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Scope.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="24" column="1" selection-start="895" selection-end="895" vertical-scroll-proportion="0.26771653">
+        <state line="30" column="6" selection-start="973" selection-end="973" vertical-scroll-proportion="-1.4194915">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/PreloadingTest.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/InternalContext.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="25" column="13" selection-start="778" selection-end="778" vertical-scroll-proportion="0.24094488">
+        <state line="71" column="1" selection-start="2161" selection-end="2161" vertical-scroll-proportion="2.0169492">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/ContainerTest.java">
+    <entry file="jar:///usr/local/src.zip!/java/text/NumberFormat.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="64" column="20" selection-start="1945" selection-end="1945" vertical-scroll-proportion="0.30393702">
+        <state line="509" column="9" selection-start="19846" selection-end="19846" vertical-scroll-proportion="0.36864406">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="149" column="37" selection-start="5048" selection-end="5048" vertical-scroll-proportion="3.1694915">
           <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="585" column="33" selection-start="17831" selection-end="17831" vertical-scroll-proportion="0.41259843">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/ConstantConversionTest.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="51" column="26" selection-start="1561" selection-end="1561" vertical-scroll-proportion="0.35905513">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Binding.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="25" column="21" selection-start="795" selection-end="795" vertical-scroll-proportion="-0.6330709">
+        <state line="130" column="36" selection-start="4273" selection-end="4273" vertical-scroll-proportion="1.0529661">
           <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/google/inject/Container.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="75" column="5" selection-start="2127" selection-end="2127" vertical-scroll-proportion="0.27716535">
+        <state line="68" column="17" selection-start="1987" selection-end="1987" vertical-scroll-proportion="0.99364406">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerScope.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="23" column="6" selection-start="747" selection-end="747" vertical-scroll-proportion="0.24094488">
+        <state line="51" column="6" selection-start="1627" selection-end="1627" vertical-scroll-proportion="0.43220338">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="35" column="7" selection-start="1001" selection-end="1001" vertical-scroll-proportion="0.28346458">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
+        <state line="0" column="18" selection-start="18" selection-end="18" vertical-scroll-proportion="0.0">
+          <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/test/com/google/inject/AllTests.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="40" column="18" selection-start="1350" selection-end="1350" vertical-scroll-proportion="0.5086614">
+        <state line="30" column="13" selection-start="1010" selection-end="1010" vertical-scroll-proportion="0.32415253">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractModule.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="36" column="6" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.5086614">
+        <state line="7" column="17" selection-start="156" selection-end="156" vertical-scroll-proportion="0.25211865">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Query.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="9" column="17" selection-start="219" selection-end="219" vertical-scroll-proportion="0.24094488">
+        <state line="7" column="13" selection-start="152" selection-end="152" vertical-scroll-proportion="0.25211865">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="31" column="0" selection-start="625" selection-end="625" vertical-scroll-proportion="0.7496063">
+        <state line="12" column="17" selection-start="292" selection-end="292" vertical-scroll-proportion="0.43220338">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="18" column="0" selection-start="441" selection-end="441" vertical-scroll-proportion="0.48188975">
+        <state line="11" column="17" selection-start="240" selection-end="240" vertical-scroll-proportion="0.39618644">
           <folding />
         </state>
       </provider>
     </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="0" column="10" selection-start="10" selection-end="10" vertical-scroll-proportion="0.0">
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
   </component>
 </project>
 
diff --git a/src/com/google/inject/Binding.java b/src/com/google/inject/Binding.java
index 2a67aa2..47285cc 100644
--- a/src/com/google/inject/Binding.java
+++ b/src/com/google/inject/Binding.java
@@ -16,6 +16,8 @@
 
 package com.google.inject;
 
+import com.google.inject.util.ToStringBuilder;
+
 /**
  * A binding from a {@link Key} (type and name) to an implementation.
  *
@@ -78,4 +80,12 @@
   public boolean isConstant() {
     return internalFactory instanceof ConstantFactory<?>;
   }
+
+  public String toString() {
+    return new ToStringBuilder(Binding.class)
+        .add("key", key)
+        .add("source", source)
+        .add("factory", internalFactory)
+        .toString();
+  }
 }
\ No newline at end of file
diff --git a/src/com/google/inject/ConstantFactory.java b/src/com/google/inject/ConstantFactory.java
index 9b10a5e..a5a2939 100644
--- a/src/com/google/inject/ConstantFactory.java
+++ b/src/com/google/inject/ConstantFactory.java
@@ -17,6 +17,7 @@
 package com.google.inject;
 
 import com.google.inject.util.Objects;
+import com.google.inject.util.ToStringBuilder;
 
 /**
  * @author crazybob@google.com (Bob Lee)
@@ -34,6 +35,8 @@
   }
 
   public String toString() {
-    return "ConstantFactory[" + value + "]";
+    return new ToStringBuilder(ConstantFactory.class)
+        .add("value", value)
+        .toString();
   }
 }
diff --git a/src/com/google/inject/ConstructionContext.java b/src/com/google/inject/ConstructionContext.java
index 25a9fe4..eb82ee5 100644
--- a/src/com/google/inject/ConstructionContext.java
+++ b/src/com/google/inject/ConstructionContext.java
@@ -66,6 +66,7 @@
     // instance (as opposed to one per caller).
 
     if (!expectedType.isInterface()) {
+      // TODO: Report better error.
       throw new ConfigurationException(
           expectedType.getName() + " is not an interface.");
     }
diff --git a/src/com/google/inject/ConstructorInjector.java b/src/com/google/inject/ConstructorInjector.java
new file mode 100644
index 0000000..dc4c781
--- /dev/null
+++ b/src/com/google/inject/ConstructorInjector.java
@@ -0,0 +1,151 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+import com.google.inject.spi.ConstructionProxy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Injects constructors.
+ *
+ * @author crazybob@google.com (Bob Lee)
+*/
+class ConstructorInjector<T> implements Factory<T> {
+
+  final Class<T> implementation;
+  final ContainerImpl.Injector[] injectors;
+  final ContainerImpl.ParameterInjector<?>[] parameterInjectors;
+  final ConstructionProxy<T> constructionProxy;
+
+  private ContainerImpl container;
+
+  ConstructorInjector(ContainerImpl container, Class<T> implementation) {
+    this.container = container;
+    this.implementation = implementation;
+    Constructor<T> constructor = findConstructorIn(implementation);
+    parameterInjectors = createParameterInjector(constructor);
+    injectors = container.injectors.get(implementation)
+        .toArray(new ContainerImpl.Injector[0]);
+    constructionProxy = container.constructionProxyFactory.get(constructor);
+  }
+
+  ContainerImpl.ParameterInjector<?>[] createParameterInjector(
+      Constructor<T> constructor) {
+    try {
+      Inject inject = constructor.getAnnotation(Inject.class);
+      return inject == null
+          ? null // default constructor.
+          : container.getParametersInjectors(
+              constructor,
+              constructor.getParameterAnnotations(),
+              constructor.getGenericParameterTypes(),
+              inject.value()
+          );
+    } catch (ContainerImpl.MissingDependencyException e) {
+      e.handle(container.errorHandler);
+      return null;
+    }
+  }
+
+  @SuppressWarnings({"unchecked"})
+  private Constructor<T> findConstructorIn(Class<T> implementation) {
+    Constructor<T> found = null;
+    for (Constructor<T> constructor
+        : implementation.getDeclaredConstructors()) {
+      if (constructor.getAnnotation(Inject.class) != null) {
+        if (found != null) {
+          container.errorHandler.handle(
+              ErrorMessage.TOO_MANY_CONSTRUCTORS, implementation);
+          return ContainerImpl.invalidConstructor();
+        }
+        found = constructor;
+      }
+    }
+    if (found != null) {
+      return found;
+    }
+
+    // If no annotated constructor is found, look for a no-arg constructor
+    // instead.
+    try {
+      return implementation.getDeclaredConstructor();
+    } catch (NoSuchMethodException e) {
+      container.errorHandler.handle(ErrorMessage.MISSING_CONSTRUCTOR, implementation);
+      return ContainerImpl.invalidConstructor();
+    }
+  }
+
+  /**
+   * Construct an instance. Returns {@code Object} instead of {@code T}
+   * because it may return a proxy.
+   */
+  Object construct(InternalContext context, Class<? super T> expectedType) {
+    ConstructionContext<T> constructionContext =
+        context.getConstructionContext(this);
+
+    // We have a circular reference between constructors. Return a proxy.
+    if (constructionContext.isConstructing()) {
+      // TODO (crazybob): if we can't proxy this object, can we proxy the
+      // other object?
+      return constructionContext.createProxy(expectedType);
+    }
+
+    // If we're re-entering this factory while injecting fields or methods,
+    // return the same instance. This prevents infinite loops.
+    T t = constructionContext.getCurrentReference();
+    if (t != null) {
+      return t;
+    }
+
+    try {
+      // First time through...
+      constructionContext.startConstruction();
+      try {
+        Object[] parameters =
+            ContainerImpl.getParameters(context, parameterInjectors);
+        t = newInstance(parameters);
+        constructionContext.setProxyDelegates(t);
+      } finally {
+        constructionContext.finishConstruction();
+      }
+
+      // Store reference. If an injector re-enters this factory, they'll
+      // get the same reference.
+      constructionContext.setCurrentReference(t);
+
+      // Inject fields and methods.
+      for (int i = 0; i < injectors.length; i++) {
+        injectors[i].inject(context, t);
+      }
+
+      return t;
+    } catch (InvocationTargetException e) {
+      throw new RuntimeException(e);
+    } finally {
+      constructionContext.removeCurrentReference();
+    }
+  }
+
+  @SuppressWarnings({"unchecked"})
+  private T newInstance(Object[] parameters)
+      throws InvocationTargetException {
+    return (T) constructionProxy.newInstance(parameters);
+  }
+
+  public T get() {
+    try {
+      return container.callInContext(new ContextualCallable<T>() {
+        @SuppressWarnings({"unchecked"})
+        public T call(InternalContext context) {
+          return (T) construct(context, implementation);
+        }
+      });
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+}
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index e2e4bed..2545197 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -18,7 +18,10 @@
 
 import com.google.inject.util.Objects;
 import com.google.inject.util.Stopwatch;
+import com.google.inject.util.ToStringBuilder;
 import static com.google.inject.util.Objects.nonNull;
+import com.google.inject.spi.ConstructionProxyFactory;
+import com.google.inject.spi.DefaultConstructionProxyFactory;
 
 import java.lang.reflect.Member;
 import java.util.ArrayList;
@@ -100,15 +103,29 @@
     }
   };
 
+  final ConstructionProxyFactory constructionProxyFactory;
+
   /**
    * Constructs a new builder.
+   *
+   * @param constructionProxyFactory to use when constructing objects
    */
-  public ContainerBuilder() {
+  public ContainerBuilder(ConstructionProxyFactory constructionProxyFactory) {
     put(Scopes.DEFAULT_SCOPE, DEFAULT_SCOPE);
     put(Scopes.CONTAINER_SCOPE, ContainerScope.INSTANCE);
 
     bind(Container.class).to(CONTAINER_FACTORY);
     bind(Logger.class).to(LOGGER_FACTORY);
+
+    this.constructionProxyFactory = nonNull(constructionProxyFactory,
+        "construction proxy factory");
+  }
+
+  /**
+   * Constructs a new builder.
+   */
+  public ContainerBuilder() {
+    this(new DefaultConstructionProxyFactory());
   }
 
   final List<Validation> validations = new ArrayList<Validation>();
@@ -286,7 +303,7 @@
     ensureNotCreated();
     Map<Key<?>, Binding<?>> bindings =
         new HashMap<Key<?>, Binding<?>>();
-    container = new ContainerImpl(bindings);
+    container = new ContainerImpl(constructionProxyFactory, bindings);
 
     createConstantBindings();
 
@@ -685,7 +702,7 @@
    */
   private static class DefaultFactory<T> implements InternalFactory<T> {
 
-    volatile ContainerImpl.ConstructorInjector<T> constructor;
+    volatile ConstructorInjector<T> constructor;
 
     private final TypeLiteral<T> implementation;
     private final Key<? super T> key;
@@ -698,16 +715,16 @@
     @SuppressWarnings("unchecked")
     public T get(InternalContext context) {
       if (constructor == null) {
-        // This unnecessary cast is a workaround for an annoying compiler
-        // bug I keep running into.
-        Object c = context.getContainerImpl().getConstructor(implementation);
-        this.constructor = (ContainerImpl.ConstructorInjector<T>) c;
+        this.constructor =
+            context.getContainerImpl().getConstructor(implementation);
       }
       return (T) constructor.construct(context, key.getRawType());
     }
 
     public String toString() {
-      return implementation.toString();
+      return new ToStringBuilder(Factory.class)
+          .add("implementation", implementation)
+          .toString();
     }
   }
 
diff --git a/src/com/google/inject/ContainerImpl.java b/src/com/google/inject/ContainerImpl.java
index c7c8e1e..ca9f897 100644
--- a/src/com/google/inject/ContainerImpl.java
+++ b/src/com/google/inject/ContainerImpl.java
@@ -18,10 +18,11 @@
 
 import com.google.inject.util.ReferenceCache;
 import com.google.inject.util.Strings;
+import com.google.inject.util.ToStringBuilder;
+import com.google.inject.spi.ConstructionProxyFactory;
 
 import net.sf.cglib.reflect.FastMethod;
 import net.sf.cglib.reflect.FastClass;
-import net.sf.cglib.reflect.FastConstructor;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AccessibleObject;
@@ -81,11 +82,14 @@
   private static final Map<Class<?>, Converter<?>> PRIMITIVE_CONVERTERS =
       new PrimitiveConverters();
 
+  final ConstructionProxyFactory constructionProxyFactory;
   final Map<Key<?>, Binding<?>> bindings;
 
   ErrorHandler errorHandler = new InvalidErrorHandler();
 
-  ContainerImpl(Map<Key<?>, Binding<?>> bindings) {
+  ContainerImpl(ConstructionProxyFactory constructionProxyFactory,
+      Map<Key<?>, Binding<?>> bindings) {
+    this.constructionProxyFactory = constructionProxyFactory;
     this.bindings = bindings;
   }
 
@@ -460,142 +464,6 @@
         }
       };
 
-  class ConstructorInjector<T> implements Factory<T> {
-
-    final Class<T> implementation;
-    final List<Injector> injectors;
-    final FastConstructor fastConstructor;
-    final ParameterInjector<?>[] parameterInjectors;
-
-    ConstructorInjector(ContainerImpl container, Class<T> implementation) {
-      this.implementation = implementation;
-      Constructor<T> constructor = findConstructorIn(implementation);
-      parameterInjectors = createParameterInjector(container, constructor);
-      injectors = container.injectors.get(implementation);
-      fastConstructor = FastClass.create(constructor.getDeclaringClass())
-          .getConstructor(constructor);
-    }
-
-    ParameterInjector<?>[] createParameterInjector(ContainerImpl container,
-        Constructor<T> constructor) {
-      try {
-        Inject inject = constructor.getAnnotation(Inject.class);
-        return inject == null
-            ? null // default constructor.
-            : container.getParametersInjectors(
-                constructor,
-                constructor.getParameterAnnotations(),
-                constructor.getGenericParameterTypes(),
-                inject.value()
-            );
-      } catch (MissingDependencyException e) {
-        e.handle(errorHandler);
-        return null;
-      }
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private Constructor<T> findConstructorIn(Class<T> implementation) {
-      Constructor<T> found = null;
-      for (Constructor<T> constructor
-          : implementation.getDeclaredConstructors()) {
-        if (constructor.getAnnotation(Inject.class) != null) {
-          if (found != null) {
-            errorHandler.handle(
-                ErrorMessage.TOO_MANY_CONSTRUCTORS, implementation);
-            return invalidConstructor();
-          }
-          found = constructor;
-        }
-      }
-      if (found != null) {
-        return found;
-      }
-
-      // If no annotated constructor is found, look for a no-arg constructor
-      // instead.
-      try {
-        return implementation.getDeclaredConstructor();
-      } catch (NoSuchMethodException e) {
-        errorHandler.handle(ErrorMessage.MISSING_CONSTRUCTOR, implementation);
-        return invalidConstructor();
-      }
-    }
-
-    /**
-     * Construct an instance. Returns {@code Object} instead of {@code T}
-     * because it may return a proxy.
-     */
-    Object construct(InternalContext context, Class<? super T> expectedType) {
-      ConstructionContext<T> constructionContext =
-          context.getConstructionContext(this);
-
-      // We have a circular reference between constructors. Return a proxy.
-      if (constructionContext.isConstructing()) {
-        // TODO (crazybob): if we can't proxy this object, can we proxy the
-        // other object?
-        return constructionContext.createProxy(expectedType);
-      }
-
-      // If we're re-entering this factory while injecting fields or methods,
-      // return the same instance. This prevents infinite loops.
-      T t = constructionContext.getCurrentReference();
-      if (t != null) {
-        return t;
-      }
-
-      try {
-        // First time through...
-        constructionContext.startConstruction();
-        try {
-          Object[] parameters = getParameters(context, parameterInjectors);
-          t = newInstance(parameters);
-          constructionContext.setProxyDelegates(t);
-        } finally {
-          constructionContext.finishConstruction();
-        }
-
-        // Store reference. If an injector re-enters this factory, they'll
-        // get the same reference.
-        constructionContext.setCurrentReference(t);
-
-        // Inject fields and methods.
-        if (!injectors.isEmpty()) {
-          for (Injector injector : injectors) {
-            injector.inject(context, t);
-          }
-        }
-
-        return t;
-      } catch (InvocationTargetException e) {
-        throw new RuntimeException(e);
-      } finally {
-        constructionContext.removeCurrentReference();
-      }
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private T newInstance(Object[] parameters)
-        throws InvocationTargetException {
-      return (T) fastConstructor.newInstance(parameters);
-    }
-
-    public T get() {
-      try {
-        return callInContext(new ContextualCallable<T>() {
-          @SuppressWarnings({"unchecked"})
-          public T call(InternalContext context) {
-            return (T) construct(context, implementation);
-          }
-        });
-      } catch (RuntimeException e) {
-        throw e;
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
   /**
    * A placeholder. This enables us to continue processing and gather more
    * errors but blows up if you actually try to use it.
@@ -637,7 +505,11 @@
     }
   }
 
-  private static Object[] getParameters(InternalContext context,
+  /**
+   * Iterates over parameter injectors and creates an array of parameter
+   * values.
+   */
+  static Object[] getParameters(InternalContext context,
       ParameterInjector[] parameterInjectors) {
     if (parameterInjectors == null) {
       return null;
@@ -852,4 +724,10 @@
       throw new AssertionError();
     }
   }
+
+  public String toString() {
+    return new ToStringBuilder(Container.class)
+        .add("bindings", bindings)
+        .toString();
+  }
 }
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
index da3af6c..117c5fd 100644
--- a/src/com/google/inject/TypeLiteral.java
+++ b/src/com/google/inject/TypeLiteral.java
@@ -23,7 +23,17 @@
 
 /**
  * Represents a generic type {@code T}. Java doesn't yet provide a way to
- * represent generic types, so this class does.
+ * represent generic types, so this class does. Forces clients to create a
+ * subclass of this class which enables retrieval the type information
+ * even at runtime.
+ *
+ * <p>For example, to create a {@code TypeLiteral} for {@code List<String>},
+ * you can create an empty anonymous inner class:
+ *
+ * <pre>
+ * TypeLiteral<List<String>> listOfString =
+ *   new TypeLiteral<List<String>>() {};
+ * </pre>
  *
  * <p>Assumes {@code Type} implements {@code equals()} and {@code hashCode()}
  * as a value (as opposed to identity) comparison.
diff --git a/src/com/google/inject/intercept/ProxyFactory.java b/src/com/google/inject/intercept/ProxyFactory.java
new file mode 100644
index 0000000..05ed3b2
--- /dev/null
+++ b/src/com/google/inject/intercept/ProxyFactory.java
@@ -0,0 +1,10 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.intercept;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ProxyFactory {
+
+}
diff --git a/src/com/google/inject/intercept/ProxyFactoryBuilder.java b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
new file mode 100644
index 0000000..9cd9a74
--- /dev/null
+++ b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
@@ -0,0 +1,10 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.intercept;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class ProxyFactoryBuilder {
+
+}
diff --git a/src/com/google/inject/intercept/Queries.java b/src/com/google/inject/intercept/Queries.java
index 153a712..eb08249 100644
--- a/src/com/google/inject/intercept/Queries.java
+++ b/src/com/google/inject/intercept/Queries.java
@@ -8,7 +8,7 @@
 import java.lang.reflect.AnnotatedElement;
 
 /**
- * Query implementations.
+ * Query implementations. Supports querying classes and methods.
  *
  * @author crazybob@google.com (Bob Lee)
  */
diff --git a/src/com/google/inject/package-info.java b/src/com/google/inject/package-info.java
index 60a5b7f..caecf22 100644
--- a/src/com/google/inject/package-info.java
+++ b/src/com/google/inject/package-info.java
@@ -15,16 +15,6 @@
  */
 
 /**
- * <i>Guice</i> (pronounced "juice"). A lightweight dependency injection
- * container. Features include:
- *
- * <ul>
- *   <li>constructor, method, and field injection</li>
- *   <li>static method and field injection</li>
- *   <li>circular reference support (including constructors if you depend upon
- *    interfaces)</li>
- *   <li>high performance</li>
- *   <li>externalize what needs to be and no more</li>
- * </ul>
+ * <i>Guice</i> (sounds like like "juice")
  */
 package com.google.inject;
\ No newline at end of file
diff --git a/src/com/google/inject/spi/ConstructionProxy.java b/src/com/google/inject/spi/ConstructionProxy.java
new file mode 100644
index 0000000..4f10d83
--- /dev/null
+++ b/src/com/google/inject/spi/ConstructionProxy.java
@@ -0,0 +1,19 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Proxies calls to a {@link java.lang.reflect.Constructor} for a class
+ * {@code T}.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ConstructionProxy<T> {
+
+  /**
+   * Constructs an instance of {@code T} for the given arguments.
+   */
+  T newInstance(Object... arguments) throws InvocationTargetException;
+}
diff --git a/src/com/google/inject/spi/ConstructionProxyFactory.java b/src/com/google/inject/spi/ConstructionProxyFactory.java
new file mode 100644
index 0000000..019c1d7
--- /dev/null
+++ b/src/com/google/inject/spi/ConstructionProxyFactory.java
@@ -0,0 +1,18 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Creates {@link ConstructionProxy} instances.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ConstructionProxyFactory {
+
+  /**
+   * Gets a construction proxy for the given constructor.
+   */
+  <T> ConstructionProxy<T> get(Constructor<T> constructor);
+}
diff --git a/src/com/google/inject/spi/DefaultConstructionProxyFactory.java b/src/com/google/inject/spi/DefaultConstructionProxyFactory.java
new file mode 100644
index 0000000..df72677
--- /dev/null
+++ b/src/com/google/inject/spi/DefaultConstructionProxyFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import net.sf.cglib.reflect.FastClass;
+import net.sf.cglib.reflect.FastConstructor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Default {@link ConstructionProxyFactory} implementation. Simply invokes the
+ * constructor. Can be reused by other {@code ConstructionProxyFactory}
+ * implementations.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class DefaultConstructionProxyFactory
+    implements ConstructionProxyFactory {
+
+  public <T> ConstructionProxy<T> get(Constructor<T> constructor) {
+    FastClass fastClass = FastClass.create(constructor.getDeclaringClass());
+    final FastConstructor fastConstructor =
+        fastClass.getConstructor(constructor);
+    return new ConstructionProxy<T>() {
+      @SuppressWarnings({"unchecked"})
+      public T newInstance(Object... arguments)
+          throws InvocationTargetException {
+        return (T) fastConstructor.newInstance(arguments);
+      }
+    };
+  }
+}
diff --git a/src/com/google/inject/util/ToStringBuilder.java b/src/com/google/inject/util/ToStringBuilder.java
new file mode 100644
index 0000000..39ba3b8
--- /dev/null
+++ b/src/com/google/inject/util/ToStringBuilder.java
@@ -0,0 +1,38 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.util;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * Helps with {@code toString()} methods.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class ToStringBuilder {
+
+  // Linked hash map ensures ordering.
+  final Map<String, Object> map = new LinkedHashMap<String, Object>();
+
+  final String name;
+
+  public ToStringBuilder(String name) {
+    this.name = name;
+  }
+
+  public ToStringBuilder(Class type) {
+    this.name = type.getSimpleName();
+  }
+
+  public ToStringBuilder add(String name, Object value) {
+    if (map.put(name, value) != null) {
+      throw new RuntimeException("Duplicate names: " + name);
+    }
+    return this;
+  }
+
+  public String toString() {
+    return name + map.toString();
+  }
+}
diff --git a/test/com/google/inject/PerformanceComparison.java b/test/com/google/inject/PerformanceComparison.java
index 4d1d769..2417b3e 100644
--- a/test/com/google/inject/PerformanceComparison.java
+++ b/test/com/google/inject/PerformanceComparison.java
@@ -27,6 +27,7 @@
 import org.springframework.beans.factory.support.RootBeanDefinition;
 
 import java.util.concurrent.Callable;
+import java.text.DecimalFormat;
 
 /**
  * A semi-useless microbenchmark. Spring and Guice constuct the same object
@@ -38,6 +39,22 @@
  */
 public class PerformanceComparison {
 
+  public static void main(String[] args) throws Exception {
+    // Once warm up. Takes lazy loading out of the equation and ensures we
+    // created the graphs properly.
+    validate(springFactory);
+    validate(juiceFactory);
+    validate(byHandFactory);
+
+    for (int i2 = 0; i2 < 10; i2++) {
+      iterate(springFactory, "Spring:  ");
+      iterate(juiceFactory,  "Guice:   ");
+      iterate(byHandFactory, "By Hand: ");
+
+      System.err.println();
+    }
+  }
+
   static final Callable<Foo> springFactory = new Callable<Foo>() {
 
     final DefaultListableBeanFactory beanFactory;
@@ -82,7 +99,7 @@
 
       builder.apply(new AbstractModule() {
         protected void configure() {
-          bind(Tee.class).named("tee").to(TeeImpl.class);
+          bind(Tee.class).to(TeeImpl.class);
           bind(Bar.class).to(BarImpl.class);
           bind(Foo.class);
           bind("i").to(5);
@@ -125,21 +142,7 @@
     assertEquals("test", foo.bar.getTee().getS());
   }
 
-  public static void main(String[] args) throws Exception {
-    // Once warm up. Takes lazy loading out of the equation and ensures we
-    // created the graphs properly.
-    validate(springFactory);
-    validate(juiceFactory);
-    validate(byHandFactory);
-
-    for (int i2 = 0; i2 < 10; i2++) {
-      iterate(springFactory, "Spring:  ");
-      iterate(juiceFactory,  "Guice:   ");
-      iterate(byHandFactory, "By Hand: ");
-
-      System.err.println();
-    }
-  }
+  static DecimalFormat format = new DecimalFormat();
 
   static void iterate(Callable<Foo> callable, String label) throws Exception {
     int count = 100000;
@@ -148,7 +151,8 @@
       callable.call();
     }
     time = System.currentTimeMillis() - time;
-    System.err.println(label + count * 1000 / time + " creations/s");
+    System.err.println(label
+        + format.format(count * 1000 / time) + " creations/s");
   }
 
   public static class Foo {