Changed line endings.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@548483 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java b/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java
index c9fc805..ccf9fff 100644
--- a/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java
+++ b/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java
@@ -1,64 +1,64 @@
-/* 

- * 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.servicebinder;

-

-import java.util.Properties;

-import java.util.ArrayList;

-import java.util.Iterator;

-import java.util.List;

-import java.util.Map;

-import java.util.HashMap;

-

-import org.apache.felix.servicebinder.architecture.Dependency;

-import org.apache.felix.servicebinder.architecture.DependencyChangeEvent;

-import org.apache.felix.servicebinder.architecture.Instance;

-import org.apache.felix.servicebinder.architecture.InstanceChangeEvent;

-import org.apache.felix.servicebinder.impl.ArchitectureServiceImpl;

-import org.osgi.framework.ServiceRegistration;

-import org.osgi.framework.BundleContext;

-import org.osgi.framework.InvalidSyntaxException;

-import org.osgi.framework.ServiceListener;

-import org.osgi.framework.ServiceEvent;

-import org.osgi.framework.ServiceReference;

-import org.osgi.framework.Bundle;

-

-import java.lang.reflect.Constructor;

-import java.lang.reflect.Method;

-import java.lang.reflect.InvocationTargetException;

+/* 
+ * 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.servicebinder;
+
+import java.util.Properties;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.felix.servicebinder.architecture.Dependency;
+import org.apache.felix.servicebinder.architecture.DependencyChangeEvent;
+import org.apache.felix.servicebinder.architecture.Instance;
+import org.apache.felix.servicebinder.architecture.InstanceChangeEvent;
+import org.apache.felix.servicebinder.impl.ArchitectureServiceImpl;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Bundle;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 
 /**
- * A InstanceManager is created for every component instance.
 * 
 * When the InstanceManager is instantiated, a collection of DependencyManagers is
 * created. Each dependency manager corresponds to a required service
 * 
 * A InstanceManager follows a sequence of clearly defined steps.
 * 
 * 1.- Creation : the binder instance is created, its state becomes CREATED. This step is further divided
 *                in the following substeps:
 *                  - The binder instance checks if all of the dependencies are valid, if this
 *                    is false, it returns.
 *                  - If the dependendencies are valid, its state becomes executing. The object from
 *                    the instance class is created (if this object receives a ServiceBinderContext as
 *                    a parameter in its constructor, the context is passed to it.
 *                  - The validate() method is called on the dependency managers, this will cause
 *                    calls on the binding methods to occur
 *                  - The binder instance adds itself to the list of binder instances in the activator
 *                  - The binder instance registers the services implemented by the instance object.
 * 
 * 2.- Disposal :
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * A InstanceManager is created for every component instance. *  * When the InstanceManager is instantiated, a collection of DependencyManagers is * created. Each dependency manager corresponds to a required service *  * A InstanceManager follows a sequence of clearly defined steps. *  * 1.- Creation : the binder instance is created, its state becomes CREATED. This step is further divided *                in the following substeps: *                  - The binder instance checks if all of the dependencies are valid, if this *                    is false, it returns. *                  - If the dependendencies are valid, its state becomes executing. The object from *                    the instance class is created (if this object receives a ServiceBinderContext as *                    a parameter in its constructor, the context is passed to it. *                  - The validate() method is called on the dependency managers, this will cause *                    calls on the binding methods to occur *                  - The binder instance adds itself to the list of binder instances in the activator *                  - The binder instance registers the services implemented by the instance object. *  * 2.- Disposal : *  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-

-public class InstanceManager implements InstanceReference, Instance

-{

-    // The values ranging from 0 to 3 are public and are defined in InstanceReference

-    static final int INSTANCE_CREATING = 4;

-    static final int INSTANCE_VALIDATING = 5;

-    static final int INSTANCE_INVALIDATING = 6;

-    static final int INSTANCE_DESTROYING = 7;

-

-    static final String m_states[]={"CREATED","VALID","INVALID",

-                                    "DESTROYED","CREATING","VALIDATING",

-                                    "INVALIDATING","DESTROYING"};

-

-    // The state of this instance manager

+
+public class InstanceManager implements InstanceReference, Instance
+{
+    // The values ranging from 0 to 3 are public and are defined in InstanceReference
+    static final int INSTANCE_CREATING = 4;
+    static final int INSTANCE_VALIDATING = 5;
+    static final int INSTANCE_INVALIDATING = 6;
+    static final int INSTANCE_DESTROYING = 7;
+
+    static final String m_states[]={"CREATED","VALID","INVALID",
+                                    "DESTROYED","CREATING","VALIDATING",
+                                    "INVALIDATING","DESTROYING"};
+
+    // The state of this instance manager
     private int m_state = INSTANCE_CREATING;
 
     /**
@@ -68,15 +68,15 @@
      */
     // The metadata
     private InstanceMetadata m_instanceMetadata;
-

-

-    // The object that implements the service and that is bound to other services

-    private Object m_implementorObject;

-

-    // The dependency managers that manage every dependency

-    private List m_dependencyManagers;

-

-    // The ServiceRegistration

+
+
+    // The object that implements the service and that is bound to other services
+    private Object m_implementorObject;
+
+    // The dependency managers that manage every dependency
+    private List m_dependencyManagers;
+
+    // The ServiceRegistration
     private ServiceRegistration m_serviceRegistration;
 
     /**
@@ -103,626 +103,626 @@
     // Listeners to validation events
     private InstanceReferenceListener m_instanceListener = null;
 
-    // Properties that can be attached to te InstanceManager

-    private Properties m_localProperties = new Properties();

-    

-    // Flag that indicates that activate was called

-    private boolean m_activateCalled = false;

-

-    /**

-    * Constructor that creates a collection of dependency managers that will be in

-    * charge of the different dependencies for a particular instance.

-    *

-    * @param   activator A reference to the generic activator

-    * @param   descriptor an InstanceMetadata that contains information found in the descriptor file

-    * @throws  java.lang.ClassNotFoundException if the instance class (declared in the descriptor file) is not found

-    * @throws  java.lang.NoSuchMethodException if the bind or unbind methods are not found on the instance class

-    * @throws  org.osgi.framework.InvalidSyntaxException if the filter declared in the requires entry has an invalid syntax

-    **/

-    InstanceManager(GenericActivator activator,InstanceMetadata descriptor)

-        throws ClassNotFoundException, NoSuchMethodException, InvalidSyntaxException

-    {

-        m_activator = activator;

-

-        m_instanceMetadata = descriptor;

-

-        m_dependencyManagers = new ArrayList();

-

-        if (m_instanceMetadata.getDependencies().size() != 0)

-        {

-            Iterator dependencyit = m_instanceMetadata.getDependencies().iterator();

-

-            while(dependencyit.hasNext())

-            {

-                DependencyMetadata currentdependency = (DependencyMetadata)dependencyit.next();

-

-                DependencyManager depmanager = new DependencyManager(currentdependency);

-

-                m_dependencyManagers.add(depmanager);

-

-                // Register the dependency managers as listeners to service events so that they begin

-                // to manage the dependency autonomously

-

-                m_activator.getBundleContext().addServiceListener(depmanager,depmanager.getDependencyMetadata().getFilter());

-            }

-        }

-

-        m_sbcontext = new ServiceBinderContextImpl(this);

-

-        // Add this instance manager to the Generic activator list

-        m_activator.addInstanceManager(this);

-

-        setState(INSTANCE_CREATED);

-    }

-

-    /**

-    * Validate this Instance manager.

-    *

-    * CONCURRENCY NOTE: This method can be called either after an instance manager is created

-    * or after the instance is validated again after by the instance manager itself

-    */

-    synchronized void validate()

-    {

-        if (m_state == INSTANCE_VALID)

-        {

-            return;

-        }

-        else if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED)

-        {

-            GenericActivator.error("InstanceManager : create() called for a non INVALID or CREATED InstanceManager ("+m_states[m_state]+")");

-            return;

-        }

-

-        setState(INSTANCE_VALIDATING);

-

-        // Test if all dependency managers are valid

-

-        Iterator it = m_dependencyManagers.iterator();

-

-        while (it.hasNext())

-        {

-            // It is not possible to call the isValid method yet in the DependencyManager

-            // since they have not been initialized yet, but we can't call initialize

-            // since the object where bindings will be done has not been created.

-            // This test is necessary, because we don't want to instantiate

-            // the object if the dependency managers won't be valid.

-            DependencyManager dm = (DependencyManager)it.next();

-            if (dm.getRequiredServiceRefs() == null && dm.getDependencyMetadata().isOptional() == false)

-            {

-                setState(INSTANCE_INVALID);

-                return;

-            }

-        }

-

-        // everything ok to go...

-

-        try

-        {

-            Class c = m_activator.getClass().getClassLoader().loadClass(m_instanceMetadata.getImplementorName());

-            try

-            {

-                Constructor cons = c.getConstructor(new Class[] {ServiceBinderContext.class});

-                m_implementorObject = cons.newInstance(new Object[] {m_sbcontext});

-            }

-            catch(NoSuchMethodException ex)

-            {

-                // Aparently he doesn't want a ServiceBinderContext...

-            }

-

-            // Create from no-param constructor

-            if (m_implementorObject == null)

-            {

-                m_implementorObject = c.newInstance();

-            }

-

-            /* is it a factory?

-            if (m_implementorObject instanceof GenericFactory)

-            {

-                ((GenericFactory) m_implementorObject).setActivator(m_activator, this);

-            }

-            */

-

-            // Allow somebody to proxy the object through the proxyProvidedServiceObject method

-            // in the activator

-            Object proxy = m_activator.proxyProvidedServiceObject(m_implementorObject, this.getInstanceMetadata());

-            if (proxy != null)

-            {

-                m_implementorObject = proxy;

-            }

-            else

-            {

-                GenericActivator.error("InstanceManager : Proxy method returned a null value");

-            }

-        }

-        catch (Throwable t)

-        {

-            // failure at creation

-            GenericActivator.error("InstanceManager : Error during instantiation : "+t);

-            t.printStackTrace();

-            _invalidate();

-            return;

-        }

