FELIX-3729 make tracking count a per-component global ordering

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1424311 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
index 4d040ee..8fce1f6 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
@@ -27,7 +27,6 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
 
@@ -602,8 +601,8 @@
         m_componentRegistry.missingServicePresent( serviceReference, m_componentActor );
     }
 
-    public void registerMissingDependency( DependencyManager dependencyManager, ServiceReference serviceReference )
+    public void registerMissingDependency( DependencyManager dependencyManager, ServiceReference serviceReference, int trackingCount )
     {
-        m_componentRegistry.registerMissingDependency(dependencyManager, serviceReference);
+        m_componentRegistry.registerMissingDependency(dependencyManager, serviceReference, trackingCount );
     }
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
index 168cfc2..9887559 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
@@ -19,7 +19,6 @@
 package org.apache.felix.scr.impl;
 
 
-import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Dictionary;
@@ -131,7 +130,7 @@
     // the ConfigurationAdmin service
     private ConfigurationSupport configurationSupport;
 
-    private final Map<ServiceReference<?>, List<DependencyManager>> m_missingDependencies = new HashMap<ServiceReference<?>, List<DependencyManager>>( );
+    private final Map<ServiceReference<?>, List<Entry>> m_missingDependencies = new HashMap<ServiceReference<?>, List<Entry>>( );
 
     protected ComponentRegistry( BundleContext context )
     {
@@ -660,7 +659,7 @@
 
     public void missingServicePresent( final ServiceReference serviceReference, ComponentActorThread actor )
     {
-        final List<DependencyManager> dependencyManagers = m_missingDependencies.remove( serviceReference );
+        final List<Entry> dependencyManagers = m_missingDependencies.remove( serviceReference );
         if ( dependencyManagers != null )
         {
             actor.schedule( new Runnable()
@@ -668,9 +667,9 @@
 
                 public void run()
                 {
-                    for ( DependencyManager dm : dependencyManagers )
+                    for ( Entry entry : dependencyManagers )
                     {
-                        dm.invokeBindMethodLate( serviceReference );
+                        entry.getDm().invokeBindMethodLate( serviceReference, entry.getTrackingCount() );
                     }
                 }
 
@@ -684,20 +683,42 @@
         }
     }
 
-    public synchronized void registerMissingDependency( DependencyManager dependencyManager, ServiceReference serviceReference )
+    public synchronized void registerMissingDependency( DependencyManager dependencyManager, ServiceReference serviceReference, int trackingCount )
     {
         //check that the service reference is from scr
         if ( serviceReference.getProperty( ComponentConstants.COMPONENT_NAME ) == null || serviceReference.getProperty( ComponentConstants.COMPONENT_ID ) == null )
         {
             return;
         }
-        List<DependencyManager> dependencyManagers = m_missingDependencies.get( serviceReference );
+        List<Entry> dependencyManagers = m_missingDependencies.get( serviceReference );
         if ( dependencyManagers == null )
         {
-            dependencyManagers = new ArrayList<DependencyManager>();
+            dependencyManagers = new ArrayList<Entry>();
             m_missingDependencies.put( serviceReference, dependencyManagers );
         }
-        dependencyManagers.add( dependencyManager );
+        dependencyManagers.add( new Entry( dependencyManager, trackingCount ) );
+    }
+
+    private static class Entry
+    {
+        private final DependencyManager dm;
+        private final int trackingCount;
+
+        private Entry( DependencyManager dm, int trackingCount )
+        {
+            this.dm = dm;
+            this.trackingCount = trackingCount;
+        }
+
+        public DependencyManager getDm()
+        {
+            return dm;
+        }
+
+        public int getTrackingCount()
+        {
+            return trackingCount;
+        }
     }
 
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index d9d126e..0010225 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -28,6 +28,7 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReentrantLock;
@@ -79,6 +80,8 @@
 
     private volatile boolean m_dependenciesCollected;
 
+    private final AtomicInteger trackingCount = new AtomicInteger( );
+
     // A reference to the BundleComponentActivator
     private BundleComponentActivator m_activator;
 
@@ -236,7 +239,7 @@
             enableInternal();
             if ( !async )
             {
-                activateInternal();
+                activateInternal( trackingCount.get() );
             }
         }
         catch ( InterruptedException e )
@@ -263,7 +266,7 @@
                 {
                     try
                     {
-                        activateInternal();
+                        activateInternal( trackingCount.get() );
                     }
                     finally
                     {
@@ -309,7 +312,7 @@
             }
             if ( !async )
             {
-                deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED, true );
+                deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED, true, trackingCount.get() );
             }
             disableInternal();
         }
