[picocontainer-dev] patch for binding annotation support (trunk)

Paul Hammant <[email protected]>
Newsgroups gmane.comp.java.picocontainer.devel
Message-ID <[email protected]>
---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email
ham.patch (application/octet-stream, 69.2 KB)
Index: pico/container/src/test/org/picocontainer/visitors/TraversalCheckingVisitorTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/visitors/TraversalCheckingVisitorTestCase.java	(revision 4004)
+++ pico/container/src/test/org/picocontainer/visitors/TraversalCheckingVisitorTestCase.java	(working copy)
@@ -130,9 +130,9 @@
 
         assertTrue(allParameters.size() == 1);
         assertTrue(allParameters.get(0) instanceof ConstantParameter);
-        assertTrue( ( (ConstantParameter) allParameters.get(0)).resolveInstance(null, null, null, null, false) instanceof Integer);
+        assertTrue( ( (ConstantParameter) allParameters.get(0)).resolveInstance(null, null, null, null, false, null) instanceof Integer);
         assertEquals(3, ( (Integer) ( (ConstantParameter) allParameters.get(0)).resolveInstance(null, null,
-            null, null, false)).intValue());
+            null, null, false, null)).intValue());
     }
 
 }    
\ No newline at end of file
Index: pico/container/src/test/org/picocontainer/behaviors/StoringTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/behaviors/StoringTestCase.java	(revision 4004)
+++ pico/container/src/test/org/picocontainer/behaviors/StoringTestCase.java	(working copy)
@@ -227,7 +227,7 @@
             Foo three = child.getComponent(Foo.class);
             fail("should have barfed");
         } catch (UnsupportedOperationException e) {
-            e.printStackTrace();
+            // expected
         }
     }
 
Index: pico/container/src/test/org/picocontainer/adapters/JasonsTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/adapters/JasonsTestCase.java	(revision 4039)
+++ pico/container/src/test/org/picocontainer/adapters/JasonsTestCase.java	(working copy)
@@ -1,17 +1,14 @@
 package org.picocontainer.adapters;
 
+import static org.picocontainer.BindKey.bindKey;
 import org.picocontainer.DefaultPicoContainer;
 import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.annotations.Bind;
 import org.picocontainer.annotations.Inject;
-import org.picocontainer.injectors.AbstractInjector;
 import org.picocontainer.injectors.AnnotatedFieldInjection;
+import org.picocontainer.injectors.MethodInjection;
 import org.picocontainer.parameters.ComponentParameter;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
 import junit.framework.TestCase;
 
 /** @author Paul Hammant */
@@ -29,6 +26,7 @@
         mpc.addComponent(Apple.class.getName()+ "three", AppleImpl3.class);
         mpc.addComponent(Apple.class.getName()+ "four", AppleImpl4.class);
         FruitBasket fb = mpc.getComponent(FruitBasket.class);
+        assertNotNull(fb);
         assertEquals(fb.one.getX(), 1);
         assertEquals(fb.two.getX(), 2);
         assertEquals(fb.three.getX(), 3);
@@ -37,26 +35,57 @@
 
     public void testJasonsNeed() {
         MutablePicoContainer mpc = new DefaultPicoContainer(new AnnotatedFieldInjection());
+
         mpc.addComponent(FruitBasket.class);
         mpc.addComponent(bindKey(Apple.class, "one"), AppleImpl1.class);
         mpc.addComponent(bindKey(Apple.class, "two"), AppleImpl2.class);
         mpc.addComponent(bindKey(Apple.class, "three"), AppleImpl3.class);
         mpc.addComponent(bindKey(Apple.class, "four"), AppleImpl4.class);
-        try {
-            // this level of terseness is the other way ....
-            // this should not be barfing if if we can get binding to annotations working
-            FruitBasket fb = mpc.getComponent(FruitBasket.class);
-            assertEquals(fb.one.getX(), 1);
-            assertEquals(fb.two.getX(), 2);
-            assertEquals(fb.three.getX(), 3);
-            assertEquals(fb.four.getX(), 4);
-            fail();
-        } catch (AbstractInjector.AmbiguousComponentResolutionException e) {
-            // which Apple to inject into which apple field ?
-        }
+        // this level of terseness is the other way ....
+        // this should not be barfing if if we can get binding to annotations working
+        FruitBasket fb = mpc.getComponent(FruitBasket.class);
+        assertEquals(fb.one.getX(), 1);
+        assertEquals(fb.two.getX(), 2);
+        assertEquals(fb.three.getX(), 3);
+        assertEquals(fb.four.getX(), 4);
     }
 
+    public void testBindingAnnotationsWithCDI() {
+        MutablePicoContainer mpc = new DefaultPicoContainer();
 
+        mpc.addComponent(FruitBasket.class);
+        mpc.addComponent(bindKey(Apple.class, "one"), AppleImpl1.class);
+        mpc.addComponent(bindKey(Apple.class, "two"), AppleImpl2.class);
+        mpc.addComponent(bindKey(Apple.class, "three"), AppleImpl3.class);
+        mpc.addComponent(bindKey(Apple.class, "four"), AppleImpl4.class);
+        // this level of terseness is the other way ....
+        // this should not be barfing if if we can get binding to annotations working
+        FruitBasket fb = mpc.getComponent(FruitBasket.class);
+        assertNotNull(fb);
+        assertEquals(fb.one.getX(), 1);
+        assertEquals(fb.two.getX(), 2);
+        assertEquals(fb.three.getX(), 3);
+        assertEquals(fb.four.getX(), 4);
+    }
+
+    public void testBindingAnnotationsWithSingleMemberInjection() {
+        MutablePicoContainer mpc = new DefaultPicoContainer(new MethodInjection("foo"));
+
+        mpc.addComponent(FruitBasket.class);
+        mpc.addComponent(bindKey(Apple.class, "one"), AppleImpl1.class);
+        mpc.addComponent(bindKey(Apple.class, "two"), AppleImpl2.class);
+        mpc.addComponent(bindKey(Apple.class, "three"), AppleImpl3.class);
+        mpc.addComponent(bindKey(Apple.class, "four"), AppleImpl4.class);
+        // this level of terseness is the other way ....
+        // this should not be barfing if if we can get binding to annotations working
+        FruitBasket fb = mpc.getComponent(FruitBasket.class);
+        assertNotNull(fb);
+        assertEquals(fb.one.getX(), 1);
+        assertEquals(fb.two.getX(), 2);
+        assertEquals(fb.three.getX(), 3);
+        assertEquals(fb.four.getX(), 4);
+    }
+
     public interface Apple {
         int getX();
     }
@@ -93,28 +122,29 @@
 
         public FruitBasket() {
         }
-    }
 
-    // to become an annotation
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target({ElementType.FIELD, ElementType.PARAMETER})
-    public @interface Bind {
-        String id();
-    }
+        public FruitBasket(@Bind(id = "one") Apple one,
+                           @Bind(id = "two") Apple two,
+                           @Bind(id = "three") Apple three,
+                           @Bind(id = "four") Apple four) {
+            this.one = one;
+            this.two = two;
+            this.three = three;
+            this.four = four;
+        }
 
