Applied patch (FELIX-192) to fix several small bugs in iPOJO core.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@498768 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index ff7ec92..519994b 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -102,6 +102,8 @@
      * FactoryClassloader.
      */
     private class FactoryClassloader extends ClassLoader  {
+    	
+    	HashMap m_definedClasses = new HashMap();
 
         /**
          * load the class.
@@ -148,7 +150,10 @@
          */
         public Class defineClass(String name, byte[] b,
                 ProtectionDomain domain) throws Exception {
-            return super.defineClass(name, b, 0, b.length, domain);
+        	if(m_definedClasses.containsKey(name)) { return (Class) m_definedClasses.get(name); } 
+            Class c = super.defineClass(name, b, 0, b.length, domain);
+            m_definedClasses.put(name, c);
+            return c;
         }
     }
 
@@ -211,8 +216,8 @@
         Collection col = m_componentInstances.values();
         Iterator it = col.iterator();
         while (it.hasNext()) {
-            InstanceManager cm = (InstanceManager) it.next();
-            cm.stop();
+            ComponentInstance ci = (ComponentInstance) it.next();
+            if(ci.isStarted()) { ci.stop(); }
         }
         m_componentInstances.clear();
         if (m_sr != null) { m_sr.unregister(); }
@@ -273,6 +278,11 @@
         }
         return m_context.getBundle().loadClass(className);
     }
+    
+    public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+    	if(m_classLoader == null) { m_classLoader = new FactoryClassloader(); }
+    	return m_classLoader.defineClass(name, b, domain);
+    }
 
     /**
      * Return the URL of a resource.
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
index 4e44aff..54a63bb 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -28,6 +28,12 @@
 public interface ComponentInstance {
 
     /**
+     * Component Instance State : STOPPED.
+     * The component instance is not started.
+     */
+    int STOPPED = 0;
+	
+	/**
      * Component Instance State : INVALID.
      * The component is invalid when it start or when a component dependency is unvalid.
      */
@@ -74,6 +80,11 @@
      * @return the name of the component instance
      */
     String getInstanceName();
+    
+    /**
+     * @return true if getState return 1 or 2.
+     */
+    boolean isStarted();
 
 
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index d7526e2..7164eea 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -73,7 +73,7 @@
     /**
      * Component state (STOPPED at the beginning).
      */
-    private int m_state = INVALID;
+    private int m_state = STOPPED;
 
     /**
      * Manipulatd clazz.
@@ -196,6 +196,8 @@
      * Start the instance manager.
      */
     public void start() {
+    	if(m_state != STOPPED) { return; } // Instance already started
+    	
         // Start all the handlers
         m_factory.getLogger().log(Logger.INFO, "[" + m_className + "] Start the instance manager with " + m_handlers.length + " handlers");
 
@@ -214,12 +216,16 @@
      * Stop the instance manager.
      */
     public void stop() {
+    	if(m_state == STOPPED) { return; } // Instance already stopped
+    	
         setState(INVALID);
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].stop();
         }
         m_pojoObjects = new Object[0];
+        
+        m_state = STOPPED;
     }
 
     /**
@@ -230,7 +236,7 @@
         if (m_state != state) {
 
             // Log the state change
-            if (state == INVALID) { m_factory.getLogger().log(Logger.INFO, "[" + m_className + "]  State -> UNRESOLVED"); }
+            if (state == INVALID) { m_factory.getLogger().log(Logger.INFO, "[" + m_className + "]  State -> INVALID"); }
             if (state == VALID) { m_factory.getLogger().log(Logger.INFO, "[" + m_className + "] State -> VALID"); }
 
             // The state changed call the handler stateChange method
@@ -244,9 +250,12 @@
     /**
      * @return the actual state of the component.
      */
-    public int getState() {
-        return m_state;
-    }
+    public int getState() { return m_state; }
+    
+    /**
+     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
+     */
+    public boolean isStarted() { return m_state != STOPPED; }
 
     // ===================== end Lifecycle management =====================
 
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
index 07d82a4..884c3f1 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
@@ -75,6 +75,10 @@
      * @param pd : the property to add
      */
     public void addProperty(PropertyDescription pd) { 
+    	for(int i = 0; i < m_properties.length; i++) {
+    		if(m_properties[i].getName().equals(pd.getName())) { return; }
+    	}
+    	
     	PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
         System.arraycopy(m_properties, 0, newProps, 0, m_properties.length);
         newProps[m_properties.length] = pd;
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyHandlerDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyHandlerDescription.java
index ee145f6..66b6e7b 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyHandlerDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyHandlerDescription.java
@@ -77,6 +77,7 @@
             while (it.hasNext()) {
                 info += "\n \t\t Uses : " + it.next();
             }
+            info += "\n";
         }
         return info;
     }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java