-        

-        // initial bindings

-

-        it = m_dependencyManagers.iterator();

-

-        while (it.hasNext())

-        {

-            DependencyManager dm = (DependencyManager)it.next();

-            if (dm.initialize() == false)

-            {

-                _invalidate();

-                return;

-            }

-        }

-        

-        // We need to check if we are still validating because it is possible that when we

-        // registered the service above our thread causes an instance to become valid which

-        // then registered a service that then generated an event that we needed that

-        // caused validate() to be called again, thus if we are not still VALIDATING, it

-        // means we are already VALID.

-        if (m_state == INSTANCE_VALIDATING)

-        {

-            // activate

-

-            if (m_implementorObject instanceof Lifecycle)

-            {

-                try

-                {

-                    ((Lifecycle)m_implementorObject).activate();

-                    this.m_activateCalled=true;

-                }

-                catch(Exception e)

-                {

-                    GenericActivator.error("InstanceManager : exception during activate:"+e);

-                    e.printStackTrace();

-                    _invalidate();

-                    return;

-                }

-            }

-

-            // validated!

-

-            fireInstanceReferenceValidated();

-            setState(INSTANCE_VALID);

-        }

-        

-

-        // register services

-

-        boolean reg = requestRegistration();

-

-        if (!reg)

-        {

-            GenericActivator.error("InstanceManager : registration of the services failed...");

-            _invalidate();

-            return;

-        }

-        

-        // Configuration ended successfuly.

-

-    }

-

-    /**

-     * This method invalidates the InstanceManager

-     *

-     * CONCURRENCY NOTE: This method may be called either from application code or event thread.

-    **/

-    synchronized void invalidate()

-    {

-        if (m_state == INSTANCE_INVALID)

-        {

-            return;

-        }

-        else if (m_state != INSTANCE_VALID && m_state != INSTANCE_DESTROYING)

-        {

-            GenericActivator.error("InstanceManager : invalidate() called for a non VALID InstanceManager ("+m_states[m_state]+")");

-            return;

-        }

-

-        if (m_state != INSTANCE_DESTROYING)

-        {

-            setState(INSTANCE_INVALIDATING);

-        }

-

-        // Fire invalidating events

-        fireInstanceReferenceInvalidating();

-

-        _invalidate();

-

-

-    }

-

-    /**

-     * this method invalidates the InstanceManager without performing any of the callbacks

-     * associated with the Lifecycle interface or the InstanceReference event listeners.

-    **/

-    private void _invalidate()