-    // implicitly this goes into the jar somewhere
-    public static class BindKey {
-      private Class type;
-      private String bindingId;
-        public BindKey(Class type, String bindingId) {
-            this.type = type;
-            this.bindingId = bindingId;
+        public void foo(@Bind(id = "one") Apple one,
+                           @Bind(id = "two") Apple two,
+                           @Bind(id = "three") Apple three,
+                           @Bind(id = "four") Apple four) {
+            this.one = one;
+            this.two = two;
+            this.three = three;
+            this.four = four;
         }
-    }
 
-    // implicitly this function goes into DPC
-    public static BindKey bindKey(Class type, String bindingId) {
-        return new BindKey(type, bindingId);
+
     }
 
+
 }
Index: pico/container/src/test/org/picocontainer/parameters/ConfigParameterTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/parameters/ConfigParameterTestCase.java	(revision 4016)
+++ pico/container/src/test/org/picocontainer/parameters/ConfigParameterTestCase.java	(working copy)
@@ -34,11 +34,11 @@
 
 		// shall be not resolvable
 		assertFalse(parameter.isResolvable(container, null, String.class,
-				paramName, false));
+				paramName, false, null));
 
 		// shall resolve instance as null
 		assertNull(parameter.resolveInstance(container, null, String.class,
-				paramName, false));
+				paramName, false, null));
 	}
 
 	public void testThatNotStringEntryIsNotResolved() throws Exception {
@@ -49,11 +49,11 @@
 
 		// shall be not resolvable
 		assertFalse(parameter.isResolvable(container, null, String.class,
-				paramName, false));
+				paramName, false, null));
 
 		// shall resolve instance as null
 		assertNull(parameter.resolveInstance(container, null, String.class,
-				paramName, false));
+				paramName, false, null));
 
 	}
 
