Begin the work about the issue Felix-968.
POJO object can be injected inside an instance through the 'instance.object' instance configuration property.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@749624 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
index abab9eb..80c7c3c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -248,6 +248,8 @@
      * where the service is get.
      * This method uses the service context if specified, the bundle
      * context otherwise.
+     * This method may throw {@link IllegalStateException} if the used bundle
+     * context is no more valid (because we're leaving).
      * @param reference the required service reference 
      * @return the service object or <code>null</code> if the service reference 
      * is no more valid or if the service object is not accessible.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index 56f6d6b..7866895 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -167,6 +167,13 @@
 
         // Add the name
         m_name = (String) configuration.get("instance.name");
+        
+        // Check if an object is injected in the instance
+        Object obj = configuration.get("instance.object");
+        if (obj != null) {
+            m_pojoObjects = new ArrayList(1);
+            m_pojoObjects.add(obj);
+        }
 
         // Get the factory method if presents.
         m_factoryMethod = (String) metadata.getAttribute("factory-method");
@@ -300,6 +307,11 @@
             }
         }
         
+        // Is an object already contained (i.e. injected)
+        if (m_pojoObjects != null && ! m_pojoObjects.isEmpty()) {
+            managedInjectedObject();
+        }
+        
         for (int i = 0; i < m_handlers.length; i++) {
             if (m_handlers[i].getState() != VALID) {
                 setState(INVALID);
@@ -773,7 +785,9 @@
         for (int i = 0; newPOJO && i < m_handlers.length; i++) {
             ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(pojo);
         } 
-        //NOTE this method allows returning a POJO object before calling the onCreation on handler.
+        //NOTE this method allows returning a POJO object before calling the onCreation on handler:
+        // a second thread get the created object before the first one (which created the object),
+        // call onCreation.
 
         return pojo;
     }
@@ -790,6 +804,42 @@
         }
         return m_clazz;
     }
+    
+    /**
+     * Configures an injected object in this container.
+     */
+    private void managedInjectedObject() {
+        Object obj = m_pojoObjects.get(0); // Get first object.
+   
+        if (! (obj instanceof Pojo)) {
+            // Error, the injected object is not a POJO.
+            throw new RuntimeException("The injected object in " + m_name + " is not a POJO");
+        }
+        
+        load(); // Load the class.
+
+        if (! m_clazz.isInstance(obj)) {
+            throw new RuntimeException("The injected object in " + m_name + " is not an instance of " + m_className);
+        }
+        
+        // Call _setInstanceManager
+        try {
+            Method setIM = m_clazz.getDeclaredMethod("_setInstanceManager", new Class[] {this.getClass()});
+            setIM.setAccessible(true); // Necessary as the method is private
+            setIM.invoke(obj, new Object[] {this});
+        } catch (Exception e) {
+            // If anything wrong happened... 
+            throw new RuntimeException("Cannot attach the injected object with the container of " + m_name + " : " + e.getMessage());
+        }
+        
+        // Call createInstance on Handlers :
+        for (int i = 0; i < m_handlers.length; i++) {
+            // This methods must be call without the monitor lock.
+            ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(obj);
+        }
+        
+        
+    }
 
     /**
      * Registers an handler.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
index 458d7af..3ba0ebf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
@@ -509,6 +509,7 @@
     public ServiceReference[] getServiceReferences() {

         synchronized (this) {

             if (m_matchingRefs.isEmpty()) { return null; }

+            // TODO Consider sorting the array (on a copy of matching ref) if dynamic priority used.

             return (ServiceReference[]) m_matchingRefs.toArray(new ServiceReference[m_matchingRefs.size()]);

         }

     }