Simplified support for the ENDMATCH service event to avoid GC issues.
(FELIX-1244)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@788729 13f79535-47bb-0310-9956-ffa450edef68
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 61a698e..3682a3b 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -617,9 +617,9 @@
 
             // Create service registry.
             m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
-                public void serviceChanged(ServiceEvent event, ServiceRegistration reg)
+                public void serviceChanged(ServiceEvent event, Dictionary oldProps)
                 {
-                    fireServiceEvent(event, reg);
+                    fireServiceEvent(event, oldProps);
                 }
             });
             m_dispatcher.setServiceRegistry(m_registry);
@@ -2639,16 +2639,16 @@
             new ListenerHookInfoImpl(bundle.getBundleContext(), f));
         for (int i = 0; i < listenerHooks.size(); i++)
         {
-            ServiceRegistry.invokeHook(listenerHooks.get(i), this, new InvokeHookCallback() 
+            ServiceRegistry.invokeHook(listenerHooks.get(i), this, new InvokeHookCallback()
             {
-                public void invokeHook(Object hook) 
+                public void invokeHook(Object hook)
                 {
                     ((ListenerHook) hook).added(c);
-                }                
+                }
             });
         }
     }
-        
+
     /**
      * Implementation for BundleContext.removeServiceListener().
      * Removes service listeners from the listener list.
@@ -2764,13 +2764,13 @@
         if (m_registry.isHook(classNames, ListenerHook.class, svcObj))
         {
             Object hookRef = ServiceRegistry.getHookRef(svcObj, reg);
-            ServiceRegistry.invokeHook(hookRef, this, new InvokeHookCallback() 
+            ServiceRegistry.invokeHook(hookRef, this, new InvokeHookCallback()
             {
-                public void invokeHook(Object hook) 
+                public void invokeHook(Object hook)
                 {
                     ((ListenerHook) hook).
-                        added(m_dispatcher.wrapAllServiceListeners());                    
-                }                
+                        added(m_dispatcher.wrapAllServiceListeners());
+                }
             });
         }
 
@@ -2830,23 +2830,23 @@
         List findHooks = m_registry.getFindHooks();
         for (int i = 0; i < findHooks.size(); i++)
         {
-            ServiceRegistry.invokeHook(findHooks.get(i), this, new InvokeHookCallback() 
+            ServiceRegistry.invokeHook(findHooks.get(i), this, new InvokeHookCallback()
             {
-                public void invokeHook(Object hook) 
+                public void invokeHook(Object hook)
                 {
                     ((FindHook) hook).find(bundle.getBundleContext(),
                         className,
                         expr,
                         !checkAssignable,
                         new ShrinkableCollection(refList));
-                }                
+                }
             });
         }
 
         if (refList.size() > 0)
         {
             return (ServiceReference[]) refList.toArray(new ServiceReference[refList.size()]);
-        } 
+        }
 
         return null;
     }
@@ -3627,9 +3627,9 @@
      * @param event The service event to fire.
      * @param reg The service registration associated with the service object.
     **/
-    private void fireServiceEvent(ServiceEvent event, ServiceRegistration reg)
+    private void fireServiceEvent(ServiceEvent event, Dictionary oldProps)
     {
-        m_dispatcher.fireServiceEvent(event, reg, this);
+        m_dispatcher.fireServiceEvent(event, oldProps, this);
     }
 
     //
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 8673eb6..8e2b055 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -23,6 +23,7 @@
 import java.security.PrivilegedExceptionAction;
 import java.util.*;
 
+import org.apache.felix.framework.util.MapToDictionary;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.moduleloader.IModule;
@@ -96,7 +97,7 @@
 
     public void setProperties(Dictionary dict)
     {
-        Map oldProps, newProps;
+        Map oldProps;
         synchronized (this)
         {
             // Make sure registration is valid.
@@ -109,11 +110,9 @@
             oldProps = m_propMap;
             // Set the properties.
             initializeProperties(dict);
-            // Keep local reference to new properties.
-            newProps = m_propMap;
         }
         // Tell registry about it.
-        m_registry.servicePropertiesModified(this, oldProps, newProps);
+        m_registry.servicePropertiesModified(this, new MapToDictionary(oldProps));
     }
 
     public void unregister()
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 09d29a6..ebd42f6 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -78,7 +78,7 @@
             // Create the service registration.
             reg = new ServiceRegistrationImpl(
                 this, bundle, classNames, new Long(m_currentServiceId++), svcObj, dict);
-                        
+
             // Keep track of registered hooks.
             addHooks(classNames, svcObj, reg);
 