@@ -69,9 +69,9 @@
 		ComponentParameter parameter = new ComponentParameter("gloo.blum");
 
 		assertEquals(new Integer(239), parameter.resolveInstance(container,
-				null, Integer.class, paramName, false));
+				null, Integer.class, paramName, false, null));
 		assertEquals("239", parameter.resolveInstance(container, null,
-				String.class, paramName, false));
+				String.class, paramName, false, null));
 	}
 
 	/**
@@ -90,7 +90,7 @@
 //		} catch (ConfigParameter.NoConverterAvailableException ex) {
 //			// that's anticipated
 //		}
-	    Object foo = parameter.resolveInstance(container, null, List.class, paramName, false);
+	    Object foo = parameter.resolveInstance(container, null, List.class, paramName, false, null);
         assertNull(foo);
 
     }
Index: pico/container/src/test/org/picocontainer/parameters/ConstantParameterTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/parameters/ConstantParameterTestCase.java	(revision 4004)
+++ pico/container/src/test/org/picocontainer/parameters/ConstantParameterTestCase.java	(working copy)
@@ -26,7 +26,7 @@
     public void testThatInstaceTypeAcceptedForPrimitives() throws Exception {
         ConstantParameter param = new ConstantParameter(239);
         try{
-            param.verify(null,null,Integer.TYPE, null, false);
+            param.verify(null,null,Integer.TYPE, null, false, null);
         } catch(PicoCompositionException ex) {
             fail("failed verification for primitive / instance ");
         }
Index: pico/container/src/test/org/picocontainer/parameters/ParameterTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/parameters/ParameterTestCase.java	(revision 4004)
+++ pico/container/src/test/org/picocontainer/parameters/ParameterTestCase.java	(working copy)
@@ -45,7 +45,7 @@
         assertNotNull(adapter);
         assertNotNull(pico.getComponent(Touchable.class));
         Touchable touchable = (Touchable) ComponentParameter.DEFAULT.resolveInstance(pico, null, Touchable.class, pn,
-                                                                                     false);
+                                                                                     false, null);
         assertNotNull(touchable);
     }
 
@@ -56,7 +56,7 @@
 
         assertNotNull(pico.getComponent(Touchable.class));
         Touchable touchable = (Touchable) ComponentParameter.DEFAULT.resolveInstance(pico, adapter, Touchable.class, pn,
-                                                                                     false);
+                                                                                     false, null);
         assertNull(touchable);
     }
 
@@ -64,7 +64,7 @@
         Object value = new Object();
         ConstantParameter parameter = new ConstantParameter(value);
         MutablePicoContainer picoContainer = new DefaultPicoContainer();
-        assertSame(value, parameter.resolveInstance(picoContainer, null, Object.class, pn, false));
+        assertSame(value, parameter.resolveInstance(picoContainer, null, Object.class, pn, false, null));
     }
 
     public void testDependsOnTouchableWithTouchableSpecifiedAsConstant() throws PicoCompositionException {
@@ -79,7 +79,7 @@
         MutablePicoContainer picoContainer = new DefaultPicoContainer();
         ComponentAdapter adapter = picoContainer.addComponent(Touchable.class, SimpleTouchable.class).getComponentAdapter(Touchable.class,
                                                                                                                           null);
-        assertNull(ComponentParameter.DEFAULT.resolveInstance(picoContainer, adapter, TestCase.class, pn, false));
+        assertNull(ComponentParameter.DEFAULT.resolveInstance(picoContainer, adapter, TestCase.class, pn, false, null));
     }
 	
 	public void testComponentParameterResolvesPrimitiveType() {
@@ -87,8 +87,8 @@
         ComponentAdapter adapter = picoContainer.addComponent("glarch", 239).getComponentAdapter("glarch");
         assertNotNull(adapter);
 		Parameter parameter = new ComponentParameter("glarch");
-		assertNotNull(parameter.resolveInstance(picoContainer,null,Integer.TYPE, pn, false));
-		assertEquals(239, ((Integer)parameter.resolveInstance(picoContainer,null,Integer.TYPE, pn, false)).intValue());
+		assertNotNull(parameter.resolveInstance(picoContainer,null,Integer.TYPE, pn, false, null));
+		assertEquals(239, ((Integer)parameter.resolveInstance(picoContainer,null,Integer.TYPE, pn, false, null)).intValue());
 	}
 
     public void testConstantParameterRespectsExpectedType() {
@@ -96,82 +96,82 @@
         Parameter parameter = new ConstantParameter(new SimpleTouchable());
         ComponentAdapter adapter = picoContainer.addComponent(Touchable.class, SimpleTouchable.class).getComponentAdapter(Touchable.class,
                                                                                                                           null);
-        assertFalse(parameter.isResolvable(picoContainer, adapter, TestCase.class, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, adapter, TestCase.class, pn, false, null));
     }
 
     public void testParameterRespectsExpectedType() throws PicoCompositionException {
         Parameter parameter = new ConstantParameter(Touchable.class);
         MutablePicoContainer picoContainer = new DefaultPicoContainer();
-        assertFalse(parameter.isResolvable(picoContainer, null, TestCase.class, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, TestCase.class, pn, false, null));
 
         ComponentAdapter adapter = picoContainer.addComponent(Touchable.class, SimpleTouchable.class).getComponentAdapter(Touchable.class,
                                                                                                                           null);
 
-        assertNull(ComponentParameter.DEFAULT.resolveInstance(picoContainer, adapter, TestCase.class, pn, false));
+        assertNull(ComponentParameter.DEFAULT.resolveInstance(picoContainer, adapter, TestCase.class, pn, false, null));
     }
 
     public void testConstantParameterWithPrimitives() throws PicoCompositionException {
         MutablePicoContainer picoContainer = new DefaultPicoContainer();
         Byte byteValue = (byte)5;
         ConstantParameter parameter = new ConstantParameter(byteValue);
-        assertSame(byteValue, parameter.resolveInstance(picoContainer, null, Byte.TYPE, pn, false));
-        assertSame(byteValue, parameter.resolveInstance(picoContainer, null, Byte.class, pn, false));
+        assertSame(byteValue, parameter.resolveInstance(picoContainer, null, Byte.TYPE, pn, false, null));
+        assertSame(byteValue, parameter.resolveInstance(picoContainer, null, Byte.class, pn, false, null));
         Short shortValue = (short)5;
         parameter = new ConstantParameter(shortValue);
-        assertSame(shortValue, parameter.resolveInstance(picoContainer, null, Short.TYPE, pn, false));
-        assertSame(shortValue, parameter.resolveInstance(picoContainer, null, Short.class, pn, false));
+        assertSame(shortValue, parameter.resolveInstance(picoContainer, null, Short.TYPE, pn, false, null));
+        assertSame(shortValue, parameter.resolveInstance(picoContainer, null, Short.class, pn, false, null));
         Integer intValue = 5;
         parameter = new ConstantParameter(intValue);
-        assertSame(intValue, parameter.resolveInstance(picoContainer, null, Integer.TYPE, pn, false));
-        assertSame(intValue, parameter.resolveInstance(picoContainer, null, Integer.class, pn, false));
+        assertSame(intValue, parameter.resolveInstance(picoContainer, null, Integer.TYPE, pn, false, null));
+        assertSame(intValue, parameter.resolveInstance(picoContainer, null, Integer.class, pn, false, null));
         Long longValue = (long)5;
         parameter = new ConstantParameter(longValue);
-        assertSame(longValue, parameter.resolveInstance(picoContainer, null, Long.TYPE, pn, false));
-        assertSame(longValue, parameter.resolveInstance(picoContainer, null, Long.class, pn, false));
+        assertSame(longValue, parameter.resolveInstance(picoContainer, null, Long.TYPE, pn, false, null));
+        assertSame(longValue, parameter.resolveInstance(picoContainer, null, Long.class, pn, false, null));
         Float floatValue = new Float(5.5);
         parameter = new ConstantParameter(floatValue);
-        assertSame(floatValue, parameter.resolveInstance(picoContainer, null, Float.TYPE, pn, false));
-        assertSame(floatValue, parameter.resolveInstance(picoContainer, null, Float.class, pn, false));
+        assertSame(floatValue, parameter.resolveInstance(picoContainer, null, Float.TYPE, pn, false, null));
+        assertSame(floatValue, parameter.resolveInstance(picoContainer, null, Float.class, pn, false, null));
         Double doubleValue = 5.5;
         parameter = new ConstantParameter(doubleValue);
-        assertSame(doubleValue, parameter.resolveInstance(picoContainer, null, Double.TYPE, pn, false));
-        assertSame(doubleValue, parameter.resolveInstance(picoContainer, null, Double.class, pn, false));
+        assertSame(doubleValue, parameter.resolveInstance(picoContainer, null, Double.TYPE, pn, false, null));
+        assertSame(doubleValue, parameter.resolveInstance(picoContainer, null, Double.class, pn, false, null));
         Boolean booleanValue = true;
         parameter = new ConstantParameter(booleanValue);
-        assertSame(booleanValue, parameter.resolveInstance(picoContainer, null, Boolean.TYPE, pn, false));
-        assertSame(booleanValue, parameter.resolveInstance(picoContainer, null, Boolean.class, pn, false));
+        assertSame(booleanValue, parameter.resolveInstance(picoContainer, null, Boolean.TYPE, pn, false, null));
+        assertSame(booleanValue, parameter.resolveInstance(picoContainer, null, Boolean.class, pn, false, null));
         Character charValue = 'x';
         parameter = new ConstantParameter(charValue);
-        assertSame(charValue, parameter.resolveInstance(picoContainer, null, Character.TYPE, pn, false));
-        assertSame(charValue, parameter.resolveInstance(picoContainer, null, Character.class, pn, false));
+        assertSame(charValue, parameter.resolveInstance(picoContainer, null, Character.TYPE, pn, false, null));
+        assertSame(charValue, parameter.resolveInstance(picoContainer, null, Character.class, pn, false, null));
     }
 
     public void testConstantParameterWithPrimitivesRejectsUnexpectedType() throws PicoCompositionException {
         MutablePicoContainer picoContainer = new DefaultPicoContainer();
         Byte byteValue = (byte)5;
         ConstantParameter parameter = new ConstantParameter(byteValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Integer.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Integer.TYPE, pn, false, null));
         Short shortValue = (short)5;
         parameter = new ConstantParameter(shortValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Integer intValue = 5;
         parameter = new ConstantParameter(intValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Long longValue = (long)5;
         parameter = new ConstantParameter(longValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Float floatValue = new Float(5.5);
         parameter = new ConstantParameter(floatValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Double doubleValue = 5.5;
         parameter = new ConstantParameter(doubleValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Boolean booleanValue = true;
         parameter = new ConstantParameter(booleanValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
         Character charValue = 'x';
         parameter = new ConstantParameter(charValue);
-        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false));
+        assertFalse(parameter.isResolvable(picoContainer, null, Byte.TYPE, pn, false, null));
     }
 
     public void testKeyClashBug118() throws PicoCompositionException {
Index: pico/container/src/test/org/picocontainer/defaults/CollectionComponentParameterTestCase.java
===================================================================
--- pico/container/src/test/org/picocontainer/defaults/CollectionComponentParameterTestCase.java	(revision 4004)
+++ pico/container/src/test/org/picocontainer/defaults/CollectionComponentParameterTestCase.java	(working copy)
@@ -65,7 +65,7 @@
         Collections.sort(expected);
         List actual = Arrays.asList((Object[]) ccp.resolveInstance(
                 (PicoContainer) containerMock.proxy(), (ComponentAdapter) componentAdapterMock.proxy(), String[].class, null,
-                false));
+                false, null));
         Collections.sort(actual);
         assertEquals(expected, actual);
     }
@@ -308,16 +308,16 @@
         MutablePicoContainer pico = new DefaultPicoContainer();
         CollectionComponentParameter parameterNonEmpty = CollectionComponentParameter.ARRAY;
         pico.addComponent(Shark.class);
-        parameterNonEmpty.verify(pico, null, Fish[].class, null, false);
+        parameterNonEmpty.verify(pico, null, Fish[].class, null, false, null);
         try {
-            parameterNonEmpty.verify(pico, null, Cod[].class, null, false);
+            parameterNonEmpty.verify(pico, null, Cod[].class, null, false, null);
             fail("(PicoCompositionException expected");
         } catch (PicoCompositionException e) {
             assertTrue(e.getMessage().indexOf(Cod.class.getName())>0);
         }
         CollectionComponentParameter parameterEmpty = CollectionComponentParameter.ARRAY_ALLOW_EMPTY;
-        parameterEmpty.verify(pico, null, Fish[].class, null, false);
-        parameterEmpty.verify(pico, null, Cod[].class, null, false);
+        parameterEmpty.verify(pico, null, Fish[].class, null, false, null);
+        parameterEmpty.verify(pico, null, Cod[].class, null, false, null);
     }
 
     // PICO-243 : this test will fail if executed on jdk1.3 without commons-collections
Index: pico/container/src/java/org/picocontainer/annotations/Bind.java
===================================================================
--- pico/container/src/java/org/picocontainer/annotations/Bind.java	(revision 0)
+++ pico/container/src/java/org/picocontainer/annotations/Bind.java	(revision 0)
@@ -0,0 +1,14 @@
+package org.picocontainer.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/** @author Paul Hammant */
+// to become an annotation
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.FIELD, ElementType.PARAMETER})
+public @interface Bind {
+    String id();
+}
Index: pico/container/src/java/org/picocontainer/Parameter.java
===================================================================
--- pico/container/src/java/org/picocontainer/Parameter.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/Parameter.java	(working copy)
@@ -40,6 +40,7 @@
      * @param expectedParameterName Expected parameter name
      *
      * @param useNames
