Refactoring binding API. Adding support for generic types.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@7 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/guice.ipr b/guice.ipr
index 503b317..e83e0f2 100644
--- a/guice.ipr
+++ b/guice.ipr
@@ -6,11 +6,11 @@
   <component name="Build editor project-level loader">
     <settings>
       <class-settings class="com.google.devtools.intellig.configcheck.ProjectPathChecker" />
+      <class-settings class="com.google.devtools.intellig.configcheck.PythonSdkChecker" />
       <class-settings class="com.google.devtools.intellig.configcheck.ProjectJdkChecker">
         <setting name="getProjectJdk" value="/usr/local/buildtools/java/jdk1.5.0_06" />
         <setting name="getModuleJdks" value="rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAABA/QAAAAAAAAHg=" />
       </class-settings>
-      <class-settings class="com.google.devtools.intellig.configcheck.PythonSdkChecker" />
       <class-settings class="com.google.devtools.intellig.configcheck.ClearOutputChecker" />
     </settings>
   </component>
@@ -248,7 +248,9 @@
           <option name="m_ignoreClassObjects" value="false" />
           <option name="m_ignorePrivateConstructors" value="false" />
         </inspection_tool>
-        <inspection_tool class="ExceptionFromCatchWhichDoesntWrap" level="WARNING" enabled="false" />
+        <inspection_tool class="ExceptionFromCatchWhichDoesntWrap" level="WARNING" enabled="false">
+          <option name="ignoreGetMessage" value="false" />
+        </inspection_tool>
         <inspection_tool class="JavaLangImport" level="WARNING" enabled="false" />
         <inspection_tool class="MethodNameSameAsParentName" level="WARNING" enabled="false" />
         <inspection_tool class="JavaLangReflect" level="WARNING" enabled="false" />
diff --git a/guice.iws b/guice.iws
index ff26e6c..daee174 100644
--- a/guice.iws
+++ b/guice.iws
@@ -18,28 +18,19 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" name="Default" comment="">
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTestSuite.java" afterPath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTestSuite.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Context.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Context.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/ContainerTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/ContainerTest.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/util/Objects.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/InternalContext.java" afterPath="$PROJECT_DIR$/src/com/google/inject/InternalContext.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" afterPath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.ipr" afterPath="$PROJECT_DIR$/guice.ipr" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceCacheTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceCacheTest.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Container.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Container.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/util/AbstractReferenceCache.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/ConstantConversionTest.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/BindingBuilder.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Key.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Key.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTest.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstantConversionException.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/util/ReferenceCache.java" afterPath="$PROJECT_DIR$/src/com/google/inject/util/ReferenceCache.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/Binding.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/KeyTest.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Inject.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Inject.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" afterPath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.ipr" afterPath="$PROJECT_DIR$/guice.ipr" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/Scope2.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Container.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Container.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iws" afterPath="$PROJECT_DIR$/guice.iws" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iml" afterPath="$PROJECT_DIR$/guice.iml" />
-      <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="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/util/FinalizableReferenceQueue.java" afterPath="$PROJECT_DIR$/src/com/google/inject/util/FinalizableReferenceQueue.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$/test/com/google/inject/ContainerTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/ContainerTest.java" />
     </list>
   </component>
   <component name="ChangeListSynchronizer" />
@@ -192,10 +183,64 @@
   </component>
   <component name="FileEditorManager">
     <leaf>
+      <file leaf-file-name="BindingBuilder.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/BindingBuilder.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="27" column="13" selection-start="893" selection-end="893" vertical-scroll-proportion="-1.7518685">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Factory.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Factory.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="32" column="4" selection-start="954" selection-end="954" vertical-scroll-proportion="0.4573991">
+              <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="668" column="23" selection-start="21542" selection-end="21542" vertical-scroll-proportion="0.3323217">
+            <state line="475" column="21" selection-start="15779" selection-end="15779" vertical-scroll-proportion="11.282511">
+              <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="23" column="13" selection-start="755" selection-end="755" vertical-scroll-proportion="0.22869955">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Scope2.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Scope2.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="21" column="17" selection-start="691" selection-end="691" vertical-scroll-proportion="0.17787743">
+              <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="404" column="0" selection-start="12663" selection-end="12663" vertical-scroll-proportion="0.025411062">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Key.java" pinned="false" current="true" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="50" column="15" selection-start="1497" selection-end="1497" vertical-scroll-proportion="-0.30343798">
               <folding>
                 <element signature="imports" expanded="true" />
               </folding>