@@ -91,7 +91,7 @@
         if (m_callbacks != null)
         {
             m_callbacks.serviceChanged(
-                new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()), reg);
+                new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()), null);
         }
         return reg;
     }
@@ -118,7 +118,7 @@
         if (m_callbacks != null)
         {
             m_callbacks.serviceChanged(
-                new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()), reg);
+                new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()), null);
         }
 
         // Now forcibly unget the service object for all stubborn clients.
@@ -508,12 +508,12 @@
         return bundles;
     }
 
-    void servicePropertiesModified(ServiceRegistration reg, Map oldProps, Map newProps)
+    void servicePropertiesModified(ServiceRegistration reg, Dictionary oldProps)
     {
         if (m_callbacks != null)
         {
             m_callbacks.serviceChanged(
-                new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()), reg);
+                new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()), oldProps);
         }
     }
 
@@ -701,7 +701,7 @@
     private static Object[] addHookToArray(Object[] src, Object svcObj, ServiceRegistration reg)
     {
         Object hookRef = getHookRef(svcObj, reg);
-        
+
         Object[] dst = new Object[src.length + 1];
         System.arraycopy(src, 0, dst, 0, src.length);
         dst[src.length] = hookRef;
@@ -710,11 +710,11 @@
 
     boolean isHook(String[] classNames, Class hookClass, Object svcObj)
     {
-        if (svcObj instanceof ServiceFactory) 
+        if (svcObj instanceof ServiceFactory)
         {
             return Arrays.asList(classNames).contains(hookClass.getName());
         }
-        
+
         if (hookClass.isAssignableFrom(svcObj.getClass()))
         {
             String hookName = hookClass.getName();
@@ -729,20 +729,20 @@
         return false;
     }
 
-    private void removeHook(ServiceRegistration reg) 
+    private void removeHook(ServiceRegistration reg)
     {
         Object svcObj = ((ServiceRegistrationImpl) reg).getService();
         String [] classNames = (String[]) reg.getReference().getProperty(Constants.OBJECTCLASS);
-        
-        if (isHook(classNames, EventHook.class, svcObj)) 
+
+        if (isHook(classNames, EventHook.class, svcObj))
         {
-            synchronized (m_eventHookLock) 
+            synchronized (m_eventHookLock)
             {
                 m_eventHooks = removeFromHookArray(m_eventHooks, svcObj, reg);
             }
         }
-        
-        if (isHook(classNames, FindHook.class, svcObj)) 
+
+        if (isHook(classNames, FindHook.class, svcObj))
         {
             synchronized (m_findHookLock)
             {
@@ -769,10 +769,10 @@
             boolean found = false;
             if (svcObj instanceof ServiceFactory)
             {
-                if (src[i] instanceof Object[]) 
+                if (src[i] instanceof Object[])
                 {
                     Object [] arrElem = (Object []) src[i];
-                    if (arrElem[0].equals(svcObj) && arrElem[1].equals(reg)) 
+                    if (arrElem[0].equals(svcObj) && arrElem[1].equals(reg))
                     {
                         found = true;
                     }
@@ -783,10 +783,10 @@
                 if (src[i].equals(svcObj))
                 {
                     found = true;
-                }                
+                }
             }
-            
-            if (found) 
+
+            if (found)
             {
                 idx = i;
                 break;
@@ -839,7 +839,7 @@
     }
 
     /**
-     * Returns a hook reference object that can be passed to the 
+     * Returns a hook reference object that can be passed to the
      * {@link #invokeHook(Object, Framework, InvokeHookCallback)} method.
      * @param svcObj The Service Object. Either the service itself, or a <tt>ServiceFactory</tt>
      *        object.
@@ -849,9 +849,9 @@
      *         cases the svcObj is returned as passed in. This is the behavior expected
      *         by the {@link #invokeHook(Object, Framework, InvokeHookCallback)} method.
      */
-    static Object getHookRef(Object svcObj, ServiceRegistration reg) 
+    static Object getHookRef(Object svcObj, ServiceRegistration reg)
     {
-        if (svcObj instanceof ServiceFactory) 
+        if (svcObj instanceof ServiceFactory)
         {
             return new Object[] {svcObj, reg};
         }
@@ -860,16 +860,16 @@
             return svcObj;
         }
     }
-    
+
     /**
      * Invokes a Service Registry Hook
-     * @param hookRef The hook to be invoked, this is an element on the list returned by the 
+     * @param hookRef The hook to be invoked, this is an element on the list returned by the
      *        {@link #getEventHooks()}, {@link #getFindHooks()} or {@link #getListenerHooks()}
      *        methods. It could either contain the hook object itself or an Object[2] when a
      *        ServiceFactory is used. In that case the first element is the hook ServiceFactory
      *        and the second element is its ServiceRegistration.
      * @param framework The framework that is invoking the hook, typically the Felix object.
-     * @param callback This is a callback object that is invoked with the actual hook object to 
+     * @param callback This is a callback object that is invoked with the actual hook object to
      *        be used, either the plain hook, or one obtained from the ServiceFactory.
      */
     public static void invokeHook(
@@ -877,37 +877,37 @@
     {
         Object hook;
         boolean serviceFactory;
-        if (hookRef instanceof Object[]) 
+        if (hookRef instanceof Object[])
         {
             serviceFactory = true;
-            Object[] array = (Object[]) hookRef; 
+            Object[] array = (Object[]) hookRef;
             ServiceFactory hookFactory = (ServiceFactory) array[0];
             ServiceRegistration sr = (ServiceRegistration) array[1];
             hook = hookFactory.getService(framework, sr);
         }
         else
         {
-            serviceFactory = false; 
+            serviceFactory = false;
             hook = hookRef;
         }
-        
-        try 
+
+        try
         {
             callback.invokeHook(hook);
             // TODO: SERVICE HOOKS - Check that "services in use" is handled
         }
         finally
         {
-            if (serviceFactory) 
+            if (serviceFactory)
             {
-                Object [] array = (Object []) hookRef; 
+                Object [] array = (Object []) hookRef;
                 ServiceFactory hookFactory = (ServiceFactory) array[0];
                 ServiceRegistration sr = (ServiceRegistration) array[1];
                 hookFactory.ungetService(framework, sr, hook);
             }
-        }        
-    }    
-    
+        }
+    }
+
     private static class UsageCount
     {
         public int m_count = 0;
@@ -917,6 +917,6 @@
 
     public interface ServiceRegistryCallbacks
     {
-        void serviceChanged(ServiceEvent event, ServiceRegistration reg);
+        void serviceChanged(ServiceEvent event, Dictionary oldProps);
     }
 }
\ No newline at end of file
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 9b6b444..a74f0b9 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,13 +22,13 @@
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Dictionary;
 import java.util.EventListener;
 import java.util.EventObject;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 
-import java.util.Set;
 import org.apache.felix.framework.InvokeHookCallback;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.ServiceRegistry;
@@ -45,7 +45,6 @@
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.framework.hooks.service.EventHook;
 import org.osgi.framework.hooks.service.ListenerHook;
@@ -57,9 +56,8 @@
     static final int LISTENER_CLASS_OFFSET = 1;
     static final int LISTENER_OBJECT_OFFSET = 2;
     static final int LISTENER_FILTER_OFFSET = 3;
-    static final int LISTENER_MATECHEDSET_OFFSET = 4;
-    static final int LISTENER_SECURITY_OFFSET = 5;
-    static final int LISTENER_ARRAY_INCREMENT = 6;
+    static final int LISTENER_SECURITY_OFFSET = 4;
+    static final int LISTENER_ARRAY_INCREMENT = 5;
 
     private Logger m_logger = null;
     private volatile ServiceRegistry m_serviceRegistry = null;
@@ -201,7 +199,6 @@
         synchronized (this)
         {
             Object[] listeners = null;
-            Set set = null;
             Object acc = null;
 
             if (clazz == FrameworkListener.class)
@@ -231,7 +228,6 @@
                 // registrations so we can fire ServiceEvent.MODIFIED_ENDMATCH
                 // events. We need a Set even if filter is null, since the
                 // listener can be updated and have a filter added later.
-                set = new SmallSet();
                 listeners = m_serviceListeners;
             }
             else
@@ -247,7 +243,6 @@
                 listeners[LISTENER_CLASS_OFFSET] = clazz;
                 listeners[LISTENER_OBJECT_OFFSET] = l;
                 listeners[LISTENER_FILTER_OFFSET] = filter;
-                listeners[LISTENER_MATECHEDSET_OFFSET] = set;
                 listeners[LISTENER_SECURITY_OFFSET] = acc;
             }
             // Otherwise, we need to do some array copying.
@@ -263,7 +258,6 @@
                 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_MATECHEDSET_OFFSET] = set;
                 newList[listeners.length + LISTENER_SECURITY_OFFSET] = acc;
                 listeners = newList;
             }