-    {

-        // Unregister services

-

-        requestUnregistration();

-        

-        if(m_activateCalled==true)

-        {        

-            // Call deactivate on the Lifecycle

-

-            if (m_implementorObject instanceof Lifecycle)

-            {

-                try

-                {

-                    ((Lifecycle)m_implementorObject).deactivate();

-                }

-                catch(Exception e)

-                {

-                    GenericActivator.error("InstanceManager : exception during call to deactivate():"+e);

-                }

-            }

-

-        }

-

-        // Unbind all services

-

-        Iterator it = m_dependencyManagers.iterator();

-

-        while (it.hasNext())

-        {

-            DependencyManager dm = (DependencyManager)it.next();

-            dm.unbindAll();

-        }

-

-        //m_activator.removeInstanceManager(this);

-

-        // remove all instances from a factory

-

-        /*

-        if (m_implementorObject instanceof GenericFactory)

-        {

-            ((GenericFactory)m_implementorObject).invalidateInstances();

-        }

-        */

-

-        // Release the object reference

-

-        m_implementorObject = null;

-

-        GenericActivator.trace("InstanceManager from bundle ["

-           + m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");

-

-        if (m_state != INSTANCE_DESTROYING)

-        {

-            setState(INSTANCE_INVALID);

-        }

-    }

-

-    /**

-     * This method should be called to completely remove the InstanceManager from the system.

-     * This means that the dependency managers will stop listening to events.

-     *

-     * CONCURRENCY NOTE: This method is only called from the GenericActivator, which is

-     *                   essentially application code and not via events.

-    **/

-    synchronized void destroy()

-    {

-        if (m_state == INSTANCE_DESTROYED)

-        {

-            return;

-        }

-

-        // Theoretically this should never be in any state other than VALID or INVALID,

-        // because validate is called right after creation.

-        boolean invalidatefirst = (m_state == INSTANCE_VALID);

-

-        setState(INSTANCE_DESTROYING);

-

-        // Stop the dependency managers to listen to events...

-        Iterator it = m_dependencyManagers.iterator();

-

-        while (it.hasNext())

-        {

-            DependencyManager dm = (DependencyManager)it.next();

-            m_activator.getBundleContext().removeServiceListener(dm);

-        }

-

-        if (invalidatefirst)

-        {

-            invalidate();

-        }

-

-        m_dependencyManagers.clear();

-

-        m_instanceListener = null;

-

-        GenericActivator.trace("InstanceManager from bundle ["

-           + m_activator.getBundleContext().getBundle().getBundleId() + "] was destroyed.");

-

-        m_activator.removeInstanceManager(this);

-        setState(INSTANCE_DESTROYED);

-

-        m_activator = null;

-    }

-

-    /**

-    * Returns the InstanceMetadata

-    */

-    public InstanceMetadata getInstanceMetadata()

-    {

-        return m_instanceMetadata;

-    }

-

-    /**

-    * Get the object that is implementing this descriptor

-    *

-    * @return the object that implements

-    */

-    public Object getObject()

-    {

-        return m_implementorObject;

-    }

-

-    /**

-    * Request the registration of the service provided by this binder instance

-    *

-    * @return returns false if registration was not successful,

-    *                returns true if registration was successful

-    **/

-    boolean requestRegistration()

-    {

-        if (!m_instanceMetadata.instanceRegistersServices())

-        {

-            return true;

-        }

-        else if (m_implementorObject == null)

-        {

-            GenericActivator.error("GenericActivator : Cannot register, implementor object not created!");

-            return false;

-        }

-        else if (m_serviceRegistration != null)

-        {

-            GenericActivator.error("GenericActivator : Cannot register, binder instance already registered :"

-                + m_instanceMetadata.getImplementorName());

-            return true;

-        }

-

-        // Check validity of dependencies before registering !

-        Iterator it = m_dependencyManagers.iterator();

-        while (it.hasNext())

-        {

-            DependencyManager dm = (DependencyManager)it.next();

-            if (dm.isValid() == false)

-                return false;

-        }

-

-        // When registering a factory, add an instanceClass property which is an array

-        // of service interfaces implemented by the objects created by the factory.

-

-        if (m_instanceMetadata.isFactory())

-        {

-            if(m_instanceMetadata.getProperties().get("instanceClass") == null)

-            {

-                m_instanceMetadata.getProperties().put("instanceClass",m_instanceMetadata.getInstantiates().getInterfaces());

-            }

-        }

-

-        m_serviceRegistration = m_activator.getBundleContext().registerService(

-            m_instanceMetadata.getInterfaces(), m_implementorObject, m_instanceMetadata.getProperties());

-

-        GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["

-            + m_activator.getBundleContext().getBundle().getBundleId()

-            + "] successfully registered its services !");

-

-        return true;

-    }

-

-

-    /**

-    *

-    * Request the unfegistration of the service provided by this binder instance

-    *

-    **/

-    void requestUnregistration()

-    {

-        if (m_serviceRegistration != null)

-        {

-            m_serviceRegistration.unregister();

-            m_serviceRegistration = null;

-

-            GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["

-                + m_activator.getBundleContext().getBundle().getBundleId()

-                + "] unregistered its services !");

-

-         }

-    }

-

-    /**

-    * Get the state

-    */

-    public int getState()

-    {

-        return m_state;

-    }

-

-    /**

-    * Get the state

-    */

-    public long getBundleId()

-    {

-        return m_activator.getBundleContext().getBundle().getBundleId();

-    }

-

-    /**

-     * Get a property associated with this instance. For classes

-     * implementing this method, special care must be taken for

-     * values implementing <tt>InstanceReference.ValueHolder</tt>.

-     * In such cases, the value itself should not be returned, but

-     * the value of <tt>InstanceReference.ValueHolder.get()</tt>

-     * should be returned instead. This may be used to defer

-     * creating value objects in cases where creating the value

-     * object is expensive.

-     * @param name the name of the property to retrieve.

-     * @return the value of the associated property or <tt>null</tt>.

-    **/

-    public Object get(String name)

-    {

-        GenericActivator.trace("InstanceManager.get("+name+")");

-

-        if(name.equals(InstanceReference.INSTANCE_STATE))

-        {

-            return new Integer(m_state);

-        }

-        else if(name.equals(InstanceReference.INSTANCE_METADATA))

-        {

-            return getInstanceMetadata();

-        }

-        else if(name.equals(InstanceReference.INSTANCE_BUNDLE))

-        {

-            return new Integer((int) getBundleId());

-        }

-        else if(name.equals(InstanceReference.INSTANCE_DEPENDENCIES))

-        {

-            return getDependencies();

-        }

-        else

-        {

-            Object ret = m_localProperties.get(name);

-

-            if (ret != null)

-            {

-                if (ret instanceof ValueHolder)

-                {

-                    return ((ValueHolder)ret).get(this);

-                }

-                return ret;

-            }

-

-            return m_instanceMetadata.getProperties().get(name);

-        }

-

-    }

-

-    /**

-     * Associate a property with this instance. For classes

-     * implementing this method, special care must be taken for

-     * values implementing <tt>InstanceReference.ValueHolder</tt>.

-     * In such cases, the value itself should not be returned, but

-     * the value of <tt>InstanceReference.ValueHolder.get()</tt>

-     * should be returned instead. This may be used to defer

-     * creating value objects in cases where creating the value

-     * object is expensive.

-     * @param name the name of the property to add.

-     * @param obj the value of the property.

-    **/

-    public void put(String name, Object obj)

-    {

-        m_localProperties.put(name,obj);

-    }

-

-    /**

-     * Adds an instance reference listener to listen for changes to

-     * the availability of the underlying object associated with this

-     * instance reference.

-     * @param l the listener to add.

-    **/

-    public void addInstanceReferenceListener(InstanceReferenceListener l)

-    {

-        m_instanceListener = StateChangeMulticaster.add(m_instanceListener, l);

-    }

-

-    /**

-     * Removes an instance reference listener.

-     * @param l the listener to remove.

-    **/

-    public void removeInstanceReferenceListener(InstanceReferenceListener l)

-    {

-        m_instanceListener = StateChangeMulticaster.remove(m_instanceListener, l);

-    }

-

-    /**

-     * Fires an event when the instance reference has been validated

-    **/

-    protected void fireInstanceReferenceValidated()

-    {

-        try

-        {

-            if (m_instanceListener != null)

-            {

-                m_instanceListener.validated(new InstanceReferenceEvent(this));

-            }

-        }

-        catch(Exception ex)

-        {

-            // Ignore any exception

-        }

-    }

-

-    /**

-     * Fires an event when the instance reference is invalidating

-    **/

-    protected void fireInstanceReferenceInvalidating()

-    {

-        try

-        {

-            if (m_instanceListener != null)

-            {

-                m_instanceListener.invalidating(new InstanceReferenceEvent(this));

-            }

-        }

-        catch(Exception ex)

-        {

-            // Ignore any exception

-        }

-    }

-

-    /**

-     * sets the state of the instanceManager

-    **/

-    synchronized void setState(int newState)

-    {

-        m_state = newState;

-

-        if(m_state == INSTANCE_CREATED || m_state == INSTANCE_VALID || m_state == INSTANCE_INVALID || m_state == INSTANCE_DESTROYED)

-        {

-            m_activator.fireInstanceChangeEvent(new InstanceChangeEvent(this,m_instanceMetadata,m_state));

-        }

-    }

-

-    /**

-     * Get an array of dependencies for this instance. This method is declared

-     * in the Instance interface

-     *

-     * @return an array of Dependencies

-    **/

-    public Dependency [] getDependencies()

-    {

-        Dependency deps [] = new Dependency[m_dependencyManagers.size()];

-        return (Dependency[]) m_dependencyManagers.toArray(deps);

-    }

-

-    /**

-     * Get a list of child instances in case this is a factory

-     *

-     * @return an array of Instances

-    **/

-     public Instance[] getChildInstances()

-    {

-        /*

-        if(m_implementorObject != null && m_implementorObject instanceof GenericFactory)

-        {

-            List instanceRefs = ((GenericFactory)m_implementorObject).getInstanceReferences();

-            Instance [] instances = new Instance[instanceRefs.size()];

-            instances = (Instance [])instanceRefs.toArray(instances);

-            return instances;

-        }

-        */

-        return null;

+    // Properties that can be attached to te InstanceManager
+    private Properties m_localProperties = new Properties();
+    
+    // Flag that indicates that activate was called
+    private boolean m_activateCalled = false;
+
+    /**
+    * Constructor that creates a collection of dependency managers that will be in
+    * charge of the different dependencies for a particular instance.
+    *
+    * @param   activator A reference to the generic activator
+    * @param   descriptor an InstanceMetadata that contains information found in the descriptor file
+    * @throws  java.lang.ClassNotFoundException if the instance class (declared in the descriptor file) is not found
+    * @throws  java.lang.NoSuchMethodException if the bind or unbind methods are not found on the instance class
+    * @throws  org.osgi.framework.InvalidSyntaxException if the filter declared in the requires entry has an invalid syntax
+    **/
+    InstanceManager(GenericActivator activator,InstanceMetadata descriptor)
+        throws ClassNotFoundException, NoSuchMethodException, InvalidSyntaxException
+    {
+        m_activator = activator;
+
+        m_instanceMetadata = descriptor;
+
+        m_dependencyManagers = new ArrayList();
+
+        if (m_instanceMetadata.getDependencies().size() != 0)
+        {
+            Iterator dependencyit = m_instanceMetadata.getDependencies().iterator();
+
+            while(dependencyit.hasNext())
+            {
+                DependencyMetadata currentdependency = (DependencyMetadata)dependencyit.next();
+
+                DependencyManager depmanager = new DependencyManager(currentdependency);
+
+                m_dependencyManagers.add(depmanager);
+
+                // Register the dependency managers as listeners to service events so that they begin
+                // to manage the dependency autonomously
+
+                m_activator.getBundleContext().addServiceListener(depmanager,depmanager.getDependencyMetadata().getFilter());
+            }
+        }
+
+        m_sbcontext = new ServiceBinderContextImpl(this);
+
+        // Add this instance manager to the Generic activator list
+        m_activator.addInstanceManager(this);
+
+        setState(INSTANCE_CREATED);
+    }
+
+    /**
+    * Validate this Instance manager.
+    *
+    * CONCURRENCY NOTE: This method can be called either after an instance manager is created
+    * or after the instance is validated again after by the instance manager itself
+    */
+    synchronized void validate()
+    {
+        if (m_state == INSTANCE_VALID)
+        {
+            return;
+        }
+        else if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED)
+        {
+            GenericActivator.error("InstanceManager : create() called for a non INVALID or CREATED InstanceManager ("+m_states[m_state]+")");
+            return;
+        }
+
+        setState(INSTANCE_VALIDATING);
+
+        // Test if all dependency managers are valid
+
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            // It is not possible to call the isValid method yet in the DependencyManager
+            // since they have not been initialized yet, but we can't call initialize
+            // since the object where bindings will be done has not been created.
+            // This test is necessary, because we don't want to instantiate
+            // the object if the dependency managers won't be valid.
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.getRequiredServiceRefs() == null && dm.getDependencyMetadata().isOptional() == false)
+            {
+                setState(INSTANCE_INVALID);
+                return;
+            }
+        }
+
+        // everything ok to go...
+
+        try
+        {
+            Class c = m_activator.getClass().getClassLoader().loadClass(m_instanceMetadata.getImplementorName());
+            try
+            {
+                Constructor cons = c.getConstructor(new Class[] {ServiceBinderContext.class});
+                m_implementorObject = cons.newInstance(new Object[] {m_sbcontext});
+            }
+            catch(NoSuchMethodException ex)
+            {
+                // Aparently he doesn't want a ServiceBinderContext...
+            }
+
+            // Create from no-param constructor
+            if (m_implementorObject == null)
+            {
+                m_implementorObject = c.newInstance();
+            }
+
+            /* is it a factory?
+            if (m_implementorObject instanceof GenericFactory)
+            {
+                ((GenericFactory) m_implementorObject).setActivator(m_activator, this);
+            }
+            */
+
+            // Allow somebody to proxy the object through the proxyProvidedServiceObject method
+            // in the activator
+            Object proxy = m_activator.proxyProvidedServiceObject(m_implementorObject, this.getInstanceMetadata());
+            if (proxy != null)
+            {
+                m_implementorObject = proxy;
+            }
+            else
+            {
+                GenericActivator.error("InstanceManager : Proxy method returned a null value");
+            }
+        }
+        catch (Throwable t)
+        {
+            // failure at creation
+            GenericActivator.error("InstanceManager : Error during instantiation : "+t);
+            t.printStackTrace();
+            _invalidate();
+            return;
+        }
+        
+        // initial bindings
+
+        it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.initialize() == false)
+            {
+                _invalidate();
+                return;
+            }
+        }
+        
+        // We need to check if we are still validating because it is possible that when we
+        // registered the service above our thread causes an instance to become valid which
+        // then registered a service that then generated an event that we needed that
+        // caused validate() to be called again, thus if we are not still VALIDATING, it
+        // means we are already VALID.
+        if (m_state == INSTANCE_VALIDATING)
+        {
+            // activate
+
+            if (m_implementorObject instanceof Lifecycle)
+            {
+                try
+                {
+                    ((Lifecycle)m_implementorObject).activate();
+                    this.m_activateCalled=true;
+                }
+                catch(Exception e)
+                {
+                    GenericActivator.error("InstanceManager : exception during activate:"+e);
+                    e.printStackTrace();
+                    _invalidate();
+                    return;
+                }
+            }
+
+            // validated!
+
+            fireInstanceReferenceValidated();
+            setState(INSTANCE_VALID);
+        }
+        
+
+        // register services
+
+        boolean reg = requestRegistration();
+
+        if (!reg)
+        {
+            GenericActivator.error("InstanceManager : registration of the services failed...");
+            _invalidate();
+            return;
+        }
+        
+        // Configuration ended successfuly.
+
+    }
+
+    /**
+     * This method invalidates the InstanceManager
+     *
+     * CONCURRENCY NOTE: This method may be called either from application code or event thread.
+    **/
+    synchronized void invalidate()
+    {
+        if (m_state == INSTANCE_INVALID)
+        {
+            return;
+        }
+        else if (m_state != INSTANCE_VALID && m_state != INSTANCE_DESTROYING)
+        {
+            GenericActivator.error("InstanceManager : invalidate() called for a non VALID InstanceManager ("+m_states[m_state]+")");
+            return;
+        }
+
+        if (m_state != INSTANCE_DESTROYING)
+        {
+            setState(INSTANCE_INVALIDATING);
+        }
+
+        // Fire invalidating events
+        fireInstanceReferenceInvalidating();
+
+        _invalidate();
+
+
+    }
+
+    /**
+     * this method invalidates the InstanceManager without performing any of the callbacks
+     * associated with the Lifecycle interface or the InstanceReference event listeners.
+    **/
+    private void _invalidate()
+    {
+        // Unregister services
+
+        requestUnregistration();
+        
+        if(m_activateCalled==true)
+        {        
+            // Call deactivate on the Lifecycle
+
+            if (m_implementorObject instanceof Lifecycle)
+            {
+                try
+                {
+                    ((Lifecycle)m_implementorObject).deactivate();
+                }
+                catch(Exception e)
+                {
+                    GenericActivator.error("InstanceManager : exception during call to deactivate():"+e);
+                }
+            }
+
+        }
+
+        // Unbind all services
+
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            dm.unbindAll();
+        }
+
+        //m_activator.removeInstanceManager(this);
+
+        // remove all instances from a factory
+
+        /*
+        if (m_implementorObject instanceof GenericFactory)
+        {
+            ((GenericFactory)m_implementorObject).invalidateInstances();
+        }
+        */
+
+        // Release the object reference
+
+        m_implementorObject = null;
+
+        GenericActivator.trace("InstanceManager from bundle ["
+           + m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+        if (m_state != INSTANCE_DESTROYING)
+        {
+            setState(INSTANCE_INVALID);
+        }
+    }
+
+    /**
+     * This method should be called to completely remove the InstanceManager from the system.
+     * This means that the dependency managers will stop listening to events.
+     *
+     * CONCURRENCY NOTE: This method is only called from the GenericActivator, which is
+     *                   essentially application code and not via events.
+    **/
+    synchronized void destroy()
+    {
+        if (m_state == INSTANCE_DESTROYED)
+        {
+            return;
+        }
+
+        // Theoretically this should never be in any state other than VALID or INVALID,
+        // because validate is called right after creation.
+        boolean invalidatefirst = (m_state == INSTANCE_VALID);
+
+        setState(INSTANCE_DESTROYING);
+
+        // Stop the dependency managers to listen to events...
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            m_activator.getBundleContext().removeServiceListener(dm);
+        }
+
+        if (invalidatefirst)
+        {
+            invalidate();
+        }
+
+        m_dependencyManagers.clear();
+
+        m_instanceListener = null;
+
+        GenericActivator.trace("InstanceManager from bundle ["
+           + m_activator.getBundleContext().getBundle().getBundleId() + "] was destroyed.");
+
+        m_activator.removeInstanceManager(this);
+        setState(INSTANCE_DESTROYED);
+
+        m_activator = null;
+    }
+
+    /**
+    * Returns the InstanceMetadata
+    */
+    public InstanceMetadata getInstanceMetadata()
+    {
+        return m_instanceMetadata;
+    }
+
+    /**
+    * Get the object that is implementing this descriptor
+    *
+    * @return the object that implements
+    */
+    public Object getObject()
+    {
+        return m_implementorObject;
+    }
+
+    /**
+    * Request the registration of the service provided by this binder instance
+    *
+    * @return returns false if registration was not successful,
+    *                returns true if registration was successful
+    **/
+    boolean requestRegistration()
+    {
+        if (!m_instanceMetadata.instanceRegistersServices())
+        {
+            return true;
+        }
+        else if (m_implementorObject == null)
+        {
+            GenericActivator.error("GenericActivator : Cannot register, implementor object not created!");
+            return false;
+        }
+        else if (m_serviceRegistration != null)
+        {
+            GenericActivator.error("GenericActivator : Cannot register, binder instance already registered :"
+                + m_instanceMetadata.getImplementorName());
+            return true;
+        }
+
+        // Check validity of dependencies before registering !
+        Iterator it = m_dependencyManagers.iterator();
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.isValid() == false)
+                return false;
+        }
+
+        // When registering a factory, add an instanceClass property which is an array
+        // of service interfaces implemented by the objects created by the factory.
+
+        if (m_instanceMetadata.isFactory())
+        {
+            if(m_instanceMetadata.getProperties().get("instanceClass") == null)
+            {
+                m_instanceMetadata.getProperties().put("instanceClass",m_instanceMetadata.getInstantiates().getInterfaces());
+            }
+        }
+
+        m_serviceRegistration = m_activator.getBundleContext().registerService(
+            m_instanceMetadata.getInterfaces(), m_implementorObject, m_instanceMetadata.getProperties());
+
+        GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
+            + m_activator.getBundleContext().getBundle().getBundleId()
+            + "] successfully registered its services !");
+
+        return true;
+    }
+
+
+    /**
+    *
+    * Request the unfegistration of the service provided by this binder instance
+    *
+    **/
+    void requestUnregistration()
+    {
+        if (m_serviceRegistration != null)
+        {
+            m_serviceRegistration.unregister();
+            m_serviceRegistration = null;
+
+            GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
+                + m_activator.getBundleContext().getBundle().getBundleId()
+                + "] unregistered its services !");
+
+         }
+    }
+
+    /**
+    * Get the state
+    */
+    public int getState()
+    {
+        return m_state;
+    }
+
+    /**
+    * Get the state
+    */
+    public long getBundleId()
+    {
+        return m_activator.getBundleContext().getBundle().getBundleId();
+    }
+
+    /**
+     * Get a property associated with this instance. For classes
+     * implementing this method, special care must be taken for
+     * values implementing <tt>InstanceReference.ValueHolder</tt>.
+     * In such cases, the value itself should not be returned, but
+     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
+     * should be returned instead. This may be used to defer
+     * creating value objects in cases where creating the value
+     * object is expensive.
+     * @param name the name of the property to retrieve.
+     * @return the value of the associated property or <tt>null</tt>.
+    **/
+    public Object get(String name)
+    {
+        GenericActivator.trace("InstanceManager.get("+name+")");
+
+        if(name.equals(InstanceReference.INSTANCE_STATE))
+        {
+            return new Integer(m_state);
+        }
+        else if(name.equals(InstanceReference.INSTANCE_METADATA))
+        {
+            return getInstanceMetadata();
+        }
+        else if(name.equals(InstanceReference.INSTANCE_BUNDLE))
+        {
+            return new Integer((int) getBundleId());
+        }
+        else if(name.equals(InstanceReference.INSTANCE_DEPENDENCIES))
+        {
+            return getDependencies();
+        }
+        else
+        {
+            Object ret = m_localProperties.get(name);
+
+            if (ret != null)
+            {
+                if (ret instanceof ValueHolder)
+                {
+                    return ((ValueHolder)ret).get(this);
+                }
+                return ret;
+            }
+
+            return m_instanceMetadata.getProperties().get(name);
+        }
+
+    }
+
+    /**
+     * Associate a property with this instance. For classes
+     * implementing this method, special care must be taken for
+     * values implementing <tt>InstanceReference.ValueHolder</tt>.
+     * In such cases, the value itself should not be returned, but
+     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
+     * should be returned instead. This may be used to defer
+     * creating value objects in cases where creating the value
+     * object is expensive.
+     * @param name the name of the property to add.
+     * @param obj the value of the property.
+    **/
+    public void put(String name, Object obj)
+    {
+        m_localProperties.put(name,obj);
+    }
+
+    /**
+     * Adds an instance reference listener to listen for changes to
+     * the availability of the underlying object associated with this
+     * instance reference.
+     * @param l the listener to add.
+    **/
+    public void addInstanceReferenceListener(InstanceReferenceListener l)
+    {
+        m_instanceListener = StateChangeMulticaster.add(m_instanceListener, l);
+    }
+
+    /**
+     * Removes an instance reference listener.
+     * @param l the listener to remove.
+    **/
+    public void removeInstanceReferenceListener(InstanceReferenceListener l)
+    {
+        m_instanceListener = StateChangeMulticaster.remove(m_instanceListener, l);
+    }
+
+    /**
+     * Fires an event when the instance reference has been validated
+    **/
+    protected void fireInstanceReferenceValidated()
+    {
+        try
+        {
+            if (m_instanceListener != null)
+            {
+                m_instanceListener.validated(new InstanceReferenceEvent(this));
+            }
+        }
+        catch(Exception ex)
+        {
+            // Ignore any exception
+        }
+    }
+
+    /**
+     * Fires an event when the instance reference is invalidating
+    **/
+    protected void fireInstanceReferenceInvalidating()
+    {
+        try
+        {
+            if (m_instanceListener != null)
+            {
+                m_instanceListener.invalidating(new InstanceReferenceEvent(this));
+            }
+        }
+        catch(Exception ex)
+        {
+            // Ignore any exception
+        }
+    }
+
+    /**
+     * sets the state of the instanceManager
+    **/
+    synchronized void setState(int newState)
+    {
+        m_state = newState;
+
+        if(m_state == INSTANCE_CREATED || m_state == INSTANCE_VALID || m_state == INSTANCE_INVALID || m_state == INSTANCE_DESTROYED)
+        {
+            m_activator.fireInstanceChangeEvent(new InstanceChangeEvent(this,m_instanceMetadata,m_state));
+        }
+    }
+
+    /**
+     * Get an array of dependencies for this instance. This method is declared
+     * in the Instance interface
+     *
+     * @return an array of Dependencies
+    **/
+    public Dependency [] getDependencies()
+    {
+        Dependency deps [] = new Dependency[m_dependencyManagers.size()];
+        return (Dependency[]) m_dependencyManagers.toArray(deps);
+    }
+
+    /**
+     * Get a list of child instances in case this is a factory
+     *
+     * @return an array of Instances
+    **/
+     public Instance[] getChildInstances()
+    {
+        /*
+        if(m_implementorObject != null && m_implementorObject instanceof GenericFactory)
+        {
+            List instanceRefs = ((GenericFactory)m_implementorObject).getInstanceReferences();
+            Instance [] instances = new Instance[instanceRefs.size()];
+            instances = (Instance [])instanceRefs.toArray(instances);
+            return instances;
+        }
+        */
+        return null;
     }
 
 /**
- * This class implements the ServiceBinderContext, which cannot be directly
 * implemented by the activator because of the getInstanceReference() method
+ * This class implements the ServiceBinderContext, which cannot be directly * implemented by the activator because of the getInstanceReference() method
  */
