diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index cdae189..847bd40 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -153,7 +153,7 @@
         
         if (sm != null)
         {
-            if(l instanceof SynchronousBundleListener)
+            if (l instanceof SynchronousBundleListener)
             {
                 ((SecurityManager) sm).checkPermission(new AdminPermission(m_bundle, 
                     AdminPermission.LISTENER));
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
index 9724413..20d6a5e 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -86,11 +86,7 @@
     private Object m_nextIdLock = new Object[0];
 
     // List of event listeners.
-    private FelixDispatchQueue m_dispatchQueue = null;
-    // Re-usable event dispatchers.
-    private Dispatcher m_frameworkDispatcher = null;
-    private Dispatcher m_bundleDispatcher = null;
-    private Dispatcher m_serviceDispatcher = null;
+    private EventDispatcher m_dispatcher = null;
 
     // Service registry.
     private ServiceRegistry m_registry = null;
@@ -215,7 +211,7 @@
         m_uninstalledBundles = null;
         m_cache = null;
         m_nextId = 1L;
-        m_dispatchQueue = null;
+        m_dispatcher = null;
         m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
         m_registry = new ServiceRegistry(m_logger);
 
@@ -327,8 +323,8 @@
         m_factory = new ModuleFactoryImpl(m_logger);
         m_policyCore.setModuleFactory(m_factory);
 
-        // Initialize dispatch queue.
-        m_dispatchQueue = new FelixDispatchQueue(m_logger);
+        // Initialize event dispatcher.
+        m_dispatcher = new EventDispatcher(m_logger);
 
         // Initialize framework properties.
         initializeFrameworkProperties();
@@ -379,7 +375,7 @@
         catch (Exception ex)
         {
             m_factory = null;
-            DispatchQueue.shutdown();
+            EventDispatcher.shutdown();
             m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
             throw new RuntimeException("Unable to start system bundle.");
         }
@@ -591,7 +587,7 @@
         }
 
         // Shutdown event dispatching queue.
-        DispatchQueue.shutdown();
+        EventDispatcher.shutdown();
 
         // The framework is no longer in a usable state.
         m_frameworkStatus = INITIAL_STATUS;
@@ -1246,7 +1242,7 @@
             m_registry.ungetServices(bundle);
 
             // Remove any listeners registered by this bundle.
-            removeListeners(bundle);
+            m_dispatcher.removeListeners(bundle);
 
             // The spec says to expect BundleException or
             // SecurityException, so rethrow these exceptions.
@@ -1572,7 +1568,7 @@
         
         // The spec says that we must remove all event
         // listeners for a bundle when it is stopped.
-        removeListeners(bundle);
+        m_dispatcher.removeListeners(bundle);
         
         info.setState(Bundle.RESOLVED);
         fireBundleEvent(BundleEvent.STOPPED, bundle);
@@ -1964,25 +1960,12 @@
 
     protected void addBundleListener(Bundle bundle, BundleListener l)
     {
-        // The spec says do nothing if the listener is
-        // already registered.
-        BundleListenerWrapper old = (BundleListenerWrapper)
-            m_dispatchQueue.getListener(BundleListener.class, l);
-        if (old == null)
-        {
-            l = new BundleListenerWrapper(bundle, l);
-            m_dispatchQueue.addListener(BundleListener.class, l);
-        }
+        m_dispatcher.addListener(bundle, BundleListener.class, l, null);
     }
 
     protected void removeBundleListener(Bundle bundle, BundleListener l)
     {
-        BundleListenerWrapper old = (BundleListenerWrapper)
-            m_dispatchQueue.getListener(BundleListener.class, l);
-        if ((old != null) && old.getBundle().equals(bundle))
-        {
-            m_dispatchQueue.removeListener(BundleListener.class, l);
-        }
+        m_dispatcher.removeListener(bundle, BundleListener.class, l);
     }
 
     /**
@@ -1997,20 +1980,8 @@
     protected void addServiceListener(Bundle bundle, ServiceListener l, String f)
         throws InvalidSyntaxException
     {
-        // The spec says if the listener is already registered,
-        // then replace filter.
-        ServiceListenerWrapper old = (ServiceListenerWrapper)
-            m_dispatchQueue.getListener(ServiceListener.class, l);
-        if (old != null)
-        {
-            old.setFilter((f == null) ? null : new FilterImpl(m_logger, f));
-        }
-        else
-        {
-            l = new ServiceListenerWrapper(
-                bundle, l, (f == null) ? null : new FilterImpl(m_logger, f));
-            m_dispatchQueue.addListener(ServiceListener.class, l);
-        }
+        m_dispatcher.addListener(
+            bundle, ServiceListener.class, l, (f == null) ? null : new FilterImpl(m_logger, f));
     }
 
     /**
@@ -2022,67 +1993,17 @@
     **/
     protected void removeServiceListener(Bundle bundle, ServiceListener l)
     {
-        ServiceListenerWrapper old = (ServiceListenerWrapper) 
-            m_dispatchQueue.getListener(ServiceListener.class, l);
-        if ((old != null) && old.getBundle().equals(bundle))
-        {
-            m_dispatchQueue.removeListener(ServiceListener.class, l);
-        }
+        m_dispatcher.removeListener(bundle, ServiceListener.class, l);
     }
 
     protected void addFrameworkListener(Bundle bundle, FrameworkListener l)
     {
-        // The spec says do nothing if the listener is
-        // already registered.
-        FrameworkListenerWrapper old = (FrameworkListenerWrapper)
-            m_dispatchQueue.getListener(FrameworkListener.class, l);
-        if (old == null)
-        {
-            l = new FrameworkListenerWrapper(bundle, l);
-            m_dispatchQueue.addListener(FrameworkListener.class, l);
-        }
+        m_dispatcher.addListener(bundle, FrameworkListener.class, l, null);
     }
 
     protected void removeFrameworkListener(Bundle bundle, FrameworkListener l)
     {
-        FrameworkListenerWrapper old = (FrameworkListenerWrapper)
-            m_dispatchQueue.getListener(FrameworkListener.class, l);
-        if ((old != null) && old.getBundle().equals(bundle))
-        {
-            m_dispatchQueue.removeListener(FrameworkListener.class, l);
-        }
-    }
-
-    /**
-     * Remove all of the specified bundle's event listeners from
-     * the framework.
-     * @param bundle The bundle whose listeners are to be removed.
-    **/
-    private void removeListeners(Bundle bundle)
-    {
-        if (bundle == null)
-        {
-            return;
-        }
-
-        // Remove all listeners associated with the supplied bundle;
-        // it is only possible to know the bundle associated with a
-        // listener if the listener was wrapper by a ListenerWrapper,
-        // so look for those.
-        Object[] listeners = m_dispatchQueue.getListeners();
-        for (int i = listeners.length - 2; i >= 0; i -= 2)
-        {
-            // Check for listener wrappers and then compare the bundle.
-            if (listeners[i + 1] instanceof ListenerWrapper)
-            {
-                ListenerWrapper lw = (ListenerWrapper) listeners[i + 1];
-                if ((lw.getBundle() != null) && (lw.getBundle().equals(bundle)))
-                {
-                    m_dispatchQueue.removeListener(
-                        (Class) listeners[i], (EventListener) listeners[i+1]);
-                }
-            }
-        }
+        m_dispatcher.removeListener(bundle, FrameworkListener.class, l);
     }
 
     /**
@@ -2191,7 +2112,7 @@
             ServiceReference ref = (ServiceReference) refList.get(refIdx);
 
             // Now check for castability.
-            if (!isServiceAssignable(bundle, ref))
+            if (!Felix.isServiceAssignable(bundle, ref))
             {
                 refList.remove(refIdx);
                 refIdx--;
@@ -2215,7 +2136,7 @@
      * @return <tt>true</tt> if the requesting bundle is able to case
      *         the service object to a known type.
     **/
-    protected boolean isServiceAssignable(BundleImpl requester, ServiceReference ref)
+    public static boolean isServiceAssignable(Bundle requester, ServiceReference ref)
     {
         // Boolean flag.
         boolean allow = true;
@@ -2854,19 +2775,7 @@
     private void fireFrameworkEvent(
         int type, Bundle bundle, Throwable throwable)
     {
-        if (m_frameworkDispatcher == null)
-        {
-            m_frameworkDispatcher = new Dispatcher() {
-                public void dispatch(EventListener l, EventObject eventObj)
-                {
-                    ((FrameworkListener) l)
-                        .frameworkEvent((FrameworkEvent) eventObj);
-                }
-            };
-        }
-        FrameworkEvent event = new FrameworkEvent(type, bundle, throwable);
-        m_dispatchQueue.dispatch(
-            m_frameworkDispatcher, FrameworkListener.class, event);
+        m_dispatcher.fireFrameworkEvent(new FrameworkEvent(type, bundle, throwable));
     }
 
     /**
@@ -2877,20 +2786,7 @@
     **/
     private void fireBundleEvent(int type, Bundle bundle)
     {
-        if (m_bundleDispatcher == null)
-        {
-            m_bundleDispatcher = new Dispatcher() {
-                public void dispatch(EventListener l, EventObject eventObj)
-                {
-                    ((BundleListener) l)
-                        .bundleChanged((BundleEvent) eventObj);
-                }
-            };
-        }
-        BundleEvent event = null;
-        event = new BundleEvent(type, bundle);
-        m_dispatchQueue.dispatch(m_bundleDispatcher,
-            BundleListener.class, event);
+        m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle));
     }
 
     /**
@@ -2901,31 +2797,7 @@
     **/
     private void fireServiceEvent(ServiceEvent event)
     {
-        if (m_serviceDispatcher == null)
-        {
-            m_serviceDispatcher = new Dispatcher() {
-                public void dispatch(EventListener l, EventObject eventObj)
-                {
-// TODO: Filter service events based on service permissions.
-                    if (l instanceof ListenerWrapper)
-                    {
-                        BundleImpl bundle = (BundleImpl) ((ServiceListenerWrapper) l).getBundle();
-                        if (isServiceAssignable(bundle, ((ServiceEvent) eventObj).getServiceReference()))
-                        {
-                            ((ServiceListener) l)
-                                .serviceChanged((ServiceEvent) eventObj);
-                        }
-                    }
-                    else
-                    {
-                        ((ServiceListener) l)
-                            .serviceChanged((ServiceEvent) eventObj);
-                    }
-                }
-            };
-        }
-        m_dispatchQueue.dispatch(m_serviceDispatcher,
-            ServiceListener.class, event);
+        m_dispatcher.fireServiceEvent(event);
     }
 
     //
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/BundleListenerWrapper.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/BundleListenerWrapper.java
deleted file mode 100644
index 7915f12..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/BundleListenerWrapper.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.osgi.framework.*;
-
-public class BundleListenerWrapper extends ListenerWrapper implements BundleListener
-{
-    public BundleListenerWrapper(Bundle bundle, BundleListener l)
-    {
-        super(bundle,
-            (l instanceof SynchronousBundleListener)
-                ? SynchronousBundleListener.class : BundleListener.class,
-            l);
-    }
-
-    public void bundleChanged(final BundleEvent event)
-    {
-        // A bundle listener is either synchronous or asynchronous.
-        // If the bundle listener is synchronous, then deliver the
-        // event to bundles with a state of STARTING, STOPPING, or
-        // ACTIVE. If the listener is asynchronous, then deliver the
-        // event only to bundles that are STARTING or ACTIVE.
-        if (((getListenerClass() == SynchronousBundleListener.class) &&
-            ((getBundle().getState() == Bundle.STARTING) ||
-            (getBundle().getState() == Bundle.STOPPING) ||
-            (getBundle().getState() == Bundle.ACTIVE)))
-            ||
-            ((getBundle().getState() == Bundle.STARTING) ||
-            (getBundle().getState() == Bundle.ACTIVE)))
-        {
-            if (System.getSecurityManager() != null)
-            {
-                AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run()
-                    {
-                        ((BundleListener) getListener()).bundleChanged(event);
-                        return null;
-                    }
-                });
-            }
-            else
-            {
-                ((BundleListener) getListener()).bundleChanged(event);
-            }
-        }
-    }
-}
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/DispatchQueue.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/DispatchQueue.java
deleted file mode 100644
index b27278d..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/DispatchQueue.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.*;
-
-import org.apache.felix.framework.Logger;
-
-/**
- * This class implements an event dispatching queue to simplify delivering
- * events to a list of event listener. To use this class, simply create an
- * instance and use it to keep track of your event listeners, much like
- * <tt>javax.swing.event.EventListenerList</tt>. To dispatch an event,
- * simply create an instance of a <tt>Dispatcher</tt> and pass the instance
- * to <tt>DispatchQueue.dispatch()</tt> method, for example:
- * <pre>
- *  Dispatcher d = new Dispatcher() {
- *      public void dispatch(EventListener l, Object eventObj)
- *      {
- *          ((FooListener) l).fooXXX((FooEvent) eventObj);
- *      }
- *  };
- *  FooEvent event = new FooEvent(this);
- *  dispatchQueue.dispatch(d, FooListener.class, event);
- * </pre>
- * In the above code substitute a specific listener and event for the
- * <tt>Foo</tt> listener and event. Since <tt>Dispatcher</tt>s are
- * reusable, it is probably a good idea to create one for each type of
- * event to be delivered and just reuse them everytime to avoid unnecessary
- * memory allocation.
- * <p>
- * Currently, the <tt>DispatchQueue</tt> creates an internal thread with
- * which all events are delivered; this means that events are never delivered
- * using the caller's thread.
-**/
-public class DispatchQueue
-{
-    // Representation of an empty listener list.
-    private static final Object[] m_emptyList = new Object[0];
-
-    // The event listeners for a particular queue instance.
-    private Object[] m_listeners = m_emptyList;
-
-    // A single thread is used to deliver events for all dispatchers.
-    private static Thread m_thread = null;
-    private static String m_threadLock = "thread lock";
-    private static boolean m_stopping = false;
-    private static boolean m_stopped = false;
-
-    // List of dispatch requests.
-    private static final ArrayList m_requestList = new ArrayList();
-    // Cached dispatch requests to avoid memory allocation.
-    private static final ArrayList m_requestCache = new ArrayList();
-    // The logger for dispatch queue.
-    private static Logger m_logger = null;
-
-    /**
-     * Constructs a dispatch queue and starts a dispather thread if
-     * necessary.
-    **/
-    public DispatchQueue(Logger logger)
-    {
-        synchronized (m_threadLock)
-        {
-            // Start event dispatching thread if necessary.
-            if (m_thread == null)
-            {
-                m_logger = logger;
-                m_thread = new Thread(new Runnable() {
-                    public void run()
-                    {
-                        DispatchQueue.run();
-                    }
-                }, "FelixDispatchQueue");
-                m_thread.start();
-            }
-        }
-    }
-
-    /**
-     * Terminates the dispatching thread for a graceful shutdown
-     * of the dispatching queue; the caller will block until the
-     * dispatching thread has completed all pending dispatches.
-     * Since there is only one thread per all instances of
-     * <tt>DispatchQueue</tt>, this method should only be called
-     * prior to exiting the JVM.
-    **/
-    public static void shutdown()
-    {
-        synchronized (m_threadLock)
-        {
-            // Return if already stopped.
-            if (m_stopped)
-            {
-                return;
-            }
-
-            // Signal dispatch thread.
-            m_stopping = true;
-            synchronized (m_requestList)
-            {
-                m_requestList.notify();
-            }
-
-            // Wait for dispatch thread to stop.
-            while (!m_stopped)
-            {
-                try {
-                    m_threadLock.wait();
-                } catch (InterruptedException ex) {
-                }
-            }
-        }
-    }
-
-    public static Logger getLogger()
-    {
-        return m_logger;
-    }
-
-    /**
-     * Returns a pointer to the array of event listeners. The array stores pairs
-     * of associated <tt>Class</tt> and <tt>EventListener</tt> objects; a pair
-     * corresponds to the arguments passed in to the <tt>addListener()</tt> method.
-     * Even numbered array elements are the class object and odd numbered elements
-     * are the corresponding event listener instance.
-     *
-     * @return guaranteed to return a non-null object array.
-    **/
-    public Object[] getListeners()
-    {
-        return m_listeners;
-    }
-
-    /**
-     * Returns the listener if it is already in the dispatch queue.
-     * @param clazz the class of the listener to find.
-     * @param l the listener instance to find.
-     * @return the listener instance or <tt>null</tt> if the listener was
-     *         not found.
-    **/
-    public EventListener getListener(Class clazz, EventListener l)
-    {
-        // Verify listener.
-        if (l == null)
-        {
-            throw new IllegalArgumentException("Listener is null");
-        }
-        else if (!clazz.isInstance(l))
-        {
-            throw new IllegalArgumentException(
-                "Listener not of type " + clazz.getName());
-        }
-
-        // Lock the object.
-        synchronized (this)
-        {
-            // Try to find the instance in our list.
-            for (int i = 0; i < m_listeners.length; i += 2)
-            {
-                if ((m_listeners[i] == clazz) &&
-                    (m_listeners[i + 1].equals(l)))
-                {
-                    return (EventListener) m_listeners[i + 1];
-                }
-            }
-        }
-        
-        return null;
-    }
-
-    /**
-     * Adds a listener to the dispatch queue's listener list; the listener
-     * is then able to receive events.
-     *
-     * @param clazz the class object associated with the event listener type.
-     * @param l the instance of the event listener to add.
-    **/
-    public void addListener(Class clazz, EventListener l)
-    {
-        // Verify listener.
-        if (l == null)
-        {
-            throw new IllegalArgumentException("Listener is null");
-        }
-        else if (!clazz.isInstance(l))
-        {
-            throw new IllegalArgumentException(
-                "Listener not of type " + clazz.getName());
-        }
-
-        // Lock the object.
-        synchronized (this)
-        {
-            // If we have no listeners, then just add the new listener.
-            if (m_listeners == m_emptyList)
-            {
-                m_listeners = new Object[] { clazz, l };
-            }
-            // 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[m_listeners.length + 2];
-                System.arraycopy(m_listeners, 0, newList, 0, m_listeners.length);
-                newList[m_listeners.length] = clazz;
-                newList[m_listeners.length + 1] = l;
-                m_listeners = newList;
-            }
-        }
-    }
-
-    /**
-     * Removes a listener from the dispatch queue's listener list; the listener
-     * is no longer able to receive events.
-     *
-     * @param clazz the class object associated with the event listener type.
-     * @param l the instance of the event listener to remove.
-    **/
-    public void removeListener(Class clazz, EventListener l)
-    {
-        // Verify listener.
-        if (l == null)
-        {
-            throw new IllegalArgumentException("Listener is null");
-        }
-        else if (!clazz.isInstance(l))
-        {
-            throw new IllegalArgumentException(
-                "Listener not of type " + clazz.getName());
-        }
-
-        // Lock the object.
-        synchronized (this)
-        {
-            // Try to find the instance in our list.
-            int idx = -1;
-            for (int i = 0; i < m_listeners.length; i += 2)
-            {
-                if ((m_listeners[i] == clazz) &&
-                    (m_listeners[i + 1].equals(l)))
-                {
-                    idx = i;
-                    break;
-                }
-            }
-
-            // If we have the instance, then remove it.
-            if (idx >= 0)
-            {
-                // If this is the last listener, then point to empty list.
-                if ((m_listeners.length - 2) == 0)
-                {
-                    m_listeners = m_emptyList;
-                }
-                // 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[m_listeners.length - 2];
-                    System.arraycopy(m_listeners, 0, newList, 0, idx);
-                    if (idx < newList.length)
-                    {
-                        System.arraycopy(m_listeners, idx + 2, newList, idx,
-                            newList.length - idx);
-                    }
-                    m_listeners = newList;
-                }
-            }
-        }
-    }
-
-    /**
-     * Dispatches an event to a set of event listeners using a specified
-     * dispatcher object.
-     *
-     * @param d the dispatcher used to actually dispatch the event; this
-     *          varies according to the type of event listener.
-     * @param clazz the class associated with the target event listener type;
-     *              only event listeners of this type will receive the event.
-     * @param eventObj the actual event object to dispatch.
-    **/
-    public void dispatch(Dispatcher d, Class clazz, EventObject eventObj)
-    {
-        dispatch(m_listeners, d, clazz, eventObj);
-    }
-
-    protected void dispatch(
-        Object[] listeners, Dispatcher d, Class clazz, EventObject eventObj)
-    {
-        // If dispatch thread is stopped, then ignore dispatch request.
-        if (m_stopped)
-        {
-            return;
-        }
-
-        // First get a dispatch request from the cache or
-        // create one if necessary.
-        DispatchRequest dr = null;
-        synchronized (m_requestCache)
-        {
-            if (m_requestCache.size() > 0)
-                dr = (DispatchRequest) m_requestCache.remove(0);
-            else
-                dr = new DispatchRequest();
-        }
-
-        // Initialize dispatch request.
-        dr.m_listeners = listeners;
-        dr.m_dispatcher = d;
-        dr.m_clazz = clazz;
-        dr.m_eventObj = eventObj;
-
-        // Lock the request list.
-        synchronized (m_requestList)
-        {
-            // Add our request to the list.
-            m_requestList.add(dr);
-            // Notify the dispatch thread that there is
-            // work to do.
-            m_requestList.notify();
-        }
-    }
-
-    private static void run()
-    {
-        DispatchRequest dr = null;
-        while (true)
-        {
-            // Lock the request list so we can try to get a
-            // dispatch request from it.
-            synchronized (m_requestList)
-            {
-                // 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)
-                {
-                    // Wait until some signals us for work.
-                    try {
-                        m_requestList.wait();
-                    } catch (InterruptedException ex) {
-                        m_logger.log(Logger.LOG_ERROR, "DispatchQueue: Thread interrupted.", ex);
-                    }
-                }
-
-                // If there are no events to dispatch and shutdown
-                // has been called then exit, otherwise dispatch event.
-                if ((m_requestList.size() == 0) && (m_stopping))
-                {
-                    synchronized (m_threadLock)
-                    {
-                        m_stopped = true;
-                        m_threadLock.notifyAll();
-                    }
-                    return;
-                }
-
-                // Get the dispatch request.
-                dr = (DispatchRequest) m_requestList.remove(0);
-            }
-
-            // Deliver event outside of synchronized block
-            // so that we don't block other requests from being
-            // queued during event processing.
-
-            // Try to dispatch to the listeners.
-            if (dr.m_listeners.length > 0)
-            {
-                // Notify appropriate listeners.
-                for (int i = dr.m_listeners.length - 2; i >= 0; i -= 2)
-                {
-                    if (dr.m_listeners[i] == dr.m_clazz)
-                    {
-                        try {
-                            dr.m_dispatcher.dispatch(
-                                (EventListener) dr.m_listeners[i + 1], dr.m_eventObj);
-                        } catch (Throwable th) {
-                            m_logger.log(Logger.LOG_ERROR, "DispatchQueue: Error during dispatch.", th);
-                        }
-                    }
-                }
-            }
-
-            // Put dispatch request in cache.
-            synchronized (m_requestCache)
-            {
-                m_requestCache.add(dr);
-            }
-        }
-    }
-
-    private static class DispatchRequest
-    {
-        public Object[] m_listeners = null;
-        public Dispatcher m_dispatcher = null;
-        public Class m_clazz = null;
-        public EventObject m_eventObj = null;
-    }
-}
\ No newline at end of file
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/Dispatcher.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/Dispatcher.java
deleted file mode 100644
index 0496e3b..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/Dispatcher.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.EventListener;
-import java.util.EventObject;
-
-/**
- * This interface is used by <tt>DispatchQueue</tt> to dispatch events.
- * Generally speaking, each type of event to dispatch will have an instance
- * of a <tt>Dispatcher</tt> so that the dispatch queue can dispatch to
- * the appropriate listener method for the specific listener type,
- * for example:
- * <pre>
- *  Dispatcher d = new Dispatcher() {
- *      public void dispatch(EventListener l, EventObject eventObj)
- *      {
- *          ((FooListener) l).fooXXX((FooEvent) eventObj);
- *      }
- *  };
- *  FooEvent event = new FooEvent(this);
- *  dispatchQueue.dispatch(d, FooListener.class, event);
- * </pre>
- * In the above code substitute a specific listener and event for the
- * <tt>Foo</tt> listener and event. <tt>Dispatcher</tt>s can be reused, so
- * it is a good idea to cache them to avoid unnecessary memory allocations.
-**/
-public interface Dispatcher
-{
-    /**
-     * Dispatch an event to a specified event listener.
-     *
-     * @param l the event listener to receive the event.
-     * @param eventObj the event to dispatch.
-    **/
-    public void dispatch(EventListener l, EventObject eventObj);
-}
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
new file mode 100644
index 0000000..ddcc34c
--- /dev/null
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -0,0 +1,784 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+
+import org.apache.felix.framework.Felix;
+import org.apache.felix.framework.Logger;
+import org.osgi.framework.*;
+
+public class EventDispatcher
+{
+    private static final int LISTENER_BUNDLE_OFFSET = 0;
+    private static final int LISTENER_CLASS_OFFSET = 1;
+    private static final int LISTENER_OBJECT_OFFSET = 2;
+    private static final int LISTENER_FILTER_OFFSET = 3;
+    private static final int LISTENER_SECURITY_OFFSET = 4;
+    private static final int LISTENER_ARRAY_INCREMENT = 5;
+
+    // Framework instance for this dispatcher.
+    private Logger m_logger = null;
+
+    // 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;
+
+    // A single thread is used to deliver events for all dispatchers.
+    private static Thread m_thread = null;
+    private static String m_threadLock = "thread lock";
+    private static boolean m_stopping = false;
+    private static boolean m_stopped = false;
+    // List of requests.
+    private static final ArrayList m_requestList = new ArrayList();
+    // Pooled requests to avoid memory allocation.
+    private static final ArrayList m_requestPool = new ArrayList();
+
+    public EventDispatcher(Logger logger)
+    {
+        m_logger = logger;
+
+        synchronized (m_threadLock)
+        {
+            // Start event dispatching thread if necessary.
+            if (m_thread == null)
+            {
+                m_thread = new Thread(new Runnable() {
+                    public void run()
+                    {
+                        EventDispatcher.run();
+                    }
+                }, "FelixDispatchQueue");
+                m_thread.start();
+            }
+        }
+    }
+
+    public static void shutdown()
+    {
+        synchronized (m_threadLock)
+        {
+            // Return if already stopped.
+            if (m_stopped)
+            {
+                return;
+            }
+
+            // Signal dispatch thread.
+            m_stopping = true;
+            synchronized (m_requestList)
+            {
+                m_requestList.notify();
+            }
+
+            // Wait for dispatch thread to stop.
+            while (!m_stopped)
+            {
+                try
+                {
+                    m_threadLock.wait();
+                }
+                catch (InterruptedException ex)
+                {
+                }
+            }
+        }
+    }
+
+    public void addListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
+    {
+        // Verify the listener.
+        if (l == null)
+        {
+            throw new IllegalArgumentException("Listener is null");
+        }
+        else if (!clazz.isInstance(l))
+        {
+            throw new IllegalArgumentException(
+                "Listener not of type " + clazz.getName());
+        }
+
+        // See if we can simply update the listener, if so then
+        // return immediately.
+        if (updateListener(bundle, clazz, l, filter))
+        {
+            return;
+        }
+
+        // Lock the object to add the listener.
+        synchronized (this)
+        {
+            Object[] listeners = null;
+            Object acc = null;
+
+            if (clazz == FrameworkListener.class)
+            {
+                listeners = m_frameworkListeners;
+            }
+            else if (clazz == BundleListener.class)
+            {
+                if (SynchronousBundleListener.class.isInstance(l))
+                {
+                    listeners = m_syncBundleListeners;
+                }
+                else
+                {
+                    listeners = m_bundleListeners;
+                }
+            }
+            else if (clazz == ServiceListener.class)
+            {
+                // Remember security context for filtering service events.
+                Object sm = System.getSecurityManager();
+                if (sm != null)
+                {
+                    acc = ((SecurityManager) sm).getSecurityContext();
+                }
+
+                listeners = m_serviceListeners;
+            }
+            else
+            {
+                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;
+            }
+
+            if (clazz == FrameworkListener.class)
+            {
+                m_frameworkListeners = listeners;
+            }
+            else if (clazz == BundleListener.class)
+            {
+                if (SynchronousBundleListener.class.isInstance(l))
+                {
+                    m_syncBundleListeners = listeners;
+                }
+                else
+                {
+                    m_bundleListeners = listeners;
+                }
+            }
+            else if (clazz == ServiceListener.class)
+            {
+                m_serviceListeners = listeners;
+            }
+        }
+    }
+
+    public void removeListener(Bundle bundle, Class clazz, EventListener l)
+    {
+        // Verify listener.
+        if (l == null)
+        {
+            throw new IllegalArgumentException("Listener is null");
+        }
+        else if (!clazz.isInstance(l))
+        {
+            throw new IllegalArgumentException(
+                "Listener not of type " + clazz.getName());
+        }
+
+        // Lock the object to remove the listener.
+        synchronized (this)
+        {
+            Object[] listeners = null;
+
+            if (clazz == FrameworkListener.class)
+            {
+                listeners = m_frameworkListeners;
+            }
+            else if (clazz == BundleListener.class)
+            {
+                if (SynchronousBundleListener.class.isInstance(l))
+                {
+                    listeners = m_syncBundleListeners;
+                }
+                else
+                {
+                    listeners = m_bundleListeners;
+                }
+            }
+            else if (clazz == ServiceListener.class)
+            {
+                listeners = m_serviceListeners;
+            }
+            else
+            {
+                throw new IllegalArgumentException("Unknown listener: " + l.getClass());
+            }
+
+            // Try to find the instance in our list.
+            int idx = -1;
+            for (int i = 0; i < listeners.length; i += LISTENER_ARRAY_INCREMENT)
+            {
+                if (listeners[i + LISTENER_BUNDLE_OFFSET].equals(bundle) &&
+                    (listeners[i + LISTENER_CLASS_OFFSET] == clazz) &&
+                    listeners[i + LISTENER_OBJECT_OFFSET].equals(l))
+                {
+                    idx = i;
+                    break;
+                }
+            }
+
+            // If we have the instance, then remove it.
+            if (idx >= 0)
+            {
+                // If this is the last listener, then point to empty list.
+                if ((listeners.length - LISTENER_ARRAY_INCREMENT) == 0)
+                {
+                    listeners = m_emptyList;
+                }
+                // 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, idx);
+                    if (idx < newList.length)
+                    {
+                        System.arraycopy(
+                            listeners, idx + LISTENER_ARRAY_INCREMENT,
+                            newList, idx, newList.length - idx);
+                    }
+                    listeners = newList;
+                }
+            }
+
+            if (clazz == FrameworkListener.class)
+            {
+                m_frameworkListeners = listeners;
+            }
+            else if (clazz == BundleListener.class)
+            {
+                if (SynchronousBundleListener.class.isInstance(l))
+                {
+                    m_syncBundleListeners = listeners;
+                }
+                else
+                {
+                    m_bundleListeners = listeners;
+                }
+            }
+            else if (clazz == ServiceListener.class)
+            {
+                m_serviceListeners = listeners;
+            }
+        }
+    }
+
+    public void removeListeners(Bundle bundle)
+    {
+        if (bundle == null)
+        {
+            return;
+        }
+
+        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)
+            {
+                // 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[LISTENER_BUNDLE_OFFSET];
+                if (bundle.equals(registeredBundle))
+                {
+                    Class clazz = (Class) listeners[LISTENER_CLASS_OFFSET];
+                    EventListener l = (EventListener) listeners[LISTENER_OBJECT_OFFSET];
+                    removeListener(bundle, clazz, l);
+                }
+            }
+
+            // 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)
+            {
+                // 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[LISTENER_BUNDLE_OFFSET];
+                if (bundle.equals(registeredBundle))
+                {
+                    Class clazz = (Class) listeners[LISTENER_CLASS_OFFSET];
+                    EventListener l = (EventListener) listeners[LISTENER_OBJECT_OFFSET];
+                    removeListener(bundle, clazz, l);
+                }
+            }
+
+            // 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)
+            {
+                // 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[LISTENER_BUNDLE_OFFSET];
+                if (bundle.equals(registeredBundle))
+                {
+                    Class clazz = (Class) listeners[LISTENER_CLASS_OFFSET];
+                    EventListener l = (EventListener) listeners[LISTENER_OBJECT_OFFSET];
+                    removeListener(bundle, clazz, l);
+                }
+            }
+
+            // 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)
+            {
+                // 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[LISTENER_BUNDLE_OFFSET];
+                if (bundle.equals(registeredBundle))
+                {
+                    Class clazz = (Class) listeners[LISTENER_CLASS_OFFSET];
+                    EventListener l = (EventListener) listeners[LISTENER_OBJECT_OFFSET];
+                    removeListener(bundle, clazz, l);
+                }
+            }
+        }
+    }
+
+    public boolean updateListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
+    {
+        synchronized (this)
+        {
+            Object[] listeners = null;
+
+            if (clazz == FrameworkListener.class)
+            {
+                listeners = m_frameworkListeners;
+            }
+            else if (clazz == BundleListener.class)
+            {
+                if (SynchronousBundleListener.class.isInstance(l))
+                {
+                    listeners = m_syncBundleListeners;
+                }
+                else
+                {
+                    listeners = m_bundleListeners;
+                }
+            }
+            else if (clazz == ServiceListener.class)
+            {
+                listeners = m_serviceListeners;
+            }
+    
+            // 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)
+            {
+                if (listeners[i + LISTENER_BUNDLE_OFFSET].equals(bundle) &&
+                    (listeners[i + LISTENER_CLASS_OFFSET] == clazz) &&
+                    listeners[i + LISTENER_OBJECT_OFFSET].equals(l))
+                {
+                    if (l instanceof FrameworkListener)
+                    {
+                        // The spec says to ignore this case.
+                    }
+                    else if (l instanceof BundleListener)
+                    {
+                        // The spec says to ignore this case.
+                    }
+                    else if (l instanceof ServiceListener)
+                    {
+                        // The spec says to update the filter in this case.
+                        listeners[i + LISTENER_FILTER_OFFSET] = filter;
+                    }
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public void fireFrameworkEvent(FrameworkEvent event)
+    {
+        // Take a snapshot of the listener array.
+        Object[] listeners = null;
+        synchronized (this)
+        {
+            listeners = m_frameworkListeners;
+        }
+
+        // Fire all framework listeners on a separate thread.
+        fireEventAsynchronously(m_logger, Request.FRAMEWORK_EVENT, listeners, event);
+    }
+
+    public void fireBundleEvent(BundleEvent event)
+    {
+        // Take a snapshot of the listener array.
+        Object[] listeners = null;
+        Object[] syncListeners = null;
+        synchronized (this)
+        {
+            listeners = m_bundleListeners;
+            syncListeners = m_syncBundleListeners;
+        }
+
+        // Fire synchronous bundle listeners immediately on the calling thread.
+        fireEventImmediately(m_logger, Request.BUNDLE_EVENT, syncListeners, event);
+
+        // Fire asynchronous bundle listeners on a separate thread.
+        fireEventAsynchronously(m_logger, Request.BUNDLE_EVENT, listeners, event);
+    }
+
+    public void fireServiceEvent(ServiceEvent event)
+    {
+        // Take a snapshot of the listener array.
+        Object[] listeners = null;
+        synchronized (this)
+        {
+            listeners = m_serviceListeners;
+        }
+
+        // Fire all service events immediately on the calling thread.
+        fireEventImmediately(m_logger, Request.SERVICE_EVENT, listeners, event);
+    }
+
+    private void fireEventAsynchronously(
+        Logger logger, int type, Object[] listeners, EventObject event)
+    {
+        // If dispatch thread is stopped, then ignore dispatch request.
+        if (m_stopped || m_stopping)
+        {
+            return;
+        }
+
+        // First get a request from the pool or create one if necessary.
+        Request req = null;
+        synchronized (m_requestPool)
+        {
+            if (m_requestPool.size() > 0)
+            {
+                req = (Request) m_requestPool.remove(0);
+            }
+            else
+            {
+                req = new Request();
+            }
+        }
+
+        // Initialize dispatch request.
+        req.m_logger = logger;
+        req.m_type = type;
+        req.m_listeners = listeners;
+        req.m_event = event;
+
+        // Lock the request list.
+        synchronized (m_requestList)
+        {
+            // Add our request to the list.
+            m_requestList.add(req);
+            // Notify the dispatch thread that there is work to do.
+            m_requestList.notify();
+        }
+    }
+
+    private static void fireEventImmediately(
+        Logger logger, int type, Object[] listeners, EventObject event)
+    {
+        if (listeners.length > 0)
+        {
+            // Notify appropriate listeners.
+            for (int i = listeners.length - LISTENER_ARRAY_INCREMENT;
+                i >= 0;
+                i -= LISTENER_ARRAY_INCREMENT)
+            {
+                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
+                {
+                    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);
+                    }
+                }
+                catch (Throwable th)
+                {
+                    logger.log(
+                        Logger.LOG_ERROR,
+                        "EventDispatcher: Error during dispatch.", th);
+                }
+            }
+        }
+    }
+
+    private static void invokeFrameworkListenerCallback(
+        Bundle bundle, final EventListener l, final EventObject event)
+    {
+        // The spec says only active bundles receive asynchronous events,
+        // but we will include starting bundles too otherwise
+        // it is impossible to see everything.
+        if ((bundle.getState() == Bundle.STARTING) ||
+            (bundle.getState() == Bundle.ACTIVE))
+        {
+            if (System.getSecurityManager() != null)
+            {
+                AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run()
+                    {
+                        ((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
+                        return null;
+                    }
+                });
+            }
+            else
+            {
+                ((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
+            }
+        }
+    }
+
+    private static void invokeBundleListenerCallback(
+        Bundle bundle, final EventListener l, final EventObject event)
+    {
+        // A bundle listener is either synchronous or asynchronous.
+        // If the bundle listener is synchronous, then deliver the
+        // event to bundles with a state of STARTING, STOPPING, or
+        // ACTIVE. If the listener is asynchronous, then deliver the
+        // event only to bundles that are STARTING or ACTIVE.
+        if (((SynchronousBundleListener.class.isAssignableFrom(l.getClass())) &&
+            ((bundle.getState() == Bundle.STARTING) ||
+            (bundle.getState() == Bundle.STOPPING) ||
+            (bundle.getState() == Bundle.ACTIVE)))
+            ||
+            ((bundle.getState() == Bundle.STARTING) ||
+            (bundle.getState() == Bundle.ACTIVE)))
+        {
+            if (System.getSecurityManager() != null)
+            {
+                AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run()
+                    {
+                        ((BundleListener) l).bundleChanged((BundleEvent) event);
+                        return null;
+                    }
+                });
+            }
+            else
+            {
+                ((BundleListener) l).bundleChanged((BundleEvent) event);
+            }
+        }
+    }
+
+    private static void invokeServiceListenerCallback(
+        Bundle bundle, final EventListener l, Filter filter, Object acc, final EventObject event)
+    {
+        // Service events should be delivered to STARTING,
+        // STOPPING, and ACTIVE bundles.
+        if ((bundle.getState() != Bundle.STARTING) &&
+            (bundle.getState() != Bundle.STOPPING) &&
+            (bundle.getState() != Bundle.ACTIVE))
+        {
+            return;
+        }
+
+        // Check that the bundle has permission to get at least
+        // one of the service interfaces; the objectClass property
+        // of the service stores its service interfaces.
+        ServiceReference ref = ((ServiceEvent) event).getServiceReference();
+        String[] objectClass = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+
+        // On the safe side, if there is no objectClass property
+        // then ignore event altogether.
+        if (objectClass != null)
+        {
+            boolean hasPermission = false;
+            
+            Object sm = System.getSecurityManager();
+            if ((acc != null) && (sm != null))
+            {
+                for (int i = 0;
+                    !hasPermission && (i < objectClass.length);
+                    i++)
+                {
+                    try 
+                    {
+                        ServicePermission perm =
+                            new ServicePermission(
+                                objectClass[i], ServicePermission.GET);
+                        ((SecurityManager) sm).checkPermission(perm, acc);
+                        hasPermission = true;
+                    } 
+                    catch (Exception ex) 
+                    {
+                    }
+                }
+            }
+            else
+            {
+                hasPermission = true;
+            }
+
+            if (hasPermission)
+            {
+                // Dispatch according to the filter.
+                if ((filter == null) || filter.match(((ServiceEvent) event).getServiceReference()))
+                {
+                    if (Felix.isServiceAssignable(bundle, ((ServiceEvent) event).getServiceReference()))
+                    {
+                        if (System.getSecurityManager() != null)
+                        {
+                            AccessController.doPrivileged(new PrivilegedAction() {
+                                public Object run()
+                                {
+                                    ((ServiceListener) l).serviceChanged((ServiceEvent) event);
+                                    return null;
+                                }
+                            });
+                        }
+                        else
+                        {
+                            {
+                                ((ServiceListener) l).serviceChanged((ServiceEvent) event);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * This is the dispatching thread's main loop.
+    **/
+    private static void run()
+    {
+        Request req = null;
+        while (true)
+        {
+            // Lock the request list so we can try to get a
+            // dispatch request from it.
+            synchronized (m_requestList)
+            {
+                // 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)
+                {
+                    // Wait until some signals us for work.
+                    try
+                    {
+                        m_requestList.wait();
+                    }
+                    catch (InterruptedException ex)
+                    {
+                        // Not much we can do here except for keep waiting.
+                    }
+                }
+
+                // If there are no events to dispatch and shutdown
+                // has been called then exit, otherwise dispatch event.
+                if ((m_requestList.size() == 0) && (m_stopping))
+                {
+                    synchronized (m_threadLock)
+                    {
+                        m_stopped = true;
+                        m_threadLock.notifyAll();
+                    }
+                    return;
+                }
+
+                // Get the dispatch request.
+                req = (Request) m_requestList.remove(0);
+            }
+
+            // Deliver event outside of synchronized block
+            // so that we don't block other requests from being
+            // queued during event processing.
+            fireEventImmediately(req.m_logger, req.m_type, req.m_listeners, req.m_event);
+
+            // Put dispatch request in cache.
+            synchronized (m_requestPool)
+            {
+                req.m_logger = null;
+                req.m_type = -1;
+                req.m_listeners = null;
+                req.m_event = null;
+                m_requestPool.add(req);
+            }
+        }
+    }
+
+    private static class Request
+    {
+        public static final int FRAMEWORK_EVENT = 0;
+        public static final int BUNDLE_EVENT = 1;
+        public static final int SERVICE_EVENT = 2;
+
+        public Logger m_logger = null;
+        public int m_type = -1;
+        public Object[] m_listeners = null;
+        public EventObject m_event = null;
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FelixDispatchQueue.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FelixDispatchQueue.java
deleted file mode 100644
index 354c05b..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FelixDispatchQueue.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.EventListener;
-import java.util.EventObject;
-
-import org.apache.felix.framework.Logger;
-import org.osgi.framework.*;
-
-/**
- * This is a subclass of <tt>DispatchQueue</tt> that specifically adds support
- * for <tt>SynchronousBundleListener</tt>s; the OSGi specification
- * says that synchronous bundle listeners should receive their events
- * immediately, i.e., they should not be delivered on a separate thread
- * like is the case with the <tt>DispatchQueue</tt>. To achieve this
- * functionality, this class overrides the dispatch method to automatically
- * fire any bundle events to synchronous bundle listeners using the
- * calling thread. In order to ensure that synchronous bundle listeners
- * do not receive an event twice, it wraps the passed in <tt>Dipatcher</tt>
- * instance so that it filters synchronous bundle listeners.
-**/
-public class FelixDispatchQueue extends DispatchQueue
-{
-    public FelixDispatchQueue(Logger logger)
-    {
-        super(logger);
-    }
-
-    /**
-     * Dispatches an event to a set of event listeners using a specified
-     * dispatcher object. This overrides the definition of the super class
-     * to deliver events to <tt>ServiceListener</tt>s and
-     * <tt>SynchronousBundleListener</tt>s using
-     * the calling thread instead of the event dispatching thread. All
-     * other events are still delivered asynchronously.
-     *
-     * @param dispatcher the dispatcher used to actually dispatch the event; this
-     *          varies according to the type of event listener.
-     * @param clazz the class associated with the target event listener type;
-     *              only event listeners of this type will receive the event.
-     * @param eventObj the actual event object to dispatch.
-    **/
-    public void dispatch(Dispatcher dispatcher, Class clazz, EventObject eventObj)
-    {
-        Object[] listeners = getListeners();
-
-        // If this is an event for service listeners, then dispatch it
-        // immediately since service events are never asynchronous.
-        if ((clazz == ServiceListener.class) && (listeners.length > 0))
-        {
-            // Notify appropriate listeners.
-            for (int i = listeners.length - 2; i >= 0; i -= 2)
-            {
-                // If the original listener is a synchronous bundle listener
-                // or a service listener, then dispatch event immediately
-                // per the specification.
-                ListenerWrapper lw = (ListenerWrapper) listeners[i + 1];
-                if (lw.getListenerClass() == ServiceListener.class)
-                {
-                    try {
-                        dispatcher.dispatch(
-                            (EventListener) lw, eventObj);
-                    } catch (Throwable th) {
-                        getLogger().log(
-                            Logger.LOG_ERROR,
-                            "FelixDispatchQueue: Error during dispatch.", th);
-                    }
-                }
-            }
-        }
-        // Dispatch bundle events to synchronous bundle listeners immediately,
-        // but deliver to standard bundle listeners asynchronously.
-        else if ((clazz == BundleListener.class) && (listeners.length > 0))
-        {
-            // Notify appropriate listeners.
-            for (int i = listeners.length - 2; i >= 0; i -= 2)
-            {
-                // If the original listener is a synchronous bundle listener,
-                // then dispatch event immediately per the specification.
-                ListenerWrapper lw = (ListenerWrapper) listeners[i + 1];
-                if (lw.getListenerClass() == SynchronousBundleListener.class)
-                {
-                    try {
-                        dispatcher.dispatch(
-                            (EventListener) lw, eventObj);
-                    } catch (Throwable th) {
-                        getLogger().log(
-                            Logger.LOG_ERROR,
-                            "FelixDispatchQueue: Error during dispatch.", th);
-                    }
-                }
-            }
-
-            // Wrap the dispatcher so that it ignores synchronous
-            // bundle listeners since they have already been dispatched.
-            IgnoreSynchronousDispatcher ignoreDispatcher = new IgnoreSynchronousDispatcher();
-            ignoreDispatcher.setDispatcher(dispatcher);
-
-            // Dispatch the bundle listener asynchronously.
-            dispatch(listeners, ignoreDispatcher, clazz, eventObj);
-        }
-        // All other events are dispatched asynchronously.
-        else
-        {
-            dispatch(listeners, dispatcher, clazz, eventObj);
-        }
-    }
-
-    private static class IgnoreSynchronousDispatcher implements Dispatcher
-    {
-        private Dispatcher m_dispatcher = null;
-
-        public void setDispatcher(Dispatcher dispatcher)
-        {
-            m_dispatcher = dispatcher;
-        }
-
-        public void dispatch(EventListener l, EventObject eventObj)
-        {
-            if (l instanceof ListenerWrapper)
-            {
-                ListenerWrapper lw = (ListenerWrapper) l;
-                // Do not dispatch events to synchronous listeners,
-                // since they are dispatched immediately above.
-                if (!(lw.getListenerClass() == SynchronousBundleListener.class))
-                {
-                    m_dispatcher.dispatch(l, eventObj);
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FrameworkListenerWrapper.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FrameworkListenerWrapper.java
deleted file mode 100644
index e0cfdc9..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/FrameworkListenerWrapper.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.osgi.framework.*;
-
-public class FrameworkListenerWrapper extends ListenerWrapper implements FrameworkListener
-{
-    public FrameworkListenerWrapper(Bundle bundle, FrameworkListener l)
-    {
-        super(bundle, FrameworkListener.class, l);
-    }
-
-    public void frameworkEvent(final FrameworkEvent event)
-    {
-        // The spec says only active bundles receive asynchronous events,
-        // but we will include starting bundles too otherwise
-        // it is impossible to see everything.
-        if ((getBundle().getState() == Bundle.STARTING) ||
-            (getBundle().getState() == Bundle.ACTIVE))
-        {
-            if (System.getSecurityManager() != null)
-            {
-                AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run()
-                    {
-                        ((FrameworkListener) getListener()).frameworkEvent(event);
-                        return null;
-                    }
-                });
-            }
-            else
-            {
-                ((FrameworkListener) getListener()).frameworkEvent(event);
-            }
-        }
-    }
-}
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ListenerWrapper.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ListenerWrapper.java
deleted file mode 100644
index eb40c93..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ListenerWrapper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *   Copyright 2005 The Apache Software Foundation
- *
- *   Licensed 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.EventListener;
-
-import org.osgi.framework.Bundle;
-
-public class ListenerWrapper
-{
-    // The bundle associated with the listener.
-    private Bundle m_bundle = null;
-    // Listener class.
-    private Class m_class = null;
-    // The original listener.
-    private EventListener m_listener = null;
-
-    public ListenerWrapper(Bundle bundle, Class clazz, EventListener l)
-    {
-        m_bundle = bundle;
-        m_class = clazz;
-        m_listener = l;
-    }
-
-    public Bundle getBundle()
-    {
-        return m_bundle;
-    }
-
-    protected Class getListenerClass()
-    {
-        return m_class;
-    }
-
-    protected EventListener getListener()
-    {
-        return m_listener;
-    }
-
-    public boolean equals(Object obj)
-    {
-        if (obj instanceof ListenerWrapper)
-        {
-            return (((ListenerWrapper) obj).m_listener == m_listener);
-        }
-        else if (obj instanceof EventListener)
-        {
-            return (obj == m_listener);
-        }
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ServiceListenerWrapper.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ServiceListenerWrapper.java
deleted file mode 100644
index 2d5f992..0000000
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ServiceListenerWrapper.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *   Copyright 2006 The Apache Software Foundation
- *
- *   Licensed 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.security.*;
-
-import org.osgi.framework.*;
-
-public class ServiceListenerWrapper extends ListenerWrapper implements ServiceListener
-{
-    // LDAP query filter.
-    private Filter m_filter = null;
-    // Remember the security context.
-    private Object m_acc = null;
-
-    public ServiceListenerWrapper(Bundle bundle, ServiceListener l, Filter filter)
-    {
-        super(bundle, ServiceListener.class, l);
-        m_filter = filter;
-
-        // Remember security context for filtering
-        // events based on security.
-        Object sm = System.getSecurityManager();
-        
-        if (sm != null)
-        {
-            m_acc = ((SecurityManager) sm).getSecurityContext();
-        }
-    }
-
-    public void setFilter(Filter filter)
-    {
-        m_filter = filter;
-    }
-    
-    public void serviceChanged(final ServiceEvent event)
-    {
-        // Service events should be delivered to STARTING,
-        // STOPPING, and ACTIVE bundles.
-        if ((getBundle().getState() != Bundle.STARTING) &&
-            (getBundle().getState() != Bundle.STOPPING) &&
-            (getBundle().getState() != Bundle.ACTIVE))
-        {
-            return;
-        }
-
-        // Check that the bundle has permission to get at least
-        // one of the service interfaces; the objectClass property
-        // of the service stores its service interfaces.
-        ServiceReference ref = event.getServiceReference();
-        String[] objectClass = (String[]) ref.getProperty(Constants.OBJECTCLASS);
-
-        // On the safe side, if there is no objectClass property
-        // then ignore event altogether.
-        if (objectClass != null)
-        {
-            boolean hasPermission = false;
-            
-            Object sm = System.getSecurityManager();
-            
-            if ((m_acc != null) && (sm != null))
-            {
-                for (int i = 0;
-                    !hasPermission && (i < objectClass.length);
-                    i++)
-                {
-                    try 
-                    {
-                        ServicePermission perm =
-                            new ServicePermission(
-                                objectClass[i], ServicePermission.GET);
-                        ((SecurityManager) sm).checkPermission(perm, m_acc);
-                        hasPermission = true;
-                    } 
-                    catch (Exception ex) 
-                    {
-                    }
-                }
-            }
-            else
-            {
-                hasPermission = true;
-            }
-
-            if (hasPermission)
-            {
-                // Dispatch according to the filter.
-                if ((m_filter == null) || m_filter.match(event.getServiceReference()))
-                {
-                    if (System.getSecurityManager() != null)
-                    {
-                        AccessController.doPrivileged(new PrivilegedAction() {
-                            public Object run()
-                            {
-                                ((ServiceListener) getListener()).serviceChanged(event);
-                                return null;
-                            }
-                        });
-                    }
-                    else
-                    {
-                        ((ServiceListener) getListener()).serviceChanged(event);
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