index 00c1ada..5d5ab3f 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java
@@ -27,6 +27,16 @@
  * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
  */
 public class ProvidedServiceDescription {
+	
+	/**
+	 * State : the service is unregistered 
+	 */
+	public static final int UNREGISTERED = 0;
+	
+	/**
+	 * State : the service is registered
+	 */
+	public static final int REGISTERED = 1;
 
     /**
      * Provided Service Specification.
@@ -94,7 +104,7 @@
      * @param props : the properties
      */
     public void setProperty(Properties props) {
-        m_properties = (Properties) props.clone();
+        m_properties = props;
     }
 
     /**
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index 83cc47f..0fd1684 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -32,7 +32,6 @@
 import org.apache.felix.ipojo.architecture.ProvidedServiceHandlerDescription;
 import org.apache.felix.ipojo.handlers.dependency.Dependency;
 import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
-import org.apache.felix.ipojo.handlers.dependency.DependencyMetadata;
 import org.apache.felix.ipojo.handlers.providedservice.Property;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
@@ -88,7 +87,7 @@
      */
     public void stop() {
         try {
-            if (m_sr != null) { m_sr.unregister(); }
+            if (m_sr != null) { m_sr.unregister(); m_sr = null; }
         } catch (Exception e) { return; }
     }
 
@@ -114,7 +113,7 @@
      */
     public InstanceDescription getInstanceDescription() {
         int componentState = m_manager.getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_className, m_name, componentState, m_manager.getContext().getBundle().getBundleId());
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, m_className, componentState, m_manager.getContext().getBundle().getBundleId());
 
         String[] objects = new String[m_manager.getPojoObjects().length];
         for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
@@ -127,12 +126,11 @@
             if (handlers[i] instanceof DependencyHandler) {
                 DependencyHandler dh = (DependencyHandler) handlers[i];
                 DependencyHandlerDescription dhd = new DependencyHandlerDescription(dh.isValid());
-
                 for (int j = 0; j < dh.getDependencies().length; j++) {
                     Dependency dep = dh.getDependencies()[j];
-                    DependencyMetadata dm = dep.getMetadata();
                     // Create & add the dependency description
-                    DependencyDescription dd = new DependencyDescription(dm.getServiceSpecification(), dm.isMultiple(), dm.isOptional(), dm.getFilter(), dep.getState(), instanceDescription);
+                    DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isMultiple(), dep.isOptional(), dep.getFilter(), dep.getState(), instanceDescription);
+                    dd.setServiceReferences(dep.getServiceReferences());
                     dd.setUsedServices(dep.getUsedServices());
                     dhd.addDependency(dd);
                 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 72f8690..388ec72 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -279,7 +279,7 @@
      */
     protected void addProperty(ConfigurableProperty p) {
         for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i] == p) { return; }
+            if (m_configurableProperties[i].getName().equals(p.getName())) { return; }
         }
 
         if (m_configurableProperties.length > 0) {
@@ -300,7 +300,7 @@
      */
     protected boolean containsProperty(String name) {
         for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName() == name) { return true; }
+            if (m_configurableProperties[i].getName().equals(name)) { return true; }
         }
         return false;
     }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
