diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 8e334ec..98a8282 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -175,7 +175,7 @@
         // the result is the same as if the calling thread had
         // won the race condition.
 
-        return m_felix.getBundle(id);
+        return m_felix.getBundle(this, id);
     }
 
     public Bundle getBundle(String location)
@@ -199,7 +199,7 @@
         // the result is the same as if the calling thread had
         // won the race condition.
 
-        return m_felix.getBundles();
+        return m_felix.getBundles(this);
     }
 
     public void addBundleListener(BundleListener l)
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index 9ee7f28..65321a3 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -1496,6 +1496,7 @@
                                 {
                                     try
                                     {
+// TODO: OSGi R4.3 - Need to call all hooks in privileged block.
                                         wh.weave(wci);
                                     }
                                     catch (Throwable th)
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index a5e5423..071818b 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -62,8 +62,6 @@
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.hooks.service.FindHook;
-import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.framework.startlevel.FrameworkStartLevel;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
@@ -2622,7 +2620,7 @@
         Bundle origin, long id, String location, BundleArchive ba, InputStream is)
         throws BundleException
     {
-        BundleImpl bundle = null;
+        BundleImpl existing, bundle = null;
 
         // Acquire an install lock.
         acquireInstallLock(location);
@@ -2638,169 +2636,167 @@
 
             // If bundle location is already installed, then
             // return it as required by the OSGi specification.
-            bundle = (BundleImpl) getBundle(location);
-            if (bundle != null)
+            existing = (BundleImpl) getBundle(location);
+            if (existing == null)
             {
-                return bundle;
-            }
+                // Determine if this is a new or existing bundle.
+                boolean isNew = (ba == null);
 
-            // Determine if this is a new or existing bundle.
-            boolean isNew = (ba == null);
+                // If the bundle is new we must cache its JAR file.
+                if (isNew)
+                {
+                    // First generate an identifier for it.
+                    id = getNextId();
 
-            // If the bundle is new we must cache its JAR file.
-            if (isNew)
-            {
-                // First generate an identifier for it.
-                id = getNextId();
-
-                try
-                {
-                    // Add the bundle to the cache.
-                    ba = m_cache.create(id, getInitialBundleStartLevel(), location, is);
-                }
-                catch (Exception ex)
-                {
-                    throw new BundleException(
-                        "Unable to cache bundle: " + location, ex);
-                }
-                finally
-                {
                     try
                     {
-                        if (is != null) is.close();
+                        // Add the bundle to the cache.
+                        ba = m_cache.create(id, getInitialBundleStartLevel(), location, is);
                     }
-                    catch (IOException ex)
+                    catch (Exception ex)
+                    {
+                        throw new BundleException(
+                            "Unable to cache bundle: " + location, ex);
+                    }
+                    finally
+                    {
+                        try
+                        {
+                            if (is != null) is.close();
+                        }
+                        catch (IOException ex)
+                        {
+                            m_logger.log(
+                                Logger.LOG_ERROR,
+                                "Unable to close input stream.", ex);
+                        }
+                    }
+                }
+                else
+                {
+                    // If the bundle we are installing is not new,
+                    // then try to purge old revisions before installing
+                    // it; this is done just in case a "refresh"
+                    // didn't occur last session...this would only be
+                    // due to an error or system crash.
+                    try
+                    {
+                        if (ba.isRemovalPending())
+                        {
+                            ba.purge();
+                        }
+                    }
+                    catch (Exception ex)
                     {
                         m_logger.log(
                             Logger.LOG_ERROR,
-                            "Unable to close input stream.", ex);
+                            "Could not purge bundle.", ex);
                     }
                 }
-            }
-            else
-            {
-                // If the bundle we are installing is not new,
-                // then try to purge old revisions before installing
-                // it; this is done just in case a "refresh"
-                // didn't occur last session...this would only be
-                // due to an error or system crash.
+
                 try
                 {
-                    if (ba.isRemovalPending())
+                    // Acquire the global lock to create the bundle,
+                    // since this impacts the global state.
+                    boolean locked = acquireGlobalLock();
+                    if (!locked)
                     {
-                        ba.purge();
+                        throw new BundleException(
+                            "Unable to acquire the global lock to install the bundle.");
+                    }
+                    try
+                    {
+                        bundle = new BundleImpl(this, ba);
+                    }
+                    finally
+                    {
+                        // Always release the global lock.
+                        releaseGlobalLock();
+                    }
+
+                    if (!bundle.isExtension())
+                    {
+                        Object sm = System.getSecurityManager();
+                        if (sm != null)
+                        {
+                            ((SecurityManager) sm).checkPermission(
+                                new AdminPermission(bundle, AdminPermission.LIFECYCLE));
+                        }
+                    }
+                    else
+                    {
+                        m_extensionManager.addExtensionBundle(this, bundle);
+                        m_resolver.addRevision(m_extensionManager.getRevision());
                     }
                 }
-                catch (Exception ex)
+                catch (Throwable ex)
                 {
-                    m_logger.log(
-                        Logger.LOG_ERROR,
-                        "Could not purge bundle.", ex);
+                    // If the bundle is new, then remove it from the cache.
+                    // TODO: FRAMEWORK - Perhaps it should be removed if it is not new too.
+                    if (isNew)
+                    {
+                        try
+                        {
+                            if (bundle != null)
+                            {
+                                bundle.closeAndDelete();
+                            }
+                            else if (ba != null)
+                            {
+                                ba.closeAndDelete();
+                            }
+                        }
+                        catch (Exception ex1)
+                        {
+                            m_logger.log(bundle,
+                                Logger.LOG_ERROR,
+                                "Could not remove from cache.", ex1);
+                        }
+                    }
+                    if (ex instanceof BundleException)
+                    {
+                        throw (BundleException) ex;
+                    }
+                    else if (ex instanceof AccessControlException)
+                    {
+                        throw (AccessControlException) ex;
+                    }
+                    else
+                    {
+                        throw new BundleException("Could not create bundle object.", ex);
+                    }
                 }
-            }
 
-            try
-            {
-                // Acquire the global lock to create the bundle,
-                // since this impacts the global state.
+                // Acquire global lock.
                 boolean locked = acquireGlobalLock();
                 if (!locked)
                 {
-                    throw new BundleException(
-                        "Unable to acquire the global lock to install the bundle.");
+                    // If the calling thread holds bundle locks, then we might not
+                    // be able to get the global lock.
+                    throw new IllegalStateException(
+                        "Unable to acquire global lock to add bundle.");
                 }
                 try
                 {
-                    bundle = new BundleImpl(this, ba);
+                    // Use a copy-on-write approach to add the bundle
+                    // to the installed maps.
+                    Map[] maps = new Map[] {
+                        new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]),
+                        new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX])
+                    };
+                    maps[LOCATION_MAP_IDX].put(location, bundle);
+                    maps[IDENTIFIER_MAP_IDX].put(new Long(bundle.getBundleId()), bundle);
+                    m_installedBundles = maps;
                 }
                 finally
                 {
-                    // Always release the global lock.
                     releaseGlobalLock();
                 }
 
-                if (!bundle.isExtension())
+                if (bundle.isExtension())
                 {
-                    Object sm = System.getSecurityManager();
-                    if (sm != null)
-                    {
-                        ((SecurityManager) sm).checkPermission(
-                            new AdminPermission(bundle, AdminPermission.LIFECYCLE));
-                    }
+                    m_extensionManager.startExtensionBundle(this, bundle);
                 }