@@ -337,7 +340,7 @@
                 {
                     try
                     {
-                        deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED, true );
+                        deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED, true, trackingCount.get() );
                     }
                     finally
                     {
@@ -528,12 +531,12 @@
         m_state.enable( this );
     }
 
-    final boolean activateInternal()
+    final boolean activateInternal( int trackingCount )
     {
         return m_state.activate( this );
     }
 
-    final void deactivateInternal( int reason, boolean disable )
+    final void deactivateInternal( int reason, boolean disable, int trackingCount )
     {
         m_state.deactivate( this, reason, disable );
     }
@@ -696,6 +699,12 @@
         }
     }
 
+    AtomicInteger getTrackingCount()
+    {
+        return trackingCount;
+    }
+
+
     boolean initDependencyManagers()
     {
         if ( m_dependencyManagersInitialized )
@@ -769,11 +778,11 @@
         }
     }
 
-    abstract <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair );
+    abstract <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount );
 
-    abstract <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair );
+    abstract <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount );
 
-    abstract <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair );
+    abstract <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair, int trackingCount );
 
     //**********************************************************************************************************
     public BundleComponentActivator getActivator()
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index c11008d..367b93f 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -114,7 +114,7 @@
         // enable
         cm.enableInternal();
         //activate immediately
-        cm.activateInternal();
+        cm.activateInternal( getTrackingCount().get() );
 
         instance = cm.getComponentInstance();
         if ( instance == null )
@@ -283,15 +283,15 @@
         return true;
     }
 
-    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> ref )
+    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> ref, int trackingCount )
     {
     }
 
-    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> reference )
+    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> reference, int trackingCount )
     {
     }
 
-    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRef )
+    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRef, int trackingCount )
     {
     }
 
@@ -331,7 +331,7 @@
             if ( ( getState() & STATE_DISPOSED ) == 0 && getComponentMetadata().isConfigurationRequired() )
             {
                 log( LogService.LOG_DEBUG, "Deactivating component factory (required configuration has gone)", null );
-                deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED, true );
+                deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED, true, getTrackingCount().get() );
             }
         }
         else
@@ -377,7 +377,7 @@
                 {
                     log( LogService.LOG_DEBUG,
                             "Component Factory target filters not satisfied anymore: deactivating", null );
-                    deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                    deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, getTrackingCount().get() );
                     return;
                 }
             }
@@ -388,7 +388,7 @@
             {
                 // try to activate our component factory, if all dependnecies are satisfied
                 log( LogService.LOG_DEBUG, "Attempting to activate unsatisfied component", null );
-                activateInternal();
+                activateInternal( getTrackingCount().get() );
             }
         }
         else
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 c427d09..32f3412 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
@@ -24,7 +24,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -257,7 +256,7 @@
 
     private class FactoryCustomizer extends AbstractCustomizer {
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
@@ -267,7 +266,7 @@
         {
             if ( !isOptional() )
             {
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -281,7 +280,7 @@
             {
                 if (getTracker().isEmpty())
                 {
-                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
                 }
             }
         }
@@ -309,7 +308,7 @@
 
         private RefPair<T> lastRefPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = getPreviousRefMap().get( serviceReference );
             if ( refPair == null )
@@ -318,10 +317,7 @@
             }
             if (isActive())
             {
-                 if (!m_bindMethods.getBind().getServiceObject( refPair, m_componentManager.getActivator().getBundleContext()))
-                 {
-                      m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, serviceReference );
-                 }
+                 m_bindMethods.getBind().getServiceObject( refPair, m_componentManager.getActivator().getBundleContext());
             }
             return refPair;
         }
@@ -334,12 +330,15 @@
                 {
                     if ( !refPair.isFailed() )
                     {
-                        m_componentManager.invokeBindMethod( DependencyManager.this, refPair );
+                        m_componentManager.invokeBindMethod( DependencyManager.this, refPair, trackingCount );
+                    }
+                    else {
+                        m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, serviceReference, trackingCount );
                     }
                 }
                 else if ( isTrackerOpened() && !isOptional() )
                 {
-                    m_componentManager.activateInternal();
+                    m_componentManager.activateInternal( trackingCount );
                 }
             }
             tracked( trackingCount );