@@ -533,7 +527,6 @@
                     {
                         // The spec says to update the filter in this case.
                         listeners[i + LISTENER_FILTER_OFFSET] = filter;
-                        ((Set) listeners[i + LISTENER_MATECHEDSET_OFFSET]).clear();
                     }
                     return true;
                 }
@@ -607,7 +600,8 @@
         }
 
         // Fire synchronous bundle listeners immediately on the calling thread.
-        fireEventImmediately(m_logger, Request.BUNDLE_EVENT, syncListeners, event, null);
+        fireEventImmediately(
+            m_logger, Request.BUNDLE_EVENT, syncListeners, event, null);
 
         // The spec says that asynchronous bundle listeners do not get events
         // of types STARTING, STOPPING, or LAZY_ACTIVATION.
@@ -621,7 +615,7 @@
     }
 
     public void fireServiceEvent(
-        final ServiceEvent event, final ServiceRegistration reg, final Framework felix)
+        final ServiceEvent event, final Dictionary oldProps, final Framework felix)
     {
         // Take a snapshot of the listener array.
         Object[] listeners = null;
@@ -639,14 +633,14 @@
                     new ListenerBundleContextCollectionWrapper(listeners);
                 for (int i = 0; i < eventHooks.size(); i++)
                 {
-                    if (felix != null) 
+                    if (felix != null)
                     {
-                        ServiceRegistry.invokeHook(eventHooks.get(i), felix, new InvokeHookCallback() 
+                        ServiceRegistry.invokeHook(eventHooks.get(i), felix, new InvokeHookCallback()
                         {
-                            public void invokeHook(Object hook) 
+                            public void invokeHook(Object hook)
                             {
-                                ((EventHook) hook).event(event, wrapper);                            
-                            }                        
+                                ((EventHook) hook).event(event, wrapper);
+                            }
                         });
                     }
                 }
@@ -656,7 +650,8 @@
         }
 
         // Fire all service events immediately on the calling thread.
