FELIX-4112 Add meta-annotations for handler description

* @HandlerBinding can be used to declare an annotation as a handler
  annotation (will produce Elements in the metadata structure). The
  supporting annotation type do not have to be in a package containing
  'handler' or 'ipojo'
* @Ignore can be used to ignore an annotation that would be (otherwise)
  mapped to a custom handler annotation (because it contains 'handler'
  or 'ipojo' in its name)
* Unified support for @Stereotype, @HandlerBinding and @Ignore
* Merged BindingRegistry and AnnotationBindingRegistry into 1 entity
** Implementation is split into 3 delegating registries for better
   separation of concerns
* Module DSL improved to support @Stereotype, @HandlerBinding and
  @Ignore registration
* Added annotations javadoc


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1507289 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerBinding.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerBinding.java
new file mode 100644
index 0000000..f18f4c4
--- /dev/null
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerBinding.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * A @{@link HandlerBinding} bind its annotated type to a given handler.
+ *
+ * The handler name is specified as parameter using the {@literal 'namespace:name'} format (qualified name).
+ *
+ * <pre>
+ *     // Namespace and name will be inferred from the annotation's package name.
+ *     &#64;HandlerBinding()
+ *     public &#64;interface Foo {}
+ *
+ *     // No namespace declared, default will be used ('org.apache.felix.ipojo')
+ *     &#64;HandlerBinding("foo")
+ *     public &#64;interface Foo {}
+ *
+ *     // Namespace will be 'com.acme' and name: 'foo'
+ *     &#64;HandlerBinding("com.acme:foo")
+ *     public &#64;interface Foo {}
+ *
+ *     // Provided namespace and value (for the name) will be used
+ *     &#64;HandlerBinding(namespace = "com.acme", value = "foo")
+ *     public &#64;interface Foo {}
+ * </pre>
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface HandlerBinding {
+    String DEFAULT = "#";
+
+    /**
+     * Defines the handler's namespace. Must be used in correlation with the {@literal value} attribute.
+     * <pre>
+     *     &#64;HandlerBinding(namespace = "com.acme", value = "foo")
+     *     public &#64;interface Foo {}
+     * </pre>
+     */
+    String namespace() default DEFAULT;
+
+    /**
+     * When used <b>without</b> the {@literal namespace} attribute, defines both the namespace + name
+     * of a handler in a short notation (if no namespace can be found in the parameter - no ':' separator - fallback
+     * on iPOJO's default namespace):
+     *
+     * <pre>
+     *     &#64;HandlerBinding("com.acme:foo")
+     *     public &#64;interface Foo {}
+     * </pre>
+     *
+     * When used <b>with</b> the {@literal namespace} attribute, holds the name of the handler (without
+     * its namespace part):
+     *
+     * <pre>
+     *     &#64;HandlerBinding(namesapce = "com.acme", value = "foo")
+     *     public &#64;interface Foo {}
+     * </pre>
+     */
+    String value() default DEFAULT;
+}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Ignore.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Ignore.java
new file mode 100644
index 0000000..ceb4171
--- /dev/null
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Ignore.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * A @{@link Ignore} annotation mark its annotated type to be ignored by the iPOJO manipulator.
+ * This is handy when the annotation could be recognized as a "custom annotation handler" (contains {@literal ".ipojo."}
+ * or {@literal ".handler."} in its package name) but in fact is not a handler annotation at all.
+ *
+ * <pre>
+ *     package com.acme.ipojo.handler;
+ *     &#64;Ignore
+ *     public &#64;interface Foo {}
+ * </pre>
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface Ignore {}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java
index e4cb647..efb8369 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java
@@ -24,7 +24,46 @@
 import java.lang.annotation.Target;
 
 /**
- * Mark the annotated annotation type to be a marker annotation dedicated to an iPOJO handler.
+ * In many systems, use of architectural patterns produces a set of recurring roles. A stereotype allows a
+ * framework developer to identify such a role and declare some common metadata for objects with that role
+ * in a central place.
+ *
+ * A stereotype is an annotation, annotated with {@literal @Stereotype}, that captures several other annotations.
+ *
+ * For example, the following stereotype defines a @PseudoSingletonComponent annotation, that will act,
+ * when applied on a component, just like if @Component and @Instantiate where directly applied on the target component.
+ * <pre>
+ *
+ *     &#64;Component
+ *     &#64;Instantiate
+ *     &#64;Stereotype
+ *     &#64;Target(TYPE)
+ *     &#64;Retention(CLASS)
+ *     public &#64;interface PseudoSingletonComponent {}
+ *
+ * </pre>
+ *
+ * Usage:
+ * <pre>
+ *
+ *     &#64;PseudoSingletonComponent
+ *     public class HelloWorldComponent {
+ *       // ...
+ *     }
+ *
+ * </pre>
+ *
+ * Equivalent to:
+ * <pre>
+ *
+ *     &#64;Component
+ *     &#64;Instantiate
+ *     public class HelloWorldComponent {
+ *       // ...
+ *     }
+ *
+ * </pre>
+ *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @Target(ElementType.ANNOTATION_TYPE)
diff --git a/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/HandlerBindingTestComponent.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/HandlerBindingTestComponent.java
new file mode 100644
index 0000000..85e7c7b
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/HandlerBindingTestComponent.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.runtime.core.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Instantiate;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.runtime.core.handlers.Foo;
+import org.apache.felix.ipojo.runtime.core.handlers.IgnoredFoo;
+import org.apache.felix.ipojo.runtime.core.services.HandlerBindingTestService;
+
+/**
+ * User: guillaume
+ * Date: 24/07/13
+ * Time: 12:31
+ */
+@Component
+@Provides
+@Instantiate
+public class HandlerBindingTestComponent implements HandlerBindingTestService {
+
+    @Foo("Bonjour")
+    private String greeting;
+
+    @Foo("Welcome")
+    private String welcome;
+
+    @IgnoredFoo("Ignored")
+    private String ignored;
+
+    @Override
+    public String get(final String name) {
+        if ("greeting".equals(name)) {
+            return greeting;
+        }
+        if ("welcome".equals(name)) {
+            return welcome;
+        }
+        if ("ignored".equals(name)) {
+            return ignored;
+        }
+        throw new IllegalArgumentException(name + " is not valid");
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/Foo.java
similarity index 63%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/Foo.java
index 1748cfc..79e93d7 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/Foo.java
@@ -17,15 +17,23 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.runtime.core.handlers;
 
-import org.objectweb.asm.AnnotationVisitor;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.felix.ipojo.annotations.HandlerBinding;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 24/07/13
+ * Time: 12:10
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.CLASS)
+@HandlerBinding("com.acme:foo")
+public @interface Foo {
+    String value();
 }
diff --git a/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/FooHandler.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/FooHandler.java
new file mode 100644
index 0000000..cc86c67
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/FooHandler.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.runtime.core.handlers;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.FieldInterceptor;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.annotations.Handler;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * User: guillaume
+ * Date: 24/07/13
+ * Time: 12:08
+ */
+@Handler(namespace = "com.acme", name = "foo")
+public class FooHandler extends PrimitiveHandler {
+
+    @Override
+    public void configure(final Element metadata, final Dictionary configuration) throws ConfigurationException {
+        Element[] elements = metadata.getElements("foo", "com.acme");
+        for (Element foo : elements) {
+            String value = foo.getAttribute("value");
+            String field = foo.getAttribute("field");
+
+            this.getInstanceManager().register(getPojoMetadata().getField(field, "java.lang.String"),
+                                               new FixedValueFieldInterceptor(value));
+
+        }
+
+    }
+
+    @Override
+    public Object onGet(final Object pojo, final String fieldName, final Object value) {
+        return value;
+    }
+
+    @Override
+    public void stop() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void start() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    private static class FixedValueFieldInterceptor implements FieldInterceptor {
+        private final String m_value;
+
+        public FixedValueFieldInterceptor(final String value) {
+            m_value = value;
+        }
+
+        @Override
+        public void onSet(final Object pojo, final String fieldName, final Object value) {
+            //To change body of implemented methods use File | Settings | File Templates.
+        }
+
+        @Override
+        public Object onGet(final Object pojo, final String fieldName, final Object value) {
+            return m_value;
+        }
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/IgnoredFoo.java
similarity index 61%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/IgnoredFoo.java
index 1748cfc..ccbff86 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/handlers/IgnoredFoo.java
@@ -17,15 +17,24 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.runtime.core.handlers;
 
-import org.objectweb.asm.AnnotationVisitor;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.felix.ipojo.annotations.HandlerBinding;
+import org.apache.felix.ipojo.annotations.Ignore;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 24/07/13
+ * Time: 12:10
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.CLASS)
+@Ignore
+public @interface IgnoredFoo {
+    String value();
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/HandlerBindingTestService.java
similarity index 75%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/HandlerBindingTestService.java
index 1748cfc..120d60b 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/HandlerBindingTestService.java
@@ -17,15 +17,13 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
-
-import org.objectweb.asm.AnnotationVisitor;
+package org.apache.felix.ipojo.runtime.core.services;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 24/07/13
+ * Time: 12:36
+ */
+public interface HandlerBindingTestService {
+    String get(String name);
 }
diff --git a/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestHandlerBindingAndIgnoreAnnotation.java b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestHandlerBindingAndIgnoreAnnotation.java
new file mode 100644
index 0000000..d70ea33
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestHandlerBindingAndIgnoreAnnotation.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.runtime.core;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.runtime.core.services.BazService;
+import org.apache.felix.ipojo.runtime.core.services.HandlerBindingTestService;
+import org.junit.Test;
+import org.ops4j.pax.exam.CoreOptions;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ow2.chameleon.testing.helpers.BaseTest;
+
+import junit.framework.Assert;
+
+public class TestHandlerBindingAndIgnoreAnnotation extends BaseTest {
+
+    public static final String FACTORY_NAME = "org.apache.felix.ipojo.runtime.core.components.HandlerBindingTestComponent";
+
+    @Test
+    public void testFooHandlerBinding() {
+
+/*
+        HandlerFactory handlerFactory = ipojoHelper.getHandlerFactory("com.acme:foo");
+        assertNotNull(handlerFactory);
+        assertEquals(Factory.VALID, handlerFactory.getState());
+*/
+
+        // verify component's factory is here
+        // verify BazService has been published
+        // --> verify instance has been created
+
+        Factory factory = ipojoHelper.getFactory(FACTORY_NAME);
+        assertNotNull(factory);
+        assertEquals(Factory.VALID, factory.getState());
+
+
+        List<HandlerBindingTestService> services = osgiHelper.getServiceObjects(HandlerBindingTestService.class);
+        assertEquals(1, services.size());
+
+        HandlerBindingTestService baz = services.get(0);
+        assertEquals("Bonjour", baz.get("greeting"));
+        assertEquals("Welcome", baz.get("welcome"));
+        assertNull(baz.get("ignored"));
+        ipojoHelper.dispose();
+    }
+    @Override
+    protected List<String> getExtraExports() {
+        return Arrays.asList("org.apache.felix.ipojo.runtime.core.components");
+    }
+
+    @Override
+    protected Option[] getCustomOptions() {
+        return new Option[] {CoreOptions.vmOption("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000")};
+        //return new Option[] {CoreOptions.vmOptions("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000")};
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
index 79a738f..47e65e1 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
@@ -99,15 +99,6 @@
      */
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
 
-    	/*
-    	 * Visible annotations are mostly destined to be read by reflection
-    	 * at runtime. We retain runtime visible annotations on component
-    	 * as they are and left them out in meta-data calculation.
-    	 */
-    	if (visible) {
-    		return null;
-    	}
-    	
         // Return the visitor to be executed (may be null)
         return registry.selection(workbench)
                 .type(this, node)
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationDiscovery.java
similarity index 79%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationDiscovery.java
index 1748cfc..9a533b6 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationDiscovery.java
@@ -17,15 +17,15 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model;
 
 import org.objectweb.asm.AnnotationVisitor;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 14:42
+ */
+public interface AnnotationDiscovery {
+    AnnotationVisitor visitAnnotation(String desc);
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationType.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationType.java
new file mode 100644
index 0000000..4fcbd73
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/AnnotationType.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 27/06/13
+ * Time: 13:37
+ */
+public class AnnotationType {
+    private final Type type;
+    private final List<Playback> m_playbacks = new ArrayList<Playback>();
+
+    public AnnotationType(final Type type) {
+        this.type = type;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public List<Playback> getPlaybacks() {
+        return m_playbacks;
+    }
+
+    public void traverse(AnnotationDiscovery visitor) {
+        for (Playback playback : m_playbacks) {
+            playback.accept(visitor);
+        }
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/Playback.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/Playback.java
new file mode 100644
index 0000000..12802f0
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/Playback.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * User: guillaume
+ * Date: 08/07/13
+ * Time: 16:30
+ */
+public interface Playback {
+    void accept(FieldVisitor visitor);
+
+    void accept(ClassVisitor visitor);
+
+    void accept(MethodVisitor visitor);
+
+    void accept(MethodVisitor visitor, int index);
+
+    void accept(AnnotationDiscovery visitor);
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/ChainedAnnotationDiscovery.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/ChainedAnnotationDiscovery.java
new file mode 100644
index 0000000..caea0b1
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/ChainedAnnotationDiscovery.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.apache.felix.ipojo.manipulator.util.ChainedAnnotationVisitor;
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+ * User: guillaume
+ * Date: 10/07/13
+ * Time: 10:48
+ */
+public class ChainedAnnotationDiscovery implements AnnotationDiscovery {
+
+    private List<AnnotationDiscovery> m_discoveries = new ArrayList<AnnotationDiscovery>();
+
+    public List<AnnotationDiscovery> getDiscoveries() {
+        return m_discoveries;
+    }
+
+    public AnnotationVisitor visitAnnotation(final String desc) {
+        ChainedAnnotationVisitor chain = null;
+        for (AnnotationDiscovery discovery : m_discoveries) {
+            AnnotationVisitor visitor = discovery.visitAnnotation(desc);
+            if (visitor != null) {
+                if (chain == null) {
+                    chain = new ChainedAnnotationVisitor();
+                }
+                chain.getVisitors().add(visitor);
+            }
+        }
+        return chain;
+    }
+
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/HandlerBindingDiscovery.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/HandlerBindingDiscovery.java
new file mode 100644
index 0000000..224f423
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/HandlerBindingDiscovery.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery;
+
+import org.apache.felix.ipojo.annotations.HandlerBinding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 14:52
+ */
+public class HandlerBindingDiscovery extends EmptyVisitor implements AnnotationDiscovery {
+
+    public static final String HANDLER_BINDING_DESCRIPTOR = Type.getType(HandlerBinding.class).getDescriptor();
+
+    private boolean m_handlerBinding = false;
+    private String m_value = null;
+    private String m_namespace = null;
+
+    public AnnotationVisitor visitAnnotation(final String desc) {
+        if (HANDLER_BINDING_DESCRIPTOR.equals(desc)) {
+            m_handlerBinding = true;
+            return this;
+        }
+        return null;
+    }
+
+    @Override
+    public void visit(final String name, final Object value) {
+        if ("value".equals(name)) {
+            m_value = (String) value;
+        }
+        if ("namespace".equals(name)) {
+            m_namespace = (String) value;
+        }
+    }
+
+    public boolean isHandlerBinding() {
+        return m_handlerBinding;
+    }
+
+    public String getValue() {
+        return m_value;
+    }
+
+    public String getNamespace() {
+        return m_namespace;
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/IgnoredDiscovery.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/IgnoredDiscovery.java
new file mode 100644
index 0000000..71c7cc0
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/IgnoredDiscovery.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery;
+
+import org.apache.felix.ipojo.annotations.Ignore;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 14:52
+ */
+public class IgnoredDiscovery implements AnnotationDiscovery {
+
+    public static final String IGNORE_DESCRIPTOR = Type.getType(Ignore.class).getDescriptor();
+
+    private boolean m_ignore = false;
+
+    public AnnotationVisitor visitAnnotation(final String desc) {
+        if (IGNORE_DESCRIPTOR.equals(desc)) {
+            m_ignore = true;
+        }
+        return null;
+    }
+
+    public boolean isIgnore() {
+        return m_ignore;
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/StereotypeDiscovery.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/StereotypeDiscovery.java
new file mode 100644
index 0000000..a8438da
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/discovery/StereotypeDiscovery.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery;
+
+import org.apache.felix.ipojo.annotations.Stereotype;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 14:52
+ */
+public class StereotypeDiscovery implements AnnotationDiscovery {
+
+    public static final String STEREOTYPE_DESCRIPTOR = Type.getType(Stereotype.class).getDescriptor();
+
+    private boolean m_stereotype = false;
+
+    public AnnotationVisitor visitAnnotation(final String desc) {
+        if (STEREOTYPE_DESCRIPTOR.equals(desc)) {
+            m_stereotype = true;
+        }
+        return null;
+    }
+
+    public boolean isStereotype() {
+        return m_stereotype;
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteral.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteral.java
new file mode 100644
index 0000000..6da7dac
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteral.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal;
+
+import static java.lang.String.format;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * User: guillaume
+ * Date: 28/06/13
+ * Time: 11:39
+ */
+public abstract class AnnotationLiteral<T extends Annotation> implements Annotation {
+
+    private Class<? extends Annotation> annotationType;
+
+    public Class<? extends Annotation> annotationType() {
+        if (annotationType == null) {
+            annotationType = findAnnotationType(getClass());
+            if (annotationType == null) {
+                throw new IllegalStateException(
+                        format("Annotation %s does not specify its annotation type (T) in AnnotationLiteral<T>",
+                               getClass().getName())
+                );
+            }
+        }
+        return annotationType;
+    }
+
+    public org.objectweb.asm.Type getType() {
+        return org.objectweb.asm.Type.getType(annotationType());
+    }
+
+    private static Class<Annotation> findAnnotationType(final Class<? extends AnnotationLiteral> type) {
+        Class<?> implementer = findImplementer(type);
+        return findTypeParameter(implementer);
+    }
+
+    private static Class<Annotation> findTypeParameter(final Class<?> clazz) {
+        // Get the T of AnnotationLiteral<T>
+        Type type = clazz.getGenericSuperclass();
+        if (type instanceof ParameterizedType) {
+            ParameterizedType pType = (ParameterizedType) type;
+            return (Class<Annotation>) pType.getActualTypeArguments()[0];
+        }
+        return null;
+    }
+
+    private static Class<? extends AnnotationLiteral> findImplementer(final Class<? extends AnnotationLiteral> type) {
+        Class<? extends AnnotationLiteral> superClass = type.getSuperclass().asSubclass(AnnotationLiteral.class);
+        if (AnnotationLiteral.class.equals(superClass)) {
+            return type;
+        } else {
+            return findImplementer(superClass);
+        }
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlayback.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlayback.java
new file mode 100644
index 0000000..3b7a529
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlayback.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal;
+
+import static java.lang.String.format;
+import static org.objectweb.asm.Type.getType;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 08/07/13
+ * Time: 17:15
+ */
+public class AnnotationPlayback implements Playback {
+
+    public static final List<? extends Class<? extends Serializable>> BOXED_TYPES = Arrays.asList(Byte.class, Long.class, Character.class, Boolean.class, Double.class, Float.class, Integer.class, Short.class);
+    private final Annotation m_annotation;
+    private final Type m_annotationType;
+
+    public AnnotationPlayback(final Annotation annotation) {
+        m_annotation = annotation;
+        m_annotationType = Type.getType(annotation.annotationType());
+    }
+
+    private Map<String, Object> getValues() {
+        Map<String, Object> values = new HashMap<String, Object>();
+        for (Method method : m_annotation.annotationType().getDeclaredMethods()) {
+            try {
+                values.put(method.getName(), method.invoke(m_annotation));
+            } catch (Throwable t) {
+                throw new IllegalStateException(
+                        format("Cannot get value of the %s.%s attribute",
+                               m_annotation.annotationType().getSimpleName(),
+                               method.getName()),
+                        t
+                );
+            }
+        }
+        return values;
+    }
+    public void accept(final FieldVisitor visitor) {
+        AnnotationVisitor av = visitor.visitAnnotation(m_annotationType.getDescriptor(),
+                                                       true);
+        if (av != null) {
+            accept(av);
+        }
+    }
+
+    public void accept(final ClassVisitor visitor) {
+        AnnotationVisitor av = visitor.visitAnnotation(m_annotationType.getDescriptor(),
+                                                       true);
+        if (av != null) {
+            accept(av);
+        }
+    }
+
+    public void accept(final MethodVisitor visitor) {
+        AnnotationVisitor av = visitor.visitAnnotation(m_annotationType.getDescriptor(),
+                                                       true);
+        if (av != null) {
+            accept(av);
+        }
+    }
+
+    public void accept(final MethodVisitor visitor, final int index) {
+        AnnotationVisitor av = visitor.visitParameterAnnotation(index,
+                                                                m_annotationType.getDescriptor(),
+                                                                true);
+        if (av != null) {
+            accept(av);
+        }
+    }
+
+    public void accept(final AnnotationDiscovery visitor) {
+        AnnotationVisitor av = visitor.visitAnnotation(m_annotationType.getDescriptor());
+        if (av != null) {
+            accept(av);
+        }
+    }
+
+    private void accept(final AnnotationVisitor visitor) {
+        // As per the ASM doc, visit methods must be called in a given order:
+        // 1. visit()
+        // 2. visitEnum()
+        // 3. visitAnnotation()
+        // 4. visitArray()
+
+        // So values must be sorted
+        Map<String, Object> values = getValues();
+        accept(values, visitor);
+        acceptEnum(values, visitor);
+        acceptAnnotation(values, visitor);
+        acceptArray(values, visitor);
+
+        // Do not forget to visitEnd()
+        visitor.visitEnd();
+
+        // TODO This should disappear, only useful for testing
+        if (!values.isEmpty()) {
+            // We missed something during serialization
+            throw new IllegalStateException(
+                    format("Attributes of @%s could not be serialized: %s",
+                           m_annotation.annotationType().getSimpleName(),
+                           values.keySet())
+            );
+        }
+    }
+
+    private void acceptAnnotation(final Map<String, Object> values, final AnnotationVisitor visitor) {
+        Map<String, Object> copy = new HashMap<String, Object>(values);
+        for (Map.Entry<String, Object> entry : copy.entrySet()) {
+
+            Class<?> type = entry.getValue().getClass();
+            if (Annotation.class.isAssignableFrom(type)) {
+
+                Annotation annotation = (Annotation) entry.getValue();
+                AnnotationVisitor annotationVisitor = visitor.visitAnnotation(entry.getKey(),
+                                                                              getType(annotation.annotationType()).getDescriptor());
+                if (annotationVisitor != null) {
+                    AnnotationPlayback playback = new AnnotationPlayback(annotation);
+                    playback.accept(annotationVisitor);
+                }
+
+                values.remove(entry.getKey());
+            }
+        }
+    }
+
+    private void acceptEnum(final Map<String, Object> values, final AnnotationVisitor visitor) {
+
+        Map<String, Object> copy = new HashMap<String, Object>(values);
+        for (Map.Entry<String, Object> entry : copy.entrySet()) {
+
+            Class<?> type = entry.getValue().getClass();
+            if (type.isEnum()) {
+                Enum<?> enumValue = (Enum<?>) entry.getValue();
+                visitor.visitEnum(entry.getKey(),
+                                  getType(type).getDescriptor(),
+                                  enumValue.name());
+
+                values.remove(entry.getKey());
+            }
+        }
+    }
+
+    private void accept(final Map<String, Object> values, final AnnotationVisitor visitor) {
+
+        Map<String, Object> copy = new HashMap<String, Object>(values);
+        for (Map.Entry<String, Object> entry : copy.entrySet()) {
+
+            Class<?> type = entry.getValue().getClass();
+            if (isSimpleType(type)) {
+
+                // Accept Byte, Boolean, Character, Short, Integer, Long, Float, Double
+                // Accept String
+                // Accept Array of byte, boolean, char, short, int, long, float, double
+                visitor.visit(entry.getKey(), transform(entry.getValue()));
+
+                values.remove(entry.getKey());
+            }
+        }
+    }
+
+    private boolean isSimpleType(final Class<?> type) {
+        return isPrimitive(type) ||
+                String.class.equals(type) ||
+                Class.class.equals(type) ||
+                (type.isArray() && isPrimitive(type.getComponentType()));
+    }
+
+    private boolean isPrimitive(final Class<?> type) {
+        if (type.isPrimitive()) {
+            return true;
+        }
+
+        if (BOXED_TYPES.contains(type)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private void acceptArray(final Map<String, Object> values, final AnnotationVisitor visitor) {
+        Map<String, Object> copy = new HashMap<String, Object>(values);
+        for (Map.Entry<String, Object> entry : copy.entrySet()) {
+
+            Class<?> type = entry.getValue().getClass();
+            if (type.isArray()) {
+
+                // Simple arrays have been visited using AnnotationVisitor.visit(String, Object)
+
+                AnnotationVisitor arrayVisitor = visitor.visitArray(entry.getKey());
+                if (arrayVisitor != null) {
+                    Object[] array = (Object[]) entry.getValue();
+                    Class<?> componentType = array.getClass().getComponentType();
+                    Type asmType = Type.getType(componentType);
+
+                    if (componentType.isEnum()) {
+                        for (Object o : array) {
+                            Enum eValue = (Enum) o;
+                            arrayVisitor.visitEnum(null, asmType.getDescriptor(), eValue.name());
+                        }
+                    } else if (componentType.isAnnotation()) {
+                        for (Object o : array) {
+                            Annotation annotation = (Annotation) o;
+                            AnnotationVisitor annotationVisitor = arrayVisitor.visitAnnotation(null, asmType.getDescriptor());
+                            if (annotationVisitor != null) {
+                                AnnotationPlayback playback = new AnnotationPlayback(annotation);
+                                playback.accept(annotationVisitor);
+                            }
+                        }
+                    } else {
+                        for (Object o : array) {
+                            arrayVisitor.visit(null, transform(o));
+                        }
+                    }
+
+                    arrayVisitor.visitEnd();
+                }
+
+                values.remove(entry.getKey());
+            }
+        }
+    }
+
+    private Object transform(final Object value) {
+        if (value instanceof Class) {
+            return getType((Class) value);
+        }
+        return value;
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationParser.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationParser.java
new file mode 100644
index 0000000..fdb000d
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationParser.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.objectweb.asm.ClassReader;
+
+/**
+ * User: guillaume
+ * Date: 01/07/13
+ * Time: 15:49
+ */
+public class AnnotationParser {
+    public AnnotationType read(byte[] resource) {
+        ClassReader reader = new ClassReader(resource);
+        AnnotationTypeVisitor visitor = new AnnotationTypeVisitor();
+        reader.accept(visitor, ClassReader.SKIP_CODE);
+        return visitor.getAnnotationType();
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationTypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationTypeVisitor.java
new file mode 100644
index 0000000..77e9c53
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/AnnotationTypeVisitor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay.AnnotationVisitorPlayback;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 01/07/13
+ * Time: 15:59
+ */
+public class AnnotationTypeVisitor extends EmptyVisitor implements ClassVisitor {
+
+    private AnnotationType annotationType;
+
+    @Override
+    public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
+        annotationType = new AnnotationType(Type.getObjectType(name));
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+        // Build annotations of this annotation type
+        AnnotationVisitorPlayback playback = new AnnotationVisitorPlayback(desc, visible);
+        annotationType.getPlaybacks().add(playback);
+        return playback;
+    }
+
+    public AnnotationType getAnnotationType() {
+        return annotationType;
+    }
+
+    // Note: if we override visitMethod here, we could get the annotation's default values.
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorder.java
similarity index 78%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorder.java
index b0afaa4..47d1071 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorder.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -31,34 +31,34 @@
 */
 public class AnnotationRecorder implements AnnotationVisitor, Replay {
 
-    private List<Replay> record = new ArrayList<Replay>();
+    private List<Replay> m_replays = new ArrayList<Replay>();
 
     public void visit(final String name, final Object value) {
-        record.add(new Visit(name, value));
+        m_replays.add(new Visit(name, value));
     }
 
     public void visitEnum(final String name, final String desc, final String value) {
-        record.add(new VisitEnum(name, desc, value));
+        m_replays.add(new VisitEnum(name, desc, value));
     }
 
     public AnnotationVisitor visitAnnotation(final String name, final String desc) {
         AnnotationRecorder sub = new AnnotationRecorder();
-        record.add(new VisitAnnotation(name, desc, sub));
+        m_replays.add(new VisitAnnotation(name, desc, sub));
         return sub;
     }
 
     public AnnotationVisitor visitArray(final String name) {
         AnnotationRecorder sub = new AnnotationRecorder();
-        record.add(new VisitArray(name, sub));
+        m_replays.add(new VisitArray(name, sub));
         return sub;
     }
 
     public void visitEnd() {
-        record.add(new VisitEnd());
+        m_replays.add(new VisitEnd());
     }
 
     public void accept(final AnnotationVisitor visitor) {
-        for (Replay replay : record) {
+        for (Replay replay : m_replays) {
             replay.accept(visitor);
         }
     }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationVisitorPlayback.java
similarity index 74%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationVisitorPlayback.java
index 70548bd..95dd6eb 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationVisitorPlayback.java
@@ -17,8 +17,10 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
@@ -26,14 +28,14 @@
 
 /**
  * User: guillaume
- * Date: 30/05/13
- * Time: 19:20
+ * Date: 08/07/13
+ * Time: 16:07
  */
-public class RootAnnotationRecorder extends AnnotationRecorder {
+public class AnnotationVisitorPlayback extends AnnotationRecorder implements Playback {
     private final String m_desc;
     private final boolean m_visible;
 
-    public RootAnnotationRecorder(final String desc, final boolean visible) {
+    public AnnotationVisitorPlayback(final String desc, final boolean visible) {
         m_desc = desc;
         m_visible = visible;
     }
@@ -65,4 +67,11 @@
             accept(av);
         }
     }
+
+    public void accept(final AnnotationDiscovery visitor) {
+        AnnotationVisitor av = visitor.visitAnnotation(m_desc);
+        if (av != null) {
+            accept(av);
+        }
+    }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Replay.java
similarity index 91%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Replay.java
index 1748cfc..1597936 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Replay.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Visit.java
similarity index 93%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Visit.java
index e0d46c2..4c3eff2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/Visit.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitAnnotation.java
similarity index 94%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitAnnotation.java
index ee61d7d..59a30e5 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitAnnotation.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitArray.java
similarity index 93%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitArray.java
index 124d75a..5a4149e 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitArray.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnd.java
similarity index 92%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnd.java
index 51ddb58..2bdebd5 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnd.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnum.java
similarity index 93%
rename from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java
rename to ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnum.java
index 12708d6..ce044d2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/VisitEnum.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.objectweb.asm.AnnotationVisitor;
 
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java
deleted file mode 100644
index 5de31f5..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.Type;
-
-/**
- * User: guillaume
- * Date: 30/05/13
- * Time: 20:35
- */
-public class AnnotationRegistry {
-
-    /**
-     * Contains the annotations definitions for the given Stereotype annotation.
-     */
-    private Map<Type, List<RootAnnotationRecorder>> stereotypes = new HashMap<Type, List<RootAnnotationRecorder>>();
-
-    /**
-     * Other annotations.
-     */
-    private List<Type> unbound = new ArrayList<Type>();
-
-    public void addStereotype(Type type, List<RootAnnotationRecorder> recorders) {
-        stereotypes.put(type, recorders);
-    }
-
-    public void addUnbound(Type type) {
-        unbound.add(type);
-    }
-
-    public List<RootAnnotationRecorder> getRecorders(Type type) {
-        List<RootAnnotationRecorder> recorders = stereotypes.get(type);
-        if (recorders == null) {
-            return Collections.emptyList();
-        }
-        return recorders;
-    }
-
-    public boolean isStereotype(Type type) {
-        return stereotypes.get(type) != null;
-    }
-
-    public boolean isUnbound(Type type) {
-        return unbound.contains(type);
-    }
-
-    public boolean isUnknown(Type type) {
-        return !isStereotype(type) && !isUnbound(type);
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Binding.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Binding.java
index e60e751..fc6a963 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Binding.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Binding.java
@@ -19,8 +19,11 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
 
+import static java.lang.String.format;
+
 import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
 import org.apache.felix.ipojo.manipulator.spi.Predicate;
+import org.objectweb.asm.Type;
 
 import java.lang.annotation.Annotation;
 
@@ -29,15 +32,15 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Binding {
-    private Class<? extends Annotation> annotationType;
+    private Type annotationType;
     private AnnotationVisitorFactory factory;
     private Predicate predicate;
 
-    public Class<? extends Annotation> getAnnotationType() {
+    public Type getAnnotationType() {
         return annotationType;
     }
 
-    public void setAnnotationType(Class<? extends Annotation> annotationType) {
+    public void setAnnotationType(Type annotationType) {
         this.annotationType = annotationType;
     }
 
@@ -56,4 +59,9 @@
     public void setPredicate(Predicate predicate) {
         this.predicate = predicate;
     }
+
+    @Override
+    public String toString() {
+        return format("Binding[@%s->%s]", annotationType.getClassName(), factory);
+    }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistry.java
index cefbf20..0c80ce7 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistry.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistry.java
@@ -19,65 +19,25 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
 
-import org.apache.felix.ipojo.manipulator.Reporter;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
-import org.apache.felix.ipojo.manipulator.spi.Predicate;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
 
 /**
- * Stores all the {@link Binding}s coming from the {@link org.apache.felix.ipojo.manipulator.spi.Module}.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 16:12
  */
-public class BindingRegistry {
-    private Map<String, List<Binding>> tree;
-    private Reporter reporter;
+public interface BindingRegistry {
+    void addBindings(Iterable<Binding> bindings);
+
+    Selection selection(ComponentWorkbench workbench);
 
     /**
-     * When no other Binding is selected, the default Bindings list is used.
+     * Find the list of {@link Binding} registered with the given annotation type.
+     * This method returns an empty List if no bindings are registered.
+     * @param descriptor denotes the annotation's type
+     * @return the list of {@link Binding} registered with the given descriptor, the list may be empty if no bindings are found.
      */
-    private List<Binding> defaultBindings;
-
-    public BindingRegistry(Reporter reporter) {
-        this.reporter = reporter;
-        tree = new HashMap<String, List<Binding>>();
-        defaultBindings = new ArrayList<Binding>();
-    }
-
-    /**
-     * Stores the given Bindings
-     */
-    public void addBindings(Iterable<Binding> bindings) {
-        for (Binding binding : bindings) {
-            Type type = Type.getType(binding.getAnnotationType());
-
-            List<Binding> potential = tree.get(type.getDescriptor());
-            if (potential == null) {
-                // Annotation is not already found in supported list
-                potential = new ArrayList<Binding>();
-                tree.put(type.getDescriptor(), potential);
-            }
-
-            potential.add(binding);
-        }
-    }
-
-    /**
-     * Initiate a {@link Selection} for the given workbench.
-     */
-    public Selection selection(ComponentWorkbench workbench) {
-        return new Selection(this, workbench, reporter);
-    }
-
-    public List<Binding> getBindings(String descriptor) {
-        return tree.get(descriptor);
-    }
-
-    public List<Binding> getDefaultBindings() {
-        return defaultBindings;
-    }
+    List<Binding> getBindings(String descriptor);
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistry.java
new file mode 100644
index 0000000..398db41
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistry.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 16:09
+ */
+public abstract class CompletableBindingRegistry implements BindingRegistry {
+    private final BindingRegistry m_delegate;
+    private final Reporter m_reporter;
+
+    public CompletableBindingRegistry(final BindingRegistry delegate, final Reporter reporter) {
+        m_delegate = delegate;
+        m_reporter = reporter;
+    }
+
+    public List<Binding> getBindings(final String descriptor) {
+        List<Binding> bindings = m_delegate.getBindings(descriptor);
+        if (bindings.isEmpty()) {
+            List<Binding> ignored = createBindings(Type.getType(descriptor));
+            m_delegate.addBindings(ignored);
+            return ignored;
+        }
+        return bindings;
+    }
+
+    protected abstract List<Binding> createBindings(final Type type);
+
+    public void addBindings(final Iterable<Binding> bindings) {
+        m_delegate.addBindings(bindings);
+    }
+
+    public Selection selection(final ComponentWorkbench workbench) {
+        return new Selection(this, workbench, m_reporter);
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistry.java
new file mode 100644
index 0000000..c41e577
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistry.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static java.util.Collections.emptyList;
+
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
+import org.objectweb.asm.Type;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Stores all the {@link Binding}s coming from the {@link org.apache.felix.ipojo.manipulator.spi.Module}.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DefaultBindingRegistry implements BindingRegistry {
+    private final Map<String, List<Binding>> tree = new HashMap<String, List<Binding>>();
+    protected final Reporter reporter;
+
+    public DefaultBindingRegistry(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    /**
+     * Stores the given Bindings
+     */
+    public void addBindings(Iterable<Binding> bindings) {
+        for (Binding binding : bindings) {
+            Type type = binding.getAnnotationType();
+
+            List<Binding> potential = tree.get(type.getDescriptor());
+            if (potential == null) {
+                // Annotation is not already found in supported list
+                potential = new ArrayList<Binding>();
+                tree.put(type.getDescriptor(), potential);
+            }
+
+            reporter.trace("Registered @%s", type.getClassName());
+            potential.add(binding);
+        }
+    }
+
+    /**
+     * Initiate a {@link Selection} for the given workbench.
+     */
+    public Selection selection(ComponentWorkbench workbench) {
+        return new Selection(this, workbench, reporter);
+    }
+
+    public List<Binding> getBindings(String descriptor) {
+        List<Binding> bindings = tree.get(descriptor);
+        if (bindings == null) {
+            bindings = emptyList();
+        }
+        return bindings;
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistry.java
new file mode 100644
index 0000000..ca84dcb
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistry.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 16:09
+ */
+public class IgnoreAllBindingRegistry extends CompletableBindingRegistry {
+
+    public IgnoreAllBindingRegistry(final BindingRegistry delegate, final Reporter reporter) {
+        super(delegate, reporter);
+    }
+
+    @Override
+    protected List<Binding> createBindings(final Type type) {
+        return singletonList((Binding) new NullBinding(type));
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistry.java
new file mode 100644
index 0000000..2f9c711
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistry.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.alwaysTrue;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.FieldGenericVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.MethodGenericVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.ParameterGenericVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.TypeGenericVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util.Elements;
+import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
+import org.apache.felix.ipojo.manipulator.spi.BindingContext;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 16:09
+ */
+public class LegacyGenericBindingRegistry extends CompletableBindingRegistry {
+    public static final Pattern CUSTOM_HANDLER_PATTERN = Pattern.compile("(.*\\.ipojo\\..*)|(.*\\.handler\\..*)");
+
+    public LegacyGenericBindingRegistry(final BindingRegistry delegate, final Reporter reporter) {
+        super(delegate, reporter);
+    }
+
+    @Override
+    protected List<Binding> createBindings(final Type type) {
+        if (CUSTOM_HANDLER_PATTERN.matcher(type.getClassName()).matches()) {
+            Binding binding = new Binding();
+            binding.setAnnotationType(type);
+            binding.setPredicate(alwaysTrue());
+            binding.setFactory(new AnnotationVisitorFactory() {
+                // Need to build a new Element instance for each created visitor
+                public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+                    if (context.getNode() instanceof ClassNode) {
+                        return new TypeGenericVisitor(context.getWorkbench(),
+                                                      Elements.buildElement(type));
+                    } else if (context.getNode() instanceof FieldNode) {
+                        return new FieldGenericVisitor(context.getWorkbench(),
+                                                       Elements.buildElement(type),
+                                                       (FieldNode) context.getNode());
+
+                    } else if ((context.getNode() instanceof MethodNode) &&
+                            (context.getParameterIndex() == BindingContext.NO_INDEX)) {
+                        return new MethodGenericVisitor(context.getWorkbench(),
+                                                        Elements.buildElement(type),
+                                                        (MethodNode) context.getNode());
+                    } else {
+                        // last case: method parameter annotation
+                        return new ParameterGenericVisitor(context.getWorkbench(),
+                                                           Elements.buildElement(type),
+                                                           (MethodNode) context.getNode(),
+                                                           context.getParameterIndex());
+                    }
+                }
+
+                @Override
+                public String toString() {
+                    return "LegacyGenericVisitorFactory";
+                }
+            });
+
+            // Return the produced generic binding
+            return singletonList(binding);
+        }
+
+        return emptyList();
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistry.java
new file mode 100644
index 0000000..8ea953f
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistry.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.unmodifiableList;
+import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.alwaysTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.annotations.HandlerBinding;
+import org.apache.felix.ipojo.annotations.Ignore;
+import org.apache.felix.ipojo.annotations.Stereotype;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery.ChainedAnnotationDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery.HandlerBindingDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery.IgnoredDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery.StereotypeDiscovery;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.AnnotationParser;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.GenericVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.StereotypeVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util.Elements;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
+
+/**
+ * The {@link MetaAnnotationBindingRegistry} is a registry that tries to complete its list
+ * of bindings when an unknown one is detected.
+ * It uses the given {@link ResourceStore} to parse the annotation's type and find if
+ * it's annotated with @{@link org.apache.felix.ipojo.annotations.Stereotype},
+ * @{@link org.apache.felix.ipojo.annotations.HandlerBinding} or @{@link org.apache.felix.ipojo.annotations.Ignore}
+ */
+public class MetaAnnotationBindingRegistry extends CompletableBindingRegistry {
+
+    private ResourceStore m_store;
+    private Reporter m_reporter;
+
+    public MetaAnnotationBindingRegistry(final BindingRegistry delegate, final Reporter reporter, final ResourceStore store) {
+        super(delegate, reporter);
+        this.m_reporter = reporter;
+        this.m_store = store;
+        addBindings(nullBindingsForMetaAnnotations());
+    }
+
+    protected Iterable<Binding> nullBindingsForMetaAnnotations() {
+        // Do not re-apply meta-annotations
+        ArrayList<Binding> bindings = new ArrayList<Binding>();
+        bindings.add(new NullBinding(Type.getType(Stereotype.class)));
+        bindings.add(new NullBinding(Type.getType(HandlerBinding.class)));
+        bindings.add(new NullBinding(Type.getType(Ignore.class)));
+        return bindings;
+    }
+
+    @Override
+    protected List<Binding> createBindings(final Type type) {
+
+        // Parse the annotation
+        byte[] bytes;
+        try {
+            bytes = m_store.read(type.getInternalName().concat(".class"));
+        } catch (IOException e) {
+            // Annotation type cannot be read
+            m_reporter.trace("Could not read bytecode for @%s", type.getClassName());
+            return emptyList();
+        }
+        AnnotationParser parser = new AnnotationParser();
+        AnnotationType annotationType = parser.read(bytes);
+
+        // Search meta-annotations
+        ChainedAnnotationDiscovery chain = new ChainedAnnotationDiscovery();
+        StereotypeDiscovery stereotypeDiscovery = new StereotypeDiscovery();
+        HandlerBindingDiscovery handlerBindingDiscovery = new HandlerBindingDiscovery();
+        IgnoredDiscovery ignoredDiscovery = new IgnoredDiscovery();
+        chain.getDiscoveries().add(stereotypeDiscovery);
+        chain.getDiscoveries().add(handlerBindingDiscovery);
+        chain.getDiscoveries().add(ignoredDiscovery);
+
+        annotationType.traverse(chain);
+
+        // Produced Bindings
+        List<Binding> bindings = new ArrayList<Binding>();
+
+        // @Stereotype support
+        if (stereotypeDiscovery.isStereotype()) {
+            m_reporter.trace("@Stereotype detected: @%s", type.getClassName());
+            Binding binding = new Binding();
+            binding.setAnnotationType(type);
+            binding.setPredicate(alwaysTrue());
+            binding.setFactory(new StereotypeVisitorFactory(annotationType));
+
+            bindings.add(binding);
+        }
+
+        // @HandlerBinding support
+        if (handlerBindingDiscovery.isHandlerBinding()) {
+
+            m_reporter.trace("@HandlerBinding detected: @%s", type.getClassName());
+            Binding binding = new Binding();
+            binding.setAnnotationType(type);
+            binding.setPredicate(alwaysTrue());
+            final Element element = buildElement(handlerBindingDiscovery, type);
+            binding.setFactory(new GenericVisitorFactory(element.getName(), element.getNameSpace()));
+
+            bindings.add(binding);
+        }
+
+        // Its IMPORTANT that the @Ignore is processed last since it removes existing bindings
+        if (ignoredDiscovery.isIgnore()) {
+            m_reporter.trace("@Ignore detected: @%s", type.getClassName());
+            Binding binding = new NullBinding(type);
+
+            bindings.clear();
+            bindings.add(binding);
+            bindings = unmodifiableList(bindings); // just in case of ...
+        }
+
+        return bindings;
+
+    }
+
+    private Element buildElement(final HandlerBindingDiscovery handler, final Type type) {
+        Element element;
+        if ((handler.getNamespace() == null) &&
+                (handler.getValue() == null)) {
+            // No attributes specified, use annotation type as element's source
+            element = Elements.buildElement(type);
+        } else if ((handler.getNamespace() == null) &&
+                (handler.getValue() != null)) {
+            // Namespace attribute is omitted
+            element = Elements.buildElement(handler.getValue());
+        } else {
+            element = Elements.buildElement(handler.getNamespace(),
+                                            handler.getValue());
+        }
+        return element;
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
index 5fb435e..f4fefc2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
@@ -22,6 +22,7 @@
 import org.apache.felix.ipojo.manipulator.Reporter;
 import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
 import org.apache.felix.ipojo.manipulator.spi.BindingContext;
+import org.apache.felix.ipojo.manipulator.util.ChainedAnnotationVisitor;
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
@@ -34,7 +35,6 @@
 
 import java.lang.annotation.ElementType;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -42,13 +42,13 @@
  * It's a query DSL.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class Selection implements Iterable<AnnotationVisitor> {
+public class Selection {
 
     private BindingRegistry registry;
     private ComponentWorkbench workbench;
     private Reporter reporter;
     private MemberNode node;
-    private int index = -1;
+    private int index = BindingContext.NO_INDEX;
     private String annotation;
     private ElementType elementType = null;
     private Object visitor;
@@ -94,32 +94,34 @@
     }
 
     public AnnotationVisitor get() {
-        Iterator<AnnotationVisitor> i = iterator();
-        if (iterator().hasNext()) {
-            return i.next();
+        List<AnnotationVisitor> visitors = list();
+
+        if (visitors.isEmpty()) {
+            return null;
         }
-        return null;
+
+        if (visitors.size() == 1) {
+            return visitors.get(0);
+        }
+
+        ChainedAnnotationVisitor chained = new ChainedAnnotationVisitor();
+        chained.getVisitors().addAll(visitors);
+        return chained;
     }
 
-    public Iterator<AnnotationVisitor> iterator() {
-
-        List<AnnotationVisitor> visitors = new ArrayList<AnnotationVisitor>();
+    private List<AnnotationVisitor> list() {
 
         BindingContext context = new BindingContext(workbench, reporter, Type.getType(annotation), node, elementType, index, visitor);
         List<Binding> predicates = registry.getBindings(annotation);
 
+        List<AnnotationVisitor> visitors = new ArrayList<AnnotationVisitor>();
         if (predicates != null && !predicates.isEmpty()) {
             collectMatchingVisitors(predicates, context, visitors);
         }
-
-        if (visitors.isEmpty() && !registry.getDefaultBindings().isEmpty()) {
-            collectMatchingVisitors(registry.getDefaultBindings(), context, visitors);
-        }
-
-
-        return visitors.iterator();
+        return visitors;
     }
 
+
     private void collectMatchingVisitors(List<Binding> bindings, BindingContext context, List<AnnotationVisitor> visitors) {
         for (Binding binding : bindings) {
             if (binding.getPredicate().matches(context)) {
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java
deleted file mode 100644
index 672edee..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.ClassReader;
-
-/**
- * User: guillaume
- * Date: 30/05/13
- * Time: 12:42
- */
-public class StereotypeParser {
-    private boolean stereotype = false;
-    private List<RootAnnotationRecorder> replays = new ArrayList<RootAnnotationRecorder>();
-
-    public void read(byte[] resource) {
-        ClassReader reader = new ClassReader(resource);
-        reader.accept(new StereotypeVisitor(this), ClassReader.SKIP_CODE);
-    }
-
-    public boolean isStereotype() {
-        return stereotype;
-    }
-
-    public void setStereotype(final boolean stereotype) {
-        this.stereotype = stereotype;
-    }
-
-    public List<RootAnnotationRecorder> getRecorders() {
-        return replays;
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java
deleted file mode 100644
index 6216831..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype;
-
-import org.apache.felix.ipojo.annotations.Stereotype;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:09
-*/
-public class StereotypeVisitor extends EmptyVisitor {
-
-    public static final Type MARKER_TYPE = Type.getType(Stereotype.class);
-
-    private StereotypeParser m_definition;
-
-    public StereotypeVisitor(final StereotypeParser definition) {
-        m_definition = definition;
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
-        Type annotationType = Type.getType(desc);
-        if (MARKER_TYPE.equals(annotationType)) {
-            m_definition.setStereotype(true);
-            return null;
-        }
-        RootAnnotationRecorder visitor = new RootAnnotationRecorder(desc, visible);
-        m_definition.getRecorders().add(visitor);
-        return visitor;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
-        return null;
-    }
-
-    @Override
-    public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
-        return null;
-    }
-
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/generic/GenericVisitorFactory.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/generic/GenericVisitorFactory.java
new file mode 100644
index 0000000..c08bdc1
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/generic/GenericVisitorFactory.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic;
+
+import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
+import org.apache.felix.ipojo.manipulator.spi.BindingContext;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+* User: guillaume
+* Date: 11/07/13
+* Time: 14:41
+*/
+public class GenericVisitorFactory implements AnnotationVisitorFactory {
+    private final String m_name;
+    private final String m_namespace;
+
+    public GenericVisitorFactory(final String name, final String namespace) {
+        m_name = name;
+        m_namespace = namespace;
+    }
+
+    // Need to build a new Element instance for each created visitor
+    public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+        if (context.getNode() instanceof ClassNode) {
+            return new TypeGenericVisitor(context.getWorkbench(),
+                                          new Element(m_name, m_namespace));
+        } else if (context.getNode() instanceof FieldNode) {
+            return new FieldGenericVisitor(context.getWorkbench(),
+                                           new Element(m_name, m_namespace),
+                                           (FieldNode) context.getNode());
+
+        } else if ((context.getNode() instanceof MethodNode) &&
+                (context.getParameterIndex() == BindingContext.NO_INDEX)) {
+            return new MethodGenericVisitor(context.getWorkbench(),
+                                            new Element(m_name, m_namespace),
+                                            (MethodNode) context.getNode());
+        } else {
+            // last case: method parameter annotation
+            return new ParameterGenericVisitor(context.getWorkbench(),
+                                               new Element(m_name, m_namespace),
+                                               (MethodNode) context.getNode(),
+                                               context.getParameterIndex());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "GenericVisitorFactory";
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullBinding.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullBinding.java
new file mode 100644
index 0000000..b736d8b
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullBinding.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore;
+
+import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.alwaysTrue;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 10/07/13
+ * Time: 15:04
+ */
+public class NullBinding extends Binding {
+    public NullBinding(final Type type) {
+        super();
+        setAnnotationType(type);
+        setPredicate(alwaysTrue());
+        setFactory(NullVisitorFactory.INSTANCE);
+
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullVisitorFactory.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullVisitorFactory.java
new file mode 100644
index 0000000..c056e9e
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/ignore/NullVisitorFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore;
+
+import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
+import org.apache.felix.ipojo.manipulator.spi.BindingContext;
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 10/07/13
+* Time: 15:05
+*/
+public class NullVisitorFactory implements AnnotationVisitorFactory {
+    public static final AnnotationVisitorFactory INSTANCE = new NullVisitorFactory();
+
+    public AnnotationVisitor newAnnotationVisitor(final BindingContext context) {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java
index 913677e..3dbf020 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java
@@ -19,10 +19,8 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype;
 
-import java.util.List;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.ClassVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.commons.EmptyVisitor;
 
@@ -33,19 +31,19 @@
  */
 public class FieldStereotypeVisitor extends EmptyVisitor {
 
-    private final FieldVisitor delegate;
-    private final List<RootAnnotationRecorder> m_recorder;
+    private final FieldVisitor m_delegate;
+    private final AnnotationType m_annotationType;
 
-    public FieldStereotypeVisitor(final FieldVisitor delegate, List<RootAnnotationRecorder> recorder) {
-        this.delegate = delegate;
-        m_recorder = recorder;
+    public FieldStereotypeVisitor(final FieldVisitor delegate, AnnotationType annotationType) {
+        this.m_delegate = delegate;
+        m_annotationType = annotationType;
     }
 
     @Override
     public void visitEnd() {
         // Replay stereotype annotations
-        for (RootAnnotationRecorder recorder : m_recorder) {
-            recorder.accept(delegate);
+        for (Playback playback : m_annotationType.getPlaybacks()) {
+            playback.accept(m_delegate);
         }
     }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java
index 06dc9af..f7f0bfd 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java
@@ -19,10 +19,8 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype;
 
-import java.util.List;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.FieldVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.commons.EmptyVisitor;
 
@@ -33,19 +31,19 @@
  */
 public class MethodStereotypeVisitor extends EmptyVisitor {
 
-    private final MethodVisitor delegate;
-    private final List<RootAnnotationRecorder> m_recorder;
+    private final MethodVisitor m_delegate;
+    private final AnnotationType m_annotationType;
 
-    public MethodStereotypeVisitor(final MethodVisitor delegate, List<RootAnnotationRecorder> recorder) {
-        this.delegate = delegate;
-        m_recorder = recorder;
+    public MethodStereotypeVisitor(final MethodVisitor delegate, AnnotationType annotationType) {
+        this.m_delegate = delegate;
+        m_annotationType = annotationType;
     }
 
     @Override
     public void visitEnd() {
         // Replay stereotype annotations
-        for (RootAnnotationRecorder recorder : m_recorder) {
-            recorder.accept(delegate);
+        for (Playback playback : m_annotationType.getPlaybacks()) {
+            playback.accept(m_delegate);
         }
     }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java
index c764399..2c8beef 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java
@@ -19,10 +19,8 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype;
 
-import java.util.List;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.FieldVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.commons.EmptyVisitor;
 
@@ -33,21 +31,21 @@
  */
 public class ParameterStereotypeVisitor extends EmptyVisitor {
 
-    private final MethodVisitor delegate;
+    private final MethodVisitor m_delegate;
     private final int index;
-    private final List<RootAnnotationRecorder> m_recorder;
+    private final AnnotationType m_annotationType;
 
-    public ParameterStereotypeVisitor(final MethodVisitor delegate, final int index, List<RootAnnotationRecorder> recorder) {
-        this.delegate = delegate;
+    public ParameterStereotypeVisitor(final MethodVisitor delegate, final int index, AnnotationType annotationType) {
+        this.m_delegate = delegate;
         this.index = index;
-        m_recorder = recorder;
+        m_annotationType = annotationType;
     }
 
     @Override
     public void visitEnd() {
         // Replay stereotype annotations
-        for (RootAnnotationRecorder recorder : m_recorder) {
-            recorder.accept(delegate, index);
+        for (Playback playback : m_annotationType.getPlaybacks()) {
+            playback.accept(m_delegate, index);
         }
     }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/StereotypeVisitorFactory.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/StereotypeVisitorFactory.java
new file mode 100644
index 0000000..c6c7122
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/StereotypeVisitorFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
+import org.apache.felix.ipojo.manipulator.spi.BindingContext;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+* User: guillaume
+* Date: 11/07/13
+* Time: 14:26
+*/
+public class StereotypeVisitorFactory implements AnnotationVisitorFactory {
+    private final AnnotationType m_annotationType;
+
+    public StereotypeVisitorFactory(final AnnotationType annotationType) {
+        m_annotationType = annotationType;
+    }
+
+    public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+        if (context.getNode() instanceof ClassNode) {
+            return new TypeStereotypeVisitor((ClassVisitor) context.getVisitor(),
+                                             m_annotationType);
+        } else if (context.getNode() instanceof FieldNode) {
+            return new FieldStereotypeVisitor((FieldVisitor) context.getVisitor(),
+                                              m_annotationType);
+
+        } else if ((context.getNode() instanceof MethodNode) &&
+                (context.getParameterIndex() == BindingContext.NO_INDEX)) {
+            return new MethodStereotypeVisitor((MethodVisitor) context.getVisitor(),
+                                               m_annotationType);
+
+        } else {
+            // last case: method parameter annotation
+            return new ParameterStereotypeVisitor((MethodVisitor) context.getVisitor(),
+                                                  context.getParameterIndex(),
+                                                  m_annotationType);
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return "StereotypeVisitorFactory";
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java
index 255219f..10493a1 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java
@@ -19,9 +19,8 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype;
 
-import java.util.List;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.Playback;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.commons.EmptyVisitor;
 
@@ -32,19 +31,19 @@
  */
 public class TypeStereotypeVisitor extends EmptyVisitor {
 
-    private final ClassVisitor delegate;
-    private final List<RootAnnotationRecorder> m_recorder;
+    private final ClassVisitor m_delegate;
+    private final AnnotationType m_annotationType;
 
-    public TypeStereotypeVisitor(final ClassVisitor delegate, List<RootAnnotationRecorder> recorder) {
-        this.delegate = delegate;
-        m_recorder = recorder;
+    public TypeStereotypeVisitor(final ClassVisitor delegate, AnnotationType annotationType) {
+        this.m_delegate = delegate;
+        m_annotationType = annotationType;
     }
 
     @Override
     public void visitEnd() {
         // Replay stereotype annotations
-        for (RootAnnotationRecorder recorder : m_recorder) {
-            recorder.accept(delegate);
+        for (Playback playback : m_annotationType.getPlaybacks()) {
+            playback.accept(m_delegate);
         }
     }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
index 3878190..2a74b87 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
@@ -21,129 +21,31 @@
 
 import org.apache.felix.ipojo.manipulator.Reporter;
 import org.apache.felix.ipojo.manipulator.ResourceStore;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.AnnotationRegistry;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.StereotypeParser;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.DefaultBindingRegistry;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.IgnoreAllBindingRegistry;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.LegacyGenericBindingRegistry;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.MetaAnnotationBindingRegistry;
 import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.BindingRegistry;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.FieldStereotypeVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.MethodStereotypeVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.ParameterStereotypeVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.TypeStereotypeVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.FieldGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.MethodGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.ParameterGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.TypeGenericVisitor;
-import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
-import org.apache.felix.ipojo.manipulator.spi.BindingContext;
 import org.apache.felix.ipojo.manipulator.spi.Module;
-import org.apache.felix.ipojo.manipulator.spi.Predicate;
-import org.apache.felix.ipojo.manipulator.util.Strings;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
 
-import java.io.IOException;
-import java.lang.annotation.ElementType;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.ServiceLoader;
 
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.and;
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.on;
 import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.or;
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.pattern;
 
 /**
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Bindings {
 
-    private static Binding newGenericTypeBinding() {
-        Binding binding = new Binding();
-        // ElementType is TYPE
-        // Annotation descriptor is matching generic pattern
-        binding.setPredicate(
-                and(
-                        on(ElementType.TYPE),
-                        customAnnotationPattern()
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                Element element = Elements.buildElement(context.getAnnotationType());
-                return new TypeGenericVisitor(context.getWorkbench(), element);
-            }
-        });
-        return binding;
-    }
-
-    private static Predicate customAnnotationPattern() {
-        return pattern("(.*\\.ipojo\\..*)|(.*\\.handler\\..*)").matches();
-    }
-
-    private static Binding newGenericFieldBinding() {
-        Binding binding = new Binding();
-        // ElementType is FIELD
-        // Annotation descriptor is matching generic pattern
-        binding.setPredicate(
-                and(
-                        on(ElementType.FIELD),
-                        customAnnotationPattern()
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                Element element = Elements.buildElement(context.getAnnotationType());
-                return new FieldGenericVisitor(context.getWorkbench(), element, (FieldNode) context.getNode());
-            }
-        });
-        return binding;
-    }
-
-    private static Binding newGenericMethodBinding() {
-        Binding binding = new Binding();
-        // ElementType is METHOD
-        // Annotation descriptor is matching generic pattern
-        binding.setPredicate(
-                and(
-                        on(ElementType.METHOD),
-                        customAnnotationPattern()
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                Element element = Elements.buildElement(context.getAnnotationType());
-                return new MethodGenericVisitor(context.getWorkbench(), element, (MethodNode) context.getNode());
-            }
-        });
-        return binding;
-    }
-
-    private static Binding newGenericParameterBinding() {
-        Binding binding = new Binding();
-        // ElementType is METHOD
-        // Annotation descriptor is matching generic pattern
-        binding.setPredicate(
-                and(
-                        on(ElementType.PARAMETER),
-                        customAnnotationPattern()
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                Element element = Elements.buildElement(context.getAnnotationType());
-                return new ParameterGenericVisitor(context.getWorkbench(), element, (MethodNode) context.getNode(), context.getParameterIndex());
-            }
-        });
-        return binding;
-    }
-
-
     public static BindingRegistry newBindingRegistry(Reporter reporter, ResourceStore store) {
 
-        AnnotationRegistry ar = new AnnotationRegistry();
-        BindingRegistry registry = new BindingRegistry(reporter);
+        // Build the registry by aggregation of the features we want
+        // TODO We can enable/disable the legacy support easily here
+        BindingRegistry registry = new DefaultBindingRegistry(reporter);
+        registry = new MetaAnnotationBindingRegistry(registry, reporter, store);
+        registry = new LegacyGenericBindingRegistry(registry, reporter);
+        registry = new IgnoreAllBindingRegistry(registry, reporter);
+
         ServiceLoader<Module> loader = ServiceLoader.load(Module.class, classloader());
 
         // Build each Module and add its contributed Bindings in the registry
@@ -152,127 +54,9 @@
             registry.addBindings(module);
         }
 
-        // Do not forget the default Bindings
-        registry.getDefaultBindings().addAll(newDefaultBindings(store, ar));
-
         return registry;
     }
 
-    public static List<Binding> newDefaultBindings(final ResourceStore store, final AnnotationRegistry ar) {
-        List<Binding> bindings = new ArrayList<Binding>();
-
-        // Register Stereotype binding support first
-        // That allows iPOJO to provide its own stereotyped annotations
-        bindings.add(newStereotypeTypeBinding(store, ar));
-        bindings.add(newStereotypeFieldBinding(store, ar));
-        bindings.add(newStereotypeMethodBinding(store, ar));
-        bindings.add(newStereotypeParameterBinding(store, ar));
-
-        // Then register the generic bindings
-        bindings.add(newGenericTypeBinding());
-        bindings.add(newGenericFieldBinding());
-        bindings.add(newGenericMethodBinding());
-        bindings.add(newGenericParameterBinding());
-        return bindings;
-
-    }
-
-    private static Binding newStereotypeParameterBinding(final ResourceStore store, final AnnotationRegistry registry) {
-        Binding binding = new Binding();
-        binding.setPredicate(
-                and(
-                        on(ElementType.PARAMETER),
-                        stereotype(store, registry)
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                return new ParameterStereotypeVisitor((MethodVisitor) context.getVisitor(),
-                                                      context.getParameterIndex(),
-                                                      registry.getRecorders(context.getAnnotationType()));
-            }
-        });
-        return binding;
-    }
-
-    private static Binding newStereotypeMethodBinding(final ResourceStore store, final AnnotationRegistry registry) {
-        Binding binding = new Binding();
-        binding.setPredicate(
-                and(
-                        on(ElementType.METHOD),
-                        stereotype(store, registry)
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                return new MethodStereotypeVisitor((MethodVisitor) context.getVisitor(),
-                                                  registry.getRecorders(context.getAnnotationType()));
-            }
-        });
-        return binding;
-    }
-
-    private static Binding newStereotypeFieldBinding(final ResourceStore store, final AnnotationRegistry registry) {
-        Binding binding = new Binding();
-        binding.setPredicate(
-                and(
-                        on(ElementType.FIELD),
-                        stereotype(store, registry)
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                return new FieldStereotypeVisitor((FieldVisitor) context.getVisitor(),
-                                                  registry.getRecorders(context.getAnnotationType()));
-            }
-        });
-        return binding;
-    }
-
-    private static Binding newStereotypeTypeBinding(final ResourceStore store, final AnnotationRegistry registry) {
-        Binding binding = new Binding();
-        binding.setPredicate(
-                and(
-                        on(ElementType.TYPE),
-                        stereotype(store, registry)
-                ));
-        binding.setFactory(new AnnotationVisitorFactory() {
-            public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
-                return new TypeStereotypeVisitor((ClassVisitor) context.getVisitor(),
-                                                 registry.getRecorders(context.getAnnotationType()));
-            }
-        });
-        return binding;
-    }
-
-    private static Predicate stereotype(final ResourceStore store, final AnnotationRegistry registry) {
-        return new Predicate() {
-            public boolean matches(final BindingContext context) {
-
-                Type type = context.getAnnotationType();
-                if (registry.isUnknown(type)) {
-                    // The given annotation type was never parsed before
-                    try {
-
-                        // Try to read the annotation's byte code
-                        byte[] bytes = store.read(Strings.asResourcePath(context.getAnnotationType().getClassName()));
-                        StereotypeParser parser = new StereotypeParser();
-                        parser.read(bytes);
-                        if (parser.isStereotype()) {
-                            registry.addStereotype(type, parser.getRecorders());
-                            return true;
-                        }
-                        registry.addUnbound(type);
-                        return false;
-                    } catch (IOException e) {
-                        // Cannot load the byte code, assume it's not a stereotype
-                        // TODO print a warning ?
-                        registry.addUnbound(type);
-                        return false;
-                    }
-                }
-                return registry.isStereotype(type);
-            }
-        };
-    }
-
     private static ClassLoader classloader() {
         return Bindings.class.getClassLoader();
     }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Elements.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Elements.java
index 28439b6..f9c2cc1 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Elements.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Elements.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util;
 
+import static java.lang.String.format;
+
 import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
 import org.apache.felix.ipojo.metadata.Element;
 import org.objectweb.asm.Type;
@@ -41,7 +43,38 @@
         int index = name.lastIndexOf('.');
         String local = name.substring(index + 1);
         String namespace = name.substring(0, index);
-        return new Element(local, namespace);
+        return buildElement(namespace, local);
+    }
+
+    /**
+     * Build an {@link Element} using the provided namespace and local name.
+     */
+    public static Element buildElement(final String namespace, final String name) {
+        return new Element(name, namespace);
+    }
+
+    /**
+     * Build an {@link Element} using the provided binding information.
+     * Expected format is {@literal [namespace:]name} (eg: {@literal com.acme:foo} or {@literal foo} if namespace
+     * by default -org.apache.felix.ipojo- has to be used).
+     * Notice that the ':' character usage in namespace or name part may lead to unexpected results.
+     * In that case, the @HandlerBinding(namespace = "urn:my:namespace", value = "foo:handler") usage is preferred.
+     * @param binding the condensed element name
+     * @return the new element
+     */
+    public static Element buildElement(String binding) {
+        String[] split = binding.split(":");
+        if (split.length == 1) {
+            return buildElement("", binding);
+        }
+        if (split.length > 2) {
+            throw new IllegalArgumentException(
+                    format("@HandlerBinding(\"%s\") is invalid: only 1 ':' char is authorized, please" +
+                           " use the @HandlerBinding(namespace=\"...\", value=\"...\") form instead.",
+                           binding)
+            );
+        }
+        return buildElement(split[0], split[1]);
     }
 
     /**
@@ -52,7 +85,7 @@
     public static Element getPropertiesElement(ComponentWorkbench workbench) {
         Element properties = workbench.getIds().get("properties");
         if (properties == null) {
-            properties = new Element("properties", "");
+            properties = buildElement("", "properties");
             workbench.getIds().put("properties", properties);
             workbench.getElements().put(properties, null);
         }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModule.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModule.java
index 7a1f1c7..c188e5e 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModule.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModule.java
@@ -19,21 +19,23 @@
 
 package org.apache.felix.ipojo.manipulator.spi;
 
-import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
+import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.onlySupportedElements;
 
 import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.alwaysTrue;
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.on;
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.onlySupportedElements;
-import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.or;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.AnnotationType;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.AnnotationLiteral;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.AnnotationPlayback;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.GenericVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.StereotypeVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util.Elements;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
 
 /**
  * All provided {@link Module}s have to inherit from this class.
@@ -66,6 +68,18 @@
         return new AnnotationBindingBuilder(bindings, annotationType);
     }
 
+    protected StereotypeBindingBuilder bindStereotype(Class<? extends Annotation> annotationType) {
+        return new StereotypeBindingBuilder(bindings, annotationType);
+    }
+
+    protected HandlerBindingBuilder bindHandlerBinding(Class<? extends Annotation> annotationType) {
+        return new HandlerBindingBuilder(bindings, annotationType);
+    }
+
+    protected void bindIgnore(Class<? extends Annotation> annotationType) {
+        bindings.add(new NullBinding(Type.getType(annotationType)));
+    }
+
     /**
      * DSL helper class.
      */
@@ -104,7 +118,7 @@
          */
         private Binding build() {
             Binding binding = new Binding();
-            binding.setAnnotationType(annotationType);
+            binding.setAnnotationType(Type.getType(annotationType));
             binding.setPredicate(onlySupportedElements(annotationType));
             binding.setFactory(factory);
             return binding;
@@ -145,4 +159,40 @@
         }
     }
 
+    public class StereotypeBindingBuilder {
+        private final AnnotationType m_annotationType;
+
+        public StereotypeBindingBuilder(final List<Binding> bindings, final Class<? extends Annotation> type) {
+            m_annotationType = new AnnotationType(Type.getType(type));
+            Binding binding = new Binding();
+            binding.setAnnotationType(m_annotationType.getType());
+            binding.setPredicate(onlySupportedElements(type));
+            binding.setFactory(new StereotypeVisitorFactory(m_annotationType));
+            bindings.add(binding);
+        }
+
+        public StereotypeBindingBuilder with(AnnotationLiteral<?> literal) {
+            m_annotationType.getPlaybacks().add(new AnnotationPlayback(literal));
+            return this;
+        }
+    }
+
+    public class HandlerBindingBuilder {
+
+        private final Binding m_binding;
+
+        public HandlerBindingBuilder(final List<Binding> bindings, final Class<? extends Annotation> annotationType) {
+            m_binding = new Binding();
+            Type type = Type.getType(annotationType);
+            m_binding.setAnnotationType(type);
+            m_binding.setPredicate(onlySupportedElements(annotationType));
+            Element e = Elements.buildElement(type);
+            m_binding.setFactory(new GenericVisitorFactory(e.getName(), e.getNameSpace()));
+            bindings.add(m_binding);
+        }
+
+        public void to(String namespace, String name) {
+            m_binding.setFactory(new GenericVisitorFactory(name, namespace));
+        }
+    }
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
index 72bdc25..316345c 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
@@ -31,6 +31,8 @@
  */
 public class BindingContext {
 
+    public static final int NO_INDEX = -1;
+
     /**
      *
      */
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/ChainedAnnotationVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/ChainedAnnotationVisitor.java
new file mode 100644
index 0000000..cf138da
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/ChainedAnnotationVisitor.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.discovery.ChainedAnnotationDiscovery;
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 10/07/13
+* Time: 16:43
+*/
+public class ChainedAnnotationVisitor implements AnnotationVisitor {
+
+    private List<AnnotationVisitor> m_visitors = new ArrayList<AnnotationVisitor>();
+
+    public List<AnnotationVisitor> getVisitors() {
+        return m_visitors;
+    }
+
+    public void visit(final String name, final Object value) {
+        for (AnnotationVisitor visitor : m_visitors) {
+            visitor.visit(name, value);
+        }
+    }
+
+    public void visitEnum(final String name, final String desc, final String value) {
+        for (AnnotationVisitor visitor : m_visitors) {
+            visitor.visitEnum(name, desc, value);
+        }
+    }
+
+    public AnnotationVisitor visitAnnotation(final String name, final String desc) {
+        ChainedAnnotationVisitor chain = null;
+        for (AnnotationVisitor visitor : m_visitors) {
+            AnnotationVisitor child = visitor.visitAnnotation(name, desc);
+            if (child != null) {
+                if (chain == null) {
+                    chain = new ChainedAnnotationVisitor();
+                }
+                chain.getVisitors().add(child);
+            }
+
+        }
+        return chain;
+    }
+
+    public AnnotationVisitor visitArray(final String name) {
+        ChainedAnnotationVisitor chain = null;
+        for (AnnotationVisitor visitor : m_visitors) {
+            AnnotationVisitor child = visitor.visitArray(name);
+            if (child != null) {
+                if (chain == null) {
+                    chain = new ChainedAnnotationVisitor();
+                }
+                chain.getVisitors().add(child);
+            }
+
+        }
+        return chain;
+    }
+
+    public void visitEnd() {
+        for (AnnotationVisitor visitor : m_visitors) {
+            visitor.visitEnd();
+        }
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java
index 5570eb6..d469495 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java
@@ -63,7 +63,11 @@
         }
 
         public byte[] read(String path) throws IOException {
-            return resources.get(path);
+            byte[] bytes = resources.get(path);
+            if (bytes == null) {
+                throw new IOException();
+            }
+            return bytes;
         }
 
         public void accept(ResourceVisitor visitor) {
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteralTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteralTestCase.java
new file mode 100644
index 0000000..9d6360d
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationLiteralTestCase.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.AnnotationLiteral;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 28/06/13
+ * Time: 14:40
+ */
+public class AnnotationLiteralTestCase extends TestCase {
+    public void testAnnotationTypeDiscovery() throws Exception {
+
+        FooLiteral fooLiteral = new FooLiteral() {
+            public String value() {
+                return "a";
+            }
+        };
+
+        assertEquals(Foo.class, fooLiteral.annotationType());
+        assertEquals("a", fooLiteral.value());
+
+    }
+
+    private static abstract class FooLiteral extends AnnotationLiteral<Foo> implements Foo { }
+
+    private static @interface Foo {
+        String value();
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlaybackTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlaybackTestCase.java
new file mode 100644
index 0000000..05c1c68
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/AnnotationPlaybackTestCase.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.AnnotationPlayback;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.AnnotationAnnotation;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.ArrayAnnotation;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.EnumAnnotation;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.InnerAnnotation;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.Mode;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.SimpleTypes;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types.Support;
+import org.mockito.Mock;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 08/07/13
+ * Time: 17:25
+ */
+
+public class AnnotationPlaybackTestCase extends TestCase {
+
+    @Mock
+    private ClassVisitor visitor;
+
+    @Mock
+    private AnnotationVisitor annotationVisitor;
+
+    @Mock
+    private AnnotationVisitor arrayVisitor;
+
+    @Mock
+    private AnnotationVisitor innerAnnotationVisitor;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testSimpleValuesPlayback() throws Exception {
+
+        when(visitor.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
+
+        AnnotationPlayback playback = new AnnotationPlayback(find(SimpleTypes.class));
+        playback.accept(visitor);
+
+        verify(visitor).visitAnnotation(Type.getType(SimpleTypes.class).getDescriptor(),
+                                        true);
+        verify(annotationVisitor).visitEnd();
+
+        // Verify simple mono-valued attributes
+        verify(annotationVisitor).visit("aByte", Byte.valueOf((byte) 42));
+        verify(annotationVisitor).visit("aBoolean", Boolean.TRUE);
+        verify(annotationVisitor).visit("anInt", Integer.valueOf(42));
+        verify(annotationVisitor).visit("aLong", Long.valueOf(42));
+        verify(annotationVisitor).visit("aShort", Short.valueOf((short) 42));
+        verify(annotationVisitor).visit("aFloat", Float.valueOf(42));
+        verify(annotationVisitor).visit("aDouble", Double.valueOf(42));
+        verify(annotationVisitor).visit("aChar", Character.valueOf('a'));
+
+        // Verify String & Class
+        verify(annotationVisitor).visit("aString", "42");
+        verify(annotationVisitor).visit("aClass", Type.getType(String.class));
+
+        // Verify array os simple types
+        verify(annotationVisitor).visit("arrayOfByte", new byte[] {(byte) 42});
+        verify(annotationVisitor).visit("arrayOfBoolean", new boolean[] {true, true});
+        verify(annotationVisitor).visit("arrayOfInt", new int[] {42});
+        verify(annotationVisitor).visit("arrayOfLong", new long[] {42});
+        verify(annotationVisitor).visit("arrayOfShort", new short[] {42});
+        verify(annotationVisitor).visit("arrayOfFloat", new float[] {42});
+        verify(annotationVisitor).visit("arrayOfDouble", new double[] {});
+        verify(annotationVisitor).visit("arrayOfChar", new char[] {'a', 'b', 'c'});
+
+    }
+
+    public void testEnumValuesPlayback() throws Exception {
+
+        when(visitor.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
+
+        AnnotationPlayback playback = new AnnotationPlayback(find(EnumAnnotation.class));
+        playback.accept(visitor);
+
+        verify(visitor).visitAnnotation(Type.getType(EnumAnnotation.class).getDescriptor(),
+                                        true);
+        verify(annotationVisitor).visitEnd();
+
+        String desc = Type.getType(Mode.class).getDescriptor();
+        verify(annotationVisitor).visitEnum("noDefault", desc, "IN");
+        verify(annotationVisitor).visitEnum("withDefault", desc, "IN");
+        verify(annotationVisitor).visitEnum("withDefaultOverridden", desc, "IN");
+    }
+
+    public void testArrayValuesPlayback() throws Exception {
+
+        AnnotationVisitor arrayOfString = mock(AnnotationVisitor.class);
+        AnnotationVisitor arrayOfEnum = mock(AnnotationVisitor.class);
+        AnnotationVisitor arrayOfClass = mock(AnnotationVisitor.class);
+        AnnotationVisitor arrayOfAnnotation = mock(AnnotationVisitor.class);
+        AnnotationVisitor emptyArray = mock(AnnotationVisitor.class);
+
+        when(visitor.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
+        when(annotationVisitor.visitArray("arrayOfString")).thenReturn(arrayOfString);
+        when(annotationVisitor.visitArray("arrayOfEnum")).thenReturn(arrayOfEnum);
+        when(annotationVisitor.visitArray("arrayOfClass")).thenReturn(arrayOfClass);
+        when(annotationVisitor.visitArray("arrayOfAnnotation")).thenReturn(arrayOfAnnotation);
+        when(annotationVisitor.visitArray("emptyArray")).thenReturn(emptyArray);
+
+        AnnotationPlayback playback = new AnnotationPlayback(find(ArrayAnnotation.class));
+        playback.accept(visitor);
+
+        verify(visitor).visitAnnotation(Type.getType(ArrayAnnotation.class).getDescriptor(),
+                                        true);
+        verify(annotationVisitor).visitEnd();
+
+        String desc = Type.getType(Mode.class).getDescriptor();
+
+        verify(arrayOfString).visit(null, "42");
+        verify(arrayOfString).visit(null, "43");
+        verify(arrayOfString).visitEnd();
+
+        verify(arrayOfEnum).visitEnum(null, desc, "IN");
+        verify(arrayOfEnum).visitEnd();
+
+        verify(arrayOfClass).visit(null, Type.getType(Object.class));
+        verify(arrayOfClass).visitEnd();
+
+        verify(arrayOfAnnotation).visitAnnotation(null, Type.getType(InnerAnnotation.class).getDescriptor());
+        verify(arrayOfAnnotation).visitEnd();
+
+        verify(emptyArray).visitEnd();
+
+    }
+
+
+    public void testAnnotationValuesPlayback() throws Exception {
+
+        when(visitor.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
+        when(annotationVisitor.visitAnnotation("value", Type.getType(InnerAnnotation.class).getDescriptor()))
+                .thenReturn(innerAnnotationVisitor);
+        when(innerAnnotationVisitor.visitArray("arrayOfClass"))
+                .thenReturn(arrayVisitor);
+
+        AnnotationPlayback playback = new AnnotationPlayback(find(AnnotationAnnotation.class));
+        playback.accept(visitor);
+
+        verify(visitor).visitAnnotation(Type.getType(AnnotationAnnotation.class).getDescriptor(),
+                                        true);
+        verify(annotationVisitor).visitEnd();
+
+        String desc = Type.getType(Mode.class).getDescriptor();
+        verify(innerAnnotationVisitor).visit("aString", "42");
+        verify(innerAnnotationVisitor).visitEnum("modeEnum", desc, "IN");
+        verify(innerAnnotationVisitor).visitEnd();
+
+        verify(arrayVisitor).visit(null, Type.getType(Object.class));
+        verify(arrayVisitor).visitEnd();
+
+    }
+    private Annotation find(final Class<? extends Annotation> type) {
+        return Support.class.getAnnotation(type);
+    }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/AnnotationAnnotation.java
similarity index 64%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/AnnotationAnnotation.java
index 1748cfc..c707d7d 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/AnnotationAnnotation.java
@@ -17,15 +17,20 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
 
-import org.objectweb.asm.AnnotationVisitor;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 10:15
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AnnotationAnnotation {
+    InnerAnnotation value();
 }
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/ArrayAnnotation.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/ArrayAnnotation.java
new file mode 100644
index 0000000..92bee87
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/ArrayAnnotation.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 10:15
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ArrayAnnotation {
+    String[] arrayOfString();
+    Class<?>[] arrayOfClass();
+    Mode[] arrayOfEnum();
+    InnerAnnotation[] arrayOfAnnotation();
+    Mode[] emptyArray() default {};
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/EnumAnnotation.java
similarity index 61%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/EnumAnnotation.java
index 1748cfc..9ec1a4a 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/EnumAnnotation.java
@@ -17,15 +17,22 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
 
-import org.objectweb.asm.AnnotationVisitor;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 10:15
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EnumAnnotation {
+    Mode noDefault();
+    Mode withDefault() default Mode.IN;
+    Mode withDefaultOverridden() default Mode.OUT;
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/InnerAnnotation.java
similarity index 62%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/InnerAnnotation.java
index 1748cfc..4bdfbd7 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/InnerAnnotation.java
@@ -17,15 +17,21 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
 
-import org.objectweb.asm.AnnotationVisitor;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 10:15
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface InnerAnnotation {
+    String aString() default "42";
+    Class[] arrayOfClass() default {};
+    Mode modeEnum() default Mode.IN;
 }
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Mode.java
similarity index 76%
copy from ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
copy to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Mode.java
index 1748cfc..dec0af2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Mode.java
@@ -17,15 +17,13 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
-
-import org.objectweb.asm.AnnotationVisitor;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
 
 /**
-* User: guillaume
-* Date: 30/05/13
-* Time: 17:23
-*/
-public interface Replay {
-    void accept(AnnotationVisitor visitor);
+ * User: guillaume
+ * Date: 09/07/13
+ * Time: 10:14
+ */
+public enum Mode {
+    IN, OUT
 }
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/SimpleTypes.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/SimpleTypes.java
new file mode 100644
index 0000000..c592962
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/SimpleTypes.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+* User: guillaume
+* Date: 08/07/13
+* Time: 17:37
+*/
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SimpleTypes {
+    boolean aBoolean() default true;
+    byte aByte() default 42;
+    long aLong() default 42;
+    int anInt() default 42;
+    short aShort() default 42;
+    float aFloat() default 42;
+    double aDouble() default 42;
+    char aChar() default 'a';
+
+    String aString() default "42";
+    Class<?> aClass() default String.class;
+
+    boolean[] arrayOfBoolean() default {true, true};
+    byte[] arrayOfByte() default {42};
+    long[] arrayOfLong() default {42};
+    int[] arrayOfInt() default {42};
+    short[] arrayOfShort() default {42};
+    float[] arrayOfFloat() default 42;
+    double[] arrayOfDouble() default {};
+    char[] arrayOfChar() default {'a', 'b', 'c'};
+
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Support.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Support.java
new file mode 100644
index 0000000..3c2bee6
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/literal/types/Support.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.types;
+
+/**
+ * User: guillaume
+ * Date: 08/07/13
+ * Time: 17:36
+ */
+@SimpleTypes
+@EnumAnnotation(
+        noDefault = Mode.IN,
+        withDefaultOverridden = Mode.IN
+)
+@ArrayAnnotation(
+        arrayOfString = {"42", "43"},
+        arrayOfEnum = Mode.IN,
+        arrayOfClass = Object.class,
+        arrayOfAnnotation = @InnerAnnotation()
+)
+@AnnotationAnnotation(
+        @InnerAnnotation(
+                arrayOfClass = Object.class
+        )
+)
+public class Support {
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorderTestCase.java
similarity index 96%
rename from ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java
rename to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorderTestCase.java
index 71e5058..fdd9244 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/model/parser/replay/AnnotationRecorderTestCase.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay;
+package org.apache.felix.ipojo.manipulator.metadata.annotation.model.parser.replay;
 
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java
deleted file mode 100644
index 1607589..0000000
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
-
-import java.util.Collections;
-
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.objectweb.asm.Type;
-
-import junit.framework.TestCase;
-
-/**
- * User: guillaume
- * Date: 31/05/13
- * Time: 00:18
- */
-public class AnnotationRegistryTestCase extends TestCase {
-    public void testEmptyRegistry() throws Exception {
-        AnnotationRegistry registry = new AnnotationRegistry();
-        assertTrue(registry.isUnknown(Type.BOOLEAN_TYPE));
-        assertFalse(registry.isStereotype(Type.BOOLEAN_TYPE));
-        assertFalse(registry.isUnbound(Type.BOOLEAN_TYPE));
-    }
-
-    public void testRegistry1() throws Exception {
-        AnnotationRegistry registry = new AnnotationRegistry();
-        registry.addStereotype(Type.BOOLEAN_TYPE, Collections.<RootAnnotationRecorder>emptyList());
-
-        assertFalse(registry.isUnknown(Type.BOOLEAN_TYPE));
-        assertTrue(registry.isStereotype(Type.BOOLEAN_TYPE));
-        assertFalse(registry.isUnbound(Type.BOOLEAN_TYPE));
-    }
-
-    public void testRegistry2() throws Exception {
-        AnnotationRegistry registry = new AnnotationRegistry();
-        registry.addUnbound(Type.BOOLEAN_TYPE);
-
-        assertFalse(registry.isUnknown(Type.BOOLEAN_TYPE));
-        assertFalse(registry.isStereotype(Type.BOOLEAN_TYPE));
-        assertTrue(registry.isUnbound(Type.BOOLEAN_TYPE));
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistryTestCase.java
new file mode 100644
index 0000000..9ff6a5a
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/CompletableBindingRegistryTestCase.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 12/07/13
+ * Time: 10:27
+ */
+public class CompletableBindingRegistryTestCase extends TestCase {
+
+    public static final String DESCRIPTOR = "[unknown;";
+
+    @Mock
+    private BindingRegistry delegate;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testUnknownDescriptorTriggerCallback() throws Exception {
+        EmptyCompletableBindingRegistry registry = new EmptyCompletableBindingRegistry(delegate);
+        when(delegate.getBindings(DESCRIPTOR)).thenReturn(Collections.<Binding>emptyList());
+
+        registry.getBindings(DESCRIPTOR);
+
+        assertNotNull(registry.type);
+    }
+
+    public void testKnownDescriptorDoNotTriggerCallback() throws Exception {
+        EmptyCompletableBindingRegistry registry = new EmptyCompletableBindingRegistry(delegate);
+        when(delegate.getBindings(DESCRIPTOR)).thenReturn(Collections.<Binding>singletonList(new NullBinding(Type.getType(DESCRIPTOR))));
+
+        registry.getBindings(DESCRIPTOR);
+
+        assertNull(registry.type);
+    }
+
+    private static class EmptyCompletableBindingRegistry extends CompletableBindingRegistry {
+
+        public Type type = null;
+
+        public EmptyCompletableBindingRegistry(final BindingRegistry delegate) {
+            super(delegate, null);
+        }
+
+        @Override
+        protected List<Binding> createBindings(final Type type) {
+            this.type = type;
+            return Collections.emptyList();
+        }
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistryTestCase.java
similarity index 88%
rename from ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistryTestCase.java
rename to ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistryTestCase.java
index 7c1bbf4..5495929 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/BindingRegistryTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/DefaultBindingRegistryTestCase.java
@@ -38,8 +38,9 @@
  * Time: 10:31 AM
  * To change this template use File | Settings | File Templates.
  */
-public class BindingRegistryTestCase extends TestCase {
+public class DefaultBindingRegistryTestCase extends TestCase {
 
+    public static final Type PROVIDES_TYPE = Type.getType(Provides.class);
     private BindingRegistry registry;
 
     @Mock
@@ -52,7 +53,7 @@
     @Override
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        registry = new BindingRegistry(reporter);
+        registry = new DefaultBindingRegistry(reporter);
     }
 
     public void testBindingAddition() throws Exception {
@@ -68,13 +69,12 @@
     }
 
     public void testGetBindingsWhenEmpty() throws Exception {
-        assertNull(registry.getBindings(Type.getType(Provides.class).getDescriptor()));
-        assertNotNull(registry.selection(null));
+        assertTrue(registry.getBindings(PROVIDES_TYPE.getDescriptor()).isEmpty());
     }
 
     private Binding binding() {
         Binding binding = new Binding();
-        binding.setAnnotationType(Provides.class);
+        binding.setAnnotationType(PROVIDES_TYPE);
         binding.setFactory(factory);
         binding.setPredicate(predicate);
         return binding;
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistryTestCase.java
new file mode 100644
index 0000000..d06fda9
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/IgnoreAllBindingRegistryTestCase.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 17:36
+ */
+public class IgnoreAllBindingRegistryTestCase extends TestCase {
+    public static final String UNKNOWN_DESCRIPTOR = "[unknown;";
+
+    @Mock
+    private BindingRegistry delegate;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testThatNullBindingIsGenerated() throws Exception {
+        when(delegate.getBindings(UNKNOWN_DESCRIPTOR)).thenReturn(Collections.<Binding>emptyList());
+
+        IgnoreAllBindingRegistry registry = new IgnoreAllBindingRegistry(delegate, null);
+
+        List<Binding> bindings = registry.getBindings(UNKNOWN_DESCRIPTOR);
+        assertTrue(bindings.get(0) instanceof NullBinding);
+
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistryTestCase.java
new file mode 100644
index 0000000..1dbdd14
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/LegacyGenericBindingRegistryTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 11/07/13
+ * Time: 17:07
+ */
+public class LegacyGenericBindingRegistryTestCase extends TestCase {
+
+    public static final String AN_IGNORED_ANNOTATION = "[an.ignored.Annotation;";
+    public static final String RECOGNISED_IPOJO_ANNOTATION = "[a.recognised.ipojo.Annotation;";
+    public static final String RECOGNISED_HANDLER_ANNOTATION = "[a.recognised.handler.Annotation;";
+
+    @Mock
+    private BindingRegistry delegate;
+
+    @Captor
+    ArgumentCaptor<List<Binding>> capture;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testNonRecognisedTypeAreIgnored() throws Exception {
+        when(delegate.getBindings(AN_IGNORED_ANNOTATION)).thenReturn(Collections.<Binding>emptyList());
+
+        LegacyGenericBindingRegistry registry = new LegacyGenericBindingRegistry(delegate, null);
+
+        List<Binding> bindings = registry.getBindings(AN_IGNORED_ANNOTATION);
+        assertTrue(bindings.isEmpty());
+
+        verify(delegate).addBindings(capture.capture());
+        assertTrue(capture.getValue().isEmpty());
+    }
+
+    public void testIPojoRecognisedTypeAreSupported() throws Exception {
+        when(delegate.getBindings(RECOGNISED_IPOJO_ANNOTATION)).thenReturn(Collections.<Binding>emptyList());
+
+        LegacyGenericBindingRegistry registry = new LegacyGenericBindingRegistry(delegate, null);
+
+        List<Binding> bindings = registry.getBindings(RECOGNISED_IPOJO_ANNOTATION);
+        assertEquals(1, bindings.size());
+
+        verify(delegate).addBindings(capture.capture());
+        Binding one = capture.getValue().get(0);
+        assertEquals(Type.getType(RECOGNISED_IPOJO_ANNOTATION), one.getAnnotationType());
+    }
+
+    public void testHandlerRecognisedTypeAreSupported() throws Exception {
+        when(delegate.getBindings(RECOGNISED_HANDLER_ANNOTATION)).thenReturn(Collections.<Binding>emptyList());
+
+        LegacyGenericBindingRegistry registry = new LegacyGenericBindingRegistry(delegate, null);
+
+        List<Binding> bindings = registry.getBindings(RECOGNISED_HANDLER_ANNOTATION);
+        assertEquals(1, bindings.size());
+
+        verify(delegate).addBindings(capture.capture());
+        Binding one = capture.getValue().get(0);
+        assertEquals(Type.getType(RECOGNISED_HANDLER_ANNOTATION), one.getAnnotationType());
+    }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistryTestCase.java
new file mode 100644
index 0000000..4e05111
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/MetaAnnotationBindingRegistryTestCase.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.registry;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.HandlerBinding;
+import org.apache.felix.ipojo.annotations.Ignore;
+import org.apache.felix.ipojo.annotations.Stereotype;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.GenericVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.StereotypeVisitorFactory;
+import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 12/07/13
+ * Time: 12:13
+ */
+public class MetaAnnotationBindingRegistryTestCase extends TestCase {
+
+    public static final String DESCRIPTOR = "[unknown;";
+    public static final Type TYPE = Type.getType(DESCRIPTOR);
+
+    @Mock
+    private BindingRegistry delegate;
+
+    @Mock
+    private ResourceStore store;
+
+    @Mock
+    private Reporter reporter;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(delegate.getBindings(DESCRIPTOR)).thenReturn(Collections.<Binding>emptyList());
+    }
+
+    public void testAnnotationTypeResourceNotFound() throws Exception {
+        when(store.read(anyString()))
+                .thenThrow(IOException.class);
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        assertTrue(registry.getBindings(DESCRIPTOR).isEmpty());
+    }
+
+    public void testClassicalAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(Classical.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        assertTrue(registry.getBindings(Type.getDescriptor(Classical.class)).isEmpty());
+    }
+
+    public void testStereotypeAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(Stereotyped.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        Binding binding = registry.getBindings(Type.getDescriptor(Stereotyped.class)).get(0);
+        assertTrue(binding.getFactory() instanceof StereotypeVisitorFactory);
+    }
+
+    public void testHandlerBindingAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(Bound.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        Binding binding = registry.getBindings(Type.getDescriptor(Bound.class)).get(0);
+        assertTrue(binding.getFactory() instanceof GenericVisitorFactory);
+    }
+
+    public void testIgnoreAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(Ignored.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        Binding binding = registry.getBindings(Type.getDescriptor(Ignored.class)).get(0);
+        assertTrue(binding instanceof NullBinding);
+    }
+
+    public void testBothStereotypeAndBindingAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(StereotypedBinding.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        List<Binding> bindings = registry.getBindings(Type.getDescriptor(StereotypedBinding.class));
+        assertEquals(2, bindings.size());
+        assertHasVisitorFactories(bindings, StereotypeVisitorFactory.class, GenericVisitorFactory.class);
+    }
+
+    public void testIgnoredWithStereotypeAnnotation() throws Exception {
+        when(store.read(anyString()))
+                .thenReturn(from(StereotypedIgnoredBinding.class));
+        MetaAnnotationBindingRegistry registry = new MetaAnnotationBindingRegistry(delegate, reporter, store);
+        List<Binding> bindings = registry.getBindings(Type.getDescriptor(StereotypedIgnoredBinding.class));
+        assertEquals(1, bindings.size());
+        assertHasVisitorFactories(bindings, NullVisitorFactory.class);
+    }
+
+    private void assertHasVisitorFactories(final List<Binding> bindings,
+                                           final Class<? extends AnnotationVisitorFactory>... factories) {
+        List<Class<? extends AnnotationVisitorFactory>> existing = new ArrayList<Class<? extends AnnotationVisitorFactory>>();
+        for (Binding binding : bindings) {
+            existing.add(binding.getFactory().getClass());
+        }
+
+        for (Class<? extends AnnotationVisitorFactory> factory : factories) {
+            if (!existing.remove(factory)) {
+                fail("Bindings do not contains expected AnnotationVisitorFactory type:  " + factory.getName());
+            }
+        }
+    }
+
+    private byte[] from(Class<?> type) throws IOException {
+        ClassLoader loader = type.getClassLoader();
+        InputStream is = loader.getResourceAsStream(Strings.asResourcePath(type.getName()));
+        return Streams.readBytes(is);
+    }
+
+    private static @interface Classical {}
+
+    @Component
+    @Stereotype
+    private static @interface Stereotyped {}
+
+    @HandlerBinding
+    private static @interface Bound {}
+
+    @Ignore
+    private static @interface Ignored {}
+
+    @Component
+    @Stereotype
+    @HandlerBinding
+    private static @interface StereotypedBinding {}
+
+    @Component
+    @Stereotype
+    @HandlerBinding
+    @Ignore
+    private static @interface StereotypedIgnoredBinding {}
+
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
index d1def40..06c337d 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
@@ -22,11 +22,6 @@
 import junit.framework.TestCase;
 import org.apache.felix.ipojo.manipulator.Reporter;
 import org.apache.felix.ipojo.manipulator.ResourceStore;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.FieldGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.MethodGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.ParameterGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.TypeGenericVisitor;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util.Bindings;
 import org.apache.felix.ipojo.manipulator.spi.AbsBindingModule;
 import org.apache.felix.ipojo.manipulator.spi.AnnotationVisitorFactory;
 import org.apache.felix.ipojo.manipulator.spi.BindingContext;
@@ -45,7 +40,6 @@
 import java.lang.annotation.Target;
 
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
@@ -73,7 +67,7 @@
     @Override
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        registry = new BindingRegistry(reporter);
+        registry = new DefaultBindingRegistry(reporter);
         when(factory.newAnnotationVisitor(any(BindingContext.class)))
                 .thenReturn(visitor);
         // Simulate a resource not found exception
@@ -150,23 +144,6 @@
 
     }
 
-    public void testSelectionForGenericVisitors() throws Exception {
-
-        assertClassSelection(OnTypeOnly.class, nullValue());
-        assertFieldSelection(OnFieldOnly.class, nullValue());
-        assertMethodSelection(OnMethodOnly.class, nullValue());
-        assertParameterSelection(OnParameterOnly.class, nullValue());
-
-        registry.getDefaultBindings().addAll(Bindings.newDefaultBindings(store, new AnnotationRegistry()));
-
-        // Verifications
-        assertClassSelection(OnTypeOnly.class, instanceOf(TypeGenericVisitor.class));
-        assertFieldSelection(OnFieldOnly.class, instanceOf(FieldGenericVisitor.class));
-        assertMethodSelection(OnMethodOnly.class, instanceOf(MethodGenericVisitor.class));
-        assertParameterSelection(OnParameterOnly.class, instanceOf(ParameterGenericVisitor.class));
-
-    }
-
     private void assertClassSelection(Class<? extends Annotation> type, Matcher matcher) {
         Selection selection = new Selection(registry, null, reporter);
         selection.type(null, classNode());
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java
deleted file mode 100644
index 10fc0ef..0000000
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype;
-
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.when;
-
-import java.net.URL;
-
-import org.apache.felix.ipojo.annotations.Component;
-import org.apache.felix.ipojo.annotations.Instantiate;
-import org.apache.felix.ipojo.annotations.Stereotype;
-import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
-import org.apache.felix.ipojo.manipulator.util.Streams;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Type;
-
-import junit.framework.TestCase;
-
-/**
- * User: guillaume
- * Date: 30/05/13
- * Time: 23:51
- */
-public class StereotypeParserTestCase extends TestCase {
-    public static final String COMPONENT_DESC = Type.getType(Component.class).getDescriptor();
-    public static final String INSTANTIATE_DESC = Type.getType(Instantiate.class).getDescriptor();
-    @Mock
-    private AnnotationVisitor av;
-
-    @Mock
-    private ClassVisitor cv;
-
-    @Override
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    public void testStereotypeParsing() throws Exception {
-        StereotypeParser parser = new StereotypeParser();
-        parser.read(resource(IsStereotype.class));
-        assertTrue(parser.isStereotype());
-    }
-
-    public void testStereotypeParsingWithAnnotations() throws Exception {
-
-        when(cv.visitAnnotation(COMPONENT_DESC, false))
-                .thenReturn(av);
-        when(cv.visitAnnotation(INSTANTIATE_DESC, false))
-                .thenReturn(av);
-
-        StereotypeParser parser = new StereotypeParser();
-        parser.read(resource(ComponentInstanceStereotype.class));
-        assertTrue(parser.isStereotype());
-        assertEquals(2, parser.getRecorders().size());
-
-        RootAnnotationRecorder rec1 = parser.getRecorders().get(0);
-        rec1.accept(cv);
-        RootAnnotationRecorder rec2 = parser.getRecorders().get(1);
-        rec2.accept(cv);
-
-        InOrder order = inOrder(cv, av);
-        order.verify(cv).visitAnnotation(COMPONENT_DESC, false);
-        order.verify(av).visit("immediate", Boolean.TRUE);
-        order.verify(av).visitEnd();
-        order.verify(cv).visitAnnotation(INSTANTIATE_DESC, false);
-        order.verify(av).visitEnd();
-    }
-
-    public void testNoStereotypeParsing() throws Exception {
-        StereotypeParser parser = new StereotypeParser();
-        parser.read(resource(NoStereotype.class));
-        assertFalse(parser.isStereotype());
-    }
-
-    private byte[] resource(final Class<?> aClass) throws Exception {
-        String name = aClass.getDeclaringClass().getSimpleName() +
-                "$" + aClass.getSimpleName()
-                + ".class";
-        URL url = aClass.getResource(name);
-        return Streams.readBytes(url.openStream());
-    }
-
-    @Stereotype
-    public static @interface IsStereotype {}
-
-    public static @interface NoStereotype {}
-
-    @Component(immediate = true)
-    @Instantiate
-    @Stereotype
-    public static @interface ComponentInstanceStereotype {}
-
-}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModuleTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModuleTestCase.java
index ca3e751..f6f6ebe 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModuleTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/spi/AbsBindingModuleTestCase.java
@@ -20,9 +20,16 @@
 package org.apache.felix.ipojo.manipulator.spi;
 
 import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.HandlerBinding;
 import org.apache.felix.ipojo.annotations.Provides;
 import org.apache.felix.ipojo.annotations.Requires;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.model.literal.AnnotationLiteral;
 import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.GenericVisitorFactory;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.ignore.NullBinding;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.StereotypeVisitorFactory;
 
 import java.lang.annotation.ElementType;
 import java.util.Iterator;
@@ -30,6 +37,7 @@
 import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.on;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.only;
+import static org.objectweb.asm.Type.getType;
 
 /**
  * Created with IntelliJ IDEA.
@@ -52,7 +60,7 @@
         Iterator<Binding> i = module.iterator();
         Binding one = i.next();
         assertNotNull(one);
-        assertEquals(Provides.class, one.getAnnotationType());
+        assertEquals(getType(Provides.class), one.getAnnotationType());
         assertEquals(factory, one.getFactory());
 
         // Only 1 Binding
@@ -72,13 +80,13 @@
         Iterator<Binding> i = module.iterator();
         Binding one = i.next();
         assertNotNull(one);
-        assertEquals(Provides.class, one.getAnnotationType());
+        assertEquals(getType(Provides.class), one.getAnnotationType());
         assertEquals(factory, one.getFactory());
 
         // Second Binding
         Binding two = i.next();
         assertNotNull(two);
-        assertEquals(Requires.class, two.getAnnotationType());
+        assertEquals(getType(Requires.class), two.getAnnotationType());
         assertEquals(factory, two.getFactory());
     }
 
@@ -96,13 +104,13 @@
         Iterator<Binding> i = module.iterator();
         Binding one = i.next();
         assertNotNull(one);
-        assertEquals(Provides.class, one.getAnnotationType());
+        assertEquals(getType(Provides.class), one.getAnnotationType());
         assertEquals(factory, one.getFactory());
 
         // Second Binding
         Binding two = i.next();
         assertNotNull(two);
-        assertEquals(Provides.class, two.getAnnotationType());
+        assertEquals(getType(Provides.class), two.getAnnotationType());
         assertEquals(factory2, two.getFactory());
     }
 
@@ -120,7 +128,7 @@
         Iterator<Binding> i = module.iterator();
         Binding one = i.next();
         assertNotNull(one);
-        assertEquals(Provides.class, one.getAnnotationType());
+        assertEquals(getType(Provides.class), one.getAnnotationType());
         assertEquals(factory, one.getFactory());
 
         // Only 1 Binding
@@ -135,8 +143,8 @@
                 bind(Provides.class)
                         .when(on(ElementType.FIELD))
                         .to(factory)
-                .when(on(ElementType.PARAMETER))
-                .to(factory2);
+                        .when(on(ElementType.PARAMETER))
+                        .to(factory2);
             }
         };
         module.configure();
@@ -144,15 +152,111 @@
         Iterator<Binding> i = module.iterator();
         Binding one = i.next();
         assertNotNull(one);
-        assertEquals(Provides.class, one.getAnnotationType());
+        assertEquals(getType(Provides.class), one.getAnnotationType());
         assertEquals(factory, one.getFactory());
 
         // Second Binding
         Binding two = i.next();
         assertNotNull(two);
-        assertEquals(Provides.class, two.getAnnotationType());
+        assertEquals(getType(Provides.class), two.getAnnotationType());
         assertEquals(factory2, two.getFactory());
     }
 
+    public void testHandlerBindings() throws Exception {
+        AbsBindingModule module = new AbsBindingModule() {
+            public void configure() {
+                bindHandlerBinding(Bound.class).to("com.acme", "foo");
+            }
+        };
+        module.configure();
+
+        Iterator<Binding> i = module.iterator();
+        Binding one = i.next();
+        assertNotNull(one);
+        assertEquals(getType(Bound.class), one.getAnnotationType());
+        assertTrue(one.getFactory() instanceof GenericVisitorFactory);
+    }
+
+    public void testStereotypeBindings() throws Exception {
+        AbsBindingModule module = new AbsBindingModule() {
+            public void configure() {
+                bindStereotype(Bound.class)
+                        .with(new ComponentLiteral() {
+                            @Override
+                            public boolean publicFactory() {
+                                return false;
+                            }
+                        });
+            }
+        };
+        module.configure();
+
+        Iterator<Binding> i = module.iterator();
+        Binding one = i.next();
+        assertNotNull(one);
+        assertEquals(getType(Bound.class), one.getAnnotationType());
+        assertTrue(one.getFactory() instanceof StereotypeVisitorFactory);
+    }
+
+
+    public void testIgnoreBindings() throws Exception {
+        AbsBindingModule module = new AbsBindingModule() {
+            public void configure() {
+                bindIgnore(Bound.class);
+            }
+        };
+        module.configure();
+
+        Iterator<Binding> i = module.iterator();
+        Binding one = i.next();
+        assertEquals(getType(Bound.class), one.getAnnotationType());
+        assertTrue(one instanceof NullBinding);
+    }
+
+    private static @interface Bound {}
+
+    private static class ComponentLiteral extends AnnotationLiteral<Component> implements Component {
+
+        public boolean public_factory() {
+            return true;
+        }
+
+        public boolean publicFactory() {
+            return true;
+        }
+
+        public String name() {
+            return "";
+        }
+
+        public boolean architecture() {
+            return false;
+        }
+
+        public boolean immediate() {
+            return false;
+        }
+
+        public boolean propagation() {
+            return false;
+        }
+
+        public String managedservice() {
+            return "";
+        }
+
+        public String factory_method() {
+            return "";
+        }
+
+        public String factoryMethod() {
+            return "";
+        }
+
+        public String version() {
+            return "";
+        }
+    }
+
 
 }