Finished interception framework. Added Container.findBindingsByType().

git-svn-id: https://google-guice.googlecode.com/svn/trunk@65 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/build.xml b/build.xml
index 10b725a..5ff7927 100644
--- a/build.xml
+++ b/build.xml
@@ -93,6 +93,7 @@
         <pathelement location="${src.dir}"/>
       </sourcepath>
       <classpath refid="compile.classpath"/>
+      <link href="http://aopalliance.sourceforge.net/doc"/>
     </javadoc>
   </target>
 
diff --git a/guice.iws b/guice.iws
index 4730906..a8a9a06 100644
--- a/guice.iws
+++ b/guice.iws
@@ -18,14 +18,27 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" name="Default" comment="">
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/lib/aopalliance.jar" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iml" afterPath="$PROJECT_DIR$/guice.iml" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.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="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ErrorMessages.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ErrorMessages.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/package-info.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/util/package-info.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$/lib/aopalliance.jar" />
+      <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/ContainerCreationException.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerCreationException.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iws" afterPath="$PROJECT_DIR$/guice.iws" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.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$/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="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/package-info.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/IntegrationTest.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java" />
     </list>
   </component>
   <component name="ChangeListSynchronizer" />
@@ -195,19 +208,10 @@
   </component>
   <component name="FileEditorManager">
     <leaf>
-      <file leaf-file-name="Message.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/Message.java">
+      <file leaf-file-name="IntegrationTest.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/IntegrationTest.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="45" column="3" selection-start="1286" selection-end="1286" vertical-scroll-proportion="0.8541329">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <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="148" column="48" selection-start="5256" selection-end="5256" vertical-scroll-proportion="0.48460293">
+            <state line="15" column="0" selection-start="596" selection-end="596" vertical-scroll-proportion="0.4132901">
               <folding>
                 <element signature="imports" expanded="true" />
               </folding>
@@ -215,22 +219,65 @@
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="FastClass.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/reflect/FastClass.java">
+      <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="38" column="0" selection-start="1207" selection-end="1207" vertical-scroll-proportion="0.33225283">
+            <state line="32" column="13" selection-start="1115" selection-end="1115" vertical-scroll-proportion="0.24797407">
               <folding />
             </state>
           </provider>
         </entry>
       </file>
-      <file leaf-file-name="ProxyFactoryTest.java" pinned="false" current="true" current-in-tab="true">
-        <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.java">
+      <file leaf-file-name="package-info.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/package-info.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="23" column="7" selection-start="654" selection-end="654" vertical-scroll-proportion="0.6337115">
-              <folding>
-                <element signature="imports" expanded="true" />
-              </folding>
+            <state line="17" column="3" selection-start="604" selection-end="604" vertical-scroll-proportion="0.46839547">
+              <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="0" column="0" selection-start="0" selection-end="674" vertical-scroll-proportion="0.0">
+              <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/intercept/package-info.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="23" column="28" selection-start="863" selection-end="863" vertical-scroll-proportion="0.6337115">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <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="65" column="15" selection-start="1732" selection-end="1732" vertical-scroll-proportion="1.4051864">
+              <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="57" column="3" selection-start="1894" selection-end="1894" vertical-scroll-proportion="-5.593193">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Exception.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="jar:///usr/local/src.zip!/java/lang/Exception.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="39" column="11" selection-start="1206" selection-end="1206" vertical-scroll-proportion="0.910859">
+              <folding />
             </state>
           </provider>
         </entry>
@@ -247,7 +294,7 @@
       <file leaf-file-name="InterceptorStackCallback.java" pinned="false" current="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="23" column="9" selection-start="596" selection-end="596" vertical-scroll-proportion="0.016207455">
+            <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
               <folding />
             </state>
           </provider>
@@ -301,7 +348,7 @@
       <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="39" column="36" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.68881685">
+            <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.0">
               <folding>
                 <element signature="imports" expanded="true" />
               </folding>
@@ -321,16 +368,7 @@
       <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">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="34" column="13" selection-start="1234" selection-end="1234" vertical-scroll-proportion="0.24797407">
-              <folding />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file leaf-file-name="MethodAspect.java" pinned="false" current="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java">
-          <provider selected="true" editor-type-id="text-editor">
-            <state line="25" column="22" selection-start="735" selection-end="735" vertical-scroll-proportion="0.68881685">
+            <state line="20" column="0" selection-start="689" selection-end="689" vertical-scroll-proportion="0.16531605">
               <folding>
                 <element signature="imports" expanded="true" />
               </folding>
@@ -338,15 +376,93 @@
           </provider>
         </entry>
       </file>