@@ -203,11 +248,13 @@
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="ContainerTest.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/ContainerTest.java">
+      <file leaf-file-name="KeyTest.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/test/com/google/inject/KeyTest.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="173" column="0" selection-start="3359" selection-end="3477" vertical-scroll-proportion="0.46130502">
-              <folding />
+            <state line="17" column="3" selection-start="327" selection-end="327" vertical-scroll-proportion="0.43198803">
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
             </state>
           </provider>
         </entry>
@@ -215,97 +262,34 @@
       <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="46" column="0" selection-start="1597" selection-end="1597" vertical-scroll-proportion="0.6707132">
+            <state line="34" column="30" selection-start="1077" selection-end="1077" vertical-scroll-proportion="0.35575485">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="ReferenceCache.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ReferenceCache.java">
+      <file leaf-file-name="Objects.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/Objects.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="30" column="0" selection-start="984" selection-end="984" vertical-scroll-proportion="0.36267072">
+            <state line="23" column="13" selection-start="716" selection-end="716" vertical-scroll-proportion="0.22869955">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="ReferenceMap.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ReferenceMap.java">
+      <file leaf-file-name="DependencyException.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/DependencyException.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="70" column="11" selection-start="2717" selection-end="2717" vertical-scroll-proportion="0.025796661">
+            <state line="23" column="13" selection-start="736" selection-end="736" vertical-scroll-proportion="0.22869955">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="AbstractReferenceCache.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/AbstractReferenceCache.java">
+      <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="170" column="16" selection-start="4593" selection-end="4593" vertical-scroll-proportion="3.9468892">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="CancellationException.class" pinned="false" current="false" current-in-tab="false">
-        <entry file="jar:///usr/local/buildtools/java/jdk1.5.0_06/jre/lib/rt.jar!/java/util/concurrent/CancellationException.class">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="5" column="13" selection-start="158" selection-end="158" vertical-scroll-proportion="0.103186645">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="ConstantConversionTest.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/ConstantConversionTest.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="89" column="14" selection-start="2479" selection-end="2479" vertical-scroll-proportion="0.36722305">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="ReferenceMapTestSuite.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTestSuite.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="186" column="19" selection-start="5207" selection-end="5207" vertical-scroll-proportion="0.3323217">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="ReferenceCacheTest.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/util/ReferenceCacheTest.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="31" column="14" selection-start="998" selection-end="998" vertical-scroll-proportion="0.2837633">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <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="64" column="17" selection-start="1877" selection-end="1877" vertical-scroll-proportion="1.2898331">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="Key.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.0">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="ContainerBuilder.java" pinned="false" current="true" current-in-tab="true">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="356" column="34" selection-start="11446" selection-end="11446" vertical-scroll-proportion="0.22610015">
+            <state line="35" column="19" selection-start="1065" selection-end="1065" vertical-scroll-proportion="0.406577">
               <folding />
             </state>
           </provider>
@@ -467,7 +451,7 @@
       <showLibraryContents PackagesPane="false" />
       <hideEmptyPackages />
       <abbreviatePackageNames />
-      <showStructure Favorites="false" PackagesPane="false" ProjectPane="false" />
+      <showStructure Favorites="false" ProjectPane="false" Scope="false" PackagesPane="false" />
       <autoscrollToSource />
       <autoscrollFromSource />
       <sortByType />
@@ -483,8 +467,8 @@
     <property name="cvs_file_history_flatWidth1" value="457" />
     <property name="cvs_file_history_treeWidth1" value="457" />
     <property name="GoToClass.includeLibraries" value="false" />