-

-    class ServiceBinderContextImpl implements ServiceBinderContext

+
+    class ServiceBinderContextImpl implements ServiceBinderContext
     {
 
         /**
@@ -732,41 +732,41 @@
          */
         private InstanceReference m_parent;
 
-        ServiceBinderContextImpl(InstanceReference parent)

-        {

-            m_parent = parent;

-        }

-

-        /**

-         * Get the bundle context

-        **/

-        public BundleContext getBundleContext()

-        {

-            return m_activator.getBundleContext();

-        }

-

-        /**

-         * Return all of the InstanceReferences created in the same bundle

-        **/

-        public List getInstanceReferences()

-        {

-            return m_activator.getInstanceReferences();

-        }

-

-        /**

-         * Get the parent InstanceReference

-        **/

-        public InstanceReference getInstanceReference()

-        {

-            return m_parent;

-        }

+        ServiceBinderContextImpl(InstanceReference parent)
+        {
+            m_parent = parent;
+        }
+
+        /**
+         * Get the bundle context
+        **/
+        public BundleContext getBundleContext()
+        {
+            return m_activator.getBundleContext();
+        }
+
+        /**
+         * Return all of the InstanceReferences created in the same bundle
+        **/
+        public List getInstanceReferences()
+        {
+            return m_activator.getInstanceReferences();
+        }
+
+        /**
+         * Get the parent InstanceReference
+        **/
+        public InstanceReference getInstanceReference()
+        {
+            return m_parent;
+        }
     }
 
 /**
- * The DependencyManager task is to listen to service events and to call the
 * bind/unbind methods on a given object. It is also responsible for requesting
 * the unregistration of a service in case a dependency is broken.
+ * The DependencyManager task is to listen to service events and to call the * bind/unbind methods on a given object. It is also responsible for requesting * the unregistration of a service in case a dependency is broken.
  */