-        fireEventImmediately(m_logger, Request.SERVICE_EVENT, listeners, event, reg);
+        fireEventImmediately(
+            m_logger, Request.SERVICE_EVENT, listeners, event, oldProps);
     }
 
     private void fireEventAsynchronously(
@@ -700,8 +695,7 @@
     }
 
     private static void fireEventImmediately(
-        Logger logger, int type, Object[] listeners, EventObject event,
-        ServiceRegistration reg)
+        Logger logger, int type, Object[] listeners, EventObject event, Dictionary oldProps)
     {
         if (listeners.length > 0)
         {
@@ -713,7 +707,6 @@
                 Bundle bundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
                 EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
                 Filter filter = (Filter) listeners[i + LISTENER_FILTER_OFFSET];
-                Set matchedSet = (Set) listeners[i + LISTENER_MATECHEDSET_OFFSET];
                 Object acc = listeners[i + LISTENER_SECURITY_OFFSET];
                 try
                 {
@@ -728,7 +721,7 @@
                     else if (type == Request.SERVICE_EVENT)
                     {
                         invokeServiceListenerCallback(
-                            bundle, l, filter, matchedSet, acc, event, reg);
+                            bundle, l, filter, acc, event, oldProps);
                     }
                 }
                 catch (Throwable th)
@@ -801,9 +794,8 @@
     }
 
     private static void invokeServiceListenerCallback(
-        Bundle bundle, final EventListener l, Filter filter,
-        Set matchedSet, Object acc, final EventObject event,
-        final ServiceRegistration reg)
+        Bundle bundle, final EventListener l, Filter filter, Object acc,
+        final EventObject event, final Dictionary oldProps)
     {
         // Service events should be delivered to STARTING,
         // STOPPING, and ACTIVE bundles.
@@ -862,16 +854,6 @@
                     if ((l instanceof AllServiceListener) ||
                         Util.isServiceAssignable(bundle, ((ServiceEvent) event).getServiceReference()))
                     {
-                        // If we have a filter, then record the matching service
-                        // registration so we can know when to fire a MODIFIED_ENDMATCH
-                        // event if the filter no longer matches.
-                        if (filter != null)
-                        {
-                            synchronized (matchedSet)
-                            {
-                                matchedSet.add(reg);
-                            }
-                        }
                         if (System.getSecurityManager() != null)
                         {
                             AccessController.doPrivileged(new PrivilegedAction() {
@@ -892,12 +874,7 @@
                 // matched previously.
                 else if (((ServiceEvent) event).getType() == ServiceEvent.MODIFIED)
                 {
-                    boolean removed = false;
-                    synchronized (matchedSet)
-                    {
-                        removed = matchedSet.remove(reg);
-                    }
-                    if (removed)
+                    if (filter.match(oldProps))
                     {
                         final ServiceEvent se = new ServiceEvent(
                             ServiceEvent.MODIFIED_ENDMATCH,
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java b/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java
deleted file mode 100644
index 567a0c5..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java
+++ /dev/null
@@ -1,198 +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.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-public class SmallSet implements Set
-{
-    private Object[] m_objs;
-    private Set m_set;
-
-    public synchronized int size()
-    {
-        if (m_objs != null)
-        {
-            return m_objs.length;
-        }
-        else if (m_set != null)
-        {
-            return m_set.size();
-        }
-        return 0;
-    }
-
-    public synchronized boolean isEmpty()
-    {
-        return (size() == 0);
-    }
-
-    public synchronized boolean contains(Object obj)
-    {
-        boolean found = false;
-        if (obj != null)
-        {
-            if (m_objs != null)
-            {
-                for (int i = 0; !found && (i < m_objs.length); i++)
-                {
-                    found = m_objs[i].equals(obj);
-                }
-            }
-            else
-            {
-                found = (m_set == null) ? false : m_set.contains(obj);
-            }
-        }
-        return found;
-    }
-
-    public synchronized Iterator iterator()
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized Object[] toArray()
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized Object[] toArray(Object[] arg0)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized boolean add(Object obj)
-    {
-        boolean found = contains(obj);
-        if (!found)
-        {
-            if (size() < 10)
-            {
-                if (m_objs == null)
-                {
-                    m_objs = new Object[] { obj };
-                }
-                else
-                {
-                    Object[] tobjs = new Object[m_objs.length + 1];
-                    System.arraycopy(m_objs, 0, tobjs, 0, m_objs.length);
-                    tobjs[m_objs.length] = obj;
-                    m_objs = tobjs;
-                }
-            }
-            else
-            {
-                if (m_set == null)
-                {
-                    m_set = new HashSet();
-                    for (int i = 0; i < m_objs.length; i++)
-                    {
-                        m_set.add(m_objs[i]);
-                    }
-                    m_objs = null;
-                }
-                m_set.add(obj);
-            }
-        }
-        return !found;
-    }
-
-    public synchronized boolean remove(Object obj)
-    {
-        boolean found = contains(obj);
-        if (found)
-        {
-            if (size() < 10)
-            {
-                if (m_objs.length == 1)
-                {
-                    m_objs = null;
-                }
-                else
-                {
-                    int idx = -1;
-                    for (int i = 0; (idx < 0) && (i < m_objs.length); i++)
-                    {
-                        if (m_objs[i].equals(obj))
-                        {
-                            idx = i;
-                        }
-                    }
-
-                    if (idx >= 0)
-                    {
-                        Object[] tobjs = new Object[m_objs.length - 1];
-                        System.arraycopy(m_objs, 0, tobjs, 0, idx);
-                        if (idx < tobjs.length)
-                        {
-                            System.arraycopy(
-                                m_objs, idx + 1, tobjs, idx, tobjs.length - idx);
-                        }
-                        m_objs = tobjs;
-                    }
-                }
-            }
-            else
-            {
-                m_set.remove(obj);
-                if (m_set.size() < 10)
-                {
-                    m_objs = new Object[m_set.size()];
-                    int i = 0;
-                    for (Iterator it = m_set.iterator(); it.hasNext(); )
-                    {
-                        m_objs[i++] = it.next();
-                    }
-                    m_set = null;
-                }
-            }
-        }
-        return found;
-    }
-
-    public synchronized boolean containsAll(Collection arg0)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized boolean addAll(Collection arg0)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized boolean retainAll(Collection arg0)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized boolean removeAll(Collection arg0)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized void clear()
-    {
-        m_objs = null;
-        m_set = 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
index 90d1f20..ce0b3e7 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
@@ -49,19 +49,16 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
         };
 
@@ -138,13 +135,11 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             new Integer(15)        // LISTENER_SECURITY_OFFSET
         };
 
@@ -279,19 +274,16 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
         };
 
@@ -332,19 +324,16 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
         };
 
@@ -381,19 +370,16 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             Boolean.TRUE,          // LISTENER_SECURITY_OFFSET
         };
 
@@ -433,13 +419,11 @@
             String.class,          // LISTENER_CLASS_OFFSET
             new Object(),          // LISTENER_OBJECT_OFFSET
             "(some=filter)",       // LISTENER_FILTER_OFFSET
-            null,                  // LISTENER_MATECHEDSET_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
-            null,                  // LISTENER_MATECHEDSET_OFFSET
             new Integer(15),       // LISTENER_SECURITY_OFFSET
         };
 
@@ -484,4 +468,4 @@
 
         return b;
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
index 62a1791..b66cff9 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
@@ -181,4 +181,4 @@
 
         return b;
     }
-}
+}
\ No newline at end of file