index e9662a4..a0d3d28 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -31,8 +31,7 @@
 import org.osgi.framework.ServiceReference;
 
 /**
- * Represent a service dependency either for a componenet dependency either for
- * a provided service dependency.
+ * Represent a service dependency of the component instance.
  * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
  */
 public class Dependency implements ServiceListener {
@@ -48,17 +47,40 @@
     public static final int UNRESOLVED = 2;
 
     /**
-     * Link to the Component Manager.
-     * m_handler : ComponentManager
+     * Reference on the Dependency Handler.
      */
     private DependencyHandler m_handler;
-
-
+    
     /**
-     * Metadata of the dependency.
-     * m_metadata : dependency metadata
+     * Field of the dependency.
      */
-    private DependencyMetadata m_metadata;
+    private String m_field;
+    
+    /**
+     * List of dependency callback. 
+     */
+    private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+    
+    /**
+     * Service Specification required by the dependency.
+     */
+    private String m_specification;
+    
+    /**
+     * Is the dependency a multiple dependency ?
+     */
+    private boolean m_isMultiple = false;
+    
+    /**
+     * Is the Dependency an optional dependency ?
+     */
+    private boolean m_isOptional = false;
+    
+    /**
+     * LDAP Filter of the Dependency (String form).
+     */
+    private String m_strFilter;
+    
 
     /**
      * Array of Service Objects.
@@ -103,15 +125,62 @@
      * @param dh : the dependency handler managing this dependency
      * @param dm : the depednency metadata
      */
-    public Dependency(DependencyHandler dh, DependencyMetadata dm) {
+    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional) {
         m_handler = dh;
-        m_metadata = dm;
+        m_field = field;
+        m_specification = spec;
+        m_isOptional = isOptional;
+        m_strFilter = filter;
     }
 
     /**
-     * @return the dependency metadata.
+     * @return the field attached to the dependency.
      */
-    public DependencyMetadata getMetadata() { return m_metadata; }
+    public String getField() { return m_field; }
+    
+    /**
+     * @return the specification tracked by the dependency.
+     */
+    public String getSpecification() { return m_specification; }
+    
+    /**
+     * @return true is the dependency is optional.
+     */
+    public boolean isOptional() { return m_isOptional; }
+    
+    /**
+     * @return true if the dependency is multiple.
+     */
+    public boolean isMultiple() { return m_isMultiple; }
+    
+    /**
+     * Set the dependency to multiple.
+     */
+    protected void setMultiple() { m_isMultiple = true; }
+    
+    /**
+     * Set the tracked specification for this dependency.
+     * @param spec : the tracked specification (interface name)
+     */
+    protected void setSpecification(String spec) { m_specification = spec; }
+    
+    /**
+     * Add a callback to the dependency.
+     * @param cb : callback to add
+     */
+    protected void addDependencyCallback(DependencyCallback cb) {
+        if (m_callbacks.length > 0) {
+            DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
+            System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
+            newCallbacks[m_callbacks.length] = cb;
+            m_callbacks = newCallbacks;
+        }
+        else {
+            m_callbacks = new DependencyCallback[] {cb};
+        }
+    }
+    
+    public String getFilter() { return m_strFilter; }
 
     /**
      * @return the dependency handler of this dependency.
@@ -123,12 +192,12 @@
      */
     public HashMap getUsedServices() {
         HashMap hm = new HashMap();
-        if (m_metadata.isMultiple()) {
+        if (m_isMultiple) {
             for (int i = 0; i < m_ref.length; i++) {
                 if (i < m_services.length) { hm.put(((Object) m_services[i]).toString(), m_ref[i]); }
             }
         } else {
-            if (m_ref.length != 0 && m_services.length != 0) { hm.put(((Object) m_services[0]).toString(), m_ref[0]); }
+            if (m_ref.length != 0 && m_services.length != 0) { hm.put((m_services[0]).toString(), m_ref[0]); }
         }
         return hm;
     }
@@ -138,7 +207,7 @@
      * @return true is the dependency is satified
      */
     protected boolean isSatisfied() {
-        return m_metadata.isOptional() || m_ref.length != 0;
+        return m_isOptional || m_ref.length != 0;
     }
 
     /**
@@ -153,7 +222,7 @@
 
             // 1 : Test if there is any change in the reference list :
             if (!m_change) {
-                if (!m_metadata.isMultiple()) {
+                if (!m_isMultiple) {
                     if (m_services.length > 0) {
                         return m_services[0]; }
                 }
@@ -176,18 +245,19 @@
 
             // 3 : The service object list is populated, I return either the first service object, either the array.
             // Return null or an empty array if no service are found.
-            if (!m_metadata.isMultiple()) {
+            if (!m_isMultiple) {
                 if (m_services.length > 0) {
                     return m_services[0];
                 } else {
                     // Load the nullable class
-                    String[] segment = m_metadata.getServiceSpecification().split("[.]");
-                    String className = "org.apache.felix.ipojo." + segment[segment.length - 1] + "Nullable";
+                    //String[] segment = m_metadata.getServiceSpecification().split("[.]");
+                    //String className = "org.apache.felix.ipojo." + segment[segment.length - 1] + "Nullable";
+                	String className = m_specification + "Nullable";
             //        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Try to load the nullable class for " + getMetadata().getServiceSpecification() + " -> " + className);
                     Class nullableClazz = m_handler.getNullableClass(className);
 
                     if (nullableClazz == null) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_metadata.getField() + " -> " + m_metadata.getServiceSpecification());
+                        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_field + " -> " + m_specification);
                         return null;
                     }
 
@@ -202,7 +272,7 @@
             }
         } catch (Exception e) {
             // There is a problem in the dependency resolving (like in stopping method)
-            if (!m_metadata.isMultiple()) {
+            if (!m_isMultiple) {
                 m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return null, an exception was throwed in the get method", e);
                 return null; }
             else {
@@ -258,7 +328,7 @@
         addReference(ref);
         if (isSatisfied()) {
             m_state = RESOLVED;
-            if (m_metadata.isMultiple() || m_ref.length == 1) { m_change = true; callBindMethod(ref); }
+            if (m_isMultiple || m_ref.length == 1) { m_change = true; callBindMethod(ref); }
         }
         m_handler.checkContext();
     }
@@ -269,27 +339,27 @@
      */
     private void departureManagement(ServiceReference ref) {
         // Call unbind method
-        if (!m_metadata.isMultiple() && ref == m_ref[0]) { callUnbindMethod(ref); }
-        if (m_metadata.isMultiple()) { callUnbindMethod(ref); }
+        if (!m_isMultiple && ref == m_ref[0]) { callUnbindMethod(ref); }
+        if (m_isMultiple) { callUnbindMethod(ref); }
 
         // Unget the service reference
         m_handler.getInstanceManager().getContext().ungetService(ref);
         int index = removeReference(ref);
 
         // Is the state valid or invalid
-        if (m_ref.length == 0 && !m_metadata.isOptional()) {
+        if (m_ref.length == 0 && !m_isOptional) {
             m_state = UNRESOLVED;
         }
-        if (m_ref.length == 0 && m_metadata.isOptional()) {
+        if (m_ref.length == 0 && m_isOptional) {
             m_state = RESOLVED;
         }
         // Is there any change ?
-        if (!m_metadata.isMultiple() && index == 0) {
+        if (!m_isMultiple && index == 0) {
             m_change = true;
             if (m_ref.length != 0) { callBindMethod(m_ref[0]); }
         }
-        if (!m_metadata.isMultiple() && index != 0) { m_change = false; }
-        if (m_metadata.isMultiple()) { m_change = true;  }
+        if (!m_isMultiple && index != 0) { m_change = false; }
+        if (m_isMultiple) { m_change = true;  }
 
         m_handler.checkContext();
         return;
@@ -301,19 +371,19 @@
      */
     private void callUnbindMethod(ServiceReference ref) {
         if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
-            for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
-                if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.UNBIND) {
+            for (int i = 0; i < m_callbacks.length; i++) {
+                if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
                     // Try to call the bind method with a service reference inside
                     try {
-                        m_metadata.getCallbacks()[i].call(new Object[] {ref});
+                        m_callbacks[i].call(ref);
                     } catch (NoSuchMethodException e) {
                         // The method was not found : try without service reference
                         try {
-                            m_metadata.getCallbacks()[i].call();
+                            m_callbacks[i].call();
                         } catch (NoSuchMethodException e1) {
                             // The method was not found : try with the service object
                             try {
-                                m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getInstanceManager().getContext().getService(ref)});
+                                m_callbacks[i].call(m_handler.getInstanceManager().getContext().getService(ref));
                             } catch (NoSuchMethodException e2) {
                                 m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Unbind method not found", e2);
                                 return;
@@ -350,24 +420,24 @@
      */
     protected void callBindMethod(Object instance) {
         // Check optional case : nullable object case : do not call bind on nullable object
-        if (m_metadata.isOptional() && m_ref.length == 0) { return; }
+        if (m_isOptional && m_ref.length == 0) { return; }
 
 
-        if (m_metadata.isMultiple()) {
+        if (m_isMultiple) {
             for (int i = 0; i < m_ref.length; i++) {
-                for (int j = 0; j < m_metadata.getCallbacks().length; j++) {
-                    if (m_metadata.getCallbacks()[j].getMethodType() == DependencyCallback.BIND) {
+                for (int j = 0; j < m_callbacks.length; j++) {
+                    if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                         // Try to call the bind method with a service reference inside
                         try {
-                            m_metadata.getCallbacks()[j].call(instance, new Object[] {m_ref[i]});
+                            m_callbacks[j].callOnInstance(instance, m_ref[i]);
                         } catch (NoSuchMethodException e) {
                             // The method was not found : try without service reference
                             try {
-                                m_metadata.getCallbacks()[j].call(instance);
+                                m_callbacks[j].callOnInstance(instance);
                             } catch (NoSuchMethodException e1) {
                                 // The method was not found : try with the service object
                                 try {
-                                    m_metadata.getCallbacks()[j].call(instance, new Object[] {m_handler.getInstanceManager().getContext().getService(m_ref[i])});
+                                    m_callbacks[j].callOnInstance(instance, m_handler.getInstanceManager().getContext().getService(m_ref[i]));
                                 } catch (NoSuchMethodException e2) {
                                     m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
                                     return;
@@ -396,19 +466,19 @@
                 }
             }
         } else {
-            for (int j = 0; j < m_metadata.getCallbacks().length; j++) {
-                if (m_metadata.getCallbacks()[j].getMethodType() == DependencyCallback.BIND) {
+            for (int j = 0; j < m_callbacks.length; j++) {
+                if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                     // Try to call the bind method with a service reference inside
                     try {
-                        m_metadata.getCallbacks()[j].call(instance, new Object[] {m_ref[0]});
+                        m_callbacks[j].callOnInstance(instance, m_ref[0]);
                     } catch (NoSuchMethodException e) {
                         // The method was not found : try without service reference
                         try {
-                            m_metadata.getCallbacks()[j].call(instance);
+                            m_callbacks[j].callOnInstance(instance);
                         } catch (NoSuchMethodException e1) {
                             // The method was not found : try with the service object
                             try {
-                                m_metadata.getCallbacks()[j].call(new Object[] {m_handler.getInstanceManager().getContext().getService(m_ref[0])});
+                                m_callbacks[j].callOnInstance(instance, m_handler.getInstanceManager().getContext().getService(m_ref[0]));
                             } catch (NoSuchMethodException e2) {
                                 m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
                                 return;
@@ -446,20 +516,20 @@
     private void callBindMethod(ServiceReference ref) {
         // call bind method :
         if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
-            for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
-                if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.BIND) {
+            for (int i = 0; i < m_callbacks.length; i++) {
+                if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
                     // Try to call the bind method with a service reference inside
                     try {
-                        m_metadata.getCallbacks()[i].call(new Object[] {ref});
+                        m_callbacks[i].call(ref);
                     } catch (NoSuchMethodException e) {
                         // The method was not found : try without service reference
                         try {
                             m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Call the Bind method");
-                            m_metadata.getCallbacks()[i].call();
+                            m_callbacks[i].call();
                         } catch (NoSuchMethodException e1) {
                             // The method was not found : try with the service object
                             try {
-                                m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getInstanceManager().getContext().getService(ref)});
+                                m_callbacks[i].call(m_handler.getInstanceManager().getContext().getService(ref));
                             } catch (NoSuchMethodException e2) {
                                 m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
                                 return;
@@ -495,29 +565,28 @@
      */
     public void start() {
         // Construct the filter with the objectclass + filter
-        String classnamefilter = "(objectClass=" + m_metadata.getServiceSpecification() + ")";
+        String classnamefilter = "(objectClass=" + m_specification + ")";
         String filter = "";
-        if (!m_metadata.getFilter().equals("")) {
-            filter = "(&" + classnamefilter + m_metadata.getFilter() + ")";
+        if (!m_strFilter.equals("")) {
+            filter = "(&" + classnamefilter + m_strFilter + ")";
         }
         else {
             filter = classnamefilter;
         }
 
-        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Start a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Start a dependency on : " + m_specification + " with " + m_strFilter);
         m_state = UNRESOLVED;
 
         try {
-            m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_metadata.getServiceSpecification());
+            m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_specification);
         } catch (ClassNotFoundException e) {
-            System.err.println("Cannot load the interface class for the dependency " + m_metadata.getField() + " [" + m_metadata.getServiceSpecification() + "]");
+            System.err.println("Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
             e.printStackTrace();
         }
 
         try {
             // Look if the service is already present :
-            ServiceReference[] sr = m_handler.getInstanceManager().getContext().getServiceReferences(
-                    m_metadata.getServiceSpecification(), filter);
+            ServiceReference[] sr = m_handler.getInstanceManager().getContext().getServiceReferences(m_specification, filter);
             if (sr != null) {
                 for (int i = 0; i < sr.length; i++) { addReference(sr[i]); }
                 m_state = RESOLVED;
@@ -538,7 +607,7 @@
      * Stop the dependency.
      */
     public void stop() {
-        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Stop a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Stop a dependency on : " + m_specification + " with " + m_strFilter);
         m_state = UNRESOLVED;
 
         // Unget all services references
@@ -549,7 +618,7 @@
         m_ref = new ServiceReference[0];
         m_handler.getInstanceManager().getContext().removeServiceListener(this);
         m_clazz = null;
-        m_services = null;
+        m_services = new Object[0];
     }
 
     /**
@@ -557,8 +626,7 @@
      * @return the state of the dependency (1 : valid, 2 : invalid)
      */
     public int getState() {
-        if (m_metadata.isOptional()) { return 1; }
-        else { return m_state; }
+        return ( m_isOptional ) ? 1 : m_state;
     }
 
     /**
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
index 7700ffc..022156b 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -19,8 +19,11 @@
 package org.apache.felix.ipojo.handlers.dependency;
 
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
-import org.apache.felix.ipojo.util.Callback;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.ServiceReference;
 
 
 /**
@@ -45,10 +48,19 @@
     private int m_methodType;
 
     /**
-     * Callback object.
+     * Callback method name.
      */
-    private Callback m_callback;
-
+    private String m_callback;
+    
+    /**
+     * Is the callback a static callback
+     */
+    private boolean m_isStatic;
+    
+    /**
+     * The instance manager
+     */
+    private InstanceManager m_manager;
 
     /**
      * Constructor.
@@ -59,7 +71,9 @@
      */
     public DependencyCallback(Dependency dep, String method, int methodType, boolean isStatic) {
         m_methodType = methodType;
-        m_callback = new Callback(method, isStatic, dep.getDependencyHandler().getInstanceManager());
+        m_callback = method;
+        m_isStatic = isStatic;
+        m_manager = dep.getDependencyHandler().getInstanceManager();
     }
 
     /**
@@ -74,38 +88,116 @@
      * @throws IllegalAccessException : The method can not be invoked
      */
     protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        m_callback.call();
+    	// Get the method object
+    	Method method = m_manager.getClazz().getMethod(m_callback, new Class[] {});
+    	
+        if (m_isStatic) { method.invoke(null, new Object[] {}); }
+        else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects().length == 0) {
+                m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
+                method.invoke(m_manager.getPojoObject(), new Object[]{});
+            } else {
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                    method.invoke(m_manager.getPojoObjects()[i], new Object[] {});
+                }
+            }
+        }
     }
 
     /**
-     * Call the callback method.
+     * Call the callback method with a service reference.
+     * @param ref : the service reference to send to the method
      * @throws NoSuchMethodException : Method is not found in the class
      * @throws InvocationTargetException : The method is not static
      * @throws IllegalAccessException : The method can not be invoked
      */
-    protected void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        m_callback.call(arg);
+    protected void call(ServiceReference ref) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	// Get the method object
+    	Method method = m_manager.getClazz().getMethod(m_callback, new Class[] {ServiceReference.class});
+    	
+        if (m_isStatic) { method.invoke(null, new Object[] {ref}); }
+        else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects().length == 0) {
+                m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
+                method.invoke(m_manager.getPojoObject(), new Object[]{ref});
+            } else {
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                    method.invoke(m_manager.getPojoObjects()[i], new Object[] {ref});
+                }
+            }
+        }
     }
 
     /**
-     * Call the callback on the given instance.
+     * Call the callback method with an object.
+     * @param o : the object to send to the method
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call(Object o) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	// Get the method object
+    	Method method = m_manager.getClazz().getMethod(m_callback, new Class[] {Object.class});
+    	
+        if (m_isStatic) { method.invoke(null, new Object[] {o}); }
+        else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects().length == 0) {
+                m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
+                method.invoke(m_manager.getPojoObject(), new Object[]{o});
+            } else {
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                    method.invoke(m_manager.getPojoObjects()[i], new Object[] {o});
+                }
+            }
+        }
+    }
+
+    /**
+     * Call the callback on the given instance with no parameters.
      * @param instance : the instance on which call the callback
      * @throws NoSuchMethodException : the method is not found
      * @throws IllegalAccessException : the method could not be called
      * @throws InvocationTargetException : an error happens in the called method
      */
-    protected void call(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { m_callback.call(instance); }
+    protected void callOnInstance(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 
+    	Method method = instance.getClass().getMethod(m_callback, new Class[] {});
+    	method.invoke(instance, new Object[] {});
+   	}
 
     /**
      * Call the callback on the given instance with the given argument.
      * @param instance : the instance on which call the callback
-     * @param arg : the argument of the callback
+     * @param ref : the service reference to send to the callback
      * @throws NoSuchMethodException : the method is not found
      * @throws IllegalAccessException : the method could not be called
      * @throws InvocationTargetException : an error happens in the called method
      * @throws InvocationTargetException
      */
-    protected void call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        m_callback.call(instance, arg);
+    protected void callOnInstance(Object instance, ServiceReference ref) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Method method = instance.getClass().getMethod(m_callback, new Class[] {ServiceReference.class});
+    	method.invoke(instance, new Object[] {ref});
+    }
+    
+    /**
+     * Call the callback on the given instance with the given argument.
+     * @param instance : the instance on which call the callback
+     * @param o : the service object to send to the callback
+     * @throws NoSuchMethodException : the method is not found
+     * @throws IllegalAccessException : the method could not be called
+     * @throws InvocationTargetException : an error happens in the called method
+     * @throws InvocationTargetException
+     */
+    protected void callOnInstance(Object instance, Object o) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Method method = instance.getClass().getMethod(m_callback, new Class[] {Object.class});
+    	method.invoke(instance, new Object[] {o});
     }
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 925c397..6d60a16 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.io.IOException;
 import java.net.URL;
 import java.util.Dictionary;
 
@@ -50,11 +49,6 @@
     private Class[] m_nullableClasses = new Class[0];
 
     /**
-     * Classloader to use to load nullable classes.
-     */
-    private NullableClassloader m_classloader;
-
-    /**
      * State of the handler.
      */
     private int m_state;
@@ -128,16 +122,7 @@
             int initialState = m_state;
 
             // Check the component dependencies
-            if (!validateComponentDependencies()) {
-                // The dependencies are not valid
-                if (initialState == InstanceManager.VALID) {
-                    //There is a state change
-                    m_state = InstanceManager.INVALID;
-                    m_manager.checkInstanceState();
-                }
-                // Else do nothing, the component state stay UNRESOLVED
-            }
-            else {
+            if (validateComponentDependencies()) {
                 // The dependencies are valid
                 if (initialState == InstanceManager.INVALID) {
                     //There is a state change
@@ -145,6 +130,14 @@
                     m_manager.checkInstanceState();
                 }
                 // Else do nothing, the component state stay VALID
+            } else {
+                // The dependencies are not valid
+                if (initialState == InstanceManager.VALID) {
+                    //There is a state change
+                    m_state = InstanceManager.INVALID;
+                    m_manager.checkInstanceState();
+                }
+                // Else do nothing, the component state stay UNRESOLVED
             }
 
         }
@@ -157,7 +150,7 @@
      */
     private boolean checkDependency(Dependency dep, Element manipulation) {
         // Check the internal type of dependency
-        String field = dep.getMetadata().getField();
+        String field = dep.getField();
 
         String type = null;
         for (int i = 0; i < manipulation.getElements("Field").length; i++) {
@@ -168,26 +161,26 @@
         }
 
         if (type == null) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] A declared dependency was not found in the class : " + dep.getMetadata().getField());
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] A declared dependency was not found in the class : " + dep.getField());
             return false;
         }
 
         if (type != null) {
             if (type.endsWith("[]")) {
                 // Set the dependency to multiple
-                dep.getMetadata().setMultiple();
+                dep.setMultiple();
                 type = type.substring(0, type.length() - 2);
             }
 
-            if (dep.getMetadata().getServiceSpecification() == null) { dep.getMetadata().setServiceSpecification(type); }
+            if (dep.getSpecification() == null) { dep.setSpecification(type); }
 
-            if (!dep.getMetadata().getServiceSpecification().equals(type)) {
-                m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + type + "] and the needed service interface [" + dep.getMetadata().getServiceSpecification() + "] are not the same");
-                dep.getMetadata().setServiceSpecification(type);
+            if (!dep.getSpecification().equals(type)) {
+                m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + type + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
+                dep.setSpecification(type);
             }
         }
         else {
-            m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The declared dependency " + dep.getMetadata().getField() + "  does not exist in the code");
+            m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The declared dependency " + dep.getField() + "  does not exist in the code");
         }
         return true;
     }
@@ -212,14 +205,12 @@
             if (deps[i].containsAttribute("filter")) { filter = deps[i].getAttribute("filter"); }
             boolean optional = false;
             if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) { optional = true; }
-            DependencyMetadata dm = new DependencyMetadata(field, serviceSpecification, filter, optional);
 
-
-            Dependency dep = new Dependency(this, dm);
+            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional);
             // Check the dependency :
             Element manipulation = componentMetadata.getElements("Manipulation")[0];
             if (checkDependency(dep, manipulation)) { addDependency(dep); }
-            else { m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] The dependency on " + dep.getMetadata().getField() + " is not valid"); }
+            else { m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] The dependency on " + dep.getField() + " is not valid"); }
 
             // Look for dependency callback :
             for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
@@ -231,21 +222,16 @@
                 boolean isStatic = false;
                 if (deps[i].getElements("Callback", "")[j].containsAttribute("isStatic") && deps[i].getElements("Callback", "")[j].getAttribute("isStatic").equals("true")) { isStatic = true; }
                 DependencyCallback dc = new DependencyCallback(dep, method, methodType, isStatic);
-                dep.getMetadata().addDependencyCallback(dc);
+                dep.addDependencyCallback(dc);
             }
         }
 
         if (deps.length > 0) {
             String[] fields = new String[m_dependencies.length];
             for (int k = 0; k < m_dependencies.length; k++) {
-                fields[k] = m_dependencies[k].getMetadata().getField();
+                fields[k] = m_dependencies[k].getField();
             }
             m_manager.register(this, fields);
-
-            // Create the nullable classloader
-            // TODO why do not use the factory class loader ?
-            m_classloader = new NullableClassloader(m_manager.getContext().getBundle());
-
         }
     }
 
@@ -254,36 +240,25 @@
      * @param dep : the dependency
      */
     private void createNullableClass(Dependency dep) {
-        m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Try to load the nullable class for " + dep.getMetadata().getServiceSpecification());
-        // Try to load the nullable object :
-        String[] segment = dep.getMetadata().getServiceSpecification().split("[.]");
-        String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
-
-        String resource = dep.getMetadata().getServiceSpecification().replace('.', '/') + ".class";
+        m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Try to load the nullable class for " + dep.getSpecification());
+        
+        //String[] segment = dep.getMetadata().getServiceSpecification().split("[.]");
+        //String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+		String className = dep.getSpecification()+"Nullable";
+        String resource = dep.getSpecification().replace('.', '/') + ".class";
         URL url =  m_manager.getContext().getBundle().getResource(resource);
 
         try {
-            byte[] b = NullableObjectWriter.dump(url,  dep.getMetadata().getServiceSpecification());
-
-//          // DEBUG :
-//          try {
-//          File file = new File("P:\\workspace\\iPOJO\\adapted\\" + className.replace('/', '.') + ".class");
-//          file.createNewFile();
-//          FileOutputStream fos = new FileOutputStream(file);
-//          fos.write(b);
-//          fos.close();
-//          } catch (Exception e3) {
-//          System.err.println("Problem to write the adapted class on the file system  : " + e3.getMessage());
-
-//          }
-
-            addNullableClass(m_classloader.defineClass(className.replace('/', '.'), b, null));
-            m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Nullable class created for " + dep.getMetadata().getServiceSpecification());
-
-        } catch (IOException e1) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] Cannot open a stream of an interface to generate the nullable class for " + dep.getMetadata().getServiceSpecification(), e1);
+            byte[] b = NullableObjectWriter.dump(url,  dep.getSpecification());
+            Class c = null;
+            try {
+            	c = m_manager.getFactory().defineClass(className, b, null);
+            }
+            catch(Exception e) { System.err.println("Cannot define !!!");}
+            addNullableClass(c); 
+            m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Nullable class created for " + dep.getSpecification());
         } catch (Exception e2) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] Cannot load the nullable class for  " + dep.getMetadata().getServiceSpecification(), e2);
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[DependencyHandler on " + m_manager.getClassName() + "] Cannot load the nullable class for  " + dep.getSpecification(), e2);
         }
     }
 
@@ -309,7 +284,7 @@
         //TODO : non effiecent
         for (int i = 0; i < m_dependencies.length; i++) {
             Dependency dep = m_dependencies[i];
-            if (dep.getMetadata().getField().equals(fieldName)) {
+            if (dep.getField().equals(fieldName)) {
                 // The field name is a dependency, return the get
                 return dep.get();
             }
@@ -334,7 +309,7 @@
         // Start the dependencies, for optional dependencies create Nullable class
         for (int i = 0; i < m_dependencies.length; i++) {
             Dependency dep = m_dependencies[i];
-            if (dep.getMetadata().isOptional() && !dep.getMetadata().isMultiple()) { createNullableClass(dep); }
+            if (dep.isOptional() && !dep.isMultiple()) { createNullableClass(dep); }
             dep.start();
         }
         // Check the state
@@ -352,6 +327,7 @@
      */
     public void stop() {
         for (int i = 0; i < m_dependencies.length; i++) { m_dependencies[i].stop(); }
+        m_nullableClasses = new Class[0];
     }
 
     /**
@@ -372,7 +348,7 @@
             Dependency dep = m_dependencies[i];
             valide = valide & dep.isSatisfied();
             if (!valide) {
-                m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Component Dependencies are not valid : " + dep.getMetadata().getServiceSpecification());
+                m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Component Dependencies are not valid : " + dep.getSpecification());
                 return false;
             }
         }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
deleted file mode 100644
index 1626ad7..0000000
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.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.handlers.dependency;
-
-/**
- * Dependency Metadata.
- * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
- */
-public class DependencyMetadata {
-
-    /**
-     * Service Specification <=> Service contract (or interface in OSGi).
-     */
-    private String m_serviceSpecification;
-
-    /**
-     * LDAP filter.
-     */
-    private String m_filter;
-
-    /**
-     * is the dependency optional ?
-     */
-    private boolean m_isOptional;
-
-    /**
-     * is the dependency multiple ?
-     */
-    private boolean m_isMultiple = false;
-
-    /**
-     * List of dependency callbacks attached to this dependency.
-     */
-    private DependencyCallback[] m_callbacks = new DependencyCallback[0];
-
-    /**
-     * The field linking the metadata and the component implementation.
-     */
-    private String m_field;
-
-    // Constructor
-
-    /**
-     * Constructor.
-     * @param field : the field name
-     * @param service : the interface name.
-     * @param filter : the filter of the dependency
-     * @param isOptional : is the dependency optional
-     */
-    public DependencyMetadata(String field, String service, String filter, boolean isOptional) {
-        m_field = field;
-        m_serviceSpecification = service;
-        m_isOptional = isOptional;
-        m_filter = filter;
-    }
-
-    /**
-     * Add a callback to the dependency.
-     * @param cb : callback to add
-     */
-    public void addDependencyCallback(DependencyCallback cb) {
-        for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
-            if (m_callbacks[i] == cb) { return; }
-        }
-
-        if (m_callbacks.length > 0) {
-            DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
-            System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
-            newCallbacks[m_callbacks.length] = cb;
-            m_callbacks = newCallbacks;
-        }
-        else {
-            m_callbacks = new DependencyCallback[] {cb};
-        }
-    }
-
-    // Getter
-
-    /**
-     * @return Returns the m_field.
-     */
-    public String getField() {
-        return m_field;
-    }
-
-    /**
-     * @return Returns the m_filter.
-     */
-    public String getFilter() {
-        return m_filter;
-    }
-
-    /**
-     * @return Returns the m_isMultiple.
-     */
-    public boolean isMultiple() {
-        return m_isMultiple;
-    }
-
-    /**
-     * @return Returns the m_isOptional.
-     */
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-    /**
-     * @return Returns the m_serviceSpecification.
-     */
-    public String getServiceSpecification() {
-        return m_serviceSpecification;
-    }
-
-    /**
-     * return true if the dependency is multiple.
-     */
-    public void setMultiple() {
-        m_isMultiple = true;
-    }
-
-    /**
-     * Set the service specification.
-     * @param serviceSpecification : the dependency service specification
-     */
-    public void setServiceSpecification(String serviceSpecification) {
-        m_serviceSpecification = serviceSpecification;
-    }
-
-    /**
-     * @return the list of the callbacks
-     */
-    public DependencyCallback[] getCallbacks() { return m_callbacks; }
-
-}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
deleted file mode 100644
index 104c26d..0000000
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
+++ /dev/null
@@ -1,105 +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.handlers.dependency;
-
-import java.io.IOException;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.Enumeration;
-
-import org.osgi.framework.Bundle;
-
-/**
- * iPOJO Classloader.
- * This classloadert is used to load manipulated class.
- * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
- */
-public class NullableClassloader extends ClassLoader {
-
-    /**
-     * The owner bundle.
-     * m_bundle : Bundle
-     */
-    private Bundle  m_bundle;
-
-    /**
-     * Constructor.
-     * @param b : the owner bundle
-     */
-    public NullableClassloader(Bundle b) {
-        m_bundle = b;
-    }
-
-    /**
-     * load the class.
-     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
-     * @param name : the name of the class
-     * @param resolve : should be the class resolve now ?
-     * @return : the loaded class
-     * @throws ClassNotFoundException : the class to load is not found
-     */
-    protected synchronized Class loadClass(final String name,
-            final boolean resolve) throws ClassNotFoundException {
-
-        Class clazz = null;
-        //Activator.getLogger().log(Level.WARNING, "Bundle " + m_bundle.getBundleId() + " -> Try to load : " + name);
-
-        if (m_bundle != null) { clazz = m_bundle.loadClass(name); }
-
-        return clazz;
-    }
-
-
-    /**
-     * Return the URL of the asked ressource.
-     * @param arg : the name of the resource to find.
-     * @return the URL of the resource.
-     * @see java.lang.ClassLoader#getResource(java.lang.String)
-     */
-    public URL getResource(String arg) {
-        return m_bundle.getResource(arg);
-    }
-
-    /**
-     * .
-     * @param arg : resource to find
-     * @return : the enumeration found
-     * @throws IOException : if the lookup failed.
-     * @see java.lang.ClassLoader#getResources(java.lang.String)
-     */
-    public Enumeration getRessources(String arg) throws IOException {
-        return m_bundle.getResources(arg);
-    }
-
-    /**
-     * The defineClass method for GenClassLoader.
-     * @param name : name of the class
-     * @param b : the byte array of the class
-     * @param domain : the protection domain
-     * @return : the defined class.
-     * @throws Exception : if a problem is detected during the loading
-     */
-    public Class defineClass(String name, byte[] b,
-            ProtectionDomain domain) throws Exception {
-        Class clazz =  super.defineClass(name, b, 0, b.length, domain);
-        return clazz;
-    }
-
-
-}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
index a4d4f29..b9d0284 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
@@ -55,8 +55,9 @@
 
             ClassWriter cw = new ClassWriter(true);
 
-            String[] segment = contractName.split("[.]");
-            String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+            //String[] segment = contractName.split("[.]");
+            //String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+            String className=contractName.replace('.', '/')+"Nullable";
 
 
             // Create the class
@@ -89,10 +90,16 @@
                     switch (returnType.getSort()) {
                     case Type.BOOLEAN:
                     case Type.INT:
+                    case Type.BYTE:
+                    case Type.SHORT:
                         // Integer or Boolean : return 0 ( false)
                         mv.visitInsn(ICONST_0);
                         mv.visitInsn(IRETURN);
                         break;
+                    case Type.LONG:
+                    	mv.visitInsn(LCONST_0);
+                    	mv.visitInsn(LRETURN);
+                    	break;
                     case Type.DOUBLE:
                         // Double : return 0.0
                         mv.visitInsn(DCONST_0);
@@ -109,6 +116,7 @@
                         break;
                     default :
                         System.err.println("Type not yet managed : " + returnType);
+                    	break;
                     }
                 mv.visitMaxs(0, 0);
                 mv.visitEnd();
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
index e071081..60779d9 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
@@ -48,7 +48,7 @@
     private InstanceManager m_manager;
 
     /**
-     * Add the given Hook to the hook list.
+     * Add the given callback to the callback list.
      * @param hk : the element to add
      */
     private void addCallback(LifecycleCallback hk) {
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 15517f8..57b584f 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -103,6 +103,7 @@
                     serviceSpecification[j] = manipulation.getElements("Interface")[j].getAttribute("name");
                 }
             }
+            if (serviceSpecification.length == 0) { m_manager.getFactory().getLogger().log(Logger.ERROR, "Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)"); return; }
 
             // Get the factory policy
             int factory = ProvidedService.SINGLETON_FACTORY;
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
index 2136329..9153e53 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -115,6 +115,7 @@
         for (int i = 0; i < arg.length; i++) {
             classes[i] = arg[i].getClass();
         }
+        
         Method method = m_manager.getClazz().getMethod(m_method, classes);
         method.setAccessible(true);
 
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java b/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java
index 69efa5b..0bf1daa 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java
@@ -93,6 +93,7 @@
                 break;
             default:
                 System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + s);
+            	break;
         }
     }