-

-    class DependencyManager implements ServiceListener, Dependency

+
+    class DependencyManager implements ServiceListener, Dependency
     {
 
         /**
@@ -776,452 +776,452 @@
          */
         private DependencyMetadata m_dependencyMetadata;
 
-        private Map m_boundServices = new HashMap();

-        private Method m_bindMethod;

-        private Method m_unbindMethod;

-        private boolean m_isValid;

-        private int m_depState;

-        private boolean m_receivesRef = false;

-

-        /**

-         * Constructor that receives several parameters.

-         *

-         * @param   dependency  An object that contains data about the dependency

-        **/

-        DependencyManager(DependencyMetadata dependency) throws ClassNotFoundException, NoSuchMethodException

-        {

-            m_dependencyMetadata = dependency;

-            m_isValid = false;

-

-            m_bindMethod = getTargetMethod(m_dependencyMetadata.getBindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());

-            m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());

-

-            setStateDependency(DependencyChangeEvent.DEPENDENCY_CREATED);

-        }

-

-        /**

-         * initializes a dependency. This method binds all of the service occurrences to the instance object

-         *

-         * @return true if the operation was successful, false otherwise

-        **/

-        boolean initialize()

-        {

-            if(getObject() == null)

-            {

-                return false;

-            }

-

-            ServiceReference refs[] = getRequiredServiceRefs();

-

-            if (refs == null && m_dependencyMetadata.isOptional() == false)

-            {

-                m_isValid = false;

-                setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);

-                return m_isValid;

-            }

-

-            m_isValid = true;

-            setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);

-

-            if (refs != null)

-            {

-                int max = 1;

-                boolean retval = true;

-

-                if (m_dependencyMetadata.isMultiple() == true)

-                {

-                    max = refs.length;

-                }

-

-                for (int index = 0; index < max; index++)

-                {

-                    retval = callBindMethod(refs[index]);

-                    if(retval == false && (max == 1))

-                    {

-                        // There was an exception when calling the bind method

-                        GenericActivator.error("Dependency Manager: Possible exception in the bind method during initialize()");

-                        m_isValid = false;

-                        setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);

-                        return m_isValid;

-                    }

-                }

-            }

-

-            return m_isValid;

-        }

-

-        /**

-         * Called upon a service event. This method is responsible for calling the

-         * binding and unbinding methods and also to request the eventual unregistering

-         * of a service when a dependency breaks

-         *

-         * @param evt  The ServiceEvent

-        **/

-        public void serviceChanged(ServiceEvent evt)

-        {

-            synchronized (InstanceManager.this)

-            {

-                // If the object is being created or destroyed, we can safely ignore events.

-                if (m_state == INSTANCE_DESTROYING || m_state == INSTANCE_DESTROYED || m_state == INSTANCE_CREATING || m_state == INSTANCE_CREATED)

-                {

-                    return;

-                }

-

-                // If we are in the process of invalidating, it is not necessary to pass

-                // unregistration events, since we are unbinding everything anyway.

-                else if (m_state == INSTANCE_INVALIDATING && evt.getType() == ServiceEvent.UNREGISTERING)

-                {

-                    return;

-                }

-

-                // We do not have an entry for VALIDATING because it is reentrant.

-

-                // A service is unregistering

-                if (evt.getType() == ServiceEvent.UNREGISTERING)

-                {

-                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)

-                    {

-                        // A static dependency is broken the instance manager will be invalidated

-                        if (m_dependencyMetadata.isStatic())

-                        {

-                            m_isValid = false;

-                            setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);

-                            try

-                            {

-                                GenericActivator.trace("Dependency Manager: Static dependency is broken");

-                                invalidate();

-                                GenericActivator.trace("Dependency Manager: RECREATING");

-                                validate();

-                            }

-                            catch(Exception e)

-                            {

-                                e.printStackTrace();

-                            }

-                        }

-                        // dynamic dependency

-                        else

-                        {

-                            // Release references to the service, call unbinder method

-                            // and eventually request service unregistration

-

-                            callUnbindMethod(evt.getServiceReference());

-

-                            // The only thing we need to do here is check if we can reinitialize

-                            // once the bound services becomes zero. This tries to repair dynamic

-                            // 1..1 or rebind 0..1, since replacement services may be available.

-                            // In the case of aggregates, this will only invalidate them since they

-                            // can't be repaired.

-                            if (m_boundServices.size() == 0)

-                            {

-                                // try to reinitialize

-                                if (!initialize())

-                                {

-                                    if (!m_dependencyMetadata.isOptional())

-                                    {

-                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...");

-                                        invalidate();

-                                        GenericActivator.trace("Dependency Manager: RECREATING");

-                                        validate();

-                                    }

-                                }

-                            }

-                        }

-                    }

-                }

-                // A service is registering.

-                else if (evt.getType() == ServiceEvent.REGISTERED)

-                {

-                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)

-                    {

-                        // This is a duplicate

-                        GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)");

-                    }

-                    else

-                    {

-                        m_isValid = true;

-                        setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);

-

-                        // If the InstanceManager is invalid, a call to validate is made

-                        // which will fix everything.

-                        if (InstanceManager.this.getState() != INSTANCE_VALID)

-                        {

-                            validate();

-                        }

-                        // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N it never

-                        // checks for 1..1 dynamic which is done above by the validate()

-                        else if (!m_dependencyMetadata.isStatic())

-                        {

-                            // For dependency that are aggregates, always bind the service

-                            // Otherwise only bind if bind services is zero, which captures the 0..1 case

-                            if (m_dependencyMetadata.isMultiple() || m_boundServices.size() == 0)

-                            {

-                                callBindMethod(evt.getServiceReference());

-                            }

-                        }

-                    }

-                }

-            }

-        }

-

-        /**

-         * Revoke all bindings. This method cannot throw an exception since it must try

-         * to complete all that it can

-         *

-        **/

-        void unbindAll()

-        {

-            Object []allrefs = m_boundServices.keySet().toArray();

-

-            if (allrefs == null)

-                return;

-

-            for (int i = 0; i < allrefs.length; i++)

-            {

-                callUnbindMethod((ServiceReference)allrefs[i]);

-            }

-        }

-

-        /**

-         * Test if this dependency managed by this object is valid

-        **/

-        boolean isValid()

-        {

-            return m_isValid;

-        }

-

-        /**

-         *

-         * Returns an array containing the service references that are pertinent to the

-         * dependency managed by this object. This method filters out services that

-         * belong to bundles that are being (or are actually) shutdown. This is an issue

-         * since is not clearly specified in the OSGi specification if a getServiceReference

-         * call should return the services that belong to bundles that are stopping.

-         *

-         * @return an array of ServiceReferences valid in the context of this dependency

-        **/

-        ServiceReference [] getRequiredServiceRefs()

-        {

-            try

-            {

-                ArrayList list=new ArrayList();

-                ServiceReference temprefs[] =

-                    m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getServiceName(), m_dependencyMetadata.getFilter());

-

-                if (temprefs == null)

-                {

-                    return null;

-                }

-

-                for (int i = 0; i < temprefs.length; i++)

-                {

-                     if (temprefs[i].getBundle().getState() == Bundle.ACTIVE

-                            || temprefs[i].getBundle().getState() == Bundle.STARTING)

-                     {

-                         list.add(temprefs[i]);

-                     }

-                }

-

-                return (ServiceReference []) list.toArray(new ServiceReference [temprefs.length]);

-

-            }

-            catch (Exception e)

-            {

-                GenericActivator.error("DependencyManager: exception while getting references :"+e);

-                return null;

-            }

-        }

-

-        /**

-         * Gets a target method based on a set of parameters

-         *

-         * @param methodname The name of the method

-         * @param targetClass the class to which the method belongs to

-         * @param paramClass the class of the parameter that is passed to the method

-         * @throws java.lang.ClassNotFoundException if the class was not found

-         * @throws java.lang.NoSuchMethodException if the method was not found

-        **/

-        private Method getTargetMethod(String methodname, String targetClass, String paramClass)

-            throws ClassNotFoundException, NoSuchMethodException

-        {

-            Class targetclass = m_activator.getClass().getClassLoader().loadClass(targetClass);

-

-            Method method = null;

-            

-            try

-            {

-                method = targetclass.getMethod(methodname, 

-                    new Class[]{m_activator.getClass().getClassLoader().loadClass(paramClass)});

-               

-            }

-            catch(NoSuchMethodException ex)

-            {

-                // Test if the bind method receives a ServiceReference as the first parameter

-                

-                method = targetclass.getMethod(methodname, 

-                    new Class[]{ServiceReference.class, m_activator.getClass().getClassLoader().loadClass(paramClass)});

-               

-                m_receivesRef = true;

-            }

-            

-            return method;

-        }

-