@@ -349,7 +348,7 @@
         {
             if (isActive())
             {
-                m_componentManager.update( DependencyManager.this, refPair );
+                m_componentManager.update( DependencyManager.this, refPair, trackingCount );
             }
             tracked( trackingCount );
         }
@@ -361,12 +360,12 @@
                 boolean unbind = isOptional() || !getTracker().isEmpty();
                 if ( unbind )
                 {
-                    m_componentManager.invokeUnbindMethod( DependencyManager.this, refPair );
+                    m_componentManager.invokeUnbindMethod( DependencyManager.this, refPair, trackingCount );
                 }
                 else
                 {
                     lastRefPair = refPair;
-                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
                     lastRefPair = null;
                 }
             }
@@ -389,7 +388,7 @@
                     }
                     else
                     {
-                         m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, refPair.getRef() );
+                         m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, refPair.getRef(), trackingCount.get() );
                     }
                 }
             }
@@ -423,7 +422,7 @@
     private class MultipleStaticGreedyCustomizer extends AbstractCustomizer {
 
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             if (isActive())
@@ -440,13 +439,13 @@
                 m_componentManager.log( LogService.LOG_DEBUG,
                         "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
                         {m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface()}, null );
-                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
-                m_componentManager.activateInternal();
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
+                m_componentManager.activateInternal( trackingCount );
 
             }
             else if ( isTrackerOpened() &&  !isOptional() )
             {
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -454,7 +453,7 @@
         {
             if (isActive())
             {
-                m_componentManager.update( DependencyManager.this, refPair );
+                m_componentManager.update( DependencyManager.this, refPair, trackingCount );
             }
         }
 
@@ -466,9 +465,9 @@
                 m_componentManager.log( LogService.LOG_DEBUG,
                         "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
                         {m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface()}, null );
-                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
                 //try to reactivate after ref is no longer tracked.
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
             //This is unlikely
             ungetService( refPair );
@@ -509,7 +508,7 @@
 
         private final Collection<RefPair<T>> refs = new ArrayList<RefPair<T>>();
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
@@ -519,7 +518,7 @@
         {
             if ( isTrackerOpened() && !isOptional() && !isActive())
             {
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -527,7 +526,7 @@
         {
             if (isActive())
             {
-                m_componentManager.update( DependencyManager.this, refPair );
+                m_componentManager.update( DependencyManager.this, refPair, trackingCount );
             }
         }
 
@@ -541,10 +540,10 @@
                     m_componentManager.log( LogService.LOG_DEBUG,
                         "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
                             { m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface() }, null );
-                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
 
                     // FELIX-2368: immediately try to reactivate
-                    m_componentManager.activateInternal();
+                    m_componentManager.activateInternal( trackingCount );
 
                 }
             }
@@ -587,7 +586,7 @@
 
         private RefPair<T> refPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
@@ -605,23 +604,23 @@
                     }
                     if ( !refPair.isFailed() )
                     {
-                        m_componentManager.invokeBindMethod( DependencyManager.this, refPair );
+                        m_componentManager.invokeBindMethod( DependencyManager.this, refPair, trackingCount );
                         if ( this.refPair != null )
                         {
-                            m_componentManager.invokeUnbindMethod( DependencyManager.this, this.refPair );
+                            m_componentManager.invokeUnbindMethod( DependencyManager.this, this.refPair, trackingCount );
                             closeRefPair();
                         }
                     }
                     else
                     {
-                        m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, serviceReference );
+                        m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, serviceReference, trackingCount );
                     }
                     this.refPair = refPair;
                 }
             }
             else if ( isTrackerOpened() && !isOptional() )
             {
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -629,7 +628,7 @@
         {
             if (isActive())
             {
-                m_componentManager.update( DependencyManager.this, refPair );
+                m_componentManager.update( DependencyManager.this, refPair, trackingCount );
             }
         }
 
@@ -654,19 +653,19 @@
                         }
                         if ( !refPair.isFailed() )
                         {
-                            m_componentManager.invokeBindMethod( DependencyManager.this, nextRefPair );
+                            m_componentManager.invokeBindMethod( DependencyManager.this, nextRefPair, trackingCount );
                         }
                     }
 
                     if ( isOptional() || nextRefPair != null)
                     {
-                        m_componentManager.invokeUnbindMethod( DependencyManager.this, refPair );
+                        m_componentManager.invokeUnbindMethod( DependencyManager.this, refPair, trackingCount );
                         closeRefPair();
                         this.refPair = nextRefPair;
                     }
                     else //required and no replacement service, deactivate
                     {
-                        m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                        m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
                     }
                 }
             }
