diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java
deleted file mode 100644
index 54e133b..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java
+++ /dev/null
@@ -1,345 +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.manipulation.annotations;
-
-import java.lang.reflect.Array;
-
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * Collect metadata from custom annotation.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CustomAnnotationVisitor extends EmptyVisitor implements AnnotationVisitor {
-
-    /**
-     * Parent element.
-     */
-    private Element m_elem;
-
-    /**
-     * Id attribute (if found)
-     * else use the annotation package name.
-     */
-    private String m_id;
-
-    /**
-     * Parent attribute (if found)
-     * else use the annotation package name.
-     */
-    private String m_parent;
-
-    /**
-     * Is the custom annotation a first-order annotation.
-     */
-    private boolean m_root;
-
-    /**
-     * Is the visit annotation a class annotation?
-     */
-    private boolean m_classAnnotation;
-
-    /**
-     * Metadata collector.
-     */
-    private MetadataCollector m_collector;
-
-    /**
-     * Flag sets to true for parameter annotation.
-     */
-    private boolean m_isParameterAnnotation = false;
-
-    /**
-     * For parameter annotations, the index of the parameter.
-     */
-    private int m_index = -1;
-
-    /**
-     * For parameter annotation, the descriptor of the method.
-     */
-    private String m_desc;
-
-    /**
-     * Constructor.
-     * @param elem the parent element
-     * @param collector the metadata collector
-     * @param root is the annotation a root
-     * @param clazz the annotation is a class annotation.
-     */
-    public CustomAnnotationVisitor(Element elem, MetadataCollector collector, boolean root, boolean clazz) {
-        m_elem = elem;
-        m_root = root;
-        m_collector = collector;
-        m_classAnnotation = clazz;
-    }
-
-    /**
-     * Constructor used for parameter annotations
-     * @param elem the parent element
-     * @param collector the metadata collector
-     * @param root is the annotation a root
-     * @param clazz the annotation is a class annotation.
-     * @param index the index of the argument
-     * @param descriptor the descriptor of the method
-     */
-    public CustomAnnotationVisitor(Element elem, MetadataCollector collector, boolean root, boolean clazz, int index, String descriptor) {
-        m_elem = elem;
-        m_root = root;
-        m_collector = collector;
-        m_classAnnotation = clazz;
-        m_isParameterAnnotation = true;
-        m_index = index;
-        m_desc = descriptor;
-    }
-
-    /**
-     * Check if the given annotation descriptor is an iPOJO custom annotation.
-     * A valid iPOJO custom annotation must contains 'ipojo' or 'handler' in its qualified name.
-     * @param desc : annotation descriptor
-     * @return : true if the given descriptor is an iPOJO custom annotation
-     */
-    public static boolean isCustomAnnotation(String desc) {
-        desc = desc.toLowerCase();
-        if (desc.indexOf("ipojo") != -1 || desc.indexOf("handler") != -1) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Build the element object from the given descriptor.
-     * @param desc : annotation descriptor
-     * @return : the element
-     */
-    public static Element buildElement(String desc) {
-        String s = (desc.replace('/', '.')).substring(1, desc.length() - 1);
-        int index = s.lastIndexOf('.');
-        String name = s.substring(index + 1);
-        String namespace = s.substring(0, index);
-        return new Element(name, namespace);
-    }
-
-
-    /**
-     * Visit a 'simple' annotation attribute.
-     * This method is used for primitive arrays too.
-     * @param arg0 : attribute name
-     * @param arg1 : attribute value
-     * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-     */
-    public void visit(String arg0, Object arg1) {
-        if (arg1.getClass().isArray()) {
-            // Primitive arrays case
-            String v = null;
-            int index = Array.getLength(arg1);
-            for (int i = 0; i < index; i++) {
-                if (v == null) {
-                    v = "{" + Array.get(arg1, i);
-                } else {
-                    v += "," + Array.get(arg1, i);
-                }
-            }
-            v += "}";
-            m_elem.addAttribute(new Attribute(arg0, v));
-            return;
-        }
-        
-        // Attributes are added as normal attributes
-        if (!(arg1 instanceof Type)) {
-            m_elem.addAttribute(new Attribute(arg0, arg1.toString()));            
-        } else {
-            // Attributes of type class need a special handling
-            m_elem.addAttribute(new Attribute(arg0, ((Type) arg1).getClassName()));        
-        }
-        
-        if (m_root) {
-            if (arg0.equals("id")) {
-                m_id = arg1.toString();
-            } else if (arg0.equals("parent")) {
-                m_parent = arg1.toString();
-            }
-        }
-    }
-
-    /**
-     * Visit a sub-annotation.
-     * @param arg0 : attribute name.
-     * @param arg1 : annotation description
-     * @return an annotation visitor which will visit the given annotation
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitAnnotation(java.lang.String, java.lang.String)
-     */
-    public AnnotationVisitor visitAnnotation(String arg0, String arg1) {
-        // Sub annotations are mapped to sub-elements
-        Element elem = buildElement(arg1);
-        m_elem.addElement(elem);
-        return new CustomAnnotationVisitor(elem, m_collector, false, false);
-    }
-
-    /**
-     * Visit an array attribute.
-     * @param arg0 : attribute name
-     * @return a visitor which will visit each element of the array
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitArray(java.lang.String)
-     */
-    public AnnotationVisitor visitArray(String arg0) {
-        return new SubArrayVisitor(m_elem, arg0);
-    }
-
-    /**
-     * Visits an enumeration attribute.
-     * @param arg0 the attribute name
-     * @param arg1 the enumeration descriptor
-     * @param arg2 the attribute value
-     * @see org.objectweb.asm.AnnotationVisitor#visitEnum(java.lang.String, java.lang.String, java.lang.String)
-     */
-    public void visitEnum(String arg0, String arg1, String arg2) {
-        m_elem.addAttribute(new Attribute(arg0, arg2));
-    }
-
-    /**
-     * End of the visit.
-     * All attribute was visited, we can update collectors data.
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-     */
-    public void visitEnd() {
-        if (m_root) {
-            if (m_id != null) {
-                m_collector.getIds().put(m_id, m_elem);
-            } else {
-            	m_id = m_elem.getNameSpace();
-                if (! m_collector.getIds().containsKey(m_elem.getNameSpace()) && m_classAnnotation) {
-                    // If the namespace is not already used, add the annotation as the
-                    // root element of this namespace.
-                    m_collector.getIds().put(m_elem.getNameSpace(), m_elem);
-                } else {
-                    // Already used, the element is the parent.
-                    if (m_parent == null) {
-                        m_parent = m_elem.getNameSpace();
-                    }
-                }
-            }
-
-            m_collector.getElements().put(m_elem, m_parent);
-
-            if (m_isParameterAnnotation) {
-            	String t = Type.getArgumentTypes(m_desc)[m_index].getClassName();
-            	m_elem.addAttribute(new Attribute("type", t));
-            	m_elem.addAttribute(
-            			new Attribute("constructor-parameter", Integer.toString(m_index)));
-            }
-        }
-    }
-
-    private class SubArrayVisitor extends EmptyVisitor implements AnnotationVisitor {
-        /**
-         * Parent element.
-         */
-        private Element m_elem;
-
-        /**
-         * Attribute name.
-         */
-        private String m_name;
-
-        /**
-         * Attribute value.
-         * (accumulator)
-         */
-        private String m_acc;
-
-        /**
-         * Constructor.
-         * @param elem : parent element.
-         * @param name : attribute name.
-         */
-        public SubArrayVisitor(Element elem, String name) {
-            m_elem = elem;
-            m_name = name;
-        }
-
-        /**
-         * Visit a 'simple' element of the visited array.
-         * @param arg0 : null
-         * @param arg1 : element value.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (m_acc == null) {
-                if (!(arg1 instanceof Type)) {
-                    m_acc = "{" + arg1.toString();            
-                } else {
-                    // Attributes of type class need a special handling
-                    m_acc = "{" + ((Type) arg1).getClassName();
-                }
-            } else {
-                if (!(arg1 instanceof Type)) {
-                    m_acc = m_acc + "," + arg1.toString();
-                } else {
-                    // Attributes of type class need a special handling
-                    m_acc = m_acc + "," + ((Type) arg1).getClassName();
-                }
-            }
-        }
-
-        /**
-         * Visits an enumeration attribute.
-         * @param arg0 the attribute name
-         * @param arg1 the enumeration descriptor
-         * @param arg2 the attribute value
-         */
-        public void visitEnum(String arg0, String arg1, String arg2) {
-            if (m_acc == null) {
-                m_acc = "{" + arg2;
-            } else {
-                m_acc = m_acc + "," + arg2;
-            }
-        }
-
-
-        /**
-         * Visit an annotation element of the visited array.
-         * @param arg0 : null
-         * @param arg1 : annotation to visit
-         * @return the visitor which will visit the annotation
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitAnnotation(java.lang.String, java.lang.String)
-         */
-        public AnnotationVisitor visitAnnotation(String arg0, String arg1) {
-            // Sub annotations are map to sub-elements
-            Element elem = buildElement(arg1);
-            m_elem.addElement(elem);
-            return new CustomAnnotationVisitor(elem, m_collector, false, false);
-        }
-
-        /**
-         * End of the visit.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            if (m_acc != null) {
-                // We have analyzed an attribute
-                m_elem.addAttribute(new Attribute(m_name, m_acc + "}"));
-            }
-        }
-
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
deleted file mode 100644
index 31905d6..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
+++ /dev/null
@@ -1,363 +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.manipulation.annotations;
-
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * Collect field annotations. 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class FieldCollector extends EmptyVisitor implements FieldVisitor {
-    
-    /**
-     * Collected element.
-     */
-    private MetadataCollector m_collector;
-    
-    /**
-     * Field name. 
-     */
-    private String m_field;
-    
-    /**
-     * Constructor.
-     * @param fieldName : field name
-     * @param collector : metadata collector.
-     */
-    public FieldCollector(String fieldName, MetadataCollector collector) {
-        m_collector = collector;
-        m_field = fieldName;
-    }
-
-    /**
-     * Visit annotations on the current field.
-     * @param arg0 : annotation name
-     * @param arg1 : is the annotation a runtime annotation.
-     * @return the annotation visitor visiting the annotation
-     * @see org.objectweb.asm.FieldVisitor#visitAnnotation(java.lang.String, boolean)
-     */
-    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Requires;")) {
-            return new RequiresAnnotationParser(m_field);
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Controller;")) {
-            Element elem = new Element("controller", "");
-            elem.addAttribute(new Attribute("field", m_field));
-            m_collector.getElements().put(elem, null);
-            return null;
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/ServiceProperty;")) {
-            if (! m_collector.getIds().containsKey("provides")) { // The provides annotation is already computed.
-                System.err.println("The component does not provide services, skip ServiceProperty for " + m_field);
-                return null;
-            } else {
-                // Get the provides element
-                Element parent = (Element) m_collector.getIds().get("provides");
-                return new PropertyAnnotationParser(m_field, parent);
-            } 
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/ServiceController;")) {
-            if (! m_collector.getIds().containsKey("provides")) { // The provides annotation is already computed.
-                System.err.println("The component does not provide services, skip ServiceController for " + m_field);
-                return null;
-            } else {
-                // Get the provides element
-                Element parent = (Element) m_collector.getIds().get("provides");
-                return new ServiceControllerAnnotationParser(m_field, parent);
-            } 
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Property;")) {
-            Element parent = null;
-            if (! m_collector.getIds().containsKey("properties")) {
-                parent = new Element("Properties", "");
-                m_collector.getIds().put("properties", parent);
-                m_collector.getElements().put(parent, null);
-            } else {
-                parent = (Element) m_collector.getIds().get("properties");
-            }
-            return new PropertyAnnotationParser(m_field, parent);
-        }
-        
-        if (CustomAnnotationVisitor.isCustomAnnotation(arg0)) {
-            Element elem = CustomAnnotationVisitor.buildElement(arg0);
-            elem.addAttribute(new Attribute("field", m_field)); // Add a field attribute
-            return new CustomAnnotationVisitor(elem, m_collector, true, false);
-        }
-        
-        return null;
-       
-    }
-    
-    /**
-     * AnnotationVisitor parsing the @requires annotation.
-     */
-    private final class RequiresAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
-        
-        /**
-         * Dependency field.
-         */
-        private String m_field;
-        
-        /**
-         * Dependency filter.
-         */
-        private String m_filter;
-        
-        /**
-         * Is the dependency optional ?
-         */
-        private String m_optional;
-        
-        /**
-         * Dependency specification.
-         */
-        private String m_specification;
-        
-        /**
-         * Dependency id.
-         */
-        private String m_id;
-        
-        /**
-         * Binding policy.
-         */
-        private String m_policy;
-        
-        /**
-         * Default-Implementation attribute.
-         */
-        private String m_defaultImplementation;
-        
-        /**
-         * Enable or Disable Nullable pattern. 
-         */
-        private String m_nullable;
-        
-        /**
-         * Comparator.
-         */
-        private String m_comparator;
-        
-        /**
-         * From attribute.
-         */
-        private String m_from;
-        
-        /**
-         * Proxy attribute.
-         */
-        private String m_proxy;
-        
-        /**
-         * Constructor.
-         * @param name : field name.
-         */
-        private RequiresAnnotationParser(String name) {
-            m_field = name;
-        }
-
-        /**
-         * Visit one "simple" annotation.
-         * @param arg0 : annotation name
-         * @param arg1 : annotation value
-         * @see org.objectweb.asm.AnnotationVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("filter")) {
-                m_filter = arg1.toString();
-                return;
-            }
-            if (arg0.equals("optional")) {
-                m_optional = arg1.toString();
-                return;
-            }
-            if (arg0.equals("nullable")) {
-                m_nullable = arg1.toString();
-                return;
-            }
-            if (arg0.equals("policy")) {
-                m_policy = arg1.toString();
-                return;
-            }
-            if (arg0.equals("defaultimplementation")) {
-                Type type = Type.getType(arg1.toString());
-                m_defaultImplementation = type.getClassName();
-                return;
-            }
-            if (arg0.equals("specification")) {
-                m_specification = arg1.toString();
-                return;
-            }
-            if (arg0.equals("id")) {
-                m_id = arg1.toString();
-                return;
-            }
-            if (arg0.equals("comparator")) {
-                Type type = Type.getType(arg1.toString());
-                m_comparator = type.getClassName();
-                return;
-            }
-            if (arg0.equals("from")) {
-                m_from = arg1.toString();
-                return;
-            }
-            if (arg0.equals("proxy")) {
-                m_proxy = arg1.toString();
-                return;
-            }
-        }
-
-        /**
-         * End of the annotation.
-         * Create a "requires" element
-         * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            Element req = null;
-            if (m_id == null) {
-                req = (Element) m_collector.getIds().get(m_field);
-            } else {
-                req = (Element) m_collector.getIds().get(m_id);
-            }
-
-            if (req == null) {
-                req = new Element("requires", "");
-            }
-
-            req.addAttribute(new Attribute("field", m_field));
-            if (m_specification != null) {
-                req.addAttribute(new Attribute("specification", m_specification));
-            }
-            if (m_filter != null) {
-                req.addAttribute(new Attribute("filter", m_filter));
-            }
-            if (m_optional != null) {
-                req.addAttribute(new Attribute("optional", m_optional));
-            }
-            if (m_nullable != null) {
-                req.addAttribute(new Attribute("nullable", m_nullable));
-            }
-            if (m_defaultImplementation != null) {
-                req.addAttribute(new Attribute("default-implementation", m_defaultImplementation));
-            }
-            if (m_policy != null) {
-                req.addAttribute(new Attribute("policy", m_policy));
-            }
-            if (m_id != null) {
-                req.addAttribute(new Attribute("id", m_id));
-            }
-            if (m_comparator != null) {
-                req.addAttribute(new Attribute("comparator", m_comparator));
-            }
-            if (m_from != null) {
-                req.addAttribute(new Attribute("from", m_from));
-            }
-            if (m_proxy != null) {
-                req.addAttribute(new Attribute("proxy", m_proxy));
-            }
-            
-            if (m_id != null) { 
-                m_collector.getIds().put(m_id, req);
-            } else {
-                m_collector.getIds().put(m_field, req);
-            }
-            
-            m_collector.getElements().put(req, null);
-                
-            return;
-        }
-    }
-    
-    /**
-     * Parses a ServiceController annotation.
-     */
-    private static final class ServiceControllerAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
-        
-        /**
-         * Parent element element.
-         */
-        private Element m_parent;
-        
-        /**
-         * Field name. 
-         */
-        private String m_field;
-        
-        /**
-         * Property value.  
-         */
-        private String m_value;
-        
-        /**
-         * Specification value.  
-         */
-        private String m_spec;   
-        
-        /**
-         * Constructor.
-         * @param parent : parent element.
-         * @param field : field name.
-         */
-        private ServiceControllerAnnotationParser(String field, Element parent) {
-            m_parent = parent;
-            m_field = field;
-        }
-
-        /**
-         * Visit one "simple" annotation.
-         * @param arg0 : annotation name
-         * @param arg1 : annotation value
-         * @see org.objectweb.asm.AnnotationVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("value")) {
-                m_value = arg1.toString();
-                return;
-            }
-            if (arg0.equals("specification")) {
-                m_spec = ((Type) arg1).getClassName();
-                return;
-            } 
-        }
-
-        /**
-         * End of the annotation.
-         * Create a "controller" element
-         * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            Element controller = new Element("controller", "");
-            m_parent.addElement(controller);
-            
-            controller.addAttribute(new Attribute("field", m_field));
-            if (m_value != null) {
-                controller.addAttribute(new Attribute("value", m_value));
-            }
-            if (m_spec != null) {
-                controller.addAttribute(new Attribute("specification", m_spec));
-            }
-        }
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
deleted file mode 100644
index 62fe47d..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
+++ /dev/null
@@ -1,669 +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.manipulation.annotations;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.NodeList;
-
-/**
- * Collect metadata from classes by parsing annotation.
- * This class collects type (i.e.) annotations and create method & field collectors.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class MetadataCollector extends EmptyVisitor implements Opcodes {
-
-    /**
-     * Class name.
-     */
-    private String m_className;
-
-    /**
-     * Root element of computed metadata.
-     */
-    private Element m_elem = null;
-
-    /**
-     * True if the visited class is a component type declaration (i.e. contains the @component annotation).
-     */
-    private boolean m_containsComponentAnnotation = false;
-
-    /**
-     * True if the visited class does not have the @Component annotation.
-     */
-    private boolean m_ignoredBecauseOfMissingComponent = false;
-
-    /**
-     * Map of [element ids, element].
-     * This map is used to easily get an already created element.
-     */
-    private Map<String, Element> m_ids = new TreeMap<String, Element>();
-
-    /**
-     * Map of [element, referto].
-     * This map is used to recreate the element hierarchy.
-     * Stored element are added under referred element.
-     */
-    private Map<Element, String> m_elements = new LinkedHashMap<Element, String>();
-
-    /**
-     * Instance declaration.
-     */
-    private Element m_instance;
-
-    /**
-     * XML document parser.
-     */
-    private DocumentBuilder m_builder;
-
-
-    public Element getComponentTypeDeclaration() {
-        return m_elem;
-    }
-
-    public Element getInstanceDeclaration() {
-        return m_instance;
-    }
-
-    public boolean isComponentType() {
-        return m_containsComponentAnnotation;
-    }
-
-    public boolean isIgnoredBecauseOfMissingComponent() {
-        return m_ignoredBecauseOfMissingComponent;
-    }
-
-    public String getClassName() {
-        return m_className;
-    }
-
-    /**
-     * Start visiting a class.
-     * Initialize the getter/setter generator, add the _cm field, add the pojo interface.
-     * @param version : class version
-     * @param access : class access
-     * @param name : class name
-     * @param signature : class signature
-     * @param superName : class super class
-     * @param interfaces : implemented interfaces
-     * @see org.objectweb.asm.ClassAdapter#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
-     */
-    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-        m_ids = new TreeMap<String, Element>();
-        m_elements = new LinkedHashMap<Element, String>();
-        m_className = name;
-    }
-
-
-    /**
-     * Visit class annotations.
-     * This method detects @component and @provides annotations.
-     * @param desc : annotation descriptor.
-     * @param visible : is the annotation visible at runtime.
-     * @return the annotation visitor.
-     * @see org.objectweb.asm.ClassAdapter#visitAnnotation(java.lang.String, boolean)
-     */
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // @Component
-        if (desc.equals("Lorg/apache/felix/ipojo/annotations/Component;")) {
-            // It is a component
-            m_elem =  new Element("component", "");
-            m_containsComponentAnnotation = true;
-            m_elem.addAttribute(new Attribute("className", m_className.replace('/', '.')));
-            return new ComponentVisitor();
-        }
-
-        // @Handler
-        if (desc.equals("Lorg/apache/felix/ipojo/annotations/Handler;")) {
-            // It is a handler, change the root element
-            m_elem = new Element("handler", "");
-            m_containsComponentAnnotation = true;
-            m_elem.addAttribute(new Attribute("classname", m_className.replace('/', '.')));
-            return new HandlerVisitor();
-        }
-
-        // @Provides
-        if (desc.equals("Lorg/apache/felix/ipojo/annotations/Provides;")) {
-            return new ProvidesVisitor();
-        }
-
-        // @HandlerDeclaration
-        if (desc.equals("Lorg/apache/felix/ipojo/annotations/HandlerDeclaration;")) {
-            return new HandlerDeclarationVisitor();
-        }
-
-        // @Instantiate
-        if (desc.equals("Lorg/apache/felix/ipojo/annotations/Instantiate;")) {
-            return new InstantiateVisitor();
-        }
-
-        if (CustomAnnotationVisitor.isCustomAnnotation(desc)) {
-            Element elem = CustomAnnotationVisitor.buildElement(desc);
-            return new CustomAnnotationVisitor(elem, this, true, true);
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Visit a field.
-     * Call the field collector visitor.
-     * @param access : field access.
-     * @param name : field name
-     * @param desc : field descriptor
-     * @param signature : field signature
-     * @param value : field value (static field only)
-     * @return the field visitor.
-     * @see org.objectweb.asm.ClassAdapter#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
-     */
-    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
-        return new FieldCollector(name, this);
-    }
-
-    /**
-     * Visit a method.
-     * Call the method collector visitor.
-     * @param access : method access
-     * @param name : method name
-     * @param desc : method descriptor
-     * @param signature : method signature
-     * @param exceptions : method exceptions
-     * @return the Method Visitor.
-     * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
-     */
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-        return new MethodCollector(name, desc, this);
-    }
-
-    /**
-     * End of the visit : compute final elements.
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-     */
-    public void visitEnd() {
-        // If m_elem (Component) is null, print a warning and ignore.
-        if (m_elem == null  &&  ! m_elements.isEmpty()) {
-            m_ignoredBecauseOfMissingComponent = true;
-            return;
-        }
-
-        if (! m_containsComponentAnnotation) {
-            m_ignoredBecauseOfMissingComponent = true;
-            return;
-        }
-
-        // Recompute the tree
-        Set<Element> elems = getElements().keySet();
-        Iterator<Element> it = elems.iterator();
-        while (it.hasNext()) {
-            Element current = it.next();
-            String reference = getElements().get(current);
-            if (reference == null) {
-                m_elem.addElement(current);
-            } else {
-                Element ref = (Element) getIds().get(reference);
-                if (ref == null) {
-                    // Add to the root
-                    m_elem.addElement(current);
-                } else {
-                    ref.addElement(current);
-                }
-            }
-        }
-    }
-
-    protected Map<String, Element> getIds() {
-        return m_ids;
-    }
-
-    protected Map<Element, String> getElements() {
-        return m_elements;
-    }
-
-    /**
-     * Creates a 'fresh' document builder.
-     * @return a new document builder is not already created, else reset
-     * the created one, and return it.
-     */
-    protected DocumentBuilder getFreshDocumentBuilder() {
-        if (m_builder == null) {
-
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setNamespaceAware(true);
-            try {
-                m_builder = factory.newDocumentBuilder();
-            } catch (ParserConfigurationException e) {
-                // TODO GSA is this acceptable to throw a RuntimeException here ?
-                e.printStackTrace();
-            }
-
-            return m_builder;
-        }
-
-        // The builder has to be reseted
-        m_builder.reset();
-
-        return m_builder;
-    }
-
-    /**
-     * Parse the @provides annotation.
-     */
-    private class ProvidesVisitor extends EmptyVisitor implements AnnotationVisitor {
-        /**
-         * Provides element.
-         */
-        Element m_prov = new Element("provides", "");
-
-        /**
-         * Visit @provides annotation attributes.
-         * @param arg0 : annotation attribute name
-         * @param arg1 : annotation attribute value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("factory")) { // Should be deprecated
-                m_prov.addAttribute(new Attribute("factory", arg1.toString()));
-            }
-            if (arg0.equals("strategy")) {
-                m_prov.addAttribute(new Attribute("strategy", arg1.toString()));
-            }
-        }
-
-        /**
-         * Visit specifications array.
-         * @param arg0 : attribute name
-         * @return a visitor visiting each element of the array.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitArray(java.lang.String)
-         */
-        public AnnotationVisitor visitArray(String arg0) {
-            if (arg0.equals("specifications")) {
-                return new InterfaceArrayVisitor();
-            } else if (arg0.equals("properties")) {
-                // Create a new simple visitor to visit the nested ServiceProperty annotations
-                // Collected properties are collected in m_prov
-                return new EmptyVisitor() {
-                    public AnnotationVisitor visitAnnotation(String ignored, String desc) {
-                        return new PropertyAnnotationParser(m_prov);
-                    }
-                };
-            } else {
-                return null;
-            }
-        }
-
-        /**
-         * End of the visit.
-         * Append to the parent element the computed "provides" element.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            getIds().put("provides", m_prov);
-            getElements().put(m_prov, null);
-        }
-
-        private class InterfaceArrayVisitor extends EmptyVisitor {
-            /**
-             * List of parsed interface.
-             */
-            private String m_itfs;
-
-            /**
-             * Visit one element of the array.
-             * @param arg0 : null
-             * @param arg1 : element value.
-             * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-             */
-            public void visit(String arg0, Object arg1) {
-                if (m_itfs == null) {
-                    m_itfs = "{" + ((Type) arg1).getClassName();
-                } else {
-                    m_itfs += "," + ((Type) arg1).getClassName();
-                }
-            }
-
-            /**
-             * End of the array visit.
-             * Add the attribute to 'provides' element.
-             * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-             */
-            public void visitEnd() {
-                m_prov.addAttribute(new Attribute("specifications", m_itfs + "}"));
-            }
-
-        }
-
-
-    }
-
-    /**
-     * Parse the @Instantitate annotation.
-     */
-    private class InstantiateVisitor extends EmptyVisitor implements AnnotationVisitor {
-        /**
-         * Instance name.
-         */
-        private String m_name;
-
-        /**
-         * Visit an annotation attribute.
-         * @param arg0 the attribute name
-         * @param arg1 the attribute value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("name")) {
-                m_name = arg1.toString();
-                return;
-            }
-        }
-
-        /**
-         * End of the visit. Creates the instance element.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            m_instance = new Element("instance", "");
-            if (m_className != null) { // Should not be null.
-                m_instance.addAttribute(new Attribute("component", m_className.replace('/', '.')));
-            }
-            if (m_name != null) {
-                m_instance.addAttribute(new Attribute("name", m_name));
-            }
-        }
-    }
-
-
-    /**
-     * Parse the @component annotation.
-     */
-    private class ComponentVisitor extends EmptyVisitor implements AnnotationVisitor {
-
-        /**
-         * Factory attribute.
-         */
-        private String m_factory;
-
-        /**
-         * Is the component an immediate component?
-         */
-        private String m_immediate;
-
-        /**
-         * Component name (cannot be null).
-         */
-        private String m_name;
-
-        /**
-         * Does the component exposes its architecture?
-         */
-        private String m_architecture;
-
-        /**
-         * Does the component propagate configuration to provided services?
-         */
-        private String m_propagation;
-
-        /**
-         * Managed Service PID.
-         */
-        private String m_managedservice;
-
-        /**
-         * Factory-Method.
-         */
-        private String m_method;
-
-        /**
-         * Version.
-         */
-        private String m_version;
-
-        /**
-         * Element properties.
-         */
-        private Element m_props;
-
-        /**
-         * Visit @component annotation attribute.
-         * @param arg0 : attribute name
-         * @param arg1 : attribute value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("public_factory")  || arg0.equals("publicFactory")) {
-                // public_factory is deprecated, but must sill be supported
-                m_factory = arg1.toString();
-                return;
-            }
-            if (arg0.equals("name")) {
-                m_name = arg1.toString();
-                return;
-            }
-            if (arg0.equals("immediate")) {
-                m_immediate = arg1.toString();
-                return;
-            }
-            if (arg0.equals("architecture")) {
-                m_architecture = arg1.toString();
-                return;
-            }
-            if (arg0.equals("propagation")) {
-                m_propagation = arg1.toString();
-                return;
-            }
-            if (arg0.equals("managedservice")) {
-                m_managedservice = arg1.toString();
-                return;
-            }
-            if (arg0.equals("factory_method")  || arg0.equals("factoryMethod")) {
-                // factory_method is deprecated, but must still be supported.
-                m_method = arg1.toString();
-                return;
-            }
-            if (arg0.equals("version")) {
-                m_version = arg1.toString();
-                return;
-            }
-        }
-
-        /**
-         * End of the visit.
-         * Append to the "component" element computed attribute.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            if (m_name == null) {
-                m_name = m_className.replace('/', '.');
-            }
-            m_elem.addAttribute(new Attribute("name", m_name));
-            if (m_factory != null && m_factory.equalsIgnoreCase("false")) {
-                m_elem.addAttribute(new Attribute("public", "false"));
-            } else {
-                m_elem.addAttribute(new Attribute("public", "true"));
-            }
-            if (m_architecture != null) {
-                m_elem.addAttribute(new Attribute("architecture", m_architecture));
-            }
-            if (m_immediate != null) {
-                m_elem.addAttribute(new Attribute("immediate", m_immediate));
-            }
-            if (m_method != null) {
-                m_elem.addAttribute(new Attribute("factory-method", m_method));
-            }
-            if (m_version != null) {
-                m_elem.addAttribute(new Attribute("version", m_version));
-            }
-            if (m_propagation != null) {
-                if (m_props == null) {
-                    m_props = new Element("properties", "");
-                    getElements().put(m_props, null);
-                    getIds().put("properties", m_props);
-                }
-                m_props.addAttribute(new Attribute("propagation", m_propagation));
-            }
-            if (m_managedservice != null) {
-                if (m_props == null) {
-                    m_props = new Element("properties", "");
-                    getElements().put(m_props, null);
-                    getIds().put("properties", m_props);
-                }
-                m_props.addAttribute(new Attribute("pid", m_managedservice));
-            }
-        }
-    }
-
-    /**
-     * Parses the @Handler annotation.
-     */
-    private class HandlerVisitor extends EmptyVisitor implements AnnotationVisitor {
-
-        /**
-         * Visit @handler annotation attributes.
-         * @param arg0 : annotation attribute name
-         * @param arg1 : annotation attribute value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("name")) {
-                m_elem.addAttribute(new Attribute("name", arg1.toString()));
-                return;
-            }
-            if (arg0.equals("namespace")) {
-                m_elem.addAttribute(new Attribute("namespace", arg1.toString()));
-                return;
-            }
-            if (arg0.equals("level")) {
-                m_elem.addAttribute(new Attribute("level", arg1.toString()));
-                return;
-            }
-            if (arg0.equals("architecture")) {
-                m_elem.addAttribute(new Attribute("architecture", arg1.toString()));
-                return;
-            }
-        }
-    }
-
-    /**
-     * Parse the @HandlerDeclaration annotation.
-     */
-    private class HandlerDeclarationVisitor extends EmptyVisitor implements AnnotationVisitor {
-
-        /**
-         * XML accepted by the handler.
-         */
-        private String m_value;
-
-        /**
-         * Parses the value attribute.
-         * @param arg0 'value'
-         * @param arg1 the value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            // there is only a 'value' attribute
-            this.m_value = (String) arg1;
-        }
-
-        /**
-         * End of the visit.
-         * Builds the XML document.
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            // The value is an XML document
-            DocumentBuilder builder = getFreshDocumentBuilder();
-            InputStream is = new ByteArrayInputStream(m_value.getBytes());
-            Document document = null;
-            try {
-                document = builder.parse(is);
-                convertDOMElements(m_elem, document.getDocumentElement());
-            } catch (Exception e) {
-                // TODO GSA change this to a logger ?
-                System.err.println("[warning] Cannot convert " + m_value + " to iPOJO Elements.");
-            } finally {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    System.err.println("[warning] Cannot close correctly the value input stream");
-                }
-            }
-        }
-
-        /**
-         * Converts recursively the given XML Element into an iPOJO Element.
-         * @param root iPOJO root Element
-         * @param xmlElement DOM Element to be converted
-         */
-        private void convertDOMElements(final Element root,
-                                        final org.w3c.dom.Element xmlElement) {
-
-            // Create an equivalent iPOJO element
-            Element converted = new Element(xmlElement.getLocalName(), xmlElement.getNamespaceURI());
-
-            // Convert attributes if any
-            if (xmlElement.hasAttributes()) {
-                NamedNodeMap attributes = xmlElement.getAttributes();
-                for (int i = 0; i < attributes.getLength(); i++) {
-                    Attr attr = (Attr) attributes.item(i);
-                    converted.addAttribute(new Attribute(attr.getName(),
-                                                         attr.getNamespaceURI(),
-                                                         attr.getValue()));
-                }
-            }
-
-            // Convert child elements if any
-            if (xmlElement.hasChildNodes()) {
-                NodeList childs = xmlElement.getChildNodes();
-                for (int i = 0; i < childs.getLength(); i++) {
-
-                    // Recursive call
-                    convertDOMElements(converted, (org.w3c.dom.Element) childs.item(i));
-                }
-            }
-
-            // Add converted element as a root's child
-            root.addElement(converted);
-        }
-    }
-
-}
-
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
deleted file mode 100644
index fb9bb72..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
+++ /dev/null
@@ -1,654 +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.manipulation.annotations;
-
-import org.apache.felix.ipojo.manipulation.MethodCreator;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * This class collects method annotations, and give them to the metadata collector.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class MethodCollector extends EmptyVisitor {
-
-    /**
-     * Parent collector.
-     */
-    private MetadataCollector m_collector;
-
-    /**
-     * Method name.
-     */
-    private String m_name;
-
-    /**
-     * Method Descriptor.
-     */
-    private String m_descriptor;
-
-    /**
-     * Constructor.
-     *
-     * @param name      : name of the method.
-     * @param collector : parent collector.
-     */
-    public MethodCollector(String name, String descriptor, MetadataCollector collector) {
-        m_collector = collector;
-        m_name = name;
-        m_descriptor = descriptor;
-    }
-
-    /**
-     * Visit a parameter annotation.
-     *
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitParameterAnnotation(int, java.lang.String, boolean)
-     */
-    public AnnotationVisitor visitParameterAnnotation(int index, String annotation,
-                                                      boolean visible) {
-        if (m_name.equals("<init>")) {
-            if (annotation.equals("Lorg/apache/felix/ipojo/annotations/Property;")) {
-                return processProperty(true, index);
-            }
-            if (annotation.equals("Lorg/apache/felix/ipojo/annotations/Requires;")) {
-                return new BindAnnotationParser(index);
-            }
-
-            if (CustomAnnotationVisitor.isCustomAnnotation(annotation)) {
-                Element elem = CustomAnnotationVisitor.buildElement(annotation);
-                elem.addAttribute(new Attribute("index", "" + index));
-                return new CustomAnnotationVisitor(elem, m_collector, true, false, index, m_descriptor);
-            }
-        }
-        return super.visitParameterAnnotation(index, annotation, visible);
-    }
-
-
-    /**
-     * Visit method annotations.
-     *
-     * @param arg0 : annotation name.
-     * @param arg1 : is the annotation visible at runtime.
-     * @return the visitor paring the visited annotation.
-     * @see org.objectweb.asm.commons.EmptyVisitor#visitAnnotation(java.lang.String, boolean)
-     */
-    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Property;")) {
-            return processProperty(false, -1);
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Validate;")) {
-            return processValidate();
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Invalidate;")) {
-            return processInvalidate();
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Updated;")) {
-            return processUpdated();
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Bind;")) {
-            return processBind("bind");
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Modified;")) {
-            return processBind("modified");
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Unbind;")) {
-            return processBind("unbind");
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/PostRegistration;")) {
-            return processPostRegistration();
-        }
-        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/PostUnregistration;")) {
-            return processPostUnregistration();
-        }
-
-        if (CustomAnnotationVisitor.isCustomAnnotation(arg0)) {
-            Element elem = CustomAnnotationVisitor.buildElement(arg0);
-            elem.addAttribute(new Attribute("method", computeEffectiveMethodName(m_name)));
-            return new CustomAnnotationVisitor(elem, m_collector, true, false);
-        }
-
-        return null;
-    }
-
-    /**
-     * Process @Updated annotation.
-     *
-     * @return null.
-     */
-    private AnnotationVisitor processUpdated() {
-        Element parent = null;
-        if (!m_collector.getIds().containsKey("properties")) {
-            parent = new Element("Properties", "");
-            m_collector.getIds().put("properties", parent);
-            m_collector.getElements().put(parent, null);
-        } else {
-            parent = (Element) m_collector.getIds().get("properties");
-        }
-
-        parent.addAttribute(new Attribute("updated", m_name));
-
-        return null;
-    }
-
-    /**
-     * Process @PostRegistration annotation.
-     *
-     * @return null.
-     */
-    private AnnotationVisitor processPostRegistration() {
-        Element parent = null;
-        if (m_collector.getIds().containsKey("provides")) {
-            parent = (Element) m_collector.getIds().get("provides");
-            parent.addAttribute(new Attribute("post-registration", m_name));
-        } else {
-            // Ignore annotation...
-        }
-
-        return null;
-    }
-
-    /**
-     * Process @PostRegistration annotation.
-     *
-     * @return null.
-     */
-    private AnnotationVisitor processPostUnregistration() {
-        Element parent = null;
-        if (m_collector.getIds().containsKey("provides")) {
-            parent = (Element) m_collector.getIds().get("provides");
-            parent.addAttribute(new Attribute("post-unregistration", m_name));
-        } else {
-            // Ignore annotation...
-        }
-
-        return null;
-    }
-
-    /**
-     * Process @bind, @modified, @unbind.
-     *
-     * @param type : bind or unbind
-     * @return the visitor parsing @bind & @unbind annotations.
-     */
-    private AnnotationVisitor processBind(String type) {
-        return new BindAnnotationParser(m_name, type);
-    }
-
-    /**
-     * Process @validate annotation.
-     *
-     * @return null.
-     */
-    private AnnotationVisitor processValidate() {
-        Element cb = new Element("callback", "");
-        cb.addAttribute(new org.apache.felix.ipojo.metadata.Attribute("transition", "validate"));
-        cb.addAttribute(new org.apache.felix.ipojo.metadata.Attribute("method", computeEffectiveMethodName(m_name)));
-        m_collector.getElements().put(cb, null);
-        return null;
-    }
-
-    /**
-     * Process @invalidate annotation.
-     *
-     * @return null.
-     */
-    private AnnotationVisitor processInvalidate() {
-        Element cb = new Element("callback", "");
-        cb.addAttribute(new org.apache.felix.ipojo.metadata.Attribute("transition", "invalidate"));
-        cb.addAttribute(new org.apache.felix.ipojo.metadata.Attribute("method", computeEffectiveMethodName(m_name)));
-        m_collector.getElements().put(cb, null);
-        return null;
-    }
-
-    /**
-     * Process @property annotation.
-     *
-     * @param parameter true if we're processing a parameter
-     * @param index     the index, meaningful only if parameter is true
-     * @return the visitor parsing the visited annotation.
-     */
-    private AnnotationVisitor processProperty(boolean parameter, int index) {
-        Element prop = null;
-        if (!m_collector.getIds().containsKey("properties")) {
-            prop = new Element("Properties", "");
-            m_collector.getIds().put("properties", prop);
-            m_collector.getElements().put(prop, null);
-        } else {
-            prop = (Element) m_collector.getIds().get("properties");
-        }
-        return new PropertyAnnotationParser(prop, m_name, parameter, index);
-    }
-
-    /**
-     * Parse @bind & @unbind annotations.
-     */
-    private final class BindAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
-
-        /**
-         * Method name.
-         */
-        private String m_name;
-
-        /**
-         * Requirement filter.
-         */
-        private String m_filter;
-
-        /**
-         * Is the requirement optional?
-         */
-        private String m_optional;
-
-        /**
-         * Is the requirement aggregate?
-         */
-        private String m_aggregate;
-
-        /**
-         * Required specification.
-         */
-        private String m_specification;
-
-        /**
-         * Requirement id.
-         */
-        private String m_id;
-
-        /**
-         * Bind, Modify or Unbind method?
-         */
-        private String m_type;
-
-        /**
-         * Binding policy.
-         */
-        private String m_policy;
-
-        /**
-         * Comparator.
-         */
-        private String m_comparator;
-
-        /**
-         * From attribute.
-         */
-        private String m_from;
-
-        /**
-         * For annotation parameter,
-         * the parameter index.
-         */
-        private int m_index = -1;
-
-        /**
-         * Constructor.
-         *
-         * @param bind : method name.
-         * @param type : is the callback a bind or an unbind method.
-         */
-        private BindAnnotationParser(String bind, String type) {
-            m_name = bind;
-            m_type = type;
-        }
-
-        private BindAnnotationParser(int index) {
-            m_index = index;
-        }
-
-        /**
-         * Visit annotation attribute.
-         *
-         * @param arg0 : annotation name
-         * @param arg1 : annotation value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("filter")) {
-                m_filter = arg1.toString();
-                return;
-            }
-            if (arg0.equals("optional")) {
-                m_optional = arg1.toString();
-                return;
-            }
-            if (arg0.equals("aggregate")) {
-                m_aggregate = arg1.toString();
-                return;
-            }
-            if (arg0.equals("specification")) {
-                m_specification = arg1.toString();
-                return;
-            }
-            if (arg0.equals("policy")) {
-                m_policy = arg1.toString();
-                return;
-            }
-            if (arg0.equals("id")) {
-                m_id = arg1.toString();
-                return;
-            }
-            if (arg0.equals("comparator")) {
-                Type type = Type.getType(arg1.toString());
-                m_comparator = type.getClassName();
-                return;
-            }
-            if (arg0.equals("from")) {
-                m_from = arg1.toString();
-                return;
-            }
-
-        }
-
-        /**
-         * End of the visit.
-         * Create or append the requirement info to a created or already existing "requires" element.
-         *
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            if (m_id == null) {
-                String effectiveName = computeEffectiveMethodName(m_name);
-
-                if (effectiveName != null && effectiveName.startsWith("bind")) {
-                    m_id = effectiveName.substring("bind".length());
-                } else if (effectiveName != null && effectiveName.startsWith("unbind")) {
-                    m_id = effectiveName.substring("unbind".length());
-                } else if (effectiveName != null && effectiveName.startsWith("modified")) {
-                    m_id = effectiveName.substring("modified".length());
-                } else if (m_index != -1) {
-                    m_id = "" + m_index;
-                } else {
-                    System.err.println("Cannot determine the id of the " + m_type + " method : " + effectiveName);
-                    return;
-                }
-            }
-
-            // Check if it is a full-determined requirement
-            Element req = (Element) m_collector.getIds().get(m_id);
-            if (req == null) {
-                // Add the complete requires
-                req = new Element("requires", "");
-                if (m_specification != null) {
-                    req.addAttribute(new Attribute("specification", m_specification));
-                }
-                if (m_aggregate != null) {
-                    req.addAttribute(new Attribute("aggregate", m_aggregate));
-                }
-                if (m_filter != null) {
-                    req.addAttribute(new Attribute("filter", m_filter));
-                }
-                if (m_optional != null) {
-                    req.addAttribute(new Attribute("optional", m_optional));
-                }
-                if (m_policy != null) {
-                    req.addAttribute(new Attribute("policy", m_policy));
-                }
-                if (m_id != null) {
-                    req.addAttribute(new Attribute("id", m_id));
-                }
-                if (m_comparator != null) {
-                    req.addAttribute(new Attribute("comparator", m_comparator));
-                }
-                if (m_from != null) {
-                    req.addAttribute(new Attribute("from", m_from));
-                }
-            } else {
-                String itf = req.getAttribute("specification");
-                String aggregate = req.getAttribute("aggregate");
-                String optional = req.getAttribute("optional");
-                String filter = req.getAttribute("filter");
-                String policy = req.getAttribute("policy");
-                String comparator = req.getAttribute("comparator");
-                String from = req.getAttribute("from");
-                if (m_specification != null) {
-                    if (itf == null) {
-                        req.addAttribute(new Attribute("specification", m_specification));
-                    } else if (!m_specification.equals(itf)) {
-                        System.err.println("The required specification is not the same as previouly : " + m_specification + " & " + itf);
-                        return;
-                    }
-                }
-
-                if (m_optional != null) {
-                    if (optional == null) {
-                        req.addAttribute(new Attribute("optional", m_optional));
-                    } else if (!m_optional.equals(optional)) {
-                        System.err.println("The optional attribute is not always the same");
-                        return;
-                    }
-                }
-
-                if (m_aggregate != null) {
-                    if (aggregate == null) {
-                        req.addAttribute(new Attribute("aggregate", m_aggregate));
-                    } else if (!m_aggregate.equals(aggregate)) {
-                        System.err.println("The aggregate attribute is not always the same");
-                        return;
-                    }
-                }
-
-                if (m_filter != null) {
-                    if (filter == null) {
-                        req.addAttribute(new Attribute("filter", m_filter));
-                    } else if (!m_filter.equals(filter)) {
-                        System.err.println("The filter attribute is not always the same");
-                        return;
-                    }
-                }
-
-                if (m_policy != null) {
-                    if (policy == null) {
-                        req.addAttribute(new Attribute("policy", m_policy));
-                    } else if (!m_policy.equals(policy)) {
-                        System.err.println("The policy attribute is not always the same");
-                        return;
-                    }
-                }
-
-                if (m_comparator != null) {
-                    if (comparator == null) {
-                        req.addAttribute(new Attribute("comparator", m_comparator));
-                    } else if (!m_comparator.equals(comparator)) {
-                        System.err.println("The comparator attribute is not always the same");
-                        return;
-                    }
-                }
-
-                if (m_from != null) {
-                    if (from == null) {
-                        req.addAttribute(new Attribute("from", m_from));
-                    } else if (!m_from.equals(from)) {
-                        System.err.println("The from attribute is not always the same");
-                        return;
-                    }
-                }
-
-            }
-            if (m_name != null) {
-                Element method = new Element("callback", "");
-                method.addAttribute(new Attribute("method", computeEffectiveMethodName(m_name)));
-                method.addAttribute(new Attribute("type", m_type));
-                req.addElement(method);
-            } else {
-                req.addAttribute(new Attribute("constructor-parameter", Integer.toString(m_index)));
-            }
-
-            m_collector.getIds().put(m_id, req);
-            m_collector.getElements().put(req, null);
-            return;
-        }
-    }
-
-    private final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
-
-        /**
-         * Parent element.
-         */
-        private Element m_parent;
-
-        /**
-         * Attached method.
-         */
-        private String m_method;
-
-        /**
-         * Property name.
-         */
-        private String m_name;
-
-        /**
-         * Property id.
-         */
-        private String m_id;
-
-        /**
-         * Property value.
-         */
-        private String m_value;
-
-        /**
-         * Property mandatory aspect.
-         */
-        private String m_mandatory;
-
-        /**
-         * Flag set to true if we're processing an annotation parameter.
-         */
-        private boolean m_isParameterAnnotation = false;
-
-        /**
-         * If this is a parameter annotation, the index of the parameter.
-         */
-        private int m_index = -1;
-
-        /**
-         * Constructor.
-         *
-         * @param parent : parent element.
-         * @param method : attached method.
-         * @param param  : we're processing a parameter
-         * @param index  : the parameter index
-         */
-        private PropertyAnnotationParser(Element parent, String method, boolean param, int index) {
-            m_parent = parent;
-            m_method = method;
-            m_isParameterAnnotation = param;
-            m_index = index;
-        }
-
-        /**
-         * Visit annotation attributes.
-         *
-         * @param arg0 : annotation name
-         * @param arg1 : annotation value
-         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
-         */
-        public void visit(String arg0, Object arg1) {
-            if (arg0.equals("name")) {
-                m_name = arg1.toString();
-                return;
-            }
-            if (arg0.equals("value")) {
-                m_value = arg1.toString();
-                return;
-            }
-            if (arg0.equals("mandatory")) {
-                m_mandatory = arg1.toString();
-                return;
-            }
-            if (arg0.equals("id")) {
-                m_id = arg1.toString();
-                return;
-            }
-        }
-
-        /**
-         * End of the visit.
-         * Append the computed element to the parent element.
-         *
-         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
-         */
-        public void visitEnd() {
-            m_method = computeEffectiveMethodName(m_method);
-
-            // If neither name not id, try to extract the name
-            if (m_name == null && m_id == null && m_method.startsWith("set")) {
-                m_name = m_method.substring("set".length());
-                m_id = m_name;
-                // Else align the two values
-            } else if (m_name != null && m_id == null) {
-                m_id = m_name;
-            } else if (m_id != null && m_name == null) {
-                m_name = m_id;
-            }
-
-            Element[] props = m_parent.getElements("Property");
-            Element prop = null;
-            for (int i = 0; props != null && prop == null && i < props.length; i++) {
-                String name = props[i].getAttribute("name");
-                if (name != null && name.equals(m_name)) {
-                    prop = props[i];
-                }
-            }
-
-            if (prop == null) {
-                prop = new Element("property", "");
-                m_parent.addElement(prop);
-                if (m_name != null) {
-                    prop.addAttribute(new Attribute("name", m_name));
-                }
-            }
-
-            if (m_value != null) {
-                prop.addAttribute(new Attribute("value", m_value));
-            }
-            if (m_mandatory != null) {
-                prop.addAttribute(new Attribute("mandatory", m_mandatory));
-            }
-
-            if (m_isParameterAnnotation) {
-                String t = Type.getArgumentTypes(m_descriptor)[m_index].getClassName();
-                prop.addAttribute(new Attribute("type", t));
-                prop.addAttribute(new Attribute("constructor-parameter", Integer.toString(m_index)));
-            } else {
-                prop.addAttribute(new Attribute("method", m_method));
-            }
-
-        }
-    }
-
-    /**
-     * Computes the real method name. This method is useful when the annotation is collected on an manipulated method
-     * (prefixed by <code>__M_</code>). This method just removes the prefix if found.
-     * @param name the collected method name
-     * @return the effective method name, can be the collected method name if the method name does not start with
-     * the prefix.
-     */
-    public static String computeEffectiveMethodName(String name) {
-        if (name != null && name.startsWith(MethodCreator.PREFIX)) {
-            return name.substring(MethodCreator.PREFIX.length());
-        } else {
-            return name;
-        }
-    }
-}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/PropertyAnnotationParser.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/PropertyAnnotationParser.java
deleted file mode 100644
index 548fd23..0000000
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/PropertyAnnotationParser.java
+++ /dev/null
@@ -1,150 +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.manipulation.annotations;
-
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * Parses a Property or ServiceProperty annotation.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
-
-    /**
-     * Parent element element.
-     */
-    private Element m_parent;
-
-    /**
-     * Field name.
-     */
-    private String m_field;
-
-    /**
-     * Property name.
-     */
-    private String m_name;
-
-    /**
-     * Property value.
-     */
-    private String m_value;
-
-    /**
-     * Property mandatory aspect.
-     */
-    private String m_mandatory;
-
-    /**
-     * Property type.
-     */
-    private String m_type;
-
-
-    /**
-     * Constructor.
-     * @param parent : parent element.
-     * @param field : field name.
-     */
-    PropertyAnnotationParser(String field, Element parent) {
-        m_parent = parent;
-        m_field = field;
-    }
-
-    /**
-     * Constructor without field
-     * @param parent : parent element..
-     */
-    PropertyAnnotationParser(Element parent) {
-        m_parent = parent;
-        m_field = null;
-    }
-
-    /**
-     * Visit one "simple" annotation.
-     * @param arg0 : annotation name
-     * @param arg1 : annotation value
-     * @see org.objectweb.asm.AnnotationVisitor#visit(java.lang.String, java.lang.Object)
-     */
-    public void visit(String arg0, Object arg1) {
-        if (arg0.equals("name")) {
-            m_name = arg1.toString();
-            return;
-        }
-        if (arg0.equals("value")) {
-            m_value = arg1.toString();
-            return;
-        }
-        if (arg0.equals("mandatory")) {
-            m_mandatory = arg1.toString();
-            return;
-        }
-        if (arg0.equals("type")) {
-        	m_type = arg1.toString();
-        	return;
-        }
-    }
-
-    /**
-     * End of the annotation.
-     * Create a "property" element
-     * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
-     */
-    public void visitEnd() {
-        if (m_field != null  && m_name == null) {
-            m_name = m_field;
-        }
-
-
-        Element[] props = m_parent.getElements("Property");
-        Element prop = null;
-        for (int i = 0; prop == null && props != null && i < props.length; i++) {
-            String name = props[i].getAttribute("name");
-            if (name != null && name.equals(m_name)) {
-                prop = props[i];
-            }
-        }
-
-        if (prop == null) {
-            prop = new Element("property", "");
-            m_parent.addElement(prop);
-            if (m_name != null) {
-                prop.addAttribute(new Attribute("name", m_name));
-            }
-        }
-
-        if (m_field != null) {
-        	prop.addAttribute(new Attribute("field", m_field));
-        }
-        if (m_type != null) {
-        	prop.addAttribute(new Attribute("type", m_type));
-        }
-
-        if (m_value != null) {
-            prop.addAttribute(new Attribute("value", m_value));
-        }
-        if (m_mandatory != null) {
-            prop.addAttribute(new Attribute("mandatory", m_mandatory));
-        }
-
-    }
-}
\ No newline at end of file