-        /**

-         * Call the bind method. In case there is an exception while calling the bind method, the service

-         * is not considered to be bound to the instance object

-         *

-         * @param ref A ServiceReference with the service that will be bound to the instance object

-         * @return true if the call was successful, false otherwise

-        **/

-        boolean callBindMethod(ServiceReference ref)

-        {

-            try

-            {

-                Object requiredService = m_activator.getBundleContext().getService(ref);

-                Object proxy = m_activator.proxyRequiredServiceObject(requiredService,m_dependencyMetadata);

-                

-                if(proxy == null)

-                {

-                    // ignore a null return value from the proxy method

-                    proxy = requiredService;

-                }

-                if(m_receivesRef == false)

-                {

-                    m_bindMethod.invoke(getObject(),new Object[] {proxy});

-                }

-                else

-                {

-                    m_bindMethod.invoke(getObject(),new Object[] {ref,proxy});

-                }

-                m_boundServices.put(ref,proxy);

-                

-                return true;

-            }

-            catch(Exception e)

-            {

-                if(e instanceof InvocationTargetException)

-                {

-                    InvocationTargetException ite = (InvocationTargetException) e;

-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+ite.getTargetException());

-                }

-                else

-                {

-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+e);

-                }

-                e.printStackTrace();

-                return false;

-            }

-        }

-

-        /**

-         * Call the unbind method

-         *

-         * @param ref A service reference corresponding to the service that will be unbound

-        **/

-        void callUnbindMethod(ServiceReference ref)

-        {

-            Object requiredService = m_boundServices.get(ref);

-            if (requiredService == null)

-            {

-                GenericActivator.error("DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!");

-                return;

-            }

-

-            try

-            {

-                if(m_receivesRef == false)

-                {

-                    m_unbindMethod.invoke(getObject(),new Object [] {requiredService});

-                }

-                else

-                {

-                    m_unbindMethod.invoke(getObject(),new Object [] {ref, requiredService});

-                }

-                

-                m_boundServices.remove(ref);

-                m_activator.getBundleContext().ungetService(ref);

-            }

-            catch(Exception e)

-            {

-                if(e instanceof InvocationTargetException)

-                {

-                    InvocationTargetException ite = (InvocationTargetException) e;

-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+ite.getTargetException());

-                }

-                else

-                {

-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+e);

-                }

-                e.printStackTrace();

-            }

-        }

-

-        /**

-         * Return the dependency descriptor

-         *

-         * @return the corresponding dependency descriptor

-        **/

-        public DependencyMetadata getDependencyMetadata()

-        {

-            return m_dependencyMetadata;

-        }

-

-        /**

-         * Fire a state change event.

-         *

-         * @param state the state of the dependency manager

-        **/

-        void setStateDependency(int state)

-        {

-            m_depState = state;

-            m_activator.fireDependencyChangeEvent(new DependencyChangeEvent(this,m_dependencyMetadata,state));

-        }

-

-        /**

-         * Get the state of the dependency.

-         *

-         * @return the state of the dependency manager

-        **/

-        public int getDependencyState()

-        {

-            return m_depState;

-        }

-

-        /**

-         * Get the bound service objects. This method is declared in the Dependency interface

-         * and is used for to get a model.

-         *

-         * @return an array containing the bound service objects

-        **/

-        public Instance[] getBoundInstances()

-        {

-            Object bound[] = m_boundServices.values().toArray();

-

-            ArrayList tempArray = new ArrayList();

-

-            for(int i=0; i<bound.length; i++)

-            {

-                InstanceReference ref = ArchitectureServiceImpl.findInstanceReference(bound[i]);

-                if(ref != null)

-                {

-                    tempArray.add(ref);

-                }

-            }

-

-            Instance instances[]= new Instance[tempArray.size()];

-            instances = (Instance [])tempArray.toArray(instances);

-

-            return instances;

-

-

-        }

