FELIX-3680 track remove events concurrently

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1397881 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 89a171d..f7ef123 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -77,6 +77,7 @@
 
     private final Object enableLock = new Object();
     private final Collection<ServiceReference> added = new ArrayList<ServiceReference>();
+    private final Collection<ServiceReference> removed = new ArrayList<ServiceReference>();
 
 
     /**
@@ -223,7 +224,27 @@
                     // manage the service counter if the filter matchs
                     if ( targetFilterMatch( ref ) )
                     {
-                        m_size.decrementAndGet();
+                        synchronized ( removed )
+                        {
+                            removed.add( ref );
+                        }
+                        synchronized (enableLock)
+                        {
+                            //wait for enable to complete
+                        }
+                        boolean process;
+                        synchronized ( removed )
+                        {
+                            if (process = removed.contains( ref ))
+                            {
+                                removed.remove( ref );
+                                m_size.decrementAndGet();
+                            }
+                        }
+                        if (process)
+                        {
+                            serviceRemoved( ref );
+                        }
                     }
                     else
                     {
@@ -234,11 +255,11 @@
                                 new Object[]
                                     { m_dependencyMetadata.getName(), ref.getProperty( Constants.SERVICE_ID ), getTarget() },
                                 null );
+                        // remove the service ignoring the filter match because if the
+                        // service is bound, it has to be removed no matter what
+                        serviceRemoved( ref );
                     }
 
-                    // remove the service ignoring the filter match because if the
-                    // service is bound, it has to be removed no matter what
-                    serviceRemoved( ref );
 
                     break;
             }
@@ -589,6 +610,19 @@
                         }
                     }
                 }
+                synchronized ( removed )
+                {
+                    if (refs != null)
+                    {
+                        for (ServiceReference ref: refs)
+                        {
+                            if (!removed.contains( ref ))
+                            {
+                                removed.remove( ref );
+                            }
+                        }
+                    }
+                }
                 m_size.set( ( refs == null ) ? 0 : refs.length);
             }