+      <file leaf-file-name="MethodAspect.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ProxyFactoryTest.java" pinned="false" current="true" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
+              <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="28" column="13" selection-start="889" selection-end="889" vertical-scroll-proportion="0.30307943">
+            <state line="101" column="28" selection-start="2794" selection-end="2794" vertical-scroll-proportion="0.8265802">
               <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="100" column="23" selection-start="2670" selection-end="2670" vertical-scroll-proportion="1.4764992">
+              <folding>
+                <element signature="imports" expanded="true" />
+              </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="0" column="0" selection-start="0" selection-end="595" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="guice.iws" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/guice.iws">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="938" column="195" selection-start="47825" selection-end="47825" vertical-scroll-proportion="0.3936877">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ErrorHandler.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ErrorHandler.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="33" column="0" selection-start="841" selection-end="841" vertical-scroll-proportion="0.5235008">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="AbstractErrorHandler.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractErrorHandler.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="32" column="0" selection-start="1032" selection-end="1032" vertical-scroll-proportion="0.38573745">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="ErrorMessages.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/com/google/inject/ErrorMessages.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="42" column="25" selection-start="1437" selection-end="1437" vertical-scroll-proportion="0.7714749">
+              <folding>
+                <element signature="imports" expanded="true" />
+              </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">
@@ -660,16 +776,16 @@
     </key>
   </component>
   <component name="RestoreUpdateTree" />
-  <component name="RunManager" selected="JUnit.ProxyFactoryTest.testSimpleCase">
-    <tempConfiguration default="false" name="ProxyFactoryTest.testSimpleCase" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
+  <component name="RunManager" selected="JUnit.AllTests">
+    <tempConfiguration default="false" name="IntegrationTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
       <pattern value="com.google.inject.intercept.*" />
       <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.ProxyFactoryTest" />
-      <option name="METHOD_NAME" value="testSimpleCase" />
-      <option name="TEST_OBJECT" value="method" />
+      <option name="MAIN_CLASS_NAME" value="com.google.inject.intercept.IntegrationTest" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
       <option name="VM_PARAMETERS" />
       <option name="PARAMETERS" />
       <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
@@ -762,7 +878,13 @@
       <option name="ALTERNATIVE_JRE_PATH" />
       <option name="ENABLE_SWING_INSPECTOR" value="false" />
       <module name="guice" />
+      <RunnerSettings RunnerId="Debug">
+        <option name="DEBUG_PORT" value="37148" />
+        <option name="TRANSPORT" value="0" />
+        <option name="LOCAL" value="true" />
+      </RunnerSettings>
       <RunnerSettings RunnerId="Run" />
+      <ConfigurationWrapper RunnerId="Debug" />
       <ConfigurationWrapper RunnerId="Run" />
       <method>
         <option name="Make" value="true" />
@@ -871,7 +993,7 @@
   </component>
   <component name="ToolWindowManager">
     <frame x="4" y="44" width="1916" height="1156" extended-state="0" />
-    <editor active="true" />
+    <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" />
       <window_info id="CVS" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" />
@@ -881,7 +1003,7 @@
       <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.15854311" order="0" />
       <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.29517502" 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="false" weight="0.27909178" order="10" />
+      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.47492903" 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.32890996" 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" />
@@ -889,7 +1011,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.40018922" order="2" />
+      <window_info id="Run" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.40018922" 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" />
@@ -988,51 +1110,83 @@
     <option name="myLastEditedConfigurable" value="Default" />
   </component>
   <component name="editorHistoryManager">
-    <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/core/ReflectUtils.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="344" column="23" selection-start="13257" selection-end="13257" vertical-scroll-proportion="0.5656402">
+        <state line="101" column="28" selection-start="2794" selection-end="2794" vertical-scroll-proportion="0.8265802">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/core/DuplicatesPredicate.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractErrorHandler.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="20" column="13" selection-start="712" selection-end="712" vertical-scroll-proportion="0.13776337">
+        <state line="32" column="0" selection-start="1032" selection-end="1032" vertical-scroll-proportion="0.38573745">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/Message.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ErrorHandler.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="45" column="3" selection-start="1286" selection-end="1286" vertical-scroll-proportion="0.8541329">
+        <state line="33" column="0" selection-start="841" selection-end="841" vertical-scroll-proportion="0.5235008">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/aopalliance.jar!/org/aopalliance/intercept/Joinpoint.class">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ErrorMessages.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="11" column="37" selection-start="313" selection-end="313" vertical-scroll-proportion="0.27552673">
+        <state line="42" column="25" selection-start="1437" selection-end="1437" vertical-scroll-proportion="0.7714749">
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/ErrorHandlingTest.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="65" column="15" selection-start="1732" selection-end="1732" vertical-scroll-proportion="1.4051864">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/proxy/MethodProxy.java">
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/AllTests.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="164" column="18" selection-start="6352" selection-end="6352" vertical-scroll-proportion="1.3111831">
+        <state line="32" column="13" selection-start="1115" selection-end="1115" vertical-scroll-proportion="0.24797407">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="26" column="17" selection-start="837" selection-end="837" vertical-scroll-proportion="0.3306321">
+        <state line="57" column="3" selection-start="1894" selection-end="1894" vertical-scroll-proportion="-5.593193">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java">
+    <entry file="file://$PROJECT_DIR$/src/com/google/inject/Container.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="46" column="0" selection-start="1116" selection-end="1602" vertical-scroll-proportion="0.88168555">
+        <state line="100" column="23" selection-start="2670" selection-end="2670" vertical-scroll-proportion="1.4764992">
+          <folding>
+            <element signature="imports" expanded="true" />
+          </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="0" column="0" selection-start="0" selection-end="595" vertical-scroll-proportion="0.0">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/guice.iws">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="938" column="195" selection-start="47825" selection-end="47825" vertical-scroll-proportion="0.3936877">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/IntegrationTest.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="15" column="0" selection-start="596" selection-end="596" vertical-scroll-proportion="0.4132901">
           <folding>
             <element signature="imports" expanded="true" />
           </folding>