-    <property name="MemberChooser.showClasses" value="true" />
     <property name="cvs_file_history_flatOrder2" value="2" />
+    <property name="MemberChooser.showClasses" value="true" />
     <property name="cvs_file_history_treeWidth2" value="458" />
     <property name="GoToClass.toSaveIncludeLibraries" value="false" />
     <property name="cvs_file_history_flatOrder3" value="3" />
@@ -504,12 +488,15 @@
     <option name="SHOW_DIALOG" value="false" />
   </component>
   <component name="RecentsManager">
+    <key name="MoveMembersDialog.RECENTS_KEY">
+      <recent name="com.google.inject.Key" />
+    </key>
     <key name="MoveClassesOrPackagesDialog.RECENTS_KEY">
       <recent name="com.google.inject.util" />
     </key>
   </component>
   <component name="RestoreUpdateTree">
-    <UpdateInfo date="11/20/06 4:44 PM" ActionInfo="_Update">
+    <UpdateInfo date="12/1/06 4:19 PM" ActionInfo="_Update">
       <UpdatedFiles>
         <FILE-GROUP>
           <option name="myUpdateName" value="Updated from server" />
@@ -566,8 +553,6 @@
           <option name="mySupportsDeletion" value="false" />
           <option name="myCanBeAbsent" value="false" />
           <option name="myId" value="MERGED_WITH_CONFLICTS" />
-          <PATH>$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java</PATH>
-          <PATH>$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java</PATH>
         </FILE-GROUP>
         <FILE-GROUP>
           <option name="myUpdateName" value="Merged" />
@@ -575,6 +560,7 @@
           <option name="mySupportsDeletion" value="false" />
           <option name="myCanBeAbsent" value="false" />
           <option name="myId" value="MERGED" />
+          <PATH>$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java</PATH>
         </FILE-GROUP>
         <FILE-GROUP>
           <option name="myUpdateName" value="Not in repository" />
@@ -632,25 +618,6 @@
       <option name="ENABLE_SWING_INSPECTOR" value="false" />
       <module name="" />
     </configuration>
-    <configuration default="true" type="Applet" factoryName="Applet">
-      <module name="" />
-      <option name="MAIN_CLASS_NAME" />
-      <option name="HTML_FILE_NAME" />
-      <option name="HTML_USED" value="false" />
-      <option name="WIDTH" value="400" />
-      <option name="HEIGHT" value="300" />
-      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
-      <option name="VM_PARAMETERS" />
-      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-      <option name="ALTERNATIVE_JRE_PATH" />
-    </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" />
@@ -670,8 +637,36 @@
         <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="Applet" factoryName="Applet">
+      <module name="" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="HTML_FILE_NAME" />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <option name="VM_PARAMETERS" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+    </configuration>
   </component>
-  <component name="ScopeViewComponent" />
+  <component name="ScopeViewComponent">
+    <subPane subId="Project">
+      <PATH>
+        <PATH_ELEMENT USER_OBJECT="Root">
+          <option name="myItemId" value="" />
+          <option name="myItemType" value="" />
+        </PATH_ELEMENT>
+      </PATH>
+    </subPane>
+  </component>
   <component name="SelectInManager" />
   <component name="StarteamConfiguration">
     <option name="SERVER" value="" />
@@ -724,7 +719,7 @@
     <option name="MERGE_DRY_RUN" value="false" />
     <configuration useDefault="true">/home/crazybob/.subversion</configuration>
     <remoteStatus />
-    <upgradeMode>none</upgradeMode>
+    <upgradeMode>auto</upgradeMode>
   </component>
   <component name="TodoView" selected-index="0">
     <todo-panel id="selected-file">
@@ -741,7 +736,7 @@
     </todo-panel>
   </component>
   <component name="ToolWindowManager">
-    <frame x="0" y="0" width="1920" height="1169" extended-state="6" />
+    <frame x="-4" y="0" width="1928" height="1173" extended-state="6" />
     <editor active="false" />
     <layout>
       <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