+     * @param id
      * @return the instance or <code>null</code> if no suitable instance can be found.
      *
      * @throws PicoCompositionException if a referenced component could not be instantiated.
@@ -47,7 +48,7 @@
      <T> T resolveInstance(PicoContainer container,
                            ComponentAdapter adapter,
                            Class<T> expectedType,
-                           ParameterName expectedParameterName, boolean useNames);
+                           ParameterName expectedParameterName, boolean useNames, String id);
 
     /**
      * Check if the Parameter can statisfy the expected type using the container.
@@ -58,13 +59,14 @@
      * @param expectedParameterName Expected parameter name
      *
      * @param useNames
+     * @param id
      * @return <code>true</code> if the component parameter can be resolved.
      *
      */
     boolean isResolvable(PicoContainer container,
                          ComponentAdapter adapter,
                          Class expectedType,
-                         ParameterName expectedParameterName, boolean useNames);
+                         ParameterName expectedParameterName, boolean useNames, String id);
 
     /**
      * Verify that the Parameter can statisfied the expected type using the container
@@ -75,12 +77,13 @@
      * @param expectedParameterName Expected parameter name
      *
      * @param useNames
+     * @param id
      * @throws PicoCompositionException if parameter and its dependencies cannot be resolved
      */
     void verify(PicoContainer container,
                 ComponentAdapter adapter,
                 Class expectedType,
-                ParameterName expectedParameterName, boolean useNames);
+                ParameterName expectedParameterName, boolean useNames, String id);
 
     /**
      * Accepts a visitor for this Parameter. The method is normally called by visiting a {@link ComponentAdapter}, that
Index: pico/container/src/java/org/picocontainer/parameters/CollectionComponentParameter.java
===================================================================
--- pico/container/src/java/org/picocontainer/parameters/CollectionComponentParameter.java	(revision 4005)
+++ pico/container/src/java/org/picocontainer/parameters/CollectionComponentParameter.java	(working copy)
@@ -115,6 +115,7 @@
      * @param expectedParameterName {@inheritDoc}
      *
      * @param useNames
+     * @param id
      * @return the instance of the collection type or <code>null</code>
      *
      * @throws PicoCompositionException {@inheritDoc}
@@ -123,7 +124,7 @@
     public Object resolveInstance(PicoContainer container,
                                   ComponentAdapter adapter,
                                   Class expectedType,
-                                  ParameterName expectedParameterName, boolean useNames)
+                                  ParameterName expectedParameterName, boolean useNames, String id)
     {
         // type check is done in isResolvable
         Object result = null;
@@ -156,13 +157,14 @@
      * @param expectedParameterName {@inheritDoc}
      *
      * @param useNames
+     * @param id
      * @return <code>true</code> if matching components were found or an empty collective type
      *         is allowed
      */
     public boolean isResolvable(PicoContainer container,
                                 ComponentAdapter adapter,
                                 Class expectedType,
-                                ParameterName expectedParameterName, boolean useNames) {
+                                ParameterName expectedParameterName, boolean useNames, String id) {
         final Class collectionType = getCollectionType(expectedType);
         final Class valueType = getValueType(expectedType);
         return collectionType != null && (emptyCollection || getMatchingComponentAdapters(container,
@@ -183,12 +185,13 @@
      * @param expectedParameterName {@inheritDoc}
      *
      * @param useNames
+     * @param id
      * @throws PicoCompositionException {@inheritDoc}
      */
     public void verify(PicoContainer container,
                        ComponentAdapter adapter,
                        Class expectedType,
-                       ParameterName expectedParameterName, boolean useNames)
+                       ParameterName expectedParameterName, boolean useNames, String id)
     {
         final Class collectionType = getCollectionType(expectedType);
         if (collectionType != null) {
Index: pico/container/src/java/org/picocontainer/parameters/ComponentParameter.java
===================================================================
--- pico/container/src/java/org/picocontainer/parameters/ComponentParameter.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/parameters/ComponentParameter.java	(working copy)
@@ -112,12 +112,12 @@
                                   ComponentAdapter adapter,
                                   Class<T> expectedType,
                                   ParameterName expectedParameterName,
-                                  boolean useNames) {
+                                  boolean useNames, String id) {
         // type check is done in isResolvable
-        T result = super.resolveInstance(container, adapter, expectedType, expectedParameterName, useNames);
+        T result = super.resolveInstance(container, adapter, expectedType, expectedParameterName, useNames, id);
         if (result == null && collectionParameter != null) {
             result = collectionParameter.resolveInstance(container, adapter, expectedType, expectedParameterName,
-                                                         useNames);
+                                                         useNames, id);
         }
         return result;
     }
@@ -126,11 +126,11 @@
                                 ComponentAdapter adapter,
                                 Class expectedType,
                                 ParameterName expectedParameterName,
-                                boolean useNames) {
-        if (!super.isResolvable(container, adapter, expectedType, expectedParameterName, useNames)) {
+                                boolean useNames, String id) {
+        if (!super.isResolvable(container, adapter, expectedType, expectedParameterName, useNames, id)) {
             if (collectionParameter != null) {
                 return collectionParameter.isResolvable(container, adapter, expectedType, expectedParameterName,
-                                                        useNames);
+                                                        useNames, id);
             }
             return false;
         }
@@ -141,12 +141,12 @@
                        ComponentAdapter adapter,
                        Class expectedType,
                        ParameterName expectedParameterName,
-                       boolean useNames) {
+                       boolean useNames, String id) {
         try {
-            super.verify(container, adapter, expectedType, expectedParameterName, useNames);
+            super.verify(container, adapter, expectedType, expectedParameterName, useNames, id);
         } catch (AbstractInjector.UnsatisfiableDependenciesException e) {
             if (collectionParameter != null) {
-                collectionParameter.verify(container, adapter, expectedType, expectedParameterName, useNames);
+                collectionParameter.verify(container, adapter, expectedType, expectedParameterName, useNames, id);
                 return;
             }
             throw e;
Index: pico/container/src/java/org/picocontainer/parameters/BasicComponentParameter.java
===================================================================
--- pico/container/src/java/org/picocontainer/parameters/BasicComponentParameter.java	(revision 4013)
+++ pico/container/src/java/org/picocontainer/parameters/BasicComponentParameter.java	(working copy)
@@ -14,7 +14,6 @@
 import org.picocontainer.ParameterName;
 import org.picocontainer.PicoContainer;
 import org.picocontainer.PicoVisitor;
-import org.picocontainer.PicoCompositionException;
 import org.picocontainer.injectors.AbstractInjector;
 
 import java.io.File;
@@ -127,21 +126,21 @@
      *
      * @throws org.picocontainer.PicoCompositionException
      *          {@inheritDoc}
-     * @see Parameter#isResolvable(PicoContainer,ComponentAdapter,Class,ParameterName,boolean)
+     * @see Parameter#isResolvable(PicoContainer, ComponentAdapter, Class, ParameterName,boolean, String)
      */
     public boolean isResolvable(PicoContainer container,
                                 ComponentAdapter adapter,
                                 Class expectedType,
-                                ParameterName expectedParameterName, boolean useNames) {
-        return resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames) != null;
+                                ParameterName expectedParameterName, boolean useNames, String id) {
+        return resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames, id) != null;
     }
 
     public <T> T resolveInstance(PicoContainer container,
-                                  ComponentAdapter adapter,
-                                  Class<T> expectedType,
-                                  ParameterName expectedParameterName, boolean useNames) {
+                                 ComponentAdapter adapter,
+                                 Class<T> expectedType,
+                                 ParameterName expectedParameterName, boolean useNames, String id) {
         final ComponentAdapter componentAdapter =
-            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames);
+            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames, id);
         if (componentAdapter != null) {
             Object o = container.getComponent(componentAdapter.getComponentKey());
             if (o instanceof String && expectedType != String.class) {
@@ -156,9 +155,9 @@
     public void verify(PicoContainer container,
                        ComponentAdapter adapter,
                        Class expectedType,
-                       ParameterName expectedParameterName, boolean useNames) {
+                       ParameterName expectedParameterName, boolean useNames, String id) {
         final ComponentAdapter componentAdapter =
-            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames);
+            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames, id);
         if (componentAdapter == null) {
             final Set<Class> set = new HashSet<Class>();
             set.add(expectedType);
@@ -179,7 +178,7 @@
     private <T> ComponentAdapter<T> resolveAdapter(PicoContainer container,
                                                    ComponentAdapter adapter,
                                                    Class<T> expectedType,
-                                                   ParameterName expectedParameterName, boolean useNames) {
+                                                   ParameterName expectedParameterName, boolean useNames, String id) {
         Class type = expectedType;
         if (type.isPrimitive()) {
             String expectedTypeName = expectedType.getName();
@@ -202,7 +201,7 @@
             }
         }
 
-        final ComponentAdapter<T> result = getTargetAdapter(container, type, expectedParameterName, adapter, useNames);
+        final ComponentAdapter<T> result = getTargetAdapter(container, type, expectedParameterName, adapter, useNames, id);
         if (result == null) {
             return null;
         }
@@ -223,7 +222,7 @@
     private <T> ComponentAdapter<T> getTargetAdapter(PicoContainer container,
                                                      Class<T> expectedType,
                                                      ParameterName expectedParameterName,
-                                                     ComponentAdapter excludeAdapter, boolean useNames) {
+                                                     ComponentAdapter excludeAdapter, boolean useNames, String id) {
         if (componentKey != null) {
             // key tells us where to look so we follow
             return typeComponentAdapter(container.getComponentAdapter(componentKey));
@@ -244,7 +243,7 @@
                     return (ComponentAdapter<T>) found;                    
                 }
             }
-            List<ComponentAdapter<T>> found = container.getComponentAdapters(expectedType);
+            List<ComponentAdapter<T>> found = container.getComponentAdapters(expectedType, id);
             ComponentAdapter exclude = null;
             for (ComponentAdapter work : found) {
                 if (work.getComponentKey().equals(excludeKey)) {
Index: pico/container/src/java/org/picocontainer/parameters/ConstantParameter.java
===================================================================
--- pico/container/src/java/org/picocontainer/parameters/ConstantParameter.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/parameters/ConstantParameter.java	(working copy)
@@ -45,7 +45,7 @@
                                   ComponentAdapter adapter,
                                   Class expectedType,
                                   ParameterName expectedParameterName,
-                                  boolean useNames) {
+                                  boolean useNames, String id) {
         return value;
     }
 
@@ -53,9 +53,9 @@
                                 ComponentAdapter adapter,
                                 Class expectedType,
                                 ParameterName expectedParameterName,
-                                boolean useNames) {
+                                boolean useNames, String id) {
         try {
-            verify(container, adapter, expectedType, expectedParameterName, useNames);
+            verify(container, adapter, expectedType, expectedParameterName, useNames, id);
             return true;
         } catch(final PicoCompositionException e) {
             return false;
@@ -65,13 +65,13 @@
     /**
      * {@inheritDoc}
      *
-     * @see Parameter#verify(PicoContainer,ComponentAdapter,Class,ParameterName,boolean)
+     * @see Parameter#verify(PicoContainer, ComponentAdapter, Class, ParameterName,boolean, String)
      */
     public void verify(PicoContainer container,
                        ComponentAdapter adapter,
                        Class expectedType,
                        ParameterName expectedParameterName,
-                       boolean useNames) throws PicoException {
+                       boolean useNames, String id) throws PicoException {
         if (!checkPrimitive(expectedType) && !expectedType.isInstance(value)) {
             throw new PicoCompositionException(expectedType.getClass().getName() + " is not assignable from " +
                                                  (value != null ? value.getClass().getName() : "null"));
Index: pico/container/src/java/org/picocontainer/PicoContainer.java
===================================================================
--- pico/container/src/java/org/picocontainer/PicoContainer.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/PicoContainer.java	(working copy)
@@ -98,6 +98,8 @@
      */
     <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType);
 
+    <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId);
+
     /**
      * Returns a List of components of a certain componentType. The list is ordered by instantiation order, starting
      * with the components instantiated first at the beginning.
Index: pico/container/src/java/org/picocontainer/DefaultPicoContainer.java
===================================================================
--- pico/container/src/java/org/picocontainer/DefaultPicoContainer.java	(revision 4034)
+++ pico/container/src/java/org/picocontainer/DefaultPicoContainer.java	(working copy)
@@ -263,14 +263,19 @@
     }
 
     public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType) {
+        return getComponentAdapters(componentType,  null);
+    }
+
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
         if (componentType == null) {
             return Collections.emptyList();
         }
         List<ComponentAdapter<T>> found = new ArrayList<ComponentAdapter<T>>();
         for (ComponentAdapter<?> componentAdapter : getComponentAdapters()) {
-            if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) {
-                ComponentAdapter<T> typedComponentAdapter = typeComponentAdapter(componentAdapter);
-                found.add(typedComponentAdapter);
+            Object k = componentAdapter.getComponentKey();
+            if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation()) &&
+                (!(k instanceof BindKey) || (k instanceof BindKey && (((BindKey)k).getId() == null || ((BindKey)k).getId().equals(bindId))))) {
+                found.add((ComponentAdapter<T>)typeComponentAdapter(componentAdapter));
             }
         }
         return found;
Index: pico/container/src/java/org/picocontainer/injectors/SingleMemberInjector.java
===================================================================
--- pico/container/src/java/org/picocontainer/injectors/SingleMemberInjector.java	(revision 4011)
+++ pico/container/src/java/org/picocontainer/injectors/SingleMemberInjector.java	(working copy)
@@ -13,9 +13,12 @@
 import org.picocontainer.Parameter;
 import org.picocontainer.ParameterName;
 import org.picocontainer.PicoContainer;
+import org.picocontainer.annotations.Bind;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 
 import com.thoughtworks.paranamer.CachingParanamer;
@@ -69,7 +72,7 @@
     }
 
 
-    protected Object[] getMemberArguments(PicoContainer container, final AccessibleObject member, final Class[] parameterTypes) {
+    protected Object[] getMemberArguments(PicoContainer container, final AccessibleObject member, final Class[] parameterTypes, final String[] bindingIds) {
         for (int i = 0; i < parameterTypes.length; i++) {
             parameterTypes[i] = box(parameterTypes[i]);
 
@@ -80,11 +83,25 @@
         for (int i = 0; i < currentParameters.length; i++) {
             result[i] = currentParameters[i].resolveInstance(container, this, parameterTypes[i],
                                                              new SingleMemberInjectorParameterName(member, i),
-                                                             useNames());
+                                                             useNames(), bindingIds[i]);
         }
         return result;
     }
 
+    protected String[] getBindIds(Annotation[][] annotationss) {
+        String[] retVal = new String[annotationss.length];
+        for (int i = 0; i < annotationss.length; i++) {
+            Annotation[] annotations = annotationss[i];
+            for (int j = 0; j < annotations.length; j++) {
+                Annotation annotation = annotations[j];
+                if (annotation instanceof Bind) {
+                    retVal[i] = ((Bind) annotation).id();
+                    break;
+                }
+            }
+        }
+        return retVal;
+    }
 
 
     protected class SingleMemberInjectorParameterName implements ParameterName {
Index: pico/container/src/java/org/picocontainer/injectors/MethodInjector.java
===================================================================
--- pico/container/src/java/org/picocontainer/injectors/MethodInjector.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/injectors/MethodInjector.java	(working copy)
@@ -14,7 +14,6 @@
 import org.picocontainer.PicoContainer;
 import org.picocontainer.PicoCompositionException;
 import org.picocontainer.LifecycleStrategy;
-import org.picocontainer.behaviors.Cached;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -114,7 +113,7 @@
     }
 
     protected Object[] getMemberArguments(PicoContainer container, final Method method) {
-        return super.getMemberArguments(container, method, method.getParameterTypes());
+        return super.getMemberArguments(container, method, method.getParameterTypes(), getBindIds(method.getParameterAnnotations()));
     }
 
 
@@ -127,7 +126,8 @@
                     final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
                     for (int i = 0; i < currentParameters.length; i++) {
                         currentParameters[i].verify(container, MethodInjector.this, parameterTypes[i],
-                                                    new SingleMemberInjectorParameterName(method, i), useNames());
+                                                    new SingleMemberInjectorParameterName(method, i), useNames(),
+                                                    getBindIds(method.getParameterAnnotations())[i]);
                     }
                     return null;
                 }
Index: pico/container/src/java/org/picocontainer/injectors/AnnotatedFieldInjector.java
===================================================================
--- pico/container/src/java/org/picocontainer/injectors/AnnotatedFieldInjector.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/injectors/AnnotatedFieldInjector.java	(working copy)
@@ -13,10 +13,11 @@
 import org.picocontainer.LifecycleStrategy;
 import org.picocontainer.Parameter;
 import org.picocontainer.ParameterName;
+import org.picocontainer.annotations.Bind;
 
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.AccessibleObject;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -42,17 +43,27 @@
 
     protected void initializeInjectionMembersAndTypeLists() {
         injectionMembers = new ArrayList<AccessibleObject>();
+        List<String> bindingIds = new ArrayList<String>();
         final List<Class> typeList = new ArrayList<Class>();
         final Field[] fields = getFields();
         for (final Field field : fields) {
             if (isAnnotatedForInjection(field)) {
                 injectionMembers.add(field);
                 typeList.add(box(field.getType()));
+                bindingIds.add(getBindingId(field));
             }
         }
         injectionTypes = typeList.toArray(new Class[0]);
+        bindIds = bindingIds.toArray(new String[0]);
     }
 
+    private String getBindingId(Field field) {
+        if (field.getAnnotation(Bind.class) != null) {
+            return ((Bind) field.getAnnotation(Bind.class)).id();
+        }
+        return null;
+    }
+
     protected boolean isAnnotatedForInjection(Field field) {
         return field.getAnnotation(injectionAnnotation) != null;
     }
Index: pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java
===================================================================
--- pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java	(revision 4011)
+++ pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java	(working copy)
@@ -11,11 +11,13 @@
 package org.picocontainer.injectors;
 
 import org.picocontainer.ComponentMonitor;
+import org.picocontainer.LifecycleStrategy;
 import org.picocontainer.Parameter;
+import org.picocontainer.PicoCompositionException;
 import org.picocontainer.PicoContainer;
-import org.picocontainer.PicoCompositionException;
-import org.picocontainer.LifecycleStrategy;
+import org.picocontainer.annotations.Bind;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Modifier;
@@ -74,6 +76,7 @@
         for (final Constructor<T> sortedMatchingConstructor : sortedMatchingConstructors) {
             boolean failedDependency = false;
             Class[] parameterTypes = sortedMatchingConstructor.getParameterTypes();
+            String[] bindIds = getBindIds(sortedMatchingConstructor.getParameterAnnotations());
             Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
 
             // remember: all constructors with less arguments than the given parameters are filtered out already
@@ -82,7 +85,7 @@
                 Class boxed = box(parameterTypes[j]);
                 boolean un = useNames();
                 if (currentParameters[j].isResolvable(container, this, boxed,
-                    new SingleMemberInjectorParameterName(sortedMatchingConstructor, j), un)) {
+                    new SingleMemberInjectorParameterName(sortedMatchingConstructor, j), un, bindIds[j])) {
                     continue;
                 }
                 unsatisfiableDependencyTypes.add(Arrays.asList(parameterTypes));
@@ -123,6 +126,7 @@
         return greediestConstructor;
     }
 
+
     public T getComponentInstance(final PicoContainer container) throws PicoCompositionException {
         if (instantiationGuard == null) {
             instantiationGuard = new ThreadLocalCyclicDependencyGuard<T>() {
@@ -166,7 +170,7 @@
     }
 
     protected Object[] getMemberArguments(PicoContainer container, final Constructor ctor) {
-        return super.getMemberArguments(container, ctor, ctor.getParameterTypes());
+        return super.getMemberArguments(container, ctor, ctor.getParameterTypes(), getBindIds(ctor.getParameterAnnotations()));
     }
 
     private List<Constructor<T>> getSortedMatchingConstructors() {
@@ -206,7 +210,8 @@
                     final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
                     for (int i = 0; i < currentParameters.length; i++) {
                         currentParameters[i].verify(container, ConstructorInjector.this, box(parameterTypes[i]),
-                                                    new SingleMemberInjectorParameterName(constructor, i), useNames());
+                                                    new SingleMemberInjectorParameterName(constructor, i), useNames(),
+                                                    getBindIds(constructor.getParameterAnnotations())[i]);
                     }
                     return null;
                 }
Index: pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java
===================================================================
--- pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java	(working copy)
@@ -6,12 +6,14 @@
 import org.picocontainer.ParameterName;
 import org.picocontainer.PicoCompositionException;
 import org.picocontainer.PicoContainer;
+import org.picocontainer.annotations.Bind;
 
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -30,6 +32,7 @@
     private transient ThreadLocalCyclicDependencyGuard instantiationGuard;
     protected transient List<AccessibleObject> injectionMembers;
     protected transient Class[] injectionTypes;
+    protected transient String[] bindIds;
     private transient CachingParanamer paranamer = new CachingParanamer();
 
     /**
@@ -82,8 +85,16 @@
             final Parameter parameter = currentParameters[i];
             boolean failedDependency = true;
             for (int j = 0; j < injectionTypes.length; j++) {
-                if (matchingParameterList.get(j) == null &&
-                    parameter.isResolvable(container, this, injectionTypes[j], makeParameterNameImpl(injectionMembers.get(i)), useNames())) {
+                Object o = matchingParameterList.get(j);
+                AccessibleObject member = injectionMembers.get(i);
+                boolean b = parameter.isResolvable(container,
+                                                   this,
+                                                   injectionTypes[j],
+                                                   makeParameterNameImpl(member),
+                                                   useNames(),
+                                                   bindIds[j]);
+                if (o == null &&
+                    b) {
                     matchingParameterList.set(j, parameter);
                     failedDependency = false;
                     break;
@@ -137,7 +148,8 @@
                             }
                             Object toInject = matchingParameters[i].resolveInstance(guardedContainer, IterativeInjector.this, injectionTypes[i],
                                                                                     makeParameterNameImpl(injectionMembers.get(i)),
-                                                                                    useNames());
+                                                                                    useNames(),
+                                                                                    bindIds[i]);
                             injectIntoMember(member, componentInstance, toInject);
                             injected[i] = toInject;
                         }
@@ -198,7 +210,7 @@
                     final Parameter[] currentParameters = getMatchingParameterListForSetters(guardedContainer);
                     for (int i = 0; i < currentParameters.length; i++) {
                         currentParameters[i].verify(container, IterativeInjector.this, injectionTypes[i],
-                                                    makeParameterNameImpl(injectionMembers.get(i)), useNames());
+                                                    makeParameterNameImpl(injectionMembers.get(i)), useNames(), bindIds[i]);
                     }
                     return null;
                 }
@@ -210,6 +222,7 @@
 
     protected void initializeInjectionMembersAndTypeLists() {
         injectionMembers = new ArrayList<AccessibleObject>();
+        List<String> bingingIds = new ArrayList<String>();
         final List<Class> typeList = new ArrayList<Class>();
         final Method[] methods = getMethods();
         for (final Method method : methods) {
@@ -220,12 +233,34 @@
                 if (isInjector) {
                     injectionMembers.add(method);
                     typeList.add(box(parameterTypes[0]));
+                    bingingIds.add(getBindingIds(method, 0));
                 }
             }
         }
         injectionTypes = typeList.toArray(new Class[0]);
+        bindIds = bingingIds.toArray(new String[0]);
     }
 
+    private String getBindingIds(Method method, int i) {
+        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        if (parameterAnnotations.length >= i +1 ) {
+            Annotation[] o = parameterAnnotations[i];
+            for (int j = 0; j < o.length; j++) {
+                Annotation annotation = o[j];
+                if (o[j] instanceof Bind) {
+                    return ((Bind) o[j]).id();
+                }
+            }
+            return null;
+
+        }
+        if (parameterAnnotations != null) {
+            return ((Bind) method.getAnnotation(Bind.class)).id();
+        }
+        return null;
+
+    }
+
     protected boolean isInjectorMethod(Method method) {
         return false;
     }
Index: pico/container/src/java/org/picocontainer/containers/AbstractDelegatingPicoContainer.java
===================================================================
--- pico/container/src/java/org/picocontainer/containers/AbstractDelegatingPicoContainer.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/containers/AbstractDelegatingPicoContainer.java	(working copy)
@@ -67,7 +67,11 @@
 		return delegate.getComponentAdapters(componentType);
 	}
 
-	public List getComponents() {
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+        return delegate.getComponentAdapters(componentType, bindId);
+    }
+
+    public List getComponents() {
 		return delegate.getComponents();
 	}
 
Index: pico/container/src/java/org/picocontainer/containers/EmptyPicoContainer.java
===================================================================
--- pico/container/src/java/org/picocontainer/containers/EmptyPicoContainer.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/containers/EmptyPicoContainer.java	(working copy)
@@ -60,6 +60,10 @@
         return Collections.emptyList();
     }
 
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+        return Collections.emptyList();
+    }
+
     /**
      * we do not have anything to do here. 
      */
Index: pico/container/src/java/org/picocontainer/containers/ImmutablePicoContainer.java
===================================================================
--- pico/container/src/java/org/picocontainer/containers/ImmutablePicoContainer.java	(revision 4004)
+++ pico/container/src/java/org/picocontainer/containers/ImmutablePicoContainer.java	(working copy)
@@ -67,6 +67,10 @@
         return delegate.getComponentAdapters(componentType);
     }
 
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+        return delegate.getComponentAdapters(componentType, bindId);
+    }
+
     public <T> List<T> getComponents(Class<T> componentType) {
         return delegate.getComponents(componentType);
     }
Index: pico/container/src/java/org/picocontainer/BindKey.java
===================================================================
--- pico/container/src/java/org/picocontainer/BindKey.java	(revision 0)
+++ pico/container/src/java/org/picocontainer/BindKey.java	(revision 0)
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Committers. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *                                                                           *
+ * Original code by Joerg Schaibe                                            *
+ *****************************************************************************/
+package org.picocontainer;
+
+/** @author Paul Hammant */
+public class BindKey {
+    private final Class type;
+    private final String id;
+
+    public BindKey(Class type, String id) {
+        this.type = type;
+        this.id = id;
+    }
+
+    public Class getType() {
+        return type;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String toString() {
+        return type.getName() + ":" + id;   
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BindKey bindKey = (BindKey)o;
+
+        if (!id.equals(bindKey.id)) return false;
+        if (!type.equals(bindKey.type)) return false;
+
+        return true;
+    }
+
+    public int hashCode() {
+        int result;
+        result = type.hashCode();
+        result = 31 * result + id.hashCode();
+        return result;
+    }
+
+    public static BindKey bindKey(Class type, String bindingId) {
+        return new BindKey(type, bindingId);
+    }
+
+}
Index: pico/gems/src/test/org/picocontainer/gems/behaviors/AssimilatedTestCase.java
===================================================================
--- pico/gems/src/test/org/picocontainer/gems/behaviors/AssimilatedTestCase.java	(revision 4004)
+++ pico/gems/src/test/org/picocontainer/gems/behaviors/AssimilatedTestCase.java	(working copy)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) NanoContainer Organization. All rights reserved.            *
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
  * ------------------------------------------------------------------------- *
  * The software in this package is published under the terms of the BSD      *
  * style license a copy of which has been included with this distribution in *
Index: pico/gems/src/test/org/picocontainer/gems/constraints/ConstraintsTestCase.java
===================================================================
--- pico/gems/src/test/org/picocontainer/gems/constraints/ConstraintsTestCase.java	(revision 4004)
+++ pico/gems/src/test/org/picocontainer/gems/constraints/ConstraintsTestCase.java	(working copy)
@@ -47,7 +47,7 @@
 
         Object object = c.resolveInstance(container, 
                 container.getComponentAdapter(DependsOnTouchable.class, null),
-                Touchable.class, null, false);
+                Touchable.class, null, false, null);
         assertEquals(SimpleTouchable.class, object.getClass());
     }
 