@@ -688,7 +687,7 @@
                     }
                     if (refPair.isFailed())
                     {
-                        m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, refPair.getRef() );
+                        m_componentManager.getActivator().registerMissingDependency( DependencyManager.this, refPair.getRef(), trackingCount.get() );
                     }
                     this.refPair = refPair;
                 }
@@ -722,7 +721,7 @@
 
         private RefPair<T> refPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference );
             return refPair;
@@ -734,13 +733,13 @@
             {
                 if ( !isReluctant() && ( this.refPair == null || refPair.getRef().compareTo( this.refPair.getRef() ) > 0 ) )
                 {
-                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
-                    m_componentManager.activateInternal();
+                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
+                    m_componentManager.activateInternal( trackingCount );
                 }
             }
             else if (isTrackerOpened() && !isOptional() )
             {
-                m_componentManager.activateInternal();
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -748,7 +747,7 @@
         {
             if ( isActive() )
             {
-                m_componentManager.update( DependencyManager.this, refPair );
+                m_componentManager.update( DependencyManager.this, refPair, trackingCount );
             }
         }
 
@@ -756,8 +755,8 @@
         {
             if ( isActive() && refPair == this.refPair )
             {
-                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
-                m_componentManager.activateInternal();
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
+                m_componentManager.activateInternal( trackingCount );
             }
         }
 
@@ -1269,7 +1268,7 @@
     }
 
 
-    public void invokeBindMethodLate( final ServiceReference<T> ref )
+    public void invokeBindMethodLate( final ServiceReference<T> ref, int trackingCount )
     {
         if ( !isSatisfied() )
         {
@@ -1303,7 +1302,7 @@
             }
             m_bindMethods.getBind().getServiceObject( refPair, m_componentManager.getActivator().getBundleContext() );
         }
-        m_componentManager.invokeBindMethod( this, refPair );
+        m_componentManager.invokeBindMethod( this, refPair, trackingCount );
     }
 
     /**
@@ -1609,7 +1608,7 @@
         customizer.setTracker( tracker );
         trackerRef.set( tracker );
         registered = true;
-        tracker.open();
+        tracker.open( m_componentManager.getTrackingCount() );
         customizer.setTrackerOpened();
         if ( oldTracker != null )
         {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 8598fac..9ed7487 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -345,19 +345,19 @@
         return Active.getInstance();
     }
 
-    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair )
+    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
     {
         final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
         dependencyManager.update( impl, refPair );
     }
 
-    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair )
+    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
     {
         final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
         dependencyManager.invokeBindMethod( impl, refPair);
     }
 
-    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair )
+    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair, int trackingCount )
     {
         final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
         dependencyManager.invokeUnbindMethod( impl, oldRefPair);
@@ -528,7 +528,7 @@
                 && !getComponentMetadata().isConfigurationIgnored() )
         {
             log( LogService.LOG_DEBUG, "Attempting to activate unsatisfied component", null );
-            activateInternal();
+            activateInternal( getTrackingCount().get() );
             return;
         }
 
@@ -544,7 +544,7 @@
         // this component must be deactivated
         if ( configuration == null && getComponentMetadata().isConfigurationRequired() )
         {
-            deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED, true );
+            deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED, true, getTrackingCount().get() );
         }
         else if ( configuration == null | !modify() )
         {
@@ -556,8 +556,8 @@
             // FELIX-2368: cycle component immediately, reconfigure() is
             //     called through ConfigurationListener API which itself is
             //     called asynchronously by the Configuration Admin Service
-            deactivateInternal( reason, false );
-            activateInternal();
+            deactivateInternal( reason, false, getTrackingCount().get() );
+            activateInternal( getTrackingCount().get() );
         }
     }
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
index 49633d4..52eb6f0 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
@@ -30,7 +30,6 @@
 import org.apache.felix.scr.impl.helper.ModifiedMethod;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentConstants;
 import org.osgi.service.component.ComponentContext;
@@ -208,7 +207,7 @@
         }
     }
 
-    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair )
+    <T> void update( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
     {
         for ( S implementationObject : serviceContexts.keySet() )
         {
@@ -216,7 +215,7 @@
         }
     }
 
-    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair )
+    <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
     {
         for ( S implementationObject : serviceContexts.keySet() )
         {
@@ -228,7 +227,7 @@
         }
     }
 
-    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair )
+    <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair, int trackingCount )
     {
         for ( S implementationObject : serviceContexts.keySet() )
         {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
index 555eb36..9e6489f 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
@@ -279,10 +279,11 @@
 	 * 
 	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
 	 *         which this {@code ServiceTracker} was created is no longer valid.
-	 * @see #open(boolean)
+	 * @see #open(boolean, java.util.concurrent.atomic.AtomicInteger)
+     * @param trackingCount
 	 */