-                else
-                {
-                    m_extensionManager.addExtensionBundle(this, bundle);
-                    m_resolver.addRevision(m_extensionManager.getRevision());
-                }
-            }
-            catch (Throwable ex)
-            {
-                // If the bundle is new, then remove it from the cache.
-                // TODO: FRAMEWORK - Perhaps it should be removed if it is not new too.
-                if (isNew)
-                {
-                    try
-                    {
-                        if (bundle != null)
-                        {
-                            bundle.closeAndDelete();
-                        }
-                        else if (ba != null)
-                        {
-                            ba.closeAndDelete();
-                        }
-                    }
-                    catch (Exception ex1)
-                    {
-                        m_logger.log(bundle,
-                            Logger.LOG_ERROR,
-                            "Could not remove from cache.", ex1);
-                    }
-                }
-                if (ex instanceof BundleException)
-                {
-                    throw (BundleException) ex;
-                }
-                else if (ex instanceof AccessControlException)
-                {
-                    throw (AccessControlException) ex;
-                }
-                else
-                {
-                    throw new BundleException("Could not create bundle object.", ex);
-                }
-            }
-
-            // Acquire global lock.
-            boolean locked = acquireGlobalLock();
-            if (!locked)
-            {
-                // If the calling thread holds bundle locks, then we might not
-                // be able to get the global lock.
-                throw new IllegalStateException(
-                    "Unable to acquire global lock to add bundle.");
-            }
-            try
-            {
-                // Use a copy-on-write approach to add the bundle
-                // to the installed maps.
-                Map[] maps = new Map[] {
-                    new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]),
-                    new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX])
-                };
-                maps[LOCATION_MAP_IDX].put(location, bundle);
-                maps[IDENTIFIER_MAP_IDX].put(new Long(bundle.getBundleId()), bundle);
-                m_installedBundles = maps;
-            }
-            finally
-            {
-                releaseGlobalLock();
-            }
-
-            if (bundle.isExtension())
-            {
-                m_extensionManager.startExtensionBundle(this, bundle);
             }
         }
         finally
@@ -2822,11 +2818,52 @@
             }
         }
 
-        // Fire bundle event.
-        fireBundleEvent(BundleEvent.INSTALLED, bundle, origin);
+        if (existing != null)
+        {
+            Set<ServiceReference<org.osgi.framework.hooks.bundle.FindHook>> hooks =
+                getHooks(org.osgi.framework.hooks.bundle.FindHook.class);
+            if (!hooks.isEmpty())
+            {
+                Collection<Bundle> bundles = new ArrayList<Bundle>(1);
+                bundles.add(existing);
+                bundles = new ShrinkableCollection<Bundle>(bundles);
+                for (ServiceReference<org.osgi.framework.hooks.bundle.FindHook> hook : hooks)
+                {
+                    org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
+                    if (fh != null)
+                    {
+// TODO: OSGi R4.3 - Call all hooks in privileged block.
+                        try
+                        {
+                            fh.find(origin.getBundleContext(), bundles);
+                        }
+                        catch (Throwable th)
+                        {
+                            m_logger.doLog(
+                                hook.getBundle(),
+                                hook,
+                                Logger.LOG_WARNING,
+                                "Problem invoking bundle hook.",
+                                th);
+                        }
+                    }
+                }
+                if (bundles.isEmpty())
+                {
+                    throw new BundleException(
+                        "Bundle installation rejected by hook.",
+                        BundleException.REJECTED_BY_HOOK);
+                }
+            }
+        }
+        else
+        {
+            // Fire bundle event.
+            fireBundleEvent(BundleEvent.INSTALLED, bundle, origin);
+        }
 
         // Return new bundle.
-        return bundle;
+        return (existing != null) ? existing : bundle;
     }
 
     /**
@@ -2849,6 +2886,64 @@
      * @return The bundle associated with the identifier or null if there
      *         is no bundle associated with the identifier.
     **/
+    Bundle getBundle(BundleContext bc, long id)
+    {
+        BundleImpl bundle = (BundleImpl)
+            m_installedBundles[IDENTIFIER_MAP_IDX].get(new Long(id));
+        if (bundle != null)
+        {
+            List<BundleImpl> uninstalledBundles = m_uninstalledBundles;
+            for (int i = 0;
+                (bundle == null)
+                    && (uninstalledBundles != null)
+                    && (i < uninstalledBundles.size());
+                i++)
+            {
+                if (uninstalledBundles.get(i).getBundleId() == id)
+                {
+                    bundle = uninstalledBundles.get(i);
+                }
+            }
+        }
+
+        Set<ServiceReference<org.osgi.framework.hooks.bundle.FindHook>> hooks =
+            getHooks(org.osgi.framework.hooks.bundle.FindHook.class);
+        if (!hooks.isEmpty() && (bundle != null))
+        {
+            Collection<Bundle> bundles = new ArrayList<Bundle>(1);
+            bundles.add(bundle);
+            bundles = new ShrinkableCollection<Bundle>(bundles);
+            for (ServiceReference<org.osgi.framework.hooks.bundle.FindHook> hook : hooks)
+            {
+                org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
+                if (fh != null)
+                {
+// TODO: OSGi R4.3 - Call all hooks in privileged block.
+                    try
+                    {
+                        fh.find(bc, bundles);
+                    }
+                    catch (Throwable th)
+                    {
+                        m_logger.doLog(
+                            hook.getBundle(),
+                            hook,
+                            Logger.LOG_WARNING,
+                            "Problem invoking bundle hook.",
+                            th);
+                    }
+                }
+            }
+            bundle = (bundles.isEmpty()) ? null : bundle;
+        }
+        return bundle;
+    }
+
+    /**
+     * Retrieves a bundle by its identifier and avoids bundles hooks.
+     *
+     * @return The bundle associated with the identifier or null.
+    **/
     Bundle getBundle(long id)
     {
         BundleImpl bundle = (BundleImpl)
@@ -2879,14 +2974,49 @@
      * @return An array containing all installed bundles or null if
      *         there are no installed bundles.
     **/
+    Bundle[] getBundles(BundleContext bc)
+    {
+        Collection<Bundle> bundles = m_installedBundles[IDENTIFIER_MAP_IDX].values();
+        Set<ServiceReference<org.osgi.framework.hooks.bundle.FindHook>> hooks =
+            getHooks(org.osgi.framework.hooks.bundle.FindHook.class);
+        if (!hooks.isEmpty())
+        {
+            bundles = new ShrinkableCollection<Bundle>(new ArrayList(bundles));
+            for (ServiceReference<org.osgi.framework.hooks.bundle.FindHook> hook : hooks)
+            {
+                org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
+                if (fh != null)
+                {
+// TODO: OSGi R4.3 - Call all hooks in privileged block.
+                    try
+                    {
+                        fh.find(bc, bundles);
+                    }
+                    catch (Throwable th)
+                    {
+                        m_logger.doLog(
+                            hook.getBundle(),
+                            hook,
+                            Logger.LOG_WARNING,
+                            "Problem invoking bundle hook.",
+                            th);
+                    }
+                }
+            }
+        }
+        return (Bundle[]) bundles.toArray(new Bundle[bundles.size()]);
+    }
+
+    /**
+     * Retrieves all installed bundles and avoids bundles hooks.
+     *
+     * @return An array containing all installed bundles or null if
+     *         there are no installed bundles.
+    **/
     Bundle[] getBundles()
     {
-        Map bundles = m_installedBundles[IDENTIFIER_MAP_IDX];
-        if (bundles.isEmpty())
-        {
-            return null;
-        }
-        return (Bundle[]) bundles.values().toArray(new Bundle[bundles.size()]);
+        Collection<Bundle> bundles = m_installedBundles[IDENTIFIER_MAP_IDX].values();
+        return (Bundle[]) bundles.toArray(new Bundle[bundles.size()]);
     }
 
     void addBundleListener(BundleImpl bundle, BundleListener l)
@@ -2954,16 +3084,16 @@
         }
 
         // Invoke ListenerHook.removed() if filter updated.
