Refactor service hooks to use new service registry hook tracking mechanism
put in place for byte-code weaving hooks. (FELIX-2959)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1127208 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index 41c7b0d..e8014ea 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -1363,7 +1363,7 @@
                     // as a race condition, doing any necessary clean up in
                     // the error handling.
                     Felix felix = ((BundleImpl) m_revision.getBundle()).getFramework();
-                    SortedSet<ServiceReference<WeavingHook>> hooks =
+                    Set<ServiceReference<WeavingHook>> hooks =
                         felix.getHooks(WeavingHook.class);
                     WovenClassImpl wci = null;
                     if ((hooks != null) && !hooks.isEmpty())
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 387c334..0dfcf10 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2897,17 +2897,17 @@
         }
 
         // Invoke ListenerHook.removed() if filter updated.
-        List listenerHooks = m_registry.getListenerHooks();
+        Set<ServiceReference<ListenerHook>> listenerHooks =
+            m_registry.getHooks(ListenerHook.class);
         if (oldFilter != null)
         {
             final Collection removed = Collections.singleton(
                 new ListenerHookInfoImpl(
                 ((BundleImpl) bundle)._getBundleContext(), l, oldFilter.toString(), true));
             InvokeHookCallback removedCallback = new ListenerHookRemovedCallback(removed);
-            for (int i = 0; i < listenerHooks.size(); i++)
+            for (ServiceReference<ListenerHook> sr : listenerHooks)
             {
-                m_registry.invokeHook(
-                    (ServiceReference) listenerHooks.get(i), this, removedCallback);
+                m_registry.invokeHook(sr, this, removedCallback);
             }
         }
 
@@ -2921,9 +2921,9 @@
                 ((ListenerHook) hook).added(added);
             }
         };
-        for (int i = 0; i < listenerHooks.size(); i++)
+        for (ServiceReference<ListenerHook> sr : listenerHooks)
         {
-            m_registry.invokeHook((ServiceReference) listenerHooks.get(i), this, addedCallback);
+            m_registry.invokeHook(sr, this, addedCallback);
         }
     }
 
@@ -2942,12 +2942,13 @@
         if (listener != null)
         {
             // Invoke the ListenerHook.removed() on all hooks.
-            List listenerHooks = m_registry.getListenerHooks();
+            Set<ServiceReference<ListenerHook>> listenerHooks =
+                m_registry.getHooks(ListenerHook.class);
             Collection c = Collections.singleton(listener);
             InvokeHookCallback callback = new ListenerHookRemovedCallback(c);
-            for (int i = 0; i < listenerHooks.size(); i++)
+            for (ServiceReference<ListenerHook> sr : listenerHooks)
             {
-                m_registry.invokeHook((ServiceReference) listenerHooks.get(i), this, callback);
+                m_registry.invokeHook(sr, this, callback);
             }
         }
     }
@@ -3122,7 +3123,8 @@
         }
 
         // activate findhooks
-        List findHooks = m_registry.getFindHooks();
+        Set<ServiceReference<FindHook>> findHooks =
+            m_registry.getHooks(FindHook.class);
         InvokeHookCallback callback = new InvokeHookCallback()
         {
             public void invokeHook(Object hook)
@@ -3134,9 +3136,9 @@
                     new ShrinkableCollection(refList));
             }
         };
-        for (int i = 0; i < findHooks.size(); i++)
+        for (ServiceReference<FindHook> sr : findHooks)
         {
-            m_registry.invokeHook((ServiceReference) findHooks.get(i), this, callback);
+            m_registry.invokeHook(sr, this, callback);
         }
 
         if (refList.size() > 0)
@@ -3247,7 +3249,7 @@
         m_registry.blackListHook(sr);
     }
 
-    public <S> SortedSet<ServiceReference<S>> getHooks(Class<S> hookClass)
+    public <S> Set<ServiceReference<S>> getHooks(Class<S> hookClass)
     {
         return m_registry.getHooks(hookClass);
     }
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 1de5e35..98d6026 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -50,19 +50,15 @@
     private final WeakHashMap<ServiceReference, ServiceReference> m_blackList =
         new WeakHashMap<ServiceReference, ServiceReference>();
 