-	public void open() {
-		open(false);
+	public void open( AtomicInteger trackingCount ) {
+		open(false, trackingCount );
 	}
 
 	/**
@@ -293,17 +294,19 @@
 	 * {@code ServiceTracker} was created are now tracked by this
 	 * {@code ServiceTracker}.
 	 * 
-	 * @param trackAllServices If {@code true}, then this {@code ServiceTracker}
-	 *        will track all matching services regardless of class loader
-	 *        accessibility. If {@code false}, then this {@code ServiceTracker}
-	 *        will only track matching services which are class loader
-	 *        accessible to the bundle whose {@code BundleContext} is used by
-	 *        this {@code ServiceTracker}.
-	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *
+     * @param trackAllServices If {@code true}, then this {@code ServiceTracker}
+     *        will track all matching services regardless of class loader
+     *        accessibility. If {@code false}, then this {@code ServiceTracker}
+     *        will only track matching services which are class loader
+     *        accessible to the bundle whose {@code BundleContext} is used by
+     *        this {@code ServiceTracker}.
+     * @param trackingCount
+     * @throws java.lang.IllegalStateException If the {@code BundleContext} with
 	 *         which this {@code ServiceTracker} was created is no longer valid.
 	 * @since 1.3
 	 */
-	public void open(boolean trackAllServices) {
+	public void open( boolean trackAllServices, AtomicInteger trackingCount ) {
 		final Tracked t;
 		synchronized (this) {
 			if (tracked != null) {
@@ -312,7 +315,7 @@
 			if (DEBUG) {
 				System.out.println("ServiceTracker.open: " + filter);
 			}
-			t = trackAllServices ? new AllTracked() : new Tracked();
+			t = trackAllServices ? new AllTracked( trackingCount ) : new Tracked( trackingCount );
 			synchronized (t) {
 				try {
 					context.addServiceListener(t, listenerFilter);
@@ -454,7 +457,7 @@
 	 *        {@code ServiceTracker}.
 	 * @return The service object to be tracked for the service added to this
 	 *         {@code ServiceTracker}.
-	 * @see ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference, int)
+	 * @see ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference
 	 */
 	public T addingService(ServiceReference<S> reference, int trackingCount) {
 		T result = (T) context.getService(reference);
@@ -964,7 +967,7 @@
          *
          * @GuardedBy this
          */
-        private int					trackingCount;
+        private final AtomicInteger					trackingCount;
 
         /**
          * List of items in the process of being added. This is used to deal with
@@ -1011,10 +1014,11 @@
 
         /**
          * AbstractTracked constructor.
+         * @param trackingCount
          */
-        AbstractTracked() {
+        AbstractTracked( AtomicInteger trackingCount ) {
             tracked = new HashMap<S, T>();
-            trackingCount = 0;
+            this.trackingCount = trackingCount;
             adding = new ArrayList<S>(6);
             initial = new LinkedList<S>();
             closed = false;
@@ -1114,6 +1118,7 @@
         void track(final S item, final R related) {
             boolean tracking;
             final T object;
+            int trackingCount = -1;
             synchronized (this) {
                 if (closed) {
                     return;
@@ -1133,7 +1138,7 @@
                     if (DEBUG) {
                         System.out.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
                     }
-                    modified(); /* increment modification count */
+                    trackingCount = modified(); /* increment modification count */
                 }
             }
 
@@ -1163,9 +1168,10 @@
             }
             T object = null;
             boolean becameUntracked = false;
+            int trackingCount = -1;
             /* Call customizer outside of synchronized region */
             try {
-                object = customizerAdding(item, related, trackingCount );
+                object = customizerAdding(item, related);
                 /*
                  * If the customizer throws an unchecked exception, it will
                  * propagate after the finally
@@ -1178,7 +1184,7 @@
                          * callback
                          */
                         tracked.put( item, object );
-                        modified(); /* increment modification count */
+                        trackingCount = modified(); /* increment modification count */
                         notifyAll(); /* notify any waiters */
                     } else {
                         becameUntracked = true;
@@ -1211,7 +1217,7 @@
          */
         void untrack(final S item, final R related) {
             final T object;
-            final int size;
+            int trackingCount;
             synchronized (this) {
                 if (initial.remove(item)) { /*
                                              * if this item is already in the list
@@ -1241,7 +1247,7 @@
                 object = tracked.remove(item); /*                                                 * must remove from tracker before
                                                  * calling customizer callback
                                                  */
-                modified(); /* increment modification count */
+                trackingCount = modified(); /* increment modification count */
             }
             if (DEBUG) {
                 System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
@@ -1307,8 +1313,8 @@
          *
          * @GuardedBy this
          */
-        void modified() {
-            trackingCount++;
+        int modified() {
+            return trackingCount.incrementAndGet();
         }
 
         /**
@@ -1322,7 +1328,7 @@
          * @return The tracking count for this object.
          */
         int getTrackingCount() {
-            return trackingCount;
+            return trackingCount.get();
         }
 
         /**
@@ -1347,13 +1353,13 @@
          * called while synchronized on this object.
          *
          *
+         *
          * @param item Item to be tracked.
          * @param related Action related object.
-         * @param trackingCount
          * @return Customized object for the tracked item or {@code null} if the
          *         item is not to be tracked.
          */
-        abstract T customizerAdding( final S item, final R related, int trackingCount );
+        abstract T customizerAdding( final S item, final R related );
 
         abstract void customizerAdded( final S item, final R related, final T object, int trackingCount );
 
@@ -1390,9 +1396,10 @@
 	private class Tracked extends AbstractTracked<ServiceReference<S>, T, ServiceEvent> implements ServiceListener {
 		/**
 		 * Tracked constructor.
-		 */
-		Tracked() {
-			super();
+         * @param trackingCount
+         */
+		Tracked( AtomicInteger trackingCount ) {
+			super( trackingCount );
 		}
 
 		/**
@@ -1440,9 +1447,10 @@
 		 * 
 		 * @GuardedBy this
 		 */
-		final void modified() {
-			super.modified(); /* increment the modification count */
+		final int modified() {
+			int trackingCount = super.modified(); /* increment the modification count */
 			ServiceTracker.this.modified();
+            return trackingCount;
 		}
 
 		/**
@@ -1450,14 +1458,14 @@
 		 * called while synchronized on this object.
 		 * 
 		 *
+         *
          * @param item Item to be tracked.
          * @param related Action related object.
-         * @param trackingCount
          * @return Customized object for the tracked item or {@code null} if the
 		 *         item is not to be tracked.
 		 */
-		final T customizerAdding( final ServiceReference<S> item, final ServiceEvent related, int trackingCount ) {
-			return customizer.addingService( item, trackingCount );
+		final T customizerAdding( final ServiceReference<S> item, final ServiceEvent related ) {
+			return customizer.addingService( item );
 		}
 
 		final void customizerAdded( final ServiceReference<S> item, final ServiceEvent related, final T object, int trackingCount ) {
@@ -1501,9 +1509,10 @@
 	private class AllTracked extends Tracked implements AllServiceListener {
 		/**
 		 * AllTracked constructor.
-		 */
-		AllTracked() {
-			super();
+         * @param trackingCount
+         */
+		AllTracked( AtomicInteger trackingCount ) {
+			super( trackingCount );
 		}
 	}
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
index 77dff79..287b823 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
@@ -60,14 +60,14 @@
 	 * from the {@code getService} and {@code getServices} methods.
 	 * 
 	 *
+     *
      * @param reference The reference to the service being added to the
      *        {@code ServiceTracker}.
-     * @param trackingCount
      * @return The service object to be tracked for the specified referenced
 	 *         service or {@code null} if the specified referenced service
 	 *         should not be tracked.
 	 */
-	public T addingService( ServiceReference<S> reference, int trackingCount );
+	public T addingService( ServiceReference<S> reference );
 
     public void addedService( ServiceReference<S> reference, T service, int trackingCount );