@@ -56,7 +56,7 @@
 
         Object object = c.resolveInstance(container, 
                 container.getComponentAdapter(DependsOnTouchable.class, null),
-                Touchable.class, null, false);
+                Touchable.class, null, false, null);
         assertEquals(AlternativeTouchable.class, object.getClass());
     }
 
@@ -70,7 +70,7 @@
 
         assertSame(t, c.resolveInstance(container, 
                 container.getComponentAdapter(DependsOnTouchable.class, null),
-                Touchable.class, null, false));
+                Touchable.class, null, false, null));
     }
 
     public void testConstraintTooBroadThrowsAmbiguityException() {
@@ -79,7 +79,7 @@
         try {
             c.resolveInstance(container, 
                     container.getComponentAdapter(DependsOnTouchable.class, null),
-                    Touchable.class, null, false);
+                    Touchable.class, null, false, null);
             fail("did not throw ambiguous resolution exception");
         } catch (AbstractInjector.AmbiguousComponentResolutionException acre) {
             // success
@@ -93,7 +93,7 @@
                 new Not(new IsType(DecoratedTouchable.class))));
         Touchable[] touchables = (Touchable[]) c.resolveInstance(container, 
                 container.getComponentAdapter(DependsOnTouchable.class, null),
-                Touchable[].class, null, false);
+                Touchable[].class, null, false, null);
         assertEquals(2, touchables.length);
         for (Touchable touchable : touchables) {
             assertFalse(touchable instanceof DecoratedTouchable);
Index: pico/gems/src/java/org/picocontainer/gems/containers/CommonsLoggingTracingContainerDecorator.java
===================================================================
--- pico/gems/src/java/org/picocontainer/gems/containers/CommonsLoggingTracingContainerDecorator.java	(revision 4004)
+++ pico/gems/src/java/org/picocontainer/gems/containers/CommonsLoggingTracingContainerDecorator.java	(working copy)
@@ -204,6 +204,14 @@
         return delegate.getComponentAdapters(componentType);
     }
 
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+        if (log.isDebugEnabled()) {
+            log.debug("Grabbing all component adapters for container: "
+                      + delegate + " of type: " + componentType.getName() + ", bindId:" + bindId);
+        }
+        return delegate.getComponentAdapters(componentType, bindId);
+    }
+
     /**
      * {@inheritDoc}
      *
Index: pico/gems/src/java/org/picocontainer/gems/containers/Log4jTracingContainerDecorator.java
===================================================================
--- pico/gems/src/java/org/picocontainer/gems/containers/Log4jTracingContainerDecorator.java	(revision 4004)
+++ pico/gems/src/java/org/picocontainer/gems/containers/Log4jTracingContainerDecorator.java	(working copy)
@@ -228,6 +228,14 @@
         return delegate.getComponentAdapters(componentType);
     }
 
+    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Grabbing all component adapters for container: " + delegate + " of type: "
+                         + componentType.getName() + ", bindId:" + bindId);
+        }
+        return delegate.getComponentAdapters(componentType, bindId);
+    }
+
     /**
      * {@inheritDoc}
      *
Index: pico/gems/src/java/org/picocontainer/gems/constraints/AbstractConstraint.java
===================================================================
--- pico/gems/src/java/org/picocontainer/gems/constraints/AbstractConstraint.java	(revision 4004)
+++ pico/gems/src/java/org/picocontainer/gems/constraints/AbstractConstraint.java	(working copy)
@@ -33,11 +33,11 @@
     public Object resolveInstance(PicoContainer container,
                                   ComponentAdapter adapter,
                                   Class expectedType,
-                                  ParameterName expectedParameterName, boolean useNames) throws PicoCompositionException
+                                  ParameterName expectedParameterName, boolean useNames, String id) throws PicoCompositionException
     {
         final Object[] array =
             (Object[])super.resolveInstance(container, adapter, getArrayType(expectedType), expectedParameterName,
-                                            useNames);
+                                            useNames, null);
         if (array.length == 1) {
             return array[0];
         }
@@ -47,17 +47,17 @@
     public boolean isResolvable(PicoContainer container,
                                 ComponentAdapter adapter,
                                 Class expectedType,
-                                ParameterName expectedParameterName, boolean useNames) throws PicoCompositionException
+                                ParameterName expectedParameterName, boolean useNames, String id) throws PicoCompositionException
     {
-        return super.isResolvable(container, adapter, getArrayType(expectedType), expectedParameterName, useNames);
+        return super.isResolvable(container, adapter, getArrayType(expectedType), expectedParameterName, useNames, id);
     }
 
     public void verify(PicoContainer container,
                        ComponentAdapter adapter,
                        Class expectedType,
-                       ParameterName expectedParameterName, boolean useNames) throws PicoCompositionException
+                       ParameterName expectedParameterName, boolean useNames, String id) throws PicoCompositionException
     {
-        super.verify(container, adapter, getArrayType(expectedType), expectedParameterName, useNames);
+        super.verify(container, adapter, getArrayType(expectedType), expectedParameterName, useNames, id);
     }
 
     public abstract boolean evaluate(ComponentAdapter adapter);
Index: nano/container/src/test/org/nanocontainer/script/xml/NonMutablePicoContainerContainerTestCase.java
===================================================================
--- nano/container/src/test/org/nanocontainer/script/xml/NonMutablePicoContainerContainerTestCase.java	(revision 4004)
+++ nano/container/src/test/org/nanocontainer/script/xml/NonMutablePicoContainerContainerTestCase.java	(working copy)
@@ -80,6 +80,10 @@
             return null;
         }
 
+        public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+            return null;
+        }
+
         public void start() {
         }
 
Index: nano/container/src/java/org/nanocontainer/DefaultNanoContainer.java
===================================================================
--- nano/container/src/java/org/nanocontainer/DefaultNanoContainer.java	(revision 4004)
+++ nano/container/src/java/org/nanocontainer/DefaultNanoContainer.java	(working copy)
@@ -465,6 +465,10 @@
             return DefaultNanoContainer.this.getComponentAdapters(componentType);
         }
 
+        public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, String bindId) {
+            return DefaultNanoContainer.this.getComponentAdapters(componentType, bindId);
+        }
+
         public <T> List<T> getComponents(Class<T> componentType) {
             return DefaultNanoContainer.this.getComponents();
         }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.