@@ -1041,53 +1195,23 @@
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="23" column="9" selection-start="596" selection-end="596" vertical-scroll-proportion="0.016207455">
+        <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
           <folding />
         </state>
       </provider>
     </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/aopalliance.jar!/org/aopalliance/intercept/MethodInterceptor.class">
+    <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="5" column="17" selection-start="167" selection-end="167" vertical-scroll-proportion="0.110210694">
-          <folding />
+        <state line="20" column="0" selection-start="689" selection-end="689" vertical-scroll-proportion="0.16531605">
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/MethodAspect.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="25" column="22" selection-start="735" selection-end="735" vertical-scroll-proportion="0.68881685">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="39" column="36" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.68881685">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/proxy/Enhancer.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="589" column="23" selection-start="26039" selection-end="26039" vertical-scroll-proportion="0.33225283">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/reflect/FastClass.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="38" column="0" selection-start="1207" selection-end="1207" vertical-scroll-proportion="0.33225283">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="148" column="48" selection-start="5256" selection-end="5256" vertical-scroll-proportion="0.48460293">
+        <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
           <folding>
             <element signature="imports" expanded="true" />
           </folding>
@@ -1096,10 +1220,8 @@
     </entry>
     <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/ProxyFactoryTest.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="23" column="7" selection-start="654" selection-end="654" vertical-scroll-proportion="0.6337115">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
+        <state line="14" column="3" selection-start="595" selection-end="595" vertical-scroll-proportion="0.38573745">
+          <folding />
         </state>
       </provider>
     </entry>
diff --git a/src/com/google/inject/Container.java b/src/com/google/inject/Container.java
index bff966c..19e78ee 100644
--- a/src/com/google/inject/Container.java
+++ b/src/com/google/inject/Container.java
@@ -17,6 +17,7 @@
 package com.google.inject;
 
 import java.util.Map;
+import java.util.List;
 
 /**
  * Injects dependencies into constructors, methods and fields annotated with
@@ -93,4 +94,9 @@
    * Gets a binding for the given key.
    */
   <T> Binding<T> getBinding(Key<T> key);
+
+  /**
+   * Finds all bindings to the given type.
+   */
+  <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type);
 }
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index 2b41a15..186060a 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -315,6 +315,8 @@
     createBindings(preload, preloaders);
     createLinkedBindings();
 
+    container.index();
+
     stopwatch.resetAndLog(logger, "Binding creation");
 
     // Run validations.
diff --git a/src/com/google/inject/ContainerCreationException.java b/src/com/google/inject/ContainerCreationException.java
index 61e67ab..ce71c04 100644
--- a/src/com/google/inject/ContainerCreationException.java
+++ b/src/com/google/inject/ContainerCreationException.java
@@ -36,10 +36,14 @@
    * Constructs a new exception for the given errors.
    */
   public ContainerCreationException(Collection<Message> errorMessages) {
-    super(createErrorMessage(errorMessages));
+    super();
     this.errorMessages = errorMessages;
   }
 