@@ -749,10 +744,10 @@
       <window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
       <window_info id="Mach" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32919848" order="9" />
       <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="7" />
-      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.1475147" order="0" />
+      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.15927312" order="0" />
       <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.29580152" order="1" />
       <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.16236559" order="1" />
-      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.35496184" order="10" />
+      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.28053436" order="10" />
       <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="6" />
       <window_info id="Profile" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32911393" order="13" />
       <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
@@ -766,7 +761,7 @@
       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39978448" order="0" />
       <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3265306" order="4" />
       <window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" />
-      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.34541985" order="12" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.34541985" order="12" />
       <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="0" />
       <window_info id="Favorites" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="4" />
       <window_info id="Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="5" />
@@ -790,7 +785,7 @@
     <option name="PERFORM_COMMIT_IN_BACKGROUND" value="false" />
     <option name="PUT_FOCUS_INTO_COMMENT" value="false" />
     <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
-    <option name="LAST_COMMIT_MESSAGE" value="Added type conversion for constants. Optimized ReferenceCache. &#10;&#10;Removed null check from ContainerImpl.getInstance(). Added Container.hasBindingFor() to provide comparable functionality.&#10;&#10;Made Key public." />
+    <option name="LAST_COMMIT_MESSAGE" value="Refactoring binding API. Adding support for generic types." />
     <option name="SAVE_LAST_COMMIT_MESSAGE" value="true" />
     <option name="CHECKIN_DIALOG_SPLITTER_PROPORTION" value="0.8" />
     <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
@@ -798,12 +793,13 @@
     <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
     <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
     <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
-    <option name="ERROR_OCCURED" value="false" />
+    <option name="ERROR_OCCURED" value="true" />
     <option name="ACTIVE_VCS_NAME" value="svn" />
     <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
     <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
     <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
     <MESSAGE value="Added type conversion for constants. Optimized ReferenceCache. &#10;&#10;Removed null check from ContainerImpl.getInstance(). Added Container.hasBindingFor() to provide comparable functionality.&#10;&#10;Made Key public." />
+    <MESSAGE value="Refactoring binding API. Adding support for generic types." />
   </component>
   <component name="VssConfiguration">
     <option name="CLIENT_PATH" value="" />
@@ -852,117 +848,119 @@
     <option name="myPlainMode" value="false" />
     <option name="myLastEditedConfigurable" />
   </component>
-  <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="0.16666667,0.5642857" version="1">
-    <option name="myLastEditedConfigurable" value="EditorHightlightingSettings" />
+  <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="0.16666667,0.60142857" version="1">
+    <option name="myLastEditedConfigurable" value="Default" />
   </component>
   <component name="editorHistoryManager">
-    <entry file="file:///usr/local/client/2/google3/java/com/google/inject/ContainerBuilder.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="478" column="0" selection-start="52" selection-end="14738" vertical-scroll-proportion="0.94917786">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file:///usr/local/client/2/google3/java/com/google/inject/ContainerImpl.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="2" column="2" selection-start="0" selection-end="21417" vertical-scroll-proportion="0.050822124">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="14" column="3" selection-start="595" selection-end="595" 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="46" column="0" selection-start="1597" selection-end="1597" vertical-scroll-proportion="0.6707132">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/util/ReferenceCacheTest.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="31" column="14" selection-start="998" selection-end="998" vertical-scroll-proportion="0.2837633">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="jar:///usr/local/buildtools/java/jdk1.5.0_06/jre/lib/rt.jar!/java/util/concurrent/CancellationException.class">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="5" column="13" selection-start="158" selection-end="158" vertical-scroll-proportion="0.103186645">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ReferenceMap.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="70" column="11" selection-start="2717" selection-end="2717" vertical-scroll-proportion="0.025796661">
-          <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="89" column="14" selection-start="2479" selection-end="2479" vertical-scroll-proportion="0.36722305">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ReferenceCache.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="30" column="0" selection-start="984" selection-end="984" vertical-scroll-proportion="0.36267072">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/AbstractReferenceCache.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="170" column="16" selection-start="4593" selection-end="4593" vertical-scroll-proportion="3.9468892">
-          <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="64" column="17" selection-start="1877" selection-end="1877" vertical-scroll-proportion="1.2898331">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="668" column="23" selection-start="21542" selection-end="21542" vertical-scroll-proportion="0.3323217">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
     <entry file="file://$PROJECT_DIR$/test/com/google/inject/ContainerTest.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="173" column="0" selection-start="3359" selection-end="3477" vertical-scroll-proportion="0.46130502">