-        Set<ServiceReference<ListenerHook>> listenerHooks =
-            m_registry.getHooks(ListenerHook.class);
+        Set<ServiceReference<org.osgi.framework.hooks.service.ListenerHook>> listenerHooks =
+            m_registry.getHooks(org.osgi.framework.hooks.service.ListenerHook.class);
         if (oldFilter != null)
         {
             final Collection removed = Collections.singleton(
                 new ListenerHookInfoImpl(
                 ((BundleImpl) bundle)._getBundleContext(), l, oldFilter.toString(), true));
-            for (ServiceReference<ListenerHook> sr : listenerHooks)
+            for (ServiceReference<org.osgi.framework.hooks.service.ListenerHook> sr : listenerHooks)
             {
-                ListenerHook lh = m_registry.getServiceSafely(this, sr);
+                org.osgi.framework.hooks.service.ListenerHook lh = getService(this, sr);
                 if (lh != null)
                 {
                     try
@@ -2986,9 +3116,9 @@
         // Invoke the ListenerHook.added() on all hooks.
         final Collection added = Collections.singleton(
             new ListenerHookInfoImpl(((BundleImpl) bundle)._getBundleContext(), l, f, false));
-        for (ServiceReference<ListenerHook> sr : listenerHooks)
+        for (ServiceReference<org.osgi.framework.hooks.service.ListenerHook> sr : listenerHooks)
         {
-            ListenerHook lh = m_registry.getServiceSafely(this, sr);
+            org.osgi.framework.hooks.service.ListenerHook lh = getService(this, sr);
             if (lh != null)
             {
                 try
@@ -3017,18 +3147,18 @@
     **/
     void removeServiceListener(BundleImpl bundle, ServiceListener l)
     {
-        ListenerHook.ListenerInfo listener =
+        org.osgi.framework.hooks.service.ListenerHook.ListenerInfo listener =
             m_dispatcher.removeListener(bundle, ServiceListener.class, l);
 
         if (listener != null)
         {
             // Invoke the ListenerHook.removed() on all hooks.
-            Set<ServiceReference<ListenerHook>> listenerHooks =
-                m_registry.getHooks(ListenerHook.class);
+            Set<ServiceReference<org.osgi.framework.hooks.service.ListenerHook>> listenerHooks =
+                m_registry.getHooks(org.osgi.framework.hooks.service.ListenerHook.class);
             Collection removed = Collections.singleton(listener);
-            for (ServiceReference<ListenerHook> sr : listenerHooks)
+            for (ServiceReference<org.osgi.framework.hooks.service.ListenerHook> sr : listenerHooks)
             {
-                ListenerHook lh = m_registry.getServiceSafely(this, sr);
+                org.osgi.framework.hooks.service.ListenerHook lh = getService(this, sr);
                 if (lh != null)
                 {
                     try
@@ -3147,9 +3277,12 @@
 
         // Check to see if this a listener hook; if so, then we need
         // to invoke the callback with all existing service listeners.
-        if (ServiceRegistry.isHook(classNames, ListenerHook.class, svcObj))
+        if (ServiceRegistry.isHook(
+            classNames, org.osgi.framework.hooks.service.ListenerHook.class, svcObj))
         {
-            ListenerHook lh = (ListenerHook) m_registry.getServiceSafely(this, reg.getReference());
+            org.osgi.framework.hooks.service.ListenerHook lh =
+                (org.osgi.framework.hooks.service.ListenerHook)
+                    getService(this, reg.getReference());
             if (lh != null)
             {
                 try
@@ -3228,11 +3361,11 @@
         }
 
         // activate findhooks
-        Set<ServiceReference<FindHook>> findHooks =
-            m_registry.getHooks(FindHook.class);
-        for (ServiceReference<FindHook> sr : findHooks)
+        Set<ServiceReference<org.osgi.framework.hooks.service.FindHook>> findHooks =
+            m_registry.getHooks(org.osgi.framework.hooks.service.FindHook.class);
+        for (ServiceReference<org.osgi.framework.hooks.service.FindHook> sr : findHooks)
         {
-            FindHook fh = m_registry.getServiceSafely(this, sr);
+            org.osgi.framework.hooks.service.FindHook fh = getService(this, sr);
             if (fh != null)
             {
                 try
@@ -4156,12 +4289,12 @@
     **/
     void fireBundleEvent(int type, Bundle bundle)
     {
-        m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle));
+        m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle), this);
     }
 
     void fireBundleEvent(int type, Bundle bundle, Bundle origin)
     {
-        m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle, origin));
+        m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle, origin), this);
     }
 
     /**
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index 8afa535..91436c0 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -18,18 +18,18 @@
  */
 package org.apache.felix.framework;
 
-import java.net.ContentHandler;
 import java.util.*;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-
-import org.osgi.framework.*;
-import org.osgi.framework.hooks.resolver.ResolverHookFactory;
-import org.osgi.framework.hooks.service.*;
-import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.service.url.URLStreamHandlerService;
 
 public class ServiceRegistry
 {
@@ -53,13 +53,15 @@
         new WeakHashMap<ServiceReference, ServiceReference>();
 
     private final static Class<?>[] m_hookClasses = {
-        EventHook.class,
-        FindHook.class,
-        ListenerHook.class,
-        WeavingHook.class,
-        ResolverHookFactory.class,
-        URLStreamHandlerService.class,
-        ContentHandler.class
+        org.osgi.framework.hooks.bundle.FindHook.class,
+        org.osgi.framework.hooks.bundle.EventHook.class,
+        org.osgi.framework.hooks.service.EventHook.class,
+        org.osgi.framework.hooks.service.FindHook.class,
+        org.osgi.framework.hooks.service.ListenerHook.class,
+        org.osgi.framework.hooks.weaving.WeavingHook.class,
+        org.osgi.framework.hooks.resolver.ResolverHookFactory.class,
+        org.osgi.service.url.URLStreamHandlerService.class,
+        java.net.ContentHandler.class
     };
     private final Map<Class<?>, Set<ServiceReference<?>>> m_allHooks =
         new HashMap<Class<?>, Set<ServiceReference<?>>>();
@@ -243,19 +245,6 @@
         return null;
     }
 
-    public <S> S getServiceSafely(Bundle bundle, ServiceReference<S> ref)
-    {
-        try
-        {
-            return getService(bundle, ref);
-        }
-        catch (ServiceException ex)
-        {
-            // Just ignore and return null.
-        }
-        return null;
-    }
-
     public <S> S getService(Bundle bundle, ServiceReference<S> ref)
     {
         UsageCount usage = null;
diff --git a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index a8c3a5f..9d7f9a5 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -22,9 +22,11 @@
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.EventListener;
 import java.util.EventObject;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -45,7 +47,6 @@
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.SynchronousBundleListener;
-import org.osgi.framework.hooks.service.EventHook;
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.framework.launch.Framework;
 
@@ -56,18 +57,15 @@
     static final int LISTENER_OBJECT_OFFSET = 2;
     static final int LISTENER_FILTER_OFFSET = 3;
     static final int LISTENER_SECURITY_OFFSET = 4;
-    static final int LISTENER_ARRAY_INCREMENT = 5;
+    static final int LISTENER_ARRAY_SIZE = 5;
 
     private final Logger m_logger;
     private final ServiceRegistry m_registry;
 
-    // Representation of an empty listener list.
-    private static final Object[] m_emptyList = new Object[0];
-
-    private Object[] m_frameworkListeners = m_emptyList;
-    private Object[] m_bundleListeners = m_emptyList;
-    private Object[] m_syncBundleListeners = m_emptyList;
-    private Object[] m_serviceListeners = m_emptyList;
+    private List<Object[]> m_frameworkListeners = Collections.EMPTY_LIST;
+    private List<Object[]> m_bundleListeners = Collections.EMPTY_LIST;
+    private List<Object[]> m_syncBundleListeners = Collections.EMPTY_LIST;
+    private List<Object[]> m_serviceListeners = Collections.EMPTY_LIST;
 
     // A single thread is used to deliver events for all dispatchers.
     private static Thread m_thread = null;
@@ -76,9 +74,9 @@
     private static volatile boolean m_stopping = false;
 
     // List of requests.
-    private static final ArrayList m_requestList = new ArrayList();
+    private static final List<Request> m_requestList = new ArrayList<Request>();
     // Pooled requests to avoid memory allocation.
-    private static final ArrayList m_requestPool = new ArrayList();
+    private static final List<Request> m_requestPool = new ArrayList<Request>();
 
     public EventDispatcher(Logger logger, ServiceRegistry registry)
     {
@@ -190,7 +188,7 @@
         // Lock the object to add the listener.
         synchronized (this)
         {
-            Object[] listeners = null;
+            List<Object[]> listeners = null;
             Object acc = null;
 
             if (clazz == FrameworkListener.class)
@@ -227,32 +225,18 @@
                 throw new IllegalArgumentException("Unknown listener: " + l.getClass());
             }
 
-            // If we have no listeners, then just add the new listener.
-            if (listeners == m_emptyList)
-            {
-                listeners = new Object[LISTENER_ARRAY_INCREMENT];
-                listeners[LISTENER_BUNDLE_OFFSET] = bundle;
-                listeners[LISTENER_CLASS_OFFSET] = clazz;
-                listeners[LISTENER_OBJECT_OFFSET] = l;
-                listeners[LISTENER_FILTER_OFFSET] = filter;
-                listeners[LISTENER_SECURITY_OFFSET] = acc;
-            }
-            // Otherwise, we need to do some array copying.
-            // Notice, the old array is always valid, so if
-            // the dispatch thread is in the middle of a dispatch,
-            // then it has a reference to the old listener array
-            // and is not affected by the new value.
-            else
-            {
-                Object[] newList = new Object[listeners.length + LISTENER_ARRAY_INCREMENT];
-                System.arraycopy(listeners, 0, newList, 0, listeners.length);
-                newList[listeners.length + LISTENER_BUNDLE_OFFSET] = bundle;
-                newList[listeners.length + LISTENER_CLASS_OFFSET] = clazz;
-                newList[listeners.length + LISTENER_OBJECT_OFFSET] = l;
-                newList[listeners.length + LISTENER_FILTER_OFFSET] = filter;
-                newList[listeners.length + LISTENER_SECURITY_OFFSET] = acc;
-                listeners = newList;
-            }
+            // Add listener.
+            Object[] listener = new Object[LISTENER_ARRAY_SIZE];
+            listener[LISTENER_BUNDLE_OFFSET] = bundle;
+            listener[LISTENER_CLASS_OFFSET] = clazz;
+            listener[LISTENER_OBJECT_OFFSET] = l;
+            listener[LISTENER_FILTER_OFFSET] = filter;
+            listener[LISTENER_SECURITY_OFFSET] = acc;
+
+            List<Object[]> newListeners = new ArrayList<Object[]>(listeners.size() + 1);
+            newListeners.addAll(listeners);
+            newListeners.add(listener);
+            listeners = newListeners;
 
             if (clazz == FrameworkListener.class)
             {
@@ -296,7 +280,7 @@
         // Lock the object to remove the listener.
         synchronized (this)
         {
-            Object[] listeners = null;
+            List<Object[]> listeners = null;
 
             if (clazz == FrameworkListener.class)
             {
@@ -324,17 +308,18 @@
 
             // Try to find the instance in our list.
             int idx = -1;
-            for (int i = 0; i < listeners.length; i += LISTENER_ARRAY_INCREMENT)
+            for (int i = 0; i < listeners.size(); i++)
             {
-                if (listeners[i + LISTENER_BUNDLE_OFFSET].equals(bundle) &&
-                    (listeners[i + LISTENER_CLASS_OFFSET] == clazz) &&
-                    (listeners[i + LISTENER_OBJECT_OFFSET] == l))
+                Object[] listener = listeners.get(i);
+                if (listener[LISTENER_BUNDLE_OFFSET].equals(bundle) &&
+                    (listener[LISTENER_CLASS_OFFSET] == clazz) &&
+                    (listener[LISTENER_OBJECT_OFFSET] == l))
                 {
                     // For service listeners, we must return some info about
                     // the listener for the ListenerHook callback.
                     if (ServiceListener.class == clazz)
                     {
-                        listenerInfo = wrapListener(listeners, i, true);
+                        listenerInfo = wrapListener(listeners.get(i), true);
                     }
                     idx = i;
                     break;
@@ -345,9 +330,9 @@
             if (idx >= 0)
             {
                 // If this is the last listener, then point to empty list.
-                if ((listeners.length - LISTENER_ARRAY_INCREMENT) == 0)
+                if (listeners.size() == 1)
                 {
-                    listeners = m_emptyList;
+                    listeners = Collections.EMPTY_LIST;
                 }
                 // Otherwise, we need to do some array copying.
                 // Notice, the old array is always valid, so if
@@ -356,15 +341,9 @@
                 // and is not affected by the new value.
                 else
                 {
-                    Object[] newList  = new Object[listeners.length - LISTENER_ARRAY_INCREMENT];
-                    System.arraycopy(listeners, 0, newList, 0, idx);
-                    if (idx < newList.length)
-                    {
-                        System.arraycopy(
-                            listeners, idx + LISTENER_ARRAY_INCREMENT,
-                            newList, idx, newList.length - idx);
-                    }
-                    listeners = newList;
+                    List<Object[]> newListeners = new ArrayList<Object[]>(listeners);
+                    newListeners.remove(idx);
+                    listeners = newListeners;
                 }
             }
 
@@ -404,73 +383,65 @@
         synchronized (this)
         {
             // Remove all framework listeners associated with the specified bundle.
-            Object[] listeners = m_frameworkListeners;
-            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
+            List<Object[]> newListeners = new ArrayList<Object[]>(m_frameworkListeners);
+            for (Iterator<Object[]> it = newListeners.iterator(); it.hasNext(); )
             {
                 // Check if the bundle associated with the current listener
                 // is the same as the specified bundle, if so remove the listener.
-                Bundle registeredBundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
+                Object[] listener = it.next();
+                Bundle registeredBundle = (Bundle) listener[LISTENER_BUNDLE_OFFSET];
                 if (bundle.equals(registeredBundle))
                 {
-                    Class clazz = (Class) listeners[i + LISTENER_CLASS_OFFSET];
-                    EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
-                    removeListener(bundle, clazz, l);
+                    it.remove();
                 }
             }
+            m_frameworkListeners = newListeners;
 
             // Remove all bundle listeners associated with the specified bundle.
-            listeners = m_bundleListeners;
-            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
+            newListeners = new ArrayList<Object[]>(m_bundleListeners);
+            for (Iterator<Object[]> it = newListeners.iterator(); it.hasNext(); )
             {
                 // Check if the bundle associated with the current listener
                 // is the same as the specified bundle, if so remove the listener.
-                Bundle registeredBundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
+                Object[] listener = it.next();
+                Bundle registeredBundle = (Bundle) listener[LISTENER_BUNDLE_OFFSET];
                 if (bundle.equals(registeredBundle))
                 {
-                    Class clazz = (Class) listeners[i + LISTENER_CLASS_OFFSET];
-                    EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
-                    removeListener(bundle, clazz, l);
+                    it.remove();
                 }
             }
+            m_bundleListeners = newListeners;
 
             // Remove all synchronous bundle listeners associated with
             // the specified bundle.
-            listeners = m_syncBundleListeners;
-            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
+            newListeners = new ArrayList<Object[]>(m_syncBundleListeners);
+            for (Iterator<Object[]> it = newListeners.iterator(); it.hasNext(); )
             {
                 // Check if the bundle associated with the current listener
                 // is the same as the specified bundle, if so remove the listener.
-                Bundle registeredBundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
+                Object[] listener = it.next();
+                Bundle registeredBundle = (Bundle) listener[LISTENER_BUNDLE_OFFSET];
                 if (bundle.equals(registeredBundle))
                 {
-                    Class clazz = (Class) listeners[i + LISTENER_CLASS_OFFSET];
-                    EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
-                    removeListener(bundle, clazz, l);
+                    it.remove();
                 }
             }
+            m_syncBundleListeners = newListeners;
 
             // Remove all service listeners associated with the specified bundle.
-            listeners = m_serviceListeners;
-            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
+            newListeners = new ArrayList<Object[]>(m_serviceListeners);
+            for (Iterator<Object[]> it = newListeners.iterator(); it.hasNext(); )
             {
                 // Check if the bundle associated with the current listener
                 // is the same as the specified bundle, if so remove the listener.
-                Bundle registeredBundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
+                Object[] listener = it.next();
+                Bundle registeredBundle = (Bundle) listener[LISTENER_BUNDLE_OFFSET];
                 if (bundle.equals(registeredBundle))
                 {
-                    Class clazz = (Class) listeners[i + LISTENER_CLASS_OFFSET];
-                    EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
-                    removeListener(bundle, clazz, l);
+                    it.remove();
                 }
             }
+            m_serviceListeners = newListeners;
         }
     }
 
@@ -478,7 +449,7 @@
     {
         synchronized (this)
         {
-            Object[] listeners = null;
+            List<Object[]> listeners = null;
 
             if (clazz == FrameworkListener.class)
             {
@@ -502,11 +473,12 @@
 
             // See if the listener is already registered, if so then
             // handle it according to the spec.
-            for (int i = 0; i < listeners.length; i += LISTENER_ARRAY_INCREMENT)
+            for (int i = 0; i < listeners.size(); i++)
             {
-                if (listeners[i + LISTENER_BUNDLE_OFFSET].equals(bundle) &&
-                    (listeners[i + LISTENER_CLASS_OFFSET] == clazz) &&
-                    (listeners[i + LISTENER_OBJECT_OFFSET] == l))
+                Object[] listener = listeners.get(i);
+                if (listener[LISTENER_BUNDLE_OFFSET].equals(bundle) &&
+                    (listener[LISTENER_CLASS_OFFSET] == clazz) &&
+                    (listener[LISTENER_OBJECT_OFFSET] == l))
                 {
                     Filter oldFilter = null;
                     if (clazz == FrameworkListener.class)
@@ -520,8 +492,8 @@
                     else if (clazz == ServiceListener.class)
                     {
                         // The spec says to update the filter in this case.
-                        oldFilter = (Filter) listeners[i + LISTENER_FILTER_OFFSET];
-                        listeners[i + LISTENER_FILTER_OFFSET] = filter;
+                        oldFilter = (Filter) listener[LISTENER_FILTER_OFFSET];
+                        listener[LISTENER_FILTER_OFFSET] = filter;
                     }
                     return oldFilter;
                 }
@@ -538,18 +510,19 @@
      * @return Returns all existing service listener information into a collection of
      *         ListenerHook.ListenerInfo objects
     **/
-    public Collection /* <? extends ListenerHook.ListenerInfo> */ wrapAllServiceListeners(boolean removed)
+    public Collection /* <? extends ListenerHook.ListenerInfo> */
+        wrapAllServiceListeners(boolean removed)
     {
-        Object[] listeners = null;
+        List<Object[]> listeners = null;
         synchronized (this)
         {
             listeners = m_serviceListeners;
         }
 
         List existingListeners = new ArrayList();
-        for (int i = 0, j = 0; i < listeners.length; i += LISTENER_ARRAY_INCREMENT, j++)
+        for (int i = 0; i < listeners.size(); i++)
         {
-            existingListeners.add(wrapListener(listeners, i, removed));
+            existingListeners.add(wrapListener(listeners.get(i), removed));
         }
         return existingListeners;
     }
@@ -561,13 +534,13 @@
      * @param offset The offset into the array of the listener to wrap.
      * @return A ListenerHook.ListenerInfo object for the specified listener.
      */
-    private static ListenerHook.ListenerInfo wrapListener(Object[] listeners, int offset, boolean removed)
+    private static ListenerHook.ListenerInfo wrapListener(Object[] listener, boolean removed)
     {
-        Filter filter = ((Filter)listeners[offset + LISTENER_FILTER_OFFSET]);
+        Filter filter = (Filter) listener[LISTENER_FILTER_OFFSET];
 
         return new ListenerHookInfoImpl(
-            ((Bundle)listeners[offset + LISTENER_BUNDLE_OFFSET]).getBundleContext(),
-            (ServiceListener) listeners[offset + LISTENER_OBJECT_OFFSET],
+            ((Bundle)listener[LISTENER_BUNDLE_OFFSET]).getBundleContext(),
+            (ServiceListener) listener[LISTENER_OBJECT_OFFSET],
             filter == null ? null : filter.toString(),
             removed);
     }
@@ -575,30 +548,38 @@
     public void fireFrameworkEvent(FrameworkEvent event)
     {
         // Take a snapshot of the listener array.
-        Object[] listeners = null;
+        List<Object[]> listeners = null;
         synchronized (this)
         {
             listeners = m_frameworkListeners;
         }
 
         // Fire all framework listeners on a separate thread.
-        fireEventAsynchronously(this, Request.FRAMEWORK_EVENT, listeners, event);
+        fireEventAsynchronously(this, Request.FRAMEWORK_EVENT, listeners, null, event);
     }
 
-    public void fireBundleEvent(BundleEvent event)
+    public void fireBundleEvent(BundleEvent event, Framework felix)
     {
         // Take a snapshot of the listener array.
-        Object[] listeners = null;
-        Object[] syncListeners = null;
+        List<Object[]> listeners = null;
+        List<Object[]> syncListeners = null;
         synchronized (this)
         {
             listeners = m_bundleListeners;
             syncListeners = m_syncBundleListeners;
         }
 
+        // Create a whitelist of bundle context for bundle listeners,
+        // if we have hooks.
+        List<Object[]> allListeners = new ArrayList(listeners);
+        allListeners.addAll(syncListeners);
+        Set<BundleContext> whitelist =
+            createWhitelistFromHooks(
+                event, felix, allListeners, org.osgi.framework.hooks.bundle.EventHook.class);
+
         // Fire synchronous bundle listeners immediately on the calling thread.
         fireEventImmediately(
-            this, Request.BUNDLE_EVENT, syncListeners, event, null);
+            this, Request.BUNDLE_EVENT, syncListeners, whitelist, event, null);
 
         // The spec says that asynchronous bundle listeners do not get events
         // of types STARTING, STOPPING, or LAZY_ACTIVATION.
@@ -607,7 +588,8 @@
             (event.getType() != BundleEvent.LAZY_ACTIVATION))
         {
             // Fire asynchronous bundle listeners on a separate thread.
-            fireEventAsynchronously(this, Request.BUNDLE_EVENT, listeners, event);
+            fireEventAsynchronously(
+                this, Request.BUNDLE_EVENT, listeners, whitelist, event);
         }
     }
 
@@ -615,32 +597,76 @@
         final ServiceEvent event, final Dictionary oldProps, final Framework felix)
     {
         // Take a snapshot of the listener array.
-        Object[] listeners = null;
+        List<Object[]> listeners = null;
         synchronized (this)
         {
             listeners = m_serviceListeners;
         }
 
-        Set<ServiceReference<EventHook>> eventHooks = m_registry.getHooks(EventHook.class);
-        if ((eventHooks != null) && !eventHooks.isEmpty())
+        // Create a whitelist of bundle context, if we have hooks.
+        Set<BundleContext> whitelist =
+            createWhitelistFromHooks(
+                event, felix, listeners, org.osgi.framework.hooks.service.EventHook.class);
+
+        // Fire all service events immediately on the calling thread.
+        fireEventImmediately(
+            this, Request.SERVICE_EVENT, listeners, whitelist, event, oldProps);
+    }
+
+
+    private Set<BundleContext> createWhitelistFromHooks(
+        EventObject event, Framework felix, List<Object[]> listeners, Class hookClass)
+    {
+        // Create a whitelist of bundle context, if we have hooks.
+        Set<BundleContext> whitelist = null;
+        Set<ServiceReference> hooks = m_registry.getHooks(hookClass);
+        if ((hooks != null) && !hooks.isEmpty())
         {
-            final ListenerBundleContextCollectionWrapper wrapper =
-                new ListenerBundleContextCollectionWrapper(listeners);
-            for (ServiceReference<EventHook> sr : eventHooks)
+            whitelist = new HashSet<BundleContext>();
+            for (Object[] listener : listeners)
+            {
+                BundleContext bc =
+                    ((Bundle) listener[LISTENER_BUNDLE_OFFSET]).getBundleContext();
+                if (bc != null)
+                {
+                    whitelist.add(bc);
+                }
+            }
+            int originalSize = whitelist.size();
+            ShrinkableCollection<BundleContext> shrinkable =
+                new ShrinkableCollection<BundleContext>(whitelist);
+            for (ServiceReference sr : hooks)
             {
                 if (felix != null)
                 {
-                    EventHook eh = m_registry.getServiceSafely(felix, sr);
+                    Object eh = null;
+                    try
+                    {
+                        eh = m_registry.getService(felix, sr);
+                    }
+                    catch (Exception ex)
+                    {
+                        // If we can't get the hook, then ignore it.
+                    }
                     if (eh != null)
                     {
                         try
                         {
-                            eh.event(event, wrapper);
+                            if (eh instanceof org.osgi.framework.hooks.service.EventHook)
+                            {
+                                ((org.osgi.framework.hooks.service.EventHook)
+                                    eh).event((ServiceEvent) event, shrinkable);
+                            }
+                            else if (eh instanceof org.osgi.framework.hooks.bundle.EventHook)
+                            {
+                                ((org.osgi.framework.hooks.bundle.EventHook)
+                                    eh).event((BundleEvent) event, shrinkable);
+                            }
                         }
                         catch (Throwable th)
                         {
                             m_logger.log(sr, Logger.LOG_WARNING,
-                                "Problem invoking service registry hook", th);
+                                "Problem invoking event hook", th);
                         }
                         finally
                         {
@@ -649,17 +675,19 @@
                     }
                 }
             }
-
-            listeners = wrapper.getListeners();
+            // If the whitelist hasn't changed, then null it to avoid having
+            // to do whitelist lookups during event delivery.
+            if (originalSize == whitelist.size())
+            {
+                whitelist = null;
+            }
         }
-
-        // Fire all service events immediately on the calling thread.
-        fireEventImmediately(
-            this, Request.SERVICE_EVENT, listeners, event, oldProps);
+        return whitelist;
     }
 
     private static void fireEventAsynchronously(
-        EventDispatcher dispatcher, int type, Object[] listeners, EventObject event)
+        EventDispatcher dispatcher, int type, List<Object[]> listeners,
+        Set<BundleContext> whitelist, EventObject event)
     {
         //TODO: should possibly check this within thread lock, seems to be ok though without
         // If dispatch thread is stopped, then ignore dispatch request.
@@ -674,7 +702,7 @@
         {
             if (m_requestPool.size() > 0)
             {
-                req = (Request) m_requestPool.remove(0);
+                req = m_requestPool.remove(0);
             }
             else
             {
@@ -686,6 +714,7 @@
         req.m_dispatcher = dispatcher;
         req.m_type = type;
         req.m_listeners = listeners;
+        req.m_whitelist = whitelist;
         req.m_event = event;
 
         // Lock the request list.
@@ -699,46 +728,49 @@
     }
 
     private static void fireEventImmediately(
-        EventDispatcher dispatcher, int type, Object[] listeners,
-        EventObject event, Dictionary oldProps)
+        EventDispatcher dispatcher, int type, List<Object[]> listeners,
+        Set<BundleContext> whitelist, EventObject event, Dictionary oldProps)
     {
-        if (listeners.length > 0)
+        if (!listeners.isEmpty())
         {
             // Notify appropriate listeners.
-            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
+            for (Object[] listener : listeners)
             {
-                Bundle bundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
-                EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
-                Filter filter = (Filter) listeners[i + LISTENER_FILTER_OFFSET];
-                Object acc = listeners[i + LISTENER_SECURITY_OFFSET];
-                try
+                Bundle bundle = (Bundle) listener[LISTENER_BUNDLE_OFFSET];
+                EventListener l = (EventListener) listener[LISTENER_OBJECT_OFFSET];
+                Filter filter = (Filter) listener[LISTENER_FILTER_OFFSET];
+                Object acc = listener[LISTENER_SECURITY_OFFSET];
+
+                // Only deliver events to bundles in the whitelist, if we have one.
+                if ((whitelist == null) || whitelist.contains(bundle.getBundleContext()))
                 {
-                    if (type == Request.FRAMEWORK_EVENT)
+                    try
                     {
-                        invokeFrameworkListenerCallback(bundle, l, event);
+                        if (type == Request.FRAMEWORK_EVENT)
+                        {
+                            invokeFrameworkListenerCallback(bundle, l, event);
+                        }
+                        else if (type == Request.BUNDLE_EVENT)
+                        {
+                            invokeBundleListenerCallback(bundle, l, event);
+                        }
+                        else if (type == Request.SERVICE_EVENT)
+                        {
+                            invokeServiceListenerCallback(
+                                bundle, l, filter, acc, event, oldProps);
+                        }
                     }
-                    else if (type == Request.BUNDLE_EVENT)
+                    catch (Throwable th)
                     {
-                        invokeBundleListenerCallback(bundle, l, event);
-                    }
-                    else if (type == Request.SERVICE_EVENT)
-                    {
-                        invokeServiceListenerCallback(
-                            bundle, l, filter, acc, event, oldProps);
-                    }
-                }
-                catch (Throwable th)
-                {
-                    if ((type != Request.FRAMEWORK_EVENT)
-                        || (((FrameworkEvent) event).getType() != FrameworkEvent.ERROR))
-                    {
-                        dispatcher.m_logger.log(bundle,
-                            Logger.LOG_ERROR,
-                            "EventDispatcher: Error during dispatch.", th);
-                        dispatcher.fireFrameworkEvent(
-                            new FrameworkEvent(FrameworkEvent.ERROR, bundle, th));
+                        if ((type != Request.FRAMEWORK_EVENT)
+                            || (((FrameworkEvent) event).getType() != FrameworkEvent.ERROR))
+                        {
+                            dispatcher.m_logger.log(bundle,
+                                Logger.LOG_ERROR,
+                                "EventDispatcher: Error during dispatch.", th);
+                            dispatcher.fireFrameworkEvent(
+                                new FrameworkEvent(FrameworkEvent.ERROR, bundle, th));
+                        }
                     }
                 }
             }
@@ -911,7 +943,7 @@
                 // Wait while there are no requests to dispatch. If the
                 // dispatcher thread is supposed to stop, then let the
                 // dispatcher thread exit the loop and stop.
-                while ((m_requestList.size() == 0) && !m_stopping)
+                while (m_requestList.isEmpty() && !m_stopping)
                 {
                     // Wait until some signals us for work.
                     try
@@ -926,13 +958,13 @@
 
                 // If there are no events to dispatch and shutdown
                 // has been called then exit, otherwise dispatch event.
-                if ((m_requestList.size() == 0) && (m_stopping))
+                if (m_requestList.isEmpty() && m_stopping)
                 {
                     return;
                 }
 
                 // Get the dispatch request.
-                req = (Request) m_requestList.remove(0);
+                req = m_requestList.remove(0);
             }
 
             // Deliver event outside of synchronized block
@@ -942,7 +974,7 @@
             // the invoked method shields us from exceptions by
             // catching Throwables when it invokes callbacks.
             fireEventImmediately(
-                req.m_dispatcher, req.m_type, req.m_listeners, req.m_event, null);
+                req.m_dispatcher, req.m_type, req.m_listeners, req.m_whitelist, req.m_event, null);
 
             // Put dispatch request in cache.
             synchronized (m_requestPool)
@@ -950,207 +982,13 @@
                 req.m_dispatcher = null;
                 req.m_type = -1;
                 req.m_listeners = null;
+                req.m_whitelist = null;
                 req.m_event = null;
                 m_requestPool.add(req);
             }
         }
     }
 
-    static class ListenerBundleContextCollectionWrapper implements Collection
-    {
-        private Object[] m_listeners;
-
-        ListenerBundleContextCollectionWrapper(Object [] listeners)
-        {
-            m_listeners = listeners;
-        }
-
-        Object [] getListeners()
-        {
-            return m_listeners;
-        }
-
-        public boolean add(Object o)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean addAll(Collection c)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public void clear()
-        {
-            m_listeners = new Object[0];
-        }
-
-        public boolean contains(Object o)
-        {
-            return indexOf(o) >= 0;
-        }
-
-        public boolean containsAll(Collection c)
-        {
-            for (Iterator it = c.iterator(); it.hasNext(); )
-            {
-                if (!contains(it.next()))
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private int indexOf(Object o)
-        {
-            if (!(o instanceof BundleContext))
-            {
-                return -1;
-            }
-
-            for (int i = m_listeners.length - LISTENER_ARRAY_INCREMENT;
-                i >= 0;
-                i -= LISTENER_ARRAY_INCREMENT)
-            {
-                Bundle bundle = (Bundle) m_listeners[i + LISTENER_BUNDLE_OFFSET];
-                if (bundle != null)
-                {
-                    if (bundle.getBundleContext().equals(o))
-                    {
-                        return i;
-                    }
-                }
-            }
-            return -1;
-        }
-
-        public boolean isEmpty()
-        {
-            return m_listeners.length == 0;
-        }
-
-        public Iterator iterator()
-        {
-            return new WrapperIterator();
-        }
-
-        public boolean remove(Object o)
-        {
-            return removeIndex(indexOf(o));
-        }
-
-        private boolean removeIndex(int idx)
-        {
-            if (idx < 0)
-            {
-                return false;
-            }
-
-            Object [] newListeners = new Object[m_listeners.length - LISTENER_ARRAY_INCREMENT];
-            System.arraycopy(m_listeners, 0, newListeners, 0, idx);
-            System.arraycopy(m_listeners, idx + LISTENER_ARRAY_INCREMENT,
-                    newListeners, idx, newListeners.length - idx);
-            m_listeners = newListeners;
-
-            return true;
-        }
-
-        public boolean removeAll(Collection c)
-        {
-            boolean rv = false;
-
-            for (Iterator it = c.iterator(); it.hasNext(); )
-            {
-                if (remove(it.next()))
-                {
-                    rv = true;
-                }
-            }
-
-            return rv;
-        }
-
-        public boolean retainAll(Collection c)
-        {
-            boolean rv = false;
-
-            for (Iterator it = iterator(); it.hasNext(); )
-            {
-                if (!(c.contains(it.next())))
-                {
-                    it.remove();
-                    rv = true;
-                }
-            }
-
-            return rv;
-        }
-
-        public int size()
-        {
-            return m_listeners.length / LISTENER_ARRAY_INCREMENT;
-        }
-
-        public Object[] toArray()
-        {
-            Object [] array = new Object[size()];
-            int idx = 0;
-            for (Iterator it = iterator(); it.hasNext(); )
-            {
-                array[idx++] = it.next();
-            }
-            return array;
-        }
-
-        public Object[] toArray(Object[] a)
-        {
-            if (!(a.getClass().equals(Object[].class)))
-            {
-                throw new ArrayStoreException();
-            }
-            return toArray();
-        }
-
-        private class WrapperIterator implements Iterator
-        {
-            int curIdx = 0;
-            int lastIdx = -1;
-
-            private WrapperIterator() {}
-
-            public boolean hasNext()
-            {
-                return curIdx < m_listeners.length;
-            }
-
-            public Object next()
-            {
-                if (!hasNext())
-                {
-                    throw new NoSuchElementException();
-                }
-
-                Bundle b = (Bundle) m_listeners[curIdx + LISTENER_BUNDLE_OFFSET];
-                lastIdx = curIdx;
-                curIdx += LISTENER_ARRAY_INCREMENT;
-                return b.getBundleContext();
-            }
-
-            public void remove()
-            {
-                if (lastIdx < 0)
-                {
-                    throw new IllegalStateException();
-                }
-                removeIndex(lastIdx);
-
-                curIdx = lastIdx;
-                lastIdx = -1;
-            }
-        }
-    }
-
     private static class Request
     {
         public static final int FRAMEWORK_EVENT = 0;
@@ -1159,7 +997,8 @@
 
         public EventDispatcher m_dispatcher = null;
         public int m_type = -1;
-        public Object[] m_listeners = null;
+        public List<Object[]> m_listeners = null;
+        public Set<BundleContext> m_whitelist = null;
         public EventObject m_event = null;
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
deleted file mode 100644
index ce0b3e7..0000000
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-public class EventDispatcherListenerWrapperTest extends TestCase
-{
-    public void testRemove()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-        Bundle b3 = getMockBundle();
-        BundleContext bc3 = b3.getBundleContext();
-        Bundle b4 = getMockBundle();
-        BundleContext bc4 = b4.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15),       // LISTENER_SECURITY_OFFSET
-            b3,                    // LISTENER_BUNDLE_OFFSET
-            BundleContext.class,   // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            null,                  // LISTENER_FILTER_OFFSET
-            Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        assertEquals(3, c.size());
-        assertFalse(c.isEmpty());
-        assertTrue(c.contains(bc1));
-        assertTrue(c.contains(bc2));
-        assertTrue(c.contains(bc3));
-        assertFalse(c.contains(bc4));
-
-        assertTrue(c.remove(bc2));
-        assertEquals(2, c.size());
-        assertTrue(c.contains(bc1));
-        assertFalse(c.contains(bc2));
-        assertTrue(c.contains(bc3));
-        assertFalse(c.contains(bc4));
-        assertFalse("Already removed", c.remove(bc2));
-
-        Object[] actualListeners =
-            ((EventDispatcher.ListenerBundleContextCollectionWrapper) c).getListeners();
-        Object[] expectedListeners = new Object[EventDispatcher.LISTENER_ARRAY_INCREMENT * 2];
-        System.arraycopy(listeners, 0, expectedListeners, 0,
-            EventDispatcher.LISTENER_ARRAY_INCREMENT);
-        System.arraycopy(
-            listeners,
-            EventDispatcher.LISTENER_ARRAY_INCREMENT * 2,
-            expectedListeners,
-            EventDispatcher.LISTENER_ARRAY_INCREMENT,
-            EventDispatcher.LISTENER_ARRAY_INCREMENT);
-        assertTrue(Arrays.equals(expectedListeners, actualListeners));
-
-        assertTrue(c.remove(bc1));
-        assertEquals(1, c.size());
-        assertFalse(c.contains(bc1));
-        assertFalse(c.contains(bc2));
-        assertTrue(c.contains(bc3));
-        assertFalse(c.contains(bc4));
-        assertFalse(c.isEmpty());
-
-        Object[] actualListeners2 =
-            ((EventDispatcher.ListenerBundleContextCollectionWrapper) c).getListeners();
-        Object[] expectedListeners2 = new Object[EventDispatcher.LISTENER_ARRAY_INCREMENT];
-        System.arraycopy(
-            listeners, EventDispatcher.LISTENER_ARRAY_INCREMENT * 2,
-            expectedListeners2,
-            0,
-            EventDispatcher.LISTENER_ARRAY_INCREMENT);
-        assertTrue(Arrays.equals(expectedListeners2, actualListeners2));
-
-        assertTrue(c.remove(bc3));
-        assertEquals(0, c.size());
-        assertFalse(c.contains(bc1));
-        assertFalse(c.contains(bc2));
-        assertFalse(c.contains(bc3));
-        assertFalse(c.contains(bc4));
-        assertTrue(c.isEmpty());
-
-        Object[] actualListeners3 =
-            ((EventDispatcher.ListenerBundleContextCollectionWrapper) c).getListeners();
-        assertEquals(0, actualListeners3.length);
-    }
-
-    public void testIterator()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15)        // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        Iterator it = c.iterator();
-
-        assertEquals(2, c.size());
-        assertTrue(it.hasNext());
-        try
-        {
-            it.remove();
-            fail("Should throw an exception");
-        }
-        catch (IllegalStateException ise)
-        {
-            // good
-        }
-        assertSame(bc1, it.next());
-        it.remove();
-        assertEquals(1, c.size());
-
-        // Create another iterator and make sure it sees the removal of it
-        Iterator it2 = c.iterator();
-        assertTrue(it2.hasNext());
-        assertSame(bc2, it2.next());
-        assertFalse(it2.hasNext());
-
-        // back to the origial iterator
-
-        try
-        {
-            it.remove();
-            fail("Should throw an exception");
-        }
-        catch (IllegalStateException ise)
-        {
-            // good
-        }
-        assertTrue(it.hasNext());
-        try
-        {
-            it.remove();
-            fail("Should throw an exception");
-        }
-        catch (IllegalStateException ise)
-        {
-            // good
-        }
-        assertSame(bc2, it.next());
-        it.remove();
-        assertEquals(0, c.size());
-
-        assertFalse(it.hasNext());
-        try
-        {
-            it.next();
-            fail("Should throw an exception");
-        }
-        catch (NoSuchElementException nse)
-        {
-            // good
-        }
-        try
-        {
-            it.remove();
-            fail("Should throw an exception");
-        }
-        catch (IllegalStateException ise)
-        {
-            // good
-        }
-    }
-
-    public void testAdd()
-    {
-        Bundle b1 = getMockBundle();
-        b1.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,
-            String.class,
-            new Object(),
-            "(some=filter)",
-            null,
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        try
-        {
-            c.add(new Object());
-            fail("Should not have been able to add to the collection");
-        }
-        catch (UnsupportedOperationException uoe)
-        {
-            // good
-        }
-    }
-
-    public void testAddAll()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Object[] listeners =
-        {
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        try
-        {
-            c.addAll(Collections.singleton(bc1));
-            fail("Should not have been able to add to the collection");
-        }
-        catch (UnsupportedOperationException uoe)
-        {
-            // good
-        }
-    }
-
-    public void testContainsAll()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-        Bundle b3 = getMockBundle();
-        BundleContext bc3 = b3.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15),       // LISTENER_SECURITY_OFFSET
-            b3,                    // LISTENER_BUNDLE_OFFSET
-            BundleContext.class,   // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            null,                  // LISTENER_FILTER_OFFSET
-            Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-
-        assertTrue(c.containsAll(Collections.emptySet()));
-        assertTrue(c.containsAll(Collections.singleton(bc2)));
-        assertTrue(c.containsAll(Arrays.asList(new Object[]
-            {
-                bc2, bc1
-            })));
-        assertTrue(c.containsAll(Arrays.asList(new Object[]
-            {
-                bc3, bc2, bc1
-            })));
-        assertFalse(c.containsAll(Arrays.asList(new Object[]
-            {
-                bc3, bc2, bc1, new Object()
-            })));
-
-        assertEquals(3, c.size());
-        c.clear();
-        assertEquals(0, c.size());
-    }
-
-    public void testRemoveAll()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-        Bundle b3 = getMockBundle();
-        BundleContext bc3 = b3.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15),       // LISTENER_SECURITY_OFFSET
-            b3,                    // LISTENER_BUNDLE_OFFSET
-            BundleContext.class,   // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            null,                  // LISTENER_FILTER_OFFSET
-            Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        assertFalse(c.removeAll(Collections.emptyList()));
-        assertFalse(c.removeAll(Collections.singleton(new Object())));
-        assertTrue(c.contains(bc2));
-        assertTrue(c.removeAll(Arrays.asList(new Object[]
-            {
-                new Object(), bc2
-            })));
-        assertFalse(c.contains(bc2));
-
-        assertEquals(2, c.size());
-        assertTrue(c.removeAll(Arrays.asList(new Object[]
-            {
-                bc1, bc3
-            })));
-        assertEquals(0, c.size());
-    }
-
-    public void testRetainAll()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-        Bundle b3 = getMockBundle();
-        BundleContext bc3 = b3.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15),       // LISTENER_SECURITY_OFFSET
-            b3,                    // LISTENER_BUNDLE_OFFSET
-            BundleContext.class,   // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            null,                  // LISTENER_FILTER_OFFSET
-            Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        assertFalse(c.retainAll(Arrays.asList(new Object[]
-            {
-                bc3, bc1, bc2
-            })));
-        assertTrue(Arrays.equals(new Object[]
-            {
-                bc1, bc2, bc3
-            }, c.toArray()));
-
-        assertTrue(c.retainAll(Arrays.asList(new Object[]
-            {
-                bc1, bc2, new Object()
-            })));
-        assertTrue(Arrays.equals(new Object[]
-            {
-                bc1, bc2
-            }, c.toArray()));
-
-        assertTrue(c.retainAll(Collections.emptyList()));
-        assertEquals(0, c.size());
-    }
-
-    public void testToArray()
-    {
-        Bundle b1 = getMockBundle();
-        BundleContext bc1 = b1.getBundleContext();
-        Bundle b2 = getMockBundle();
-        BundleContext bc2 = b2.getBundleContext();
-
-        Object[] listeners = new Object[]
-        {
-            b1,                    // LISTENER_BUNDLE_OFFSET
-            String.class,          // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_SECURITY_OFFSET
-            b2,                    // LISTENER_BUNDLE_OFFSET
-            Integer.class,         // LISTENER_CLASS_OFFSET
-            new Object(),          // LISTENER_OBJECT_OFFSET
-            "(some.other=filter)", // LISTENER_FILTER_OFFSET
-            new Integer(15),       // LISTENER_SECURITY_OFFSET
-        };
-
-        Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
-        assertTrue(Arrays.equals(new Object[]
-            {
-                bc1, bc2
-            }, c.toArray()));
-        assertTrue(Arrays.equals(new Object[]
-            {
-                bc1, bc2
-            }, c.toArray(new Object[]
-            {
-            })));
-
-        try
-        {
-            c.toArray(new String[]
-                {
-                });
-            fail("Should not be allowed");
-        }
-        catch (ArrayStoreException ase)
-        {
-            // good
-        }
-    }
-
-    private Bundle getMockBundle()
-    {
-        BundleContext bc = (BundleContext) EasyMock.createNiceMock(BundleContext.class);
-        Bundle b = (Bundle) EasyMock.createNiceMock(Bundle.class);
-        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
-        b.getState();
-        EasyMock.expectLastCall().andReturn(Integer.valueOf(Bundle.ACTIVE)).anyTimes();
-
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.replay(new Object[]
-            {
-                b, bc
-            });
-
-        return b;
-    }
-}
\ No newline at end of file