+  public String getMessage() {
+    return createErrorMessage(errorMessages);
+  }
+
   private static String createErrorMessage(Collection<Message> errorMessages) {
     StringBuilder error = new StringBuilder();
     error.append("Guice configuration errors:\n\n");
diff --git a/src/com/google/inject/ContainerImpl.java b/src/com/google/inject/ContainerImpl.java
index 781853d..c0720e3 100644
--- a/src/com/google/inject/ContainerImpl.java
+++ b/src/com/google/inject/ContainerImpl.java
@@ -84,6 +84,8 @@
 
   final ConstructionProxyFactory constructionProxyFactory;
   final Map<Key<?>, Binding<?>> bindings;
+  final Map<TypeLiteral<?>, List<Binding<?>>> bindingsByType =
+      new HashMap<TypeLiteral<?>, List<Binding<?>>>();
 
   ErrorHandler errorHandler = new InvalidErrorHandler();
 
@@ -93,6 +95,42 @@
     this.bindings = bindings;
   }
 
+  /**
+   * Indexes bindings by type.
+   */
+  void index() {
+    for (Binding<?> binding : bindings.values()) {
+      index(binding);
+    }
+  }
+
+  <T> void index(Binding<T> binding) {
+    TypeLiteral<T> type = binding.getKey().getType();
+    List<Binding<?>> bindings = bindingsByType.get(type);
+    if (bindings == null) {
+      bindings = new ArrayList<Binding<?>>();
+      bindingsByType.put(type, bindings);
+    }
+    bindings.add(binding);
+  }
+
+  @SuppressWarnings({"unchecked"})
+  public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
+    List bindings = bindingsByType.get(type);
+    if (bindings == null) {
+      return Collections.emptyList();
+    }
+    return (List<Binding<T>>) bindings;
+  }
+
+  <T> List<String> getNamesOfBindingsTo(TypeLiteral<T> type) {
+    List<String> names = new ArrayList<String>();
+    for (Binding<T> binding : findBindingsByType(type)) {
+      names.add(binding.getKey().getName());
+    }
+    return names;
+  }
+
   void withErrorHandler(ErrorHandler errorHandler, Runnable runnable) {
     ErrorHandler previous = this.errorHandler;
     this.errorHandler = errorHandler;
@@ -135,7 +173,8 @@
           }
         };
       } catch (ConfigurationException e) {
-        errorHandler.handle(ErrorMessages.MISSING_BINDING, member, key);
+        ErrorMessages.handleMissingBinding(errorHandler, member, key,
+            getNamesOfBindingsTo(key.getType()));
         return invalidFactory();
       }
     }
@@ -312,7 +351,7 @@
     return Modifier.isStatic(member.getModifiers());
   }
 