+        <state line="173" column="0" selection-start="3359" selection-end="3477" vertical-scroll-proportion="0.9361111">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/test/com/google/inject/util/ReferenceMapTestSuite.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Context.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="186" column="19" selection-start="5207" selection-end="5207" vertical-scroll-proportion="0.3323217">
+        <state line="25" column="17" selection-start="765" selection-end="765" vertical-scroll-proportion="0.10277778">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Factory.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="32" column="4" selection-start="954" selection-end="954" vertical-scroll-proportion="0.4573991">
           <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="356" column="34" selection-start="11446" selection-end="11446" vertical-scroll-proportion="0.22610015">
+        <state line="404" column="0" selection-start="12663" selection-end="12663" vertical-scroll-proportion="0.025411062">
           <folding />
         </state>
       </provider>
     </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/Objects.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="23" column="13" selection-start="716" selection-end="716" vertical-scroll-proportion="0.22869955">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/DependencyException.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="23" column="13" selection-start="736" selection-end="736" vertical-scroll-proportion="0.22869955">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="35" column="19" selection-start="1065" selection-end="1065" vertical-scroll-proportion="0.406577">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="475" column="21" selection-start="15779" selection-end="15779" vertical-scroll-proportion="11.282511">
+          <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="34" column="30" selection-start="1077" selection-end="1077" vertical-scroll-proportion="0.35575485">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/KeyTest.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="17" column="3" selection-start="327" selection-end="327" vertical-scroll-proportion="0.43198803">
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="jar:///usr/local/buildtools/java/jdk1.5.0_06/jre/lib/rt.jar!/java/util/Arrays.class">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="216" column="41" selection-start="9391" selection-end="9399" vertical-scroll-proportion="0.33333334">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Scope2.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="21" column="17" selection-start="691" selection-end="691" vertical-scroll-proportion="0.17787743">
+          <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="23" column="13" selection-start="755" selection-end="755" vertical-scroll-proportion="0.22869955">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/BindingBuilder.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="27" column="13" selection-start="893" selection-end="893" vertical-scroll-proportion="-1.7518685">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="50" column="15" selection-start="1497" selection-end="1497" vertical-scroll-proportion="-0.30343798">
+          <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
new file mode 100644
index 0000000..ac5c060
--- /dev/null
+++ b/src/com/google/inject/Binding.java
@@ -0,0 +1,27 @@
+/**
+ * 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;
+
+/**
+ * Binds an interface with a name to a scope and implementation.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class Binding<T> {
+
+
+}
diff --git a/src/com/google/inject/BindingBuilder.java b/src/com/google/inject/BindingBuilder.java
new file mode 100644
index 0000000..b20acc2
--- /dev/null
+++ b/src/com/google/inject/BindingBuilder.java
@@ -0,0 +1,151 @@
+/**
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builds a binding from a type and optional name to a given implementation
+ * in a given scope. Uses the given type as the implementation by default.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class BindingBuilder<T> {
+
+  final Key<T> key;
+  String source;
+  InternalFactory<? extends T> factory;
+  Factory<? extends T> externalFactory;
+  final List<Key<? super T>> exportKeys = new ArrayList<Key<? super T>>();
+
+  /**
+   * Creates a new binding for the given key.
+   */
+  public BindingBuilder(Key<T> key) {
+    this.key = key;
+  }
+
+  /**
+   * Exports this binding.
+   */
+  public BindingBuilder exportBinding() {
+    return exportBinding(this.key);
+  }
+
+  /**
+   * Exports this binding with the given key.
+   */
+  public BindingBuilder exportBinding(Key<? super T> exportKey) {
+    this.exportKeys.add(exportKey);
+    return this;
+  }
+
+  /**
+   * Sets the implementation to the given class.
+   */
+  public <I extends T> BindingBuilder implementation(
+      final Class<I> implementation) {
+    ensureImplementationIsNotSet();
+    this.factory = new DefaultFactory<I>(implementation);
+    return this;
+  }
+
+  /**
+   * Uses the given factory to create instances of the implementation.
+   */
+  public BindingBuilder factory(final Factory<? extends T> factory) {
+    ensureImplementationIsNotSet();
+
+    this.externalFactory = factory;
+
+    this.factory = new InternalFactory<T>() {
+      public T create(InternalContext context) {
+        try {
+          Context externalContext = context.getExternalContext();
+          return factory.create(externalContext);
+        } catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+      }
+
+      public String toString() {
+        return factory.toString();
+      }
+    };
+
+    return this;
+  }
+
+  private <I extends T> void ensureImplementationIsNotSet() {
+    if (factory != null) {
+      throw new IllegalStateException("An implementation is already set.");
+    }
+  }
+
+  /**
+   * Specifies the scope.
+   */
+  public BindingBuilder scope(Scope scope) {
+    if (scope != null) {
+      throw new IllegalStateException("Scope is already set.");
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the source string. Useful for debugging. Contents may include the
+   * name of the file and the line number this binding came from, a code
+   * snippet, etc.
+   */
+  public BindingBuilder source(String source) {
+    if (source != null) {
+      throw new IllegalStateException("Source is already set.");
+    }
+
+    this.source = source;
+    return this;
+  }
+
+  /**
+   * Injects new instances of the specified implementation class.
+   */
+  private class DefaultFactory<I extends T> implements InternalFactory<I> {
+
+    volatile ContainerImpl.ConstructorInjector<I> constructor;
+
+    private final Class<I> implementation;
+
+    public DefaultFactory(Class<I> implementation) {
+      this.implementation = implementation;
+    }
+
+    @SuppressWarnings("unchecked")
+      public I create(InternalContext context) {
+      if (constructor == null) {
+        this.constructor =
+            context.getContainerImpl().getConstructor(implementation);
+      }
+      return (I) constructor.construct(context, key.getType());
+    }
+
+    public String toString() {
+      return implementation.toString();
+    }
+  }
+}
diff --git a/src/com/google/inject/Container.java b/src/com/google/inject/Container.java
index 08c2ffb..24a4d48 100644
--- a/src/com/google/inject/Container.java
+++ b/src/com/google/inject/Container.java
@@ -65,11 +65,6 @@
 public interface Container {
 
   /**
-   * Default dependency name.
-   */
-  String DEFAULT_NAME = "default";
-
-  /**
    * Injects dependencies into the fields and methods of an existing object.
    */
   void inject(Object o);
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index 5aca155..5480729 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -73,11 +73,11 @@
    */
   public ContainerBuilder() {
     // In the current container as the default Container implementation.
-    factories.put(Key.newInstance(Container.class, Container.DEFAULT_NAME),
+    factories.put(Key.newInstance(Container.class, Key.DEFAULT_NAME),
         CONTAINER_FACTORY);
 
     // Inject the logger for the injected member's declaring class.
-    factories.put(Key.newInstance(Logger.class, Container.DEFAULT_NAME),
+    factories.put(Key.newInstance(Logger.class, Key.DEFAULT_NAME),
         LOGGER_FACTORY);
   }
 
@@ -161,7 +161,7 @@
    */
   public <T> ContainerBuilder factory(Class<T> type,
       Factory<? extends T> factory, Scope scope) {
-    return factory(type, Container.DEFAULT_NAME, factory, scope);
+    return factory(type, Key.DEFAULT_NAME, factory, scope);
   }
 
   /**
@@ -183,7 +183,7 @@
    */
   public <T> ContainerBuilder factory(Class<T> type,
       Factory<? extends T> factory) {
-    return factory(type, Container.DEFAULT_NAME, factory, Scope.DEFAULT);
+    return factory(type, Key.DEFAULT_NAME, factory, Scope.DEFAULT);
   }
 
   /**
@@ -255,7 +255,7 @@
    */
   public <T> ContainerBuilder factory(Class<T> type,
       Class<? extends T> implementation) {
-    return factory(type, Container.DEFAULT_NAME, implementation);
+    return factory(type, Key.DEFAULT_NAME, implementation);
   }
 
   /**
@@ -265,7 +265,7 @@
    * @see #factory(Class, String, Class)
    */
   public <T> ContainerBuilder factory(Class<T> type) {
-    return factory(type, Container.DEFAULT_NAME, type);
+    return factory(type, Key.DEFAULT_NAME, type);
   }
 
   /**
@@ -285,7 +285,7 @@
    */
   public <T> ContainerBuilder factory(Class<T> type,
       Class<? extends T> implementation, Scope scope) {
-    return factory(type, Container.DEFAULT_NAME, implementation, scope);
+    return factory(type, Key.DEFAULT_NAME, implementation, scope);
   }
 
   /**
@@ -295,7 +295,7 @@
    * @see #factory(Class, String, Class, Scope)
    */
   public <T> ContainerBuilder factory(Class<T> type, Scope scope) {
-    return factory(type, Container.DEFAULT_NAME, type, scope);
+    return factory(type, Key.DEFAULT_NAME, type, scope);
   }
 
   /**
@@ -335,7 +335,7 @@
    * @see #alias(Class, String, String)
    */
   public <T> ContainerBuilder alias(Class<T> type, String alias) {
-    return alias(type, Container.DEFAULT_NAME, alias);
+    return alias(type, Key.DEFAULT_NAME, alias);
   }
 
   /**
@@ -473,7 +473,7 @@
    * Container.DEFAULT_NAME)}.
    */
   public boolean contains(Class<?> type) {
-    return contains(type, Container.DEFAULT_NAME);
+    return contains(type, Key.DEFAULT_NAME);
   }
 
   /**
diff --git a/src/com/google/inject/ContainerImpl.java b/src/com/google/inject/ContainerImpl.java
index c6e967a..a4fba2c 100644
--- a/src/com/google/inject/ContainerImpl.java
+++ b/src/com/google/inject/ContainerImpl.java
@@ -520,7 +520,7 @@
   }
 
   <T> T getInstance(Class<T> type, InternalContext context) {
-    return getInstance(type, DEFAULT_NAME, context);
+    return getInstance(type, Key.DEFAULT_NAME, context);
   }
 
   public boolean hasBindingFor(Key<?> key) {
diff --git a/src/com/google/inject/Inject.java b/src/com/google/inject/Inject.java
index 86a9b2b..ea04dbf 100644
--- a/src/com/google/inject/Inject.java
+++ b/src/com/google/inject/Inject.java
@@ -16,8 +16,6 @@
 
 package com.google.inject;
 
-import static com.google.inject.Container.*;
-
 import static java.lang.annotation.ElementType.*;
 import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.*;
@@ -34,9 +32,9 @@
 public @interface Inject {
 
   /**
-   * Dependency name. Defaults to {@link Container#DEFAULT_NAME}.
+   * Dependency name. Defaults to {@link Key#DEFAULT_NAME}.
    */
-  String value() default DEFAULT_NAME;
+  String value() default Key.DEFAULT_NAME;
 
   /**
    * Whether or not injection is required. Applicable only to methods and
diff --git a/src/com/google/inject/Key.java b/src/com/google/inject/Key.java
index 239c86f..746dbc9 100644
--- a/src/com/google/inject/Key.java
+++ b/src/com/google/inject/Key.java
@@ -18,22 +18,60 @@
 
 import static com.google.inject.util.Objects.nonNull;
 
+import java.lang.reflect.Type;
+import java.lang.reflect.ParameterizedType;
+
 /**
- * Binding key. Uniquely identified by the type and name.
+ * Binding key. Composed of the type to be injected and a name.
  *
  * @author crazybob@google.com (Bob Lee)
  */
-public class Key<T> {
+public abstract class Key<T> {
+
+  /**
+   * Default dependency name.
+   */
+  public static final String DEFAULT_NAME = "default";
 
   final Class<T> type;
+  final Type[] typeArguments;
   final String name;
   final int hashCode;
 
+  protected Key(String name) {
+    this.name = nonNull(name, "name");
+
+    Type superclass = getClass().getGenericSuperclass();
+    if (superclass instanceof Class) {
+      throw new RuntimeException("Missing type parameter.");
+    }
+    Type type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
+    if (type instanceof Class<?>) {
+      this.type = (Class<T>) type;
+      this.typeArguments = null;
+    } else {
+      ParameterizedType parameterizedType = (ParameterizedType) type;
+      this.type = (Class<T>) parameterizedType.getRawType();
+      this.typeArguments = parameterizedType.getActualTypeArguments();
+    }
+
+    this.hashCode = computeHashCode();
+  }
+
+  protected Key() {
+    this(DEFAULT_NAME);
+  }
+
   private Key(Class<T> type, String name) {
     this.type = nonNull(type, "type");
     this.name = nonNull(name, "name");
+    this.typeArguments = null;
 
-    hashCode = type.hashCode() * 31 + name.hashCode();
+    this.hashCode = computeHashCode();
+  }
+
+  private int computeHashCode() {
+    return type.hashCode() * 31 + name.hashCode();
   }
 
   Class<T> getType() {
@@ -63,7 +101,17 @@
     return "[type=" + type.getName() + ", name='" + name + "']";
   }
 
+  /**
+   * Constructs a key from a raw type.
+   */
+  public static <T> Key<T> newInstance(Class<T> type) {
+    return new Key<T>(type, DEFAULT_NAME) {};
+  }
+
+  /**
+   * Constructs a key from a raw type and a name.
+   */
   public static <T> Key<T> newInstance(Class<T> type, String name) {
-    return new Key<T>(type, name);
+    return new Key<T>(type, name) {};
   }
 }
diff --git a/src/com/google/inject/Scope2.java b/src/com/google/inject/Scope2.java
new file mode 100644
index 0000000..010f9e4
--- /dev/null
+++ b/src/com/google/inject/Scope2.java
@@ -0,0 +1,25 @@
+/**
+ * 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;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Scope2 {
+
+  <T> Factory<T> scope(Binding<T> binding);
+}
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index 70367d9..0e5123f 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -32,6 +32,7 @@
   public static Test suite() {
     TestSuite suite = new TestSuite();
 
+    suite.addTestSuite(KeyTest.class);
     suite.addTestSuite(ConstantConversionTest.class);
     suite.addTestSuite(ContainerTest.class);
     suite.addTestSuite(CircularDependencyTest.class);
diff --git a/test/com/google/inject/ContainerTest.java b/test/com/google/inject/ContainerTest.java
index 8b2d0ae..c4c38a5 100644
--- a/test/com/google/inject/ContainerTest.java
+++ b/test/com/google/inject/ContainerTest.java
@@ -53,7 +53,7 @@
   public void testGetInstance() {
     Container container = createFooContainer();
 
-    Bar bar = container.getInstance(Bar.class, Container.DEFAULT_NAME);
+    Bar bar = container.getInstance(Bar.class, Key.DEFAULT_NAME);
     assertEquals("test", bar.getTee().getS());
     assertEquals(5, bar.getI());
   }
diff --git a/test/com/google/inject/KeyTest.java b/test/com/google/inject/KeyTest.java
new file mode 100644
index 0000000..c7e11cf
--- /dev/null
+++ b/test/com/google/inject/KeyTest.java
@@ -0,0 +1,19 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class KeyTest extends TestCase {
+
+  void foo(List<String> a, List<String> b) {}
+
+  public void testParameterizedTypeEquality() {
+
+  }
+}