+        private Map m_boundServices = new HashMap();
+        private Method m_bindMethod;
+        private Method m_unbindMethod;
+        private boolean m_isValid;
+        private int m_depState;
+        private boolean m_receivesRef = false;
+
+        /**
+         * Constructor that receives several parameters.
+         *
+         * @param   dependency  An object that contains data about the dependency
+        **/
+        DependencyManager(DependencyMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
+        {
+            m_dependencyMetadata = dependency;
+            m_isValid = false;
+
+            m_bindMethod = getTargetMethod(m_dependencyMetadata.getBindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
+            m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
+
+            setStateDependency(DependencyChangeEvent.DEPENDENCY_CREATED);
+        }
+
+        /**
+         * initializes a dependency. This method binds all of the service occurrences to the instance object
+         *
+         * @return true if the operation was successful, false otherwise
+        **/
+        boolean initialize()
+        {
+            if(getObject() == null)
+            {
+                return false;
+            }
+
+            ServiceReference refs[] = getRequiredServiceRefs();
+
+            if (refs == null && m_dependencyMetadata.isOptional() == false)
+            {
+                m_isValid = false;
+                setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                return m_isValid;
+            }
+
+            m_isValid = true;
+            setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
+
+            if (refs != null)
+            {
+                int max = 1;
+                boolean retval = true;
+
+                if (m_dependencyMetadata.isMultiple() == true)
+                {
+                    max = refs.length;
+                }
+
+                for (int index = 0; index < max; index++)
+                {
+                    retval = callBindMethod(refs[index]);
+                    if(retval == false && (max == 1))
+                    {
+                        // There was an exception when calling the bind method
+                        GenericActivator.error("Dependency Manager: Possible exception in the bind method during initialize()");
+                        m_isValid = false;
+                        setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                        return m_isValid;
+                    }
+                }
+            }
+
+            return m_isValid;
+        }
+
+        /**
+         * Called upon a service event. This method is responsible for calling the
+         * binding and unbinding methods and also to request the eventual unregistering
+         * of a service when a dependency breaks
+         *
+         * @param evt  The ServiceEvent
+        **/
+        public void serviceChanged(ServiceEvent evt)
+        {
+            synchronized (InstanceManager.this)
+            {
+                // If the object is being created or destroyed, we can safely ignore events.
+                if (m_state == INSTANCE_DESTROYING || m_state == INSTANCE_DESTROYED || m_state == INSTANCE_CREATING || m_state == INSTANCE_CREATED)
+                {
+                    return;
+                }
+
+                // If we are in the process of invalidating, it is not necessary to pass
+                // unregistration events, since we are unbinding everything anyway.
+                else if (m_state == INSTANCE_INVALIDATING && evt.getType() == ServiceEvent.UNREGISTERING)
+                {
+                    return;
+                }
+
+                // We do not have an entry for VALIDATING because it is reentrant.
+
+                // A service is unregistering
+                if (evt.getType() == ServiceEvent.UNREGISTERING)
+                {
+                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
+                    {
+                        // A static dependency is broken the instance manager will be invalidated
+                        if (m_dependencyMetadata.isStatic())
+                        {
+                            m_isValid = false;
+                            setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                            try
+                            {
+                                GenericActivator.trace("Dependency Manager: Static dependency is broken");
+                                invalidate();
+                                GenericActivator.trace("Dependency Manager: RECREATING");
+                                validate();
+                            }
+                            catch(Exception e)
+                            {
+                                e.printStackTrace();
+                            }
+                        }
+                        // dynamic dependency
+                        else
+                        {
+                            // Release references to the service, call unbinder method
+                            // and eventually request service unregistration
+
+                            callUnbindMethod(evt.getServiceReference());
+
+                            // The only thing we need to do here is check if we can reinitialize
+                            // once the bound services becomes zero. This tries to repair dynamic
+                            // 1..1 or rebind 0..1, since replacement services may be available.
+                            // In the case of aggregates, this will only invalidate them since they
+                            // can't be repaired.
+                            if (m_boundServices.size() == 0)
+                            {
+                                // try to reinitialize
+                                if (!initialize())
+                                {
+                                    if (!m_dependencyMetadata.isOptional())
+                                    {
+                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...");
+                                        invalidate();
+                                        GenericActivator.trace("Dependency Manager: RECREATING");
+                                        validate();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                // A service is registering.
+                else if (evt.getType() == ServiceEvent.REGISTERED)
+                {
+                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
+                    {
+                        // This is a duplicate
+                        GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)");
+                    }
+                    else
+                    {
+                        m_isValid = true;
+                        setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
+
+                        // If the InstanceManager is invalid, a call to validate is made
+                        // which will fix everything.
+                        if (InstanceManager.this.getState() != INSTANCE_VALID)
+                        {
+                            validate();
+                        }
+                        // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N it never
+                        // checks for 1..1 dynamic which is done above by the validate()
+                        else if (!m_dependencyMetadata.isStatic())
+                        {
+                            // For dependency that are aggregates, always bind the service
+                            // Otherwise only bind if bind services is zero, which captures the 0..1 case
+                            if (m_dependencyMetadata.isMultiple() || m_boundServices.size() == 0)
+                            {
+                                callBindMethod(evt.getServiceReference());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Revoke all bindings. This method cannot throw an exception since it must try
+         * to complete all that it can
+         *
+        **/
+        void unbindAll()
+        {
+            Object []allrefs = m_boundServices.keySet().toArray();
+
+            if (allrefs == null)
+                return;
+
+            for (int i = 0; i < allrefs.length; i++)
+            {
+                callUnbindMethod((ServiceReference)allrefs[i]);
+            }
+        }
+
+        /**
+         * Test if this dependency managed by this object is valid
+        **/
+        boolean isValid()
+        {
+            return m_isValid;
+        }
+
+        /**
+         *
+         * Returns an array containing the service references that are pertinent to the
+         * dependency managed by this object. This method filters out services that
+         * belong to bundles that are being (or are actually) shutdown. This is an issue
+         * since is not clearly specified in the OSGi specification if a getServiceReference
+         * call should return the services that belong to bundles that are stopping.
+         *
+         * @return an array of ServiceReferences valid in the context of this dependency
+        **/
+        ServiceReference [] getRequiredServiceRefs()
+        {
+            try
+            {
+                ArrayList list=new ArrayList();
+                ServiceReference temprefs[] =
+                    m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getServiceName(), m_dependencyMetadata.getFilter());
+
+                if (temprefs == null)
+                {
+                    return null;
+                }
+
+                for (int i = 0; i < temprefs.length; i++)
+                {
+                     if (temprefs[i].getBundle().getState() == Bundle.ACTIVE
+                            || temprefs[i].getBundle().getState() == Bundle.STARTING)
+                     {
+                         list.add(temprefs[i]);
+                     }
+                }
+
+                return (ServiceReference []) list.toArray(new ServiceReference [temprefs.length]);
+
+            }
+            catch (Exception e)
+            {
+                GenericActivator.error("DependencyManager: exception while getting references :"+e);
+                return null;
+            }
+        }
+
+        /**
+         * Gets a target method based on a set of parameters
+         *
+         * @param methodname The name of the method
+         * @param targetClass the class to which the method belongs to
+         * @param paramClass the class of the parameter that is passed to the method
+         * @throws java.lang.ClassNotFoundException if the class was not found
+         * @throws java.lang.NoSuchMethodException if the method was not found
+        **/
+        private Method getTargetMethod(String methodname, String targetClass, String paramClass)
+            throws ClassNotFoundException, NoSuchMethodException
+        {
+            Class targetclass = m_activator.getClass().getClassLoader().loadClass(targetClass);
+
+            Method method = null;
+            
+            try
+            {
+                method = targetclass.getMethod(methodname, 
+                    new Class[]{m_activator.getClass().getClassLoader().loadClass(paramClass)});
+               
+            }
+            catch(NoSuchMethodException ex)
+            {
+                // Test if the bind method receives a ServiceReference as the first parameter
+                
+                method = targetclass.getMethod(methodname, 
+                    new Class[]{ServiceReference.class, m_activator.getClass().getClassLoader().loadClass(paramClass)});
+               
+                m_receivesRef = true;
+            }
+            
+            return method;
+        }
+
+        /**
+         * Call the bind method. In case there is an exception while calling the bind method, the service
+         * is not considered to be bound to the instance object
+         *
+         * @param ref A ServiceReference with the service that will be bound to the instance object
+         * @return true if the call was successful, false otherwise
+        **/
+        boolean callBindMethod(ServiceReference ref)
+        {
+            try
+            {
+                Object requiredService = m_activator.getBundleContext().getService(ref);
+                Object proxy = m_activator.proxyRequiredServiceObject(requiredService,m_dependencyMetadata);
+                
+                if(proxy == null)
+                {
+                    // ignore a null return value from the proxy method
+                    proxy = requiredService;
+                }
+                if(m_receivesRef == false)
+                {
+                    m_bindMethod.invoke(getObject(),new Object[] {proxy});
+                }
+                else
+                {
+                    m_bindMethod.invoke(getObject(),new Object[] {ref,proxy});
+                }
+                m_boundServices.put(ref,proxy);
+                
+                return true;
+            }
+            catch(Exception e)
+            {
+                if(e instanceof InvocationTargetException)
+                {
+                    InvocationTargetException ite = (InvocationTargetException) e;
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+ite.getTargetException());
+                }
+                else
+                {
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+e);
+                }
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        /**
+         * Call the unbind method
+         *
+         * @param ref A service reference corresponding to the service that will be unbound
+        **/
+        void callUnbindMethod(ServiceReference ref)
+        {
+            Object requiredService = m_boundServices.get(ref);
+            if (requiredService == null)
+            {
+                GenericActivator.error("DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!");
+                return;
+            }
+
+            try
+            {
+                if(m_receivesRef == false)
+                {
+                    m_unbindMethod.invoke(getObject(),new Object [] {requiredService});
+                }
+                else
+                {
+                    m_unbindMethod.invoke(getObject(),new Object [] {ref, requiredService});
+                }
+                
+                m_boundServices.remove(ref);
+                m_activator.getBundleContext().ungetService(ref);
+            }
+            catch(Exception e)
+            {
+                if(e instanceof InvocationTargetException)
+                {
+                    InvocationTargetException ite = (InvocationTargetException) e;
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+ite.getTargetException());
+                }
+                else
+                {
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+e);
+                }
+                e.printStackTrace();
+            }
+        }
+
+        /**
+         * Return the dependency descriptor
+         *
+         * @return the corresponding dependency descriptor
+        **/
+        public DependencyMetadata getDependencyMetadata()
+        {
+            return m_dependencyMetadata;
+        }
+
+        /**
+         * Fire a state change event.
+         *
+         * @param state the state of the dependency manager
+        **/
+        void setStateDependency(int state)
+        {
+            m_depState = state;
+            m_activator.fireDependencyChangeEvent(new DependencyChangeEvent(this,m_dependencyMetadata,state));
+        }
+
+        /**
+         * Get the state of the dependency.
+         *
+         * @return the state of the dependency manager
+        **/
+        public int getDependencyState()
+        {
+            return m_depState;
+        }
+
+        /**
+         * Get the bound service objects. This method is declared in the Dependency interface
+         * and is used for to get a model.
+         *
+         * @return an array containing the bound service objects
+        **/
+        public Instance[] getBoundInstances()
+        {
+            Object bound[] = m_boundServices.values().toArray();
+
+            ArrayList tempArray = new ArrayList();
+
+            for(int i=0; i<bound.length; i++)
+            {
+                InstanceReference ref = ArchitectureServiceImpl.findInstanceReference(bound[i]);
+                if(ref != null)
+                {
+                    tempArray.add(ref);
+                }
+            }
+
+            Instance instances[]= new Instance[tempArray.size()];
+            instances = (Instance [])tempArray.toArray(instances);
+
+            return instances;
+
+
+        }
     }
 
 /**
- * @version X.XX Feb 3, 2004 
 * @author Humberto Cervantes
+ * @version X.XX Feb 3, 2004  * @author Humberto Cervantes
  */
-

-    static public class StateChangeMulticaster implements InstanceReferenceListener

+
+    static public class StateChangeMulticaster implements InstanceReferenceListener
     {
 
         /**
@@ -1238,43 +1238,43 @@
          */
         protected InstanceReferenceListener b;
 
-        protected StateChangeMulticaster(InstanceReferenceListener a, InstanceReferenceListener b)    

-        {        

-            this.a = a;        

-            this.b = b;    

-        }    

-    

-    

-        public void validated(InstanceReferenceEvent e)    

-        {

-            a.validated(e);        

-            b.validated(e);

-        }

-    

-        public void invalidating(InstanceReferenceEvent e)    

-        {

-            a.invalidating(e);        

-            b.invalidating(e);

-        }

-    

-        public static InstanceReferenceListener add(InstanceReferenceListener a, InstanceReferenceListener b)

-        {

-            if (a == null)

-                return b;

-            else if (b == null)

-                return a;

-            else

-                return new StateChangeMulticaster(a, b);

-        }

-    

-        public static InstanceReferenceListener remove(InstanceReferenceListener a, InstanceReferenceListener b)

-        {

-            if ((a == null) || (a == b))            

-                return null;        

-            else if (a instanceof StateChangeMulticaster)            

-                return add (remove (((StateChangeMulticaster) a).a, b),remove (((StateChangeMulticaster) a).b, b));        

-            else            

-                return a;    

-        }

-    }

-}

+        protected StateChangeMulticaster(InstanceReferenceListener a, InstanceReferenceListener b)    
+        {        
+            this.a = a;        
+            this.b = b;    
+        }    
+    
+    
+        public void validated(InstanceReferenceEvent e)    
+        {
+            a.validated(e);        
+            b.validated(e);
+        }
+    
+        public void invalidating(InstanceReferenceEvent e)    
+        {
+            a.invalidating(e);        
+            b.invalidating(e);
+        }
+    
+        public static InstanceReferenceListener add(InstanceReferenceListener a, InstanceReferenceListener b)
+        {
+            if (a == null)
+                return b;
+            else if (b == null)
+                return a;
+            else
+                return new StateChangeMulticaster(a, b);
+        }
+    
+        public static InstanceReferenceListener remove(InstanceReferenceListener a, InstanceReferenceListener b)
+        {
+            if ((a == null) || (a == b))            
+                return null;        
+            else if (a instanceof StateChangeMulticaster)            
+                return add (remove (((StateChangeMulticaster) a).a, b),remove (((StateChangeMulticaster) a).b, b));        
+            else            
+                return a;    
+        }
+    }
+}
diff --git a/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceMetadata.java b/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceMetadata.java
index b692dff..63f697e 100644
--- a/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceMetadata.java
+++ b/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceMetadata.java
@@ -1,37 +1,37 @@
-/* 

- * 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.servicebinder;

-

-import java.util.Properties;

-import java.util.Collection;

-import java.util.ArrayList;

+/* 
+ * 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.servicebinder;
+
+import java.util.Properties;
+import java.util.Collection;
+import java.util.ArrayList;
 import java.util.Iterator;
 
 /**
- * Description of an instance entry in the descriptor file
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * Description of an instance entry in the descriptor file *  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceMetadata

-{

-    // These properties will be filled by the parser

-    private String m_implementorName;

-    private Collection m_interfaces = null;

-    private Properties m_properties = new Properties();

+public class InstanceMetadata
+{
+    // These properties will be filled by the parser
+    private String m_implementorName;
+    private Collection m_interfaces = null;
+    private Properties m_properties = new Properties();
     private Collection m_dependencies = null;
 
     /**
@@ -48,159 +48,159 @@
      */
     private InstanceMetadata m_parent = null;
 
-    private boolean m_isFactory = false;

-    private boolean m_registersService = false;

-    private boolean m_isInstance = false;

-

-    /**

-     * Constructor

-     *

-     * @param   implementorName name of the class of the implementation object

-     * @param   parent the parent to this service descriptor

-     */

-    InstanceMetadata(String implementorName,InstanceMetadata parent)

-    {

-        m_interfaces = new ArrayList();

-        m_dependencies = new ArrayList();

-

-        m_implementorName = implementorName;

-

-        // The parent will be != null if this descriptor corresponds to an

-        // instantiate entry

-

-        if(parent != null)

-        {

-            m_parent = parent;

-            m_parent.m_instantiates = this;

-            m_parent.m_isFactory = true;

-            m_isInstance = true;

-        }

-    }

-

-    /**

-     * Returns the name of the implementor

-     *

-     * @return the name of the implementor

-     */

-    public String getImplementorName()

-    {

-        return m_implementorName;

-    }

-

-

-    /**

-     * Used to add an interface to the service descriptor

-     *

-     * @param   newInterface name of the interface implemented by the implementation object

-     */

-    void addInterface(String newInterface)

-    {

-        // As soon as there is one interface provided, it cannot be a bundle-to-service.

-        m_registersService = true;

-        m_interfaces.add(newInterface);

-    }

-

-    /**

-     * Returns the implemented interfaces

-     *

-     * @return the implemented interfaces as a string array

-     */

-    public String [] getInterfaces()

-    {

-        String interfaces[] = new String[m_interfaces.size()];

-        Iterator it = m_interfaces.iterator();

-        int count = 0;

-        while (it.hasNext())

-        {

-            interfaces[count++] = it.next().toString();

-        }

-        return interfaces;

-    }

-

-    /**

-     * Used to add a property to the instance

-     *

-     * @param   newProperty a property descriptor

-     */

-    void addProperty(PropertyMetadata newProperty)

-    {

-        String key = newProperty.getName();

-        Object value = newProperty.getValue();

-        if(key != null && value != null)

-        {

-            m_properties.put(key,value);

-        }

-    }

-

-    /**

-     * Returns the property descriptors

-     *

-     * @return the property descriptors as a Collection

-     */

-    public Properties getProperties()

-    {

-        return m_properties;

-    }

-

-    /**

-     * Used to add a dependency descriptor to the service descriptor

-     *

-     * @param newDependency a new dependency to be added

-     */

-    void addDependency(DependencyMetadata newDependency)

-    {

-        m_dependencies.add(newDependency);

-    }

-

-

-    /**

-     * Returns the dependency descriptors

-     *

-     * @return a Collection of dependency descriptors

-     */

-    public Collection getDependencies()

-    {

-        return m_dependencies;

-    }

-

-    /**

-     * Test to see if this service is a factory

-     *

-     * @return true if it is a factory, false otherwise

-     */

-    public boolean isFactory()

-    {

-        return m_isFactory;

-    }

-

-     /**

-     * Get the meta data of the instances

-     *

-     * @return the instance metadata

-     */

-    public InstanceMetadata getInstantiates()

-    {

-        return m_instantiates;

-    }

-

-     /**

-     * Test to see if this descriptor describes a bundle-to-service dependency

-     * that means that the instance does not register any services.

-     *

-     * @return true if the dependency is bundle-to-service

-     */

-    public boolean instanceRegistersServices()

-    {

-        return m_registersService;

-    }

-

-     /**

-     * Test to see if this descriptor is registered from an instance from a factory.

-     *

-     * @return true if this descriptor is registered from an instance from a factory.

-     */

-    public boolean isInstance()

-    {

-        return m_isInstance;

-    }

-}

+    private boolean m_isFactory = false;
+    private boolean m_registersService = false;
+    private boolean m_isInstance = false;
+
+    /**
+     * Constructor
+     *
+     * @param   implementorName name of the class of the implementation object
+     * @param   parent the parent to this service descriptor
+     */
+    InstanceMetadata(String implementorName,InstanceMetadata parent)
+    {
+        m_interfaces = new ArrayList();
+        m_dependencies = new ArrayList();
+
+        m_implementorName = implementorName;
+
+        // The parent will be != null if this descriptor corresponds to an
+        // instantiate entry
+
+        if(parent != null)
+        {
+            m_parent = parent;
+            m_parent.m_instantiates = this;
+            m_parent.m_isFactory = true;
+            m_isInstance = true;
+        }
+    }
+
+    /**
+     * Returns the name of the implementor
+     *
+     * @return the name of the implementor
+     */
+    public String getImplementorName()
+    {
+        return m_implementorName;
+    }
+
+
+    /**
+     * Used to add an interface to the service descriptor
+     *
+     * @param   newInterface name of the interface implemented by the implementation object
+     */
+    void addInterface(String newInterface)
+    {
+        // As soon as there is one interface provided, it cannot be a bundle-to-service.
+        m_registersService = true;
+        m_interfaces.add(newInterface);
+    }
+
+    /**
+     * Returns the implemented interfaces
+     *
+     * @return the implemented interfaces as a string array
+     */
+    public String [] getInterfaces()
+    {
+        String interfaces[] = new String[m_interfaces.size()];
+        Iterator it = m_interfaces.iterator();
+        int count = 0;
+        while (it.hasNext())
+        {
+            interfaces[count++] = it.next().toString();
+        }
+        return interfaces;
+    }
+
+    /**
+     * Used to add a property to the instance
+     *
+     * @param   newProperty a property descriptor
+     */
+    void addProperty(PropertyMetadata newProperty)
+    {
+        String key = newProperty.getName();
+        Object value = newProperty.getValue();
+        if(key != null && value != null)
+        {
+            m_properties.put(key,value);
+        }
+    }
+
+    /**
+     * Returns the property descriptors
+     *
+     * @return the property descriptors as a Collection
+     */
+    public Properties getProperties()
+    {
+        return m_properties;
+    }
+
+    /**
+     * Used to add a dependency descriptor to the service descriptor
+     *
+     * @param newDependency a new dependency to be added
+     */
+    void addDependency(DependencyMetadata newDependency)
+    {
+        m_dependencies.add(newDependency);
+    }
+
+
+    /**
+     * Returns the dependency descriptors
+     *
+     * @return a Collection of dependency descriptors
+     */
+    public Collection getDependencies()
+    {
+        return m_dependencies;
+    }
+
+    /**
+     * Test to see if this service is a factory
+     *
+     * @return true if it is a factory, false otherwise
+     */
+    public boolean isFactory()
+    {
+        return m_isFactory;
+    }
+
+     /**
+     * Get the meta data of the instances
+     *
+     * @return the instance metadata
+     */
+    public InstanceMetadata getInstantiates()
+    {
+        return m_instantiates;
+    }
+
+     /**
+     * Test to see if this descriptor describes a bundle-to-service dependency
+     * that means that the instance does not register any services.
+     *
+     * @return true if the dependency is bundle-to-service
+     */
+    public boolean instanceRegistersServices()
+    {
+        return m_registersService;
+    }
+
+     /**
+     * Test to see if this descriptor is registered from an instance from a factory.
+     *
+     * @return true if this descriptor is registered from an instance from a factory.
+     */
+    public boolean isInstance()
+    {
+        return m_isInstance;
+    }
+}
diff --git a/servicebinder/src/main/java/org/apache/felix/servicebinder/PropertyMetadata.java b/servicebinder/src/main/java/org/apache/felix/servicebinder/PropertyMetadata.java
index aaefc81..ef3d671 100644
--- a/servicebinder/src/main/java/org/apache/felix/servicebinder/PropertyMetadata.java
+++ b/servicebinder/src/main/java/org/apache/felix/servicebinder/PropertyMetadata.java
@@ -1,85 +1,85 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.servicebinder;

-

-/**

- * A property descriptor that contains the information for properties

- * defined in the meta-data file.

- *

- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

- */

-public class PropertyMetadata

-{

-	String name;

-	String type;

-	Object value;

-

-	/**

-	 * Create a PropertyMetadata object

-	 *

-	 * @param   name the name of the property

-	 * @param   type the type of the property (string, boolean, byte, char, short, int, long, float or double)

-	 * @param   val the value of the property

-	 */

-	public PropertyMetadata(String name, String type, String val)

-	{

-		this.name = name;

-		type.toLowerCase();

-		this.type = type;

-		value = null;

-

-		if(type.equals("string") || type.equals("String"))

-        {

-			value = new String(val);

-        }

-		else if(type.equals("boolean"))

-        {

-			value = new Boolean(val);

-        }

-		else if(type.equals("byte"))

-        {

-			value = new Byte(val);

-        }

-		else if(type.equals("char"))

-        {

-			value = new Byte(val);

-        }

-		else if(type.equals("short"))

-        {

-			value = new Short(val);

-        }

-		else if(type.equals("int"))

-        {

-			value = new Integer(val);

-        }

-		else if(type.equals("long"))

-        {

-			value = new Long(val);

-        }

-		else if(type.equals("float"))

-        {

-			value = new Float(val);

-        }

-		else if(type.equals("double"))

-        {

-			value = new Double(val);

-        }

+/* 
+ * 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.servicebinder;
+
+/**
+ * A property descriptor that contains the information for properties
+ * defined in the meta-data file.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PropertyMetadata
+{
+	String name;
+	String type;
+	Object value;
+
+	/**
+	 * Create a PropertyMetadata object
+	 *
+	 * @param   name the name of the property
+	 * @param   type the type of the property (string, boolean, byte, char, short, int, long, float or double)
+	 * @param   val the value of the property
+	 */
+	public PropertyMetadata(String name, String type, String val)
+	{
+		this.name = name;
+		type.toLowerCase();
+		this.type = type;
+		value = null;
+
+		if(type.equals("string") || type.equals("String"))
+        {
+			value = new String(val);
+        }
+		else if(type.equals("boolean"))
+        {
+			value = new Boolean(val);
+        }
+		else if(type.equals("byte"))
+        {
+			value = new Byte(val);
+        }
+		else if(type.equals("char"))
+        {
+			value = new Byte(val);
+        }
+		else if(type.equals("short"))
+        {
+			value = new Short(val);
+        }
+		else if(type.equals("int"))
+        {
+			value = new Integer(val);
+        }
+		else if(type.equals("long"))
+        {
+			value = new Long(val);
+        }
+		else if(type.equals("float"))
+        {
+			value = new Float(val);
+        }
+		else if(type.equals("double"))
+        {
+			value = new Double(val);
+        }
 	}
 
     /**
@@ -114,4 +114,4 @@
     public Object getValue() {
         return value;
     }
-}

+}