-  static class FieldInjector implements Injector {
+  class FieldInjector implements Injector {
 
     final Field field;
     final InternalFactory<?> factory;
@@ -614,7 +653,7 @@
     void inject(InternalContext context, Object o);
   }
 
-  static class MissingDependencyException extends Exception {
+  class MissingDependencyException extends Exception {
 
     final Key<?> key;
     final Member member;
@@ -625,7 +664,8 @@
     }
 
     void handle(ErrorHandler errorHandler) {
-      errorHandler.handle(ErrorMessages.MISSING_BINDING, member, key);
+      ErrorMessages.handleMissingBinding(errorHandler, member, key,
+          getNamesOfBindingsTo(key.getType()));
     }
   }
 
diff --git a/src/com/google/inject/ErrorMessages.java b/src/com/google/inject/ErrorMessages.java
index 38d2761..b670bea 100644
--- a/src/com/google/inject/ErrorMessages.java
+++ b/src/com/google/inject/ErrorMessages.java
@@ -16,6 +16,9 @@
 
 package com.google.inject;
 
+import java.lang.reflect.Member;
+import java.util.List;
+
 /**
  * Error message templates.
  *
@@ -23,8 +26,23 @@
  */
 class ErrorMessages {
 
-  static final String MISSING_BINDING =
-      "Binding to %2$s not found, but %1$s requires it.";
+  private static final String MISSING_BINDING =
+      "Binding to %s not found, but %s requires it. No bindings to that"
+          + " type were found.";
+
+  private static final String MISSING_BINDING_BUT_OTHERS_EXIST =
+      "Binding to %s not found, but %s requires it. The names of other"
+          + " bindings to that type include: %s";
+
+  static void handleMissingBinding(ErrorHandler errorHandler, Member member,
+      Key<?> key, List<String> otherNames) {
+    if (otherNames.isEmpty()) {
+      errorHandler.handle(MISSING_BINDING, key, member);
+    } else {
+      errorHandler.handle(MISSING_BINDING_BUT_OTHERS_EXIST,
+          key, member, otherNames);
+    }
+  }
 
   static final String CONSTRUCTOR_RULES = "Classes must have either one (and"
       + " only one) constructor annotated with @Inject or a zero-argument"
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
index 117c5fd..391c256 100644
--- a/src/com/google/inject/TypeLiteral.java
+++ b/src/com/google/inject/TypeLiteral.java
@@ -31,8 +31,8 @@
  * you can create an empty anonymous inner class:
  *
  * <pre>
- * TypeLiteral<List<String>> listOfString =
- *   new TypeLiteral<List<String>>() {};
+ * TypeLiteral&lt;List&lt;String>> listOfString =
+ *   new TypeLiteral&lt;List&lt;String>>() {};
  * </pre>
  *
  * <p>Assumes {@code Type} implements {@code equals()} and {@code hashCode()}
diff --git a/src/com/google/inject/intercept/InterceptorStackCallback.java b/src/com/google/inject/intercept/InterceptorStackCallback.java
index 703c4a8..5c31378 100644
--- a/src/com/google/inject/intercept/InterceptorStackCallback.java
+++ b/src/com/google/inject/intercept/InterceptorStackCallback.java
@@ -1,4 +1,18 @@
-// Copyright 2006 Google Inc. All Rights Reserved.
+/**
+ * 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.intercept;
 
diff --git a/src/com/google/inject/intercept/MethodAspect.java b/src/com/google/inject/intercept/MethodAspect.java
index ff5765d..1e5bee4 100644
--- a/src/com/google/inject/intercept/MethodAspect.java
+++ b/src/com/google/inject/intercept/MethodAspect.java
@@ -1,4 +1,18 @@
-// Copyright 2006 Google Inc. All Rights Reserved.
+/**
+ * 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.intercept;
 
@@ -7,6 +21,8 @@
 import org.aopalliance.intercept.MethodInterceptor;
 
 import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Arrays;
 
 /**
  * Ties a query to a method interceptor.
@@ -15,15 +31,16 @@
  */
 class MethodAspect {
 
-  final Query<? super Class> classQuery;
+  final Query<? super Class<?>> classQuery;
   final Query<? super Method> methodQuery;
-  final MethodInterceptor interceptor;
+  final List<MethodInterceptor> interceptors;
 
-  MethodAspect(Query<? super Class> classQuery, Query<? super Method> methodQuery,
-      MethodInterceptor interceptor) {
+  MethodAspect(Query<? super Class<?>> classQuery, Query<? super Method> methodQuery,
+      MethodInterceptor... interceptors) {
     this.classQuery = Objects.nonNull(classQuery, "class query");
     this.methodQuery = Objects.nonNull(methodQuery, "method query");
-    this.interceptor = Objects.nonNull(interceptor, "interceptor");
+    this.interceptors =
+        Arrays.asList(Objects.nonNull(interceptors, "interceptors"));
   }
 
   boolean matches(Class<?> clazz) {
@@ -34,7 +51,7 @@
     return methodQuery.matches(method);
   }
 
-  MethodInterceptor interceptor() {
-    return interceptor;
+  List<MethodInterceptor> interceptors() {
+    return interceptors;
   }
 }
diff --git a/src/com/google/inject/intercept/ProxyFactory.java b/src/com/google/inject/intercept/ProxyFactory.java
index 719acba..4e3bf58 100644
--- a/src/com/google/inject/intercept/ProxyFactory.java
+++ b/src/com/google/inject/intercept/ProxyFactory.java
@@ -96,7 +96,7 @@
       for (MethodInterceptorsPair methodInterceptorsPair
           : methodInterceptorsPairs) {
         if (methodAspect.matches(methodInterceptorsPair.method)) {
-          methodInterceptorsPair.add(methodAspect.interceptor());
+          methodInterceptorsPair.addAll(methodAspect.interceptors());
           anyMatched = true;
         }
       }
@@ -107,6 +107,7 @@
 
     // Create callbacks.
     Callback[] callbacks = new Callback[methods.size()];
+    // noinspection unchecked
     Class<? extends Callback>[] callbackTypes = new Class[methods.size()];
     for (int i = 0; i < methods.size(); i++) {
       MethodInterceptorsPair methodInterceptorsPair =
@@ -167,11 +168,11 @@
       this.method = method;
     }
 
-    void add(MethodInterceptor interceptor) {
-      if (interceptors == null) {
-        interceptors = new ArrayList<MethodInterceptor>();
+    void addAll(List<MethodInterceptor> interceptors) {
+      if (this.interceptors == null) {
+        this.interceptors = new ArrayList<MethodInterceptor>();
       }
-      interceptors.add(interceptor);
+      this.interceptors.addAll(interceptors);
     }
 
     boolean hasInterceptors() {
diff --git a/src/com/google/inject/intercept/ProxyFactoryBuilder.java b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
index bedcfe6..eb08af6 100644
--- a/src/com/google/inject/intercept/ProxyFactoryBuilder.java
+++ b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
@@ -34,10 +34,16 @@
   /**
    * Applies the given method interceptor to the methods matched by the class
    * and method queries.
+   *
+   * @param classQuery matches classes the interceptor should apply to. For
+   *  example: {@code only(Runnable.class)}.
+   * @param methodQuery matches methods the interceptor should apply to. For
+   *  example: {@code annotatedWith(Transactional.class)}.
+   * @param interceptors to apply
    */
-  public ProxyFactoryBuilder intercept(Query<? super Class> classQuery,
-      Query<? super Method> methodQuery, MethodInterceptor interceptor) {
-    methodAspects.add(new MethodAspect(classQuery, methodQuery, interceptor));
+  public ProxyFactoryBuilder intercept(Query<? super Class<?>> classQuery,
+      Query<? super Method> methodQuery, MethodInterceptor... interceptors) {
+    methodAspects.add(new MethodAspect(classQuery, methodQuery, interceptors));
     return this;
   }
 
diff --git a/src/com/google/inject/intercept/Queries.java b/src/com/google/inject/intercept/Queries.java
index 4911750..79a503f 100644
--- a/src/com/google/inject/intercept/Queries.java
+++ b/src/com/google/inject/intercept/Queries.java
@@ -30,7 +30,7 @@
 
   private Queries() {}
 
-  static Query<?> ANY = new AbstractQuery<Object>() {
+  static Query<?> ALL = new AbstractQuery<Object>() {
     public boolean matches(Object o) {
       return true;
     }
@@ -40,8 +40,8 @@
    * Returns a query which matches any input.
    */
   @SuppressWarnings({"unchecked"})
-  public static <T> Query<T> any() {
-    return (Query<T>) ANY;
+  public static <T> Query<T> all() {
+    return (Query<T>) ALL;
   }
 
   /**
@@ -86,11 +86,11 @@
   /**
    * Returns a query which matches objects equal to the given object.
    */
-  public static <T> Query<T> equalTo(final T t) {
-    Objects.nonNull(t, "t");
-    return new AbstractQuery<T>() {
-      public boolean matches(T other) {
-        return t.equals(other);
+  public static Query<Object> only(final Object o) {
+    Objects.nonNull(o, "o");
+    return new AbstractQuery<Object>() {
+      public boolean matches(Object other) {
+        return o.equals(other);
       }
     };
   }
@@ -98,11 +98,11 @@
   /**
    * Returns a query which matches only the given object.
    */
-  public static <T> Query<T> sameAs(final T t) {
-    Objects.nonNull(t, "t");
-    return new AbstractQuery<T>() {
-      public boolean matches(T other) {
-        return t == other;
+  public static Query<Object> identicalTo(final Object o) {
+    Objects.nonNull(o, "o");
+    return new AbstractQuery<Object>() {
+      public boolean matches(Object other) {
+        return o == other;
       }
     };
   }
diff --git a/src/com/google/inject/intercept/package-info.java b/src/com/google/inject/intercept/package-info.java
new file mode 100644
index 0000000..663ed7e
--- /dev/null
+++ b/src/com/google/inject/intercept/package-info.java
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+/**
+ * A simple and very efficient AOP Alliance-based interception framework for
+ * Guice. To use with Guice, create a
+ * {@link com.google.inject.intercept.ProxyFactory} and pass it to
+ * {@link com.google.inject.ContainerBuilder}.
+ */
+
+package com.google.inject.intercept;
\ No newline at end of file
diff --git a/src/com/google/inject/spi/package-info.java b/src/com/google/inject/spi/package-info.java
new file mode 100644
index 0000000..0e47c3a
--- /dev/null
+++ b/src/com/google/inject/spi/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+/**
+ * Guice service provider interface
+ */
+
+package com.google.inject.spi;
\ No newline at end of file
diff --git a/src/com/google/inject/util/package-info.java b/src/com/google/inject/util/package-info.java
new file mode 100644
index 0000000..e0c3008
--- /dev/null
+++ b/src/com/google/inject/util/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+/**
+ * <i>Guice</i> (sounds like like "juice")
+ */
+
+package com.google.inject.util;
\ No newline at end of file
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index 423e230..ec1cea9 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -16,11 +16,13 @@
 
 package com.google.inject;
 
+import com.google.inject.intercept.ProxyFactoryTest;
+import com.google.inject.intercept.QueryTest;
+import com.google.inject.intercept.IntegrationTest;
 import com.google.inject.util.FinalizableReferenceQueueTest;
 import com.google.inject.util.ReferenceCacheTest;
 import com.google.inject.util.ReferenceMapTest;
 import com.google.inject.util.ReferenceMapTestSuite;
-import com.google.inject.intercept.QueryTest;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -47,6 +49,9 @@
     suite.addTestSuite(ReflectionTest.class);
     suite.addTestSuite(QueryTest.class);
 
+    suite.addTestSuite(ProxyFactoryTest.class);
+    suite.addTestSuite(IntegrationTest.class);
+
     suite.addTestSuite(FinalizableReferenceQueueTest.class);
     suite.addTestSuite(ReferenceMapTest.class);
     suite.addTest(ReferenceMapTestSuite.suite());
diff --git a/test/com/google/inject/intercept/IntegrationTest.java b/test/com/google/inject/intercept/IntegrationTest.java
new file mode 100644
index 0000000..8009246
--- /dev/null
+++ b/test/com/google/inject/intercept/IntegrationTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.intercept;
+
+import static com.google.inject.intercept.Queries.*;
+import com.google.inject.ContainerBuilder;
+import com.google.inject.Container;
+import com.google.inject.ContainerCreationException;
+import com.google.inject.Key;
+
+import junit.framework.TestCase;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class IntegrationTest extends TestCase {
+
+  public void testIntegration() throws ContainerCreationException {
+    CountingInterceptor counter = new CountingInterceptor();
+    ProxyFactoryBuilder proxyFactoryBuilder = new ProxyFactoryBuilder();
+    proxyFactoryBuilder.intercept(all(), all(), counter);
+    ProxyFactory proxyFactory = proxyFactoryBuilder.create();
+
+    ContainerBuilder containerBuilder = new ContainerBuilder(proxyFactory);
+    containerBuilder.bind(Foo.class);
+    Container container = containerBuilder.create(false);
+
+    Foo foo = container.getFactory(Key.get(Foo.class)).get();
+    foo.foo();
+    assertTrue(foo.invoked);
+    assertEquals(1, counter.count);
+
+    foo = container.getCreator(Foo.class).get();
+    foo.foo();
+    assertTrue(foo.invoked);
+    assertEquals(2, counter.count);
+  }
+
+  static class Foo {
+    boolean invoked;
+    public void foo() {
+      invoked = true;
+    }
+  }
+
+  static class CountingInterceptor implements MethodInterceptor {
+
+    int count;
+
+    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+      count++;
+      return methodInvocation.proceed();
+    }
+  }
+
+}
diff --git a/test/com/google/inject/intercept/ProxyFactoryTest.java b/test/com/google/inject/intercept/ProxyFactoryTest.java
index c042eb8..df65af2 100644
--- a/test/com/google/inject/intercept/ProxyFactoryTest.java
+++ b/test/com/google/inject/intercept/ProxyFactoryTest.java
@@ -1,8 +1,23 @@
-// Copyright 2006 Google Inc. All Rights Reserved.
+/**
+ * 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.intercept;
 
 import com.google.inject.spi.ConstructionProxy;
+import static com.google.inject.intercept.Queries.*;
 
 import junit.framework.TestCase;
 
@@ -10,6 +25,8 @@
 import org.aopalliance.intercept.MethodInvocation;
 
 import java.lang.reflect.InvocationTargetException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * @author crazybob@google.com (Bob Lee)
@@ -21,7 +38,7 @@
     SimpleInterceptor interceptor = new SimpleInterceptor();
 
     ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
-    builder.intercept(Queries.any(), Queries.any(), interceptor);
+    builder.intercept(all(), all(), interceptor);
     ProxyFactory factory = builder.create();
 
     ConstructionProxy<Simple> constructor =
@@ -50,5 +67,142 @@
     }
   }
 
+  public void testInterceptOneMethod()
+      throws NoSuchMethodException, InvocationTargetException {
+    SimpleInterceptor interceptor = new SimpleInterceptor();
 
+    ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
+
+    builder.intercept(
+        only(Bar.class), annotatedWith(Intercept.class), interceptor);
+    ProxyFactory factory = builder.create();
+
+    ConstructionProxy<Foo> fooFactory =
+        factory.get(Foo.class.getDeclaredConstructor());
+    ConstructionProxy<Bar> barFactory =
+        factory.get(Bar.class.getDeclaredConstructor());
+
+    Foo foo = fooFactory.newInstance();
+    Bar bar = barFactory.newInstance();
+
+    foo.foo();
+    assertTrue(foo.fooCalled);
+    assertFalse(interceptor.invoked);
+
+    bar.bar();
+    assertTrue(bar.barCalled);
+    assertFalse(interceptor.invoked);
+
+    bar.intercepted();
+    assertTrue(bar.interceptedCalled);
+    assertTrue(interceptor.invoked);
+  }
+
+  static class Foo {
+    boolean fooCalled;
+    @Intercept
+    void foo() {
+      fooCalled = true;
+    }
+  }
+
+  static class Bar {
+
+    boolean barCalled;
+    void bar() {
+      barCalled = true;
+    }
+
+    boolean interceptedCalled;
+
+    @Intercept
+    void intercepted() {
+      interceptedCalled = true;
+    }
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface Intercept {}
+
+  public void testWithConstructorArguments()
+      throws InvocationTargetException, NoSuchMethodException {
+    SimpleInterceptor interceptor = new SimpleInterceptor();
+
+    ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
+    builder.intercept(all(), all(), interceptor);
+    ProxyFactory factory = builder.create();
+
+    ConstructionProxy<A> constructor =
+        factory.get(A.class.getDeclaredConstructor(int.class));
+
+    A a = constructor.newInstance(5);
+    a.a();
+    assertEquals(5, a.i);
+  }
+
+  public void testNotProxied()
+      throws NoSuchMethodException, InvocationTargetException {
+    SimpleInterceptor interceptor = new SimpleInterceptor();
+
+    ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
+    builder.intercept(not(all()), not(all()), interceptor);
+    ProxyFactory factory = builder.create();
+
+    ConstructionProxy<A> constructor =
+        factory.get(A.class.getDeclaredConstructor(int.class));
+
+    A a = constructor.newInstance(5);
+    assertEquals(A.class, a.getClass());
+  }
+
+  static class A {
+    final int i;
+    public A(int i) {
+      this.i = i;
+    }
+    public void a() {}
+  }
+
+  public void testMultipleInterceptors()
+      throws NoSuchMethodException, InvocationTargetException {
+    DoubleInterceptor doubleInterceptor = new DoubleInterceptor();
+    CountingInterceptor countingInterceptor = new CountingInterceptor();
+
+    ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
+    builder.intercept(all(), all(), doubleInterceptor, countingInterceptor);
+    ProxyFactory factory = builder.create();
+
+    ConstructionProxy<Counter> constructor =
+        factory.get(Counter.class.getDeclaredConstructor());
+
+    Counter counter = constructor.newInstance();
+    counter.inc();
+    assertEquals(2, counter.count);
+    assertEquals(2, countingInterceptor.count);
+  }
+
+  static class CountingInterceptor implements MethodInterceptor {
+
+    int count;
+
+    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+      count++;
+      return methodInvocation.proceed();
+    }
+  }
+
+  static class DoubleInterceptor implements MethodInterceptor {
+
+    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+      methodInvocation.proceed();
+      return methodInvocation.proceed();
+    }
+  }
+
+  static class Counter {
+    int count;
+    void inc() {
+      count++;
+    }
+  }
 }
diff --git a/test/com/google/inject/intercept/QueryTest.java b/test/com/google/inject/intercept/QueryTest.java
index ad87190..148ce97 100644
--- a/test/com/google/inject/intercept/QueryTest.java
+++ b/test/com/google/inject/intercept/QueryTest.java
@@ -16,13 +16,7 @@
 
 package com.google.inject.intercept;
 
-import static com.google.inject.intercept.Queries.annotatedWith;
-import static com.google.inject.intercept.Queries.any;
-import static com.google.inject.intercept.Queries.equalTo;
-import static com.google.inject.intercept.Queries.inPackage;
-import static com.google.inject.intercept.Queries.not;
-import static com.google.inject.intercept.Queries.sameAs;
-import static com.google.inject.intercept.Queries.subclassesOf;
+import static com.google.inject.intercept.Queries.*;
 
 import junit.framework.TestCase;
 
@@ -35,16 +29,16 @@
 public class QueryTest extends TestCase {
 
   public void testAny() {
-    assertTrue(any().matches(null));
+    assertTrue(all().matches(null));
   }
 
   public void testNot() {
-    assertFalse(not(any()).matches(null));
+    assertFalse(not(all()).matches(null));
   }
 
   public void testAnd() {
-    assertTrue(any().and(any()).matches(null));
-    assertFalse(any().and(not(any())).matches(null));
+    assertTrue(all().and(all()).matches(null));
+    assertFalse(all().and(not(all())).matches(null));
   }
 
   public void testAnnotatedWith() {
@@ -59,15 +53,15 @@
     assertFalse(subclassesOf(Runnable.class).matches(Object.class));
   }
 
-  public void testEqualTo() {
-    assertTrue(equalTo(1000).matches(new Integer(1000)));
-    assertFalse(equalTo(1).matches(new Integer(1000)));
+  public void testOnly() {
+    assertTrue(only(1000).matches(new Integer(1000)));
+    assertFalse(only(1).matches(new Integer(1000)));
   }
 
   public void testSameAs() {
     Object o = new Object();
-    assertTrue(sameAs(o).matches(o));
-    assertFalse(sameAs(o).matches(new Object()));
+    assertTrue(only(o).matches(o));
+    assertFalse(only(o).matches(new Object()));
   }
 
   public void testInPackage() {