-    private final Class<?>[] m_hookClasses = {
+    private final static Class<?>[] m_hookClasses = {
+        EventHook.class,
+        FindHook.class,
+        ListenerHook.class,
         WeavingHook.class
     };
     private final Map<Class<?>, Set<ServiceReference<?>>> m_allHooks =
         new HashMap<Class<?>, Set<ServiceReference<?>>>();
 
-    private final Set<ServiceReference> m_eventHooks =
-        new TreeSet<ServiceReference>(Collections.reverseOrder());
-    private final Set<ServiceReference> m_findHooks =
-        new TreeSet<ServiceReference>(Collections.reverseOrder());
-    private final Set<ServiceReference> m_listenerHooks =
-        new TreeSet<ServiceReference>(Collections.reverseOrder());
-
     public ServiceRegistry(Logger logger, ServiceRegistryCallbacks callbacks)
     {
         m_logger = logger;
@@ -664,94 +660,28 @@
         m_blackList.put(sr, sr);
     }
 
-    private void addHooks(String[] classNames, Object svcObj, ServiceReference<?> ref)
+    static boolean isHook(String[] classNames, Class<?> hookClass, Object svcObj)
     {
-        Class<?> hookClass = isHook(classNames, m_hookClasses, svcObj);
-        if (hookClass != null)
-        {
-            synchronized (m_allHooks)
-            {
-                Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
-                if (hooks == null)
-                {
-                    hooks = new HashSet<ServiceReference<?>>();
-                    m_allHooks.put(hookClass, hooks);
-                }
-                hooks.add(ref);
-            }
-        }
-
-        if (isHook(classNames, EventHook.class, svcObj))
-        {
-            synchronized (m_eventHooks)
-            {
-                m_eventHooks.add(ref);
-            }
-        }
-
-        if (isHook(classNames, FindHook.class, svcObj))
-        {
-            synchronized (m_findHooks)
-            {
-                m_findHooks.add(ref);
-            }
-        }
-
-        if (isHook(classNames, ListenerHook.class, svcObj))
-        {
-            synchronized (m_listenerHooks)
-            {
-                m_listenerHooks.add(ref);
-            }
-        }
-    }
-
-    static Class<?> isHook(String[] classNames, Class<?>[] hookClasses, Object svcObj)
-    {
-        for (Class<?> hookClass : hookClasses)
-        {
-            // For a service factory, we can only match names.
-            if (svcObj instanceof ServiceFactory)
-            {
-                for (String className : classNames)
-                {
-                    if (className.equals(hookClass.getName()))
-                    {
-                        return hookClass;
-                    }
-                }
-            }
-
-            // For a service object, check if its class matches.
-            if (hookClass.isAssignableFrom(svcObj.getClass()))
-            {
-                // But still only if it is registered under that interface.
-                String hookName = hookClass.getName();
-                for (String className : classNames)
-                {
-                    if (className.equals(hookName))
-                    {
-                        return hookClass;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    static boolean isHook(String[] classNames, Class hookClass, Object svcObj)
-    {
+        // For a service factory, we can only match names.
         if (svcObj instanceof ServiceFactory)
         {
-            return Arrays.asList(classNames).contains(hookClass.getName());
+            for (String className : classNames)
+            {
+                if (className.equals(hookClass.getName()))
+                {
+                    return true;
+                }
+            }
         }
 
+        // For a service object, check if its class matches.
         if (hookClass.isAssignableFrom(svcObj.getClass()))
         {
+            // But still only if it is registered under that interface.
             String hookName = hookClass.getName();
-            for (int i = 0; i < classNames.length; i++)
+            for (String className : classNames)
             {
-                if (classNames[i].equals(hookName))
+                if (className.equals(hookName))
                 {
                     return true;
                 }
@@ -760,55 +690,53 @@
         return false;
     }
 
+    private void addHooks(String[] classNames, Object svcObj, ServiceReference<?> ref)
+    {
+        for (Class<?> hookClass : m_hookClasses)
+        {
+            if (isHook(classNames, hookClass, svcObj))
+            {
+                synchronized (m_allHooks)
+                {
+                    Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
+                    if (hooks == null)
+                    {
+                        hooks = new HashSet<ServiceReference<?>>();
+                        m_allHooks.put(hookClass, hooks);
+                    }
+                    hooks.add(ref);
+                }
+            }
+        }
+    }
+
     private void removeHook(ServiceReference ref)
     {
         Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
             .getRegistration().getService();
         String [] classNames = (String[]) ref.getProperty(Constants.OBJECTCLASS);
 
-        Class hookClass = isHook(classNames, m_hookClasses, svcObj);
-        if (hookClass != null)
+        for (Class<?> hookClass : m_hookClasses)
         {
-            synchronized (m_allHooks)
+            if (isHook(classNames, hookClass, svcObj))
             {
-                Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
-                if (hooks != null)
+                synchronized (m_allHooks)
                 {
-                    hooks.remove(ref);
-                    if (hooks.isEmpty())
+                    Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
+                    if (hooks != null)
                     {
-                        m_allHooks.remove(hookClass);
+                        hooks.remove(ref);
+                        if (hooks.isEmpty())
+                        {
+                            m_allHooks.remove(hookClass);
+                        }
                     }
                 }
             }
         }
-
-        if (isHook(classNames, EventHook.class, svcObj))
-        {
-            synchronized (m_eventHooks)
-            {
-                m_eventHooks.remove(ref);
-            }
-        }
-
-        if (isHook(classNames, FindHook.class, svcObj))
-        {
-            synchronized (m_findHooks)
-            {
-                m_findHooks.remove(ref);
-            }
-        }
-
-        if (isHook(classNames, ListenerHook.class, svcObj))
-        {
-            synchronized (m_listenerHooks)
-            {
-                m_listenerHooks.remove(ref);
-            }
-        }
     }
 
-    public <S> SortedSet<ServiceReference<S>> getHooks(Class<S> hookClass)
+    public <S> Set<ServiceReference<S>> getHooks(Class<S> hookClass)
     {
         synchronized (m_allHooks)
         {
@@ -819,7 +747,7 @@
                 sorted.addAll(hooks);
                 return asTypedSortedSet(sorted);
             }
-            return null;
+            return Collections.EMPTY_SET;
         }
     }
 
@@ -829,30 +757,6 @@
         return (SortedSet<ServiceReference<S>>) (SortedSet) ss;
     }
 
-    public List getEventHooks()
-    {
-        synchronized (m_eventHooks)
-        {
-            return new ArrayList(m_eventHooks);
-        }
-    }
-
-    List getFindHooks()
-    {
-        synchronized (m_findHooks)
-        {
-            return new ArrayList(m_findHooks);
-        }
-    }
-
-    List getListenerHooks()
-    {
-        synchronized (m_listenerHooks)
-        {
-            return new ArrayList(m_listenerHooks);
-        }
-    }
-
     /**
      * Invokes a Service Registry Hook
      * @param ref The ServiceReference associated with the hook to be invoked, the hook
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 548e3ff..6b7c8a1 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
@@ -28,6 +28,7 @@
 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;
@@ -37,7 +38,6 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.FrameworkListener;
@@ -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;
@@ -286,7 +285,7 @@
         }
         return null;
     }
-    
+
     public ListenerHook.ListenerInfo removeListener(
         Bundle bundle, Class clazz, EventListener l)
     {
@@ -577,7 +576,7 @@
 
         return new ListenerHookInfoImpl(
             ((Bundle)listeners[offset + LISTENER_BUNDLE_OFFSET]).getBundleContext(),
-            (ServiceListener) listeners[offset + LISTENER_OBJECT_OFFSET], 
+            (ServiceListener) listeners[offset + LISTENER_OBJECT_OFFSET],
             filter == null ? null : filter.toString(),
             removed);
     }
@@ -633,24 +632,24 @@
 
         if (m_serviceRegistry != null)
         {
-            List eventHooks = m_serviceRegistry.getEventHooks();
-            if ((eventHooks != null) && (eventHooks.size() > 0))
+            Set<ServiceReference<EventHook>> eventHooks =
+                m_serviceRegistry.getHooks(EventHook.class);
+            if ((eventHooks != null) && !eventHooks.isEmpty())
             {
                 final ListenerBundleContextCollectionWrapper wrapper =
                     new ListenerBundleContextCollectionWrapper(listeners);
-                InvokeHookCallback callback = new InvokeHookCallback() 
+                InvokeHookCallback callback = new InvokeHookCallback()
                 {
-                    public void invokeHook(Object hook) 
+                    public void invokeHook(Object hook)
                     {
-                        ((EventHook) hook).event(event, wrapper);                            
-                    }                        
-                }; 
-                for (int i = 0; i < eventHooks.size(); i++)
+                        ((EventHook) hook).event(event, wrapper);
+                    }
+                };
+                for (ServiceReference<EventHook> sr : eventHooks)
                 {
-                    if (felix != null) 
+                    if (felix != null)
                     {
-                        m_serviceRegistry.invokeHook(
-                            (ServiceReference) eventHooks.get(i), felix, callback);
+                        m_serviceRegistry.invokeHook(sr, felix, callback);
                     }
                 }
 
@@ -857,7 +856,7 @@
                 {
                     if (System.getSecurityManager() != null)
                     {
-                        AccessController.doPrivileged(new PrivilegedAction() 
+                        AccessController.doPrivileged(new PrivilegedAction()
                         {
                             public Object run()
                             {
@@ -883,7 +882,7 @@
                         ((ServiceEvent) event).getServiceReference());
                     if (System.getSecurityManager() != null)
                     {
-                        AccessController.doPrivileged(new PrivilegedAction() 
+                        AccessController.doPrivileged(new PrivilegedAction()
                         {
                             public Object run()
                             {
diff --git a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
index 7034774..ac1c25d 100644
--- a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -37,343 +37,343 @@
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.framework.launch.Framework;
 
-public class ServiceRegistryTest extends TestCase 
+public class ServiceRegistryTest extends TestCase
 {
-    public void testRegisterEventHookService() 
+    public void testRegisterEventHookService()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
-        EventHook hook = new EventHook() 
+        EventHook hook = new EventHook()
         {
-            public void event(ServiceEvent event, Collection contexts) 
+            public void event(ServiceEvent event, Collection contexts)
             {
-            }            
+            }
         };
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, hook, new Hashtable());
-        assertEquals(1, sr.getEventHooks().size());
-        assertTrue(sr.getEventHooks().iterator().next() instanceof ServiceReference);
-        assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
+        assertEquals(1, sr.getHooks(EventHook.class).size());
+        assertTrue(sr.getHooks(EventHook.class).iterator().next() instanceof ServiceReference);
+        assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
-        assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
-        
+        assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
+
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterEventHookServiceFactory() 
+    public void testRegisterEventHookServiceFactory()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
         ServiceFactory sf = (ServiceFactory) sfControl.getMock();
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, sf, new Hashtable());
-        assertEquals(1, sr.getEventHooks().size());
-        assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
-        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());        
-        assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
+        assertEquals(1, sr.getHooks(EventHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
+        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
+        assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
-    
-    public void testRegisterFindHookService() 
+
+    public void testRegisterFindHookService()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
-        FindHook hook = new FindHook() 
+        FindHook hook = new FindHook()
         {
             public void find(BundleContext context, String name, String filter,
-                boolean allServices, Collection references) 
+                boolean allServices, Collection references)
             {
             }
         };
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, hook, new Hashtable());
-        assertEquals(1, sr.getFindHooks().size());
-        assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
+        assertEquals(1, sr.getHooks(FindHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
-        assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterFindHookServiceFactory() 
+    public void testRegisterFindHookServiceFactory()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
         ServiceFactory sf = (ServiceFactory) sfControl.getMock();
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, sf, new Hashtable());
-        assertEquals(1, sr.getFindHooks().size());
-        assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
-        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());        
-        assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
+        assertEquals(1, sr.getHooks(FindHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
+        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
+        assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterListenerHookService() 
+    public void testRegisterListenerHookService()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
-        ListenerHook hook = new ListenerHook() 
+        ListenerHook hook = new ListenerHook()
         {
-            public void added(Collection listeners) 
+            public void added(Collection listeners)
             {
             }
 
-            public void removed(Collection listener) 
+            public void removed(Collection listener)
             {
             }
         };
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
-        assertEquals(1, sr.getListenerHooks().size());
-        assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
+        assertEquals(1, sr.getHooks(ListenerHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
-        assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterListenerHookServiceFactory() 
+    public void testRegisterListenerHookServiceFactory()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
         ServiceFactory sf = (ServiceFactory) sfControl.getMock();
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
-        assertEquals(1, sr.getListenerHooks().size());
-        assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
-        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());        
-        assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
+        assertEquals(1, sr.getHooks(ListenerHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
+        assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
+        assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterCombinedService() 
+    public void testRegisterCombinedService()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         class CombinedService implements ListenerHook, FindHook, EventHook, Runnable
         {
-            public void added(Collection listeners) 
+            public void added(Collection listeners)
             {
             }
 
-            public void removed(Collection listener) 
+            public void removed(Collection listener)
             {
             }
 
             public void find(BundleContext context, String name, String filter,
-                    boolean allServices, Collection references) 
+                    boolean allServices, Collection references)
             {
             }
 
-            public void event(ServiceEvent event, Collection contexts) 
+            public void event(ServiceEvent event, Collection contexts)
             {
             }
 
-            public void run() 
+            public void run()
             {
             }
-            
+
         }
         CombinedService hook = new CombinedService();
-        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {
             Runnable.class.getName(),
             ListenerHook.class.getName(),
             FindHook.class.getName(),
             EventHook.class.getName()}, hook, new Hashtable());
-        assertEquals(1, sr.getListenerHooks().size());
-        assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
+        assertEquals(1, sr.getHooks(ListenerHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
-        assertEquals(1, sr.getEventHooks().size());
-        assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
+        assertEquals(1, sr.getHooks(EventHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
-        assertEquals(1, sr.getFindHooks().size());
-        assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
+        assertEquals(1, sr.getHooks(FindHook.class).size());
+        assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
 
         sr.unregisterService(b, reg);
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getFindHooks().size());
-        assertEquals("Should be no hooks left after unregistration", 0, sr.getListenerHooks().size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Should be no hooks left after unregistration", 0, sr.getHooks(ListenerHook.class).size());
     }
 
-    public void testRegisterPlainService() 
+    public void testRegisterPlainService()
     {
         MockControl control = MockControl.createNiceControl(Bundle.class);
         Bundle b = (Bundle) control.getMock();
         control.replay();
-        
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
-        String svcObj = "hello";        
-        assertEquals("Precondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Precondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
+        String svcObj = "hello";
+        assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
         ServiceRegistration reg = sr.registerService(b, new String [] {String.class.getName()}, svcObj, new Hashtable());
-        assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
-        assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
 
         sr.unregisterService(b, reg);
-        assertEquals("Unregistration should have no effect", 0, sr.getEventHooks().size());
-        assertEquals("Unregistration should have no effect", 0, sr.getFindHooks().size());
-        assertEquals("Unregistration should have no effect", 0, sr.getListenerHooks().size());
+        assertEquals("Unregistration should have no effect", 0, sr.getHooks(EventHook.class).size());
+        assertEquals("Unregistration should have no effect", 0, sr.getHooks(FindHook.class).size());
+        assertEquals("Unregistration should have no effect", 0, sr.getHooks(ListenerHook.class).size());
     }
-    
-    public void testInvokeHook() 
+
+    public void testInvokeHook()
     {
         ServiceRegistry sr = new ServiceRegistry(null, null);
-        
+
         final List result = new ArrayList();
-        InvokeHookCallback callback = new InvokeHookCallback() 
+        InvokeHookCallback callback = new InvokeHookCallback()
         {
-            public void invokeHook(Object hook) 
+            public void invokeHook(Object hook)
             {
                 result.add(hook);
-            }            
+            }
         };
-        
+
         MockControl control = MockControl.createNiceControl(Framework.class);
         Framework fr = (Framework) control.getMock();
         control.replay();
-        
-        FindHook hook = new FindHook() 
+
+        FindHook hook = new FindHook()
         {
             public void find(BundleContext context, String name, String filter,
-                    boolean allServices, Collection references) 
+                    boolean allServices, Collection references)
             {
-            }            
+            }
         };
-        ServiceRegistration reg = new ServiceRegistrationImpl(sr, null, null, null, 
+        ServiceRegistration reg = new ServiceRegistrationImpl(sr, null, null, null,
             hook, new Hashtable());
-        
+
         assertEquals("Precondition failed", 0, result.size());
         sr.invokeHook(reg.getReference(), fr, callback);
         assertEquals(1, result.size());
         assertSame(hook, result.iterator().next());
     }
-    
-    public void testInvokeHookFactory() 
+
+    public void testInvokeHookFactory()
     {
         ServiceRegistry sr = new ServiceRegistry(null, null);
 
         final List result = new ArrayList();
-        InvokeHookCallback callback = new InvokeHookCallback() 
+        InvokeHookCallback callback = new InvokeHookCallback()
         {
-            public void invokeHook(Object hook) 
+            public void invokeHook(Object hook)
             {
                 result.add(hook);
-            }            
+            }
         };
 
         MockControl control = MockControl.createNiceControl(Framework.class);
         Framework fr = (Framework) control.getMock();
         control.replay();
-        
-        final FindHook hook = new FindHook() 
+
+        final FindHook hook = new FindHook()
         {
             public void find(BundleContext context, String name, String filter,
-                    boolean allServices, Collection references) 
+                    boolean allServices, Collection references)
             {
-            }            
+            }
         };
-        
+
         final List sfGet = new ArrayList();
         final List sfUnget = new ArrayList();
-        ServiceFactory sf = new ServiceFactory() 
+        ServiceFactory sf = new ServiceFactory()
         {
-            public Object getService(Bundle b, ServiceRegistration reg) 
+            public Object getService(Bundle b, ServiceRegistration reg)
             {
                 sfGet.add(reg);
                 return hook;
             }
 
-            public void ungetService(Bundle b, ServiceRegistration reg, Object svcObj) 
+            public void ungetService(Bundle b, ServiceRegistration reg, Object svcObj)
             {
                 sfUnget.add(reg);
                 assertSame(svcObj, hook);
-            }            
+            }
         };
 
-        ServiceRegistration reg = new ServiceRegistrationImpl(sr, null, 
-            new String[] {FindHook.class.getName()}, null, 
-            sf, new Hashtable());       
-    
+        ServiceRegistration reg = new ServiceRegistrationImpl(sr, null,
+            new String[] {FindHook.class.getName()}, null,
+            sf, new Hashtable());
+
         assertEquals("Precondition failed", 0, result.size());
         assertEquals("Precondition failed", 0, sfGet.size());
         assertEquals("Precondition failed", 0, sfUnget.size());
@@ -382,7 +382,7 @@
         assertSame(hook, result.iterator().next());
         assertEquals(1, sfGet.size());
         assertEquals(1, sfUnget.size());
-        assertSame(reg, sfGet.iterator().next());        
-        assertSame(reg, sfUnget.iterator().next());        
-    } 
+        assertSame(reg, sfGet.iterator().next());
+        assertSame(reg, sfUnget.iterator().next());
+    }
 }