FELIX-3729 Fix NPE in isSatisfied.  Start setting up using trackingCount to track how much work is done when deactivating a component instance

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1424309 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 6832c45..de7403b 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,8 +24,10 @@
 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;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -137,6 +139,12 @@
 
         private volatile Map<ServiceReference<T>, RefPair<T>> previousRefMap = EMPTY_REF_MAP;
 
+        private volatile int floor;
+
+        private volatile int ceiling;
+
+        private final Set<Integer> missing = new HashSet<Integer>( );
+
         public void setTracker( ServiceTracker<T, RefPair<T>> tracker )
         {
             this.tracker = tracker;
@@ -200,18 +208,46 @@
                 }
             }
         }
+
+        protected void tracked( int trackingCount )
+        {
+            synchronized ( missing )
+            {
+                if (trackingCount == floor + 1 )
+                {
+                    floor++;
+                    missing.remove( trackingCount );
+                }
+                else if ( trackingCount < ceiling )
+                {
+                    missing.remove( trackingCount );
+                }
+                if ( trackingCount > ceiling )
+                {
+                    for (int i = ceiling + 1; i < trackingCount; i++ )
+                    {
+                        missing.add( i );
+                    }
+                    ceiling = trackingCount;
+                }
+                if ( missing.isEmpty() )
+                {
+                    missing.notifyAll();
+                }
+            }
+        }
     }
 
 
     private class FactoryCustomizer extends AbstractCustomizer {
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( !isOptional() )
             {
@@ -219,11 +255,11 @@
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( !isOptional() )
             {
@@ -237,7 +273,8 @@
         public boolean open()
         {
             boolean success = m_dependencyMetadata.isOptional() || !getTracker().isEmpty();
-            getTracker().getTracked( true );   //TODO activate method??
+            AtomicInteger trackingCount = new AtomicInteger( );
+            getTracker().getTracked( true, trackingCount );   //TODO activate method??
             return success;
         }
 
@@ -256,7 +293,7 @@
 
         private RefPair<T> lastRefPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = getPreviousRefMap().get( serviceReference );
             if ( refPair == null )
@@ -273,7 +310,7 @@
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( getPreviousRefMap().remove( serviceReference ) == null )
             {
@@ -289,17 +326,19 @@
                     m_componentManager.activateInternal();
                 }
             }
+            tracked( trackingCount );
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive())
             {
                 m_componentManager.update( DependencyManager.this, refPair );
             }
+            tracked( trackingCount );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() )
             {
@@ -316,12 +355,14 @@
                 }
             }
             ungetService( refPair );
+            tracked( trackingCount );
         }
 
         public boolean open()
         {
             boolean success = m_dependencyMetadata.isOptional();
-            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true );
+            AtomicInteger trackingCount = new AtomicInteger( );
+            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true, trackingCount );
             for (RefPair<T> refPair: tracked.values())
             {
                 synchronized (refPair)
@@ -353,7 +394,8 @@
         {
             if ( lastRefPair == null )
             {
-                return getTracker().getTracked( true ).values();
+                AtomicInteger trackingCount = new AtomicInteger( );
+                return getTracker().getTracked( true, trackingCount ).values();
             }
             else
             {
@@ -365,7 +407,7 @@
     private class MultipleStaticGreedyCustomizer extends AbstractCustomizer {
 
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             if (isActive())
@@ -375,7 +417,7 @@
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive())
             {
@@ -392,7 +434,7 @@
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive())
             {
@@ -400,7 +442,7 @@
             }
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() )
             {
@@ -419,7 +461,8 @@
         public boolean open()
         {
             boolean success = m_dependencyMetadata.isOptional();
-            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( success || !getTracker().isEmpty() );
+            AtomicInteger trackingCount = new AtomicInteger( );
+            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( success || !getTracker().isEmpty(), trackingCount );
             for (RefPair<T> refPair: tracked.values())
             {
                 synchronized (refPair)
@@ -441,7 +484,8 @@
 
         public Collection<RefPair<T>> getRefs()
         {
-            return getTracker().getTracked( null ).values();
+            AtomicInteger trackingCount = new AtomicInteger( );
+            return getTracker().getTracked( null, trackingCount ).values();
         }
     }
 
@@ -449,13 +493,13 @@
 
         private final Collection<RefPair<T>> refs = new ArrayList<RefPair<T>>();
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isTrackerOpened() && !isOptional() && !isActive())
             {
@@ -463,7 +507,7 @@
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive())
             {
@@ -471,7 +515,7 @@
             }
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() )
             {
@@ -494,7 +538,8 @@
         public boolean open()
         {
             boolean success = m_dependencyMetadata.isOptional();
-            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true );
+            AtomicInteger trackingCount = new AtomicInteger( );
+            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true, trackingCount );
             for (RefPair<T> refPair: tracked.values())
             {
                 synchronized (refPair)
@@ -526,13 +571,13 @@
 
         private RefPair<T> refPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference  );
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive() )
             {
@@ -564,7 +609,7 @@
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (isActive())
             {
@@ -572,7 +617,7 @@
             }
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if (refPair == this.refPair)
             {
@@ -581,7 +626,8 @@
                     RefPair<T> nextRefPair = null;
                     if ( !getTracker().isEmpty() )
                     {
-                        SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true );
+                        AtomicInteger trackingCount2 = new AtomicInteger( );
+                        SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true, trackingCount2 );
                         nextRefPair = tracked.values().iterator().next();
                         synchronized ( nextRefPair )
                         {
@@ -615,7 +661,8 @@
             boolean success = m_dependencyMetadata.isOptional();
             if ( success || !getTracker().isEmpty() )
             {
-                SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true );
+                AtomicInteger trackingCount = new AtomicInteger( );
+                SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true, trackingCount );
                 if ( !tracked.isEmpty() )
                 {
                     RefPair<T> refPair = tracked.values().iterator().next();
@@ -659,13 +706,13 @@
 
         private RefPair<T> refPair;
 
-        public RefPair<T> addingService( ServiceReference<T> serviceReference )
+        public RefPair<T> addingService( ServiceReference<T> serviceReference, int trackingCount )
         {
             RefPair<T> refPair = new RefPair<T>( serviceReference );
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() )
             {
@@ -681,7 +728,7 @@
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() )
             {
@@ -689,7 +736,7 @@
             }
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             if ( isActive() && refPair == this.refPair )
             {
@@ -703,7 +750,8 @@
             boolean success = m_dependencyMetadata.isOptional();
             if ( success || !getTracker().isEmpty() )
             {
-                SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true );
+                AtomicInteger trackingCount = new AtomicInteger( );
+                SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true, trackingCount );
                 if ( !tracked.isEmpty() )
                 {
                     RefPair<T> refPair = tracked.values().iterator().next();
@@ -826,7 +874,8 @@
      */
     int size()
     {
-        return trackerRef.get().getTracked( null ).size();
+        AtomicInteger trackingCount = new AtomicInteger( );
+        return trackerRef.get().getTracked( null, trackingCount ).size();
     }
 
 
@@ -976,7 +1025,8 @@
      */
     private RefPair<T> getRefPair( ServiceReference<T> serviceReference )
     {
-        return trackerRef.get().getTracked( null ).get( serviceReference );
+        AtomicInteger trackingCount = new AtomicInteger( );
+        return trackerRef.get().getTracked( null, trackingCount ).get( serviceReference );
     }
 
 
@@ -1055,7 +1105,8 @@
      */
     public boolean isSatisfied()
     {
-        return customizerRef.get().isSatisfied();
+        Customizer<T> customizer = customizerRef.get();
+        return customizer != null && customizer.isSatisfied();
     }
 
 
@@ -1594,7 +1645,8 @@
 //        trackerRef.set( null ); //???
         if ( tracker != null )
         {
-            refMap = tracker.close();
+            AtomicInteger trackingCount = new AtomicInteger( );
+            refMap = tracker.close( trackingCount );
         }
         else
         {
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 2e1eeec..555eb36 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
@@ -25,6 +25,8 @@
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.osgi.framework.AllServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -367,8 +369,9 @@
 	 * <p>
 	 * This implementation calls {@link #getServiceReferences()} to get the list
 	 * of tracked services to remove.
-	 */
-	public SortedMap<ServiceReference<S>, T> close() {
+     * @param trackingCount
+     */
+	public SortedMap<ServiceReference<S>, T> close( AtomicInteger trackingCount ) {
 		final Tracked outgoing;
 //		final ServiceReference<S>[] references;
         SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(Collections.reverseOrder());
@@ -381,7 +384,11 @@
 				System.out.println("ServiceTracker.close: " + filter);
 			}
 			outgoing.close();
-            outgoing.copyEntries( map );
+            synchronized ( outgoing )
+            {
+                trackingCount.set( outgoing.getTrackingCount() );
+                outgoing.copyEntries( map );
+            }
 //			references = getServiceReferences();
 //			tracked = null;
 			try {
@@ -440,16 +447,16 @@
 	 * This method can be overridden in a subclass to customize the service
 	 * object to be tracked for the service being added. In that case, take care
 	 * not to rely on the default implementation of
-	 * {@link #removedService(ServiceReference, Object) removedService} to unget
+	 * {@link #removedService(ServiceReference, Object, int) removedService} to unget
 	 * the service.
 	 * 
 	 * @param reference The reference to the service being added to this
 	 *        {@code ServiceTracker}.
 	 * @return The service object to be tracked for the service added to this
 	 *         {@code ServiceTracker}.
-	 * @see ServiceTrackerCustomizer#addingService(ServiceReference)
+	 * @see ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference, int)
 	 */
-	public T addingService(ServiceReference<S> reference) {
+	public T addingService(ServiceReference<S> reference, int trackingCount) {
 		T result = (T) context.getService(reference);
 		return result;
 	}
@@ -467,9 +474,9 @@
 	 * 
 	 * @param reference The reference to modified service.
 	 * @param service The service object for the modified service.
-	 * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
+	 * @see ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, Object, int)
 	 */
-	public void modifiedService(ServiceReference<S> reference, T service) {
+	public void modifiedService(ServiceReference<S> reference, T service, int trackingCount) {
 		/* do nothing */
 	}
 
@@ -487,14 +494,14 @@
 	 * passing the specified {@code ServiceReference}.
 	 * <p>
 	 * This method can be overridden in a subclass. If the default
-	 * implementation of {@link #addingService(ServiceReference) addingService}
+	 * implementation of {@link #addingService(ServiceReference, int) addingService}
 	 * method was used, this method must unget the service.
 	 * 
 	 * @param reference The reference to removed service.
 	 * @param service The service object for the removed service.
-	 * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
+	 * @see ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, Object, int)
 	 */
-	public void removedService(ServiceReference<S> reference, T service) {
+	public void removedService(ServiceReference<S> reference, T service, int trackingCount) {
 		context.ungetService(reference);
 	}
 
@@ -818,8 +825,9 @@
 	 *         the returned map is empty.
 	 * @since 1.5
      * @param activate
-	 */
-	public SortedMap<ServiceReference<S>, T> getTracked( Boolean activate ) {
+     * @param trackingCount
+     */
+	public SortedMap<ServiceReference<S>, T> getTracked( Boolean activate, AtomicInteger trackingCount ) {
 		SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(Collections.reverseOrder());
 		final Tracked t = tracked();
 		if (t == null) { /* if ServiceTracker is not open */
@@ -830,6 +838,7 @@
             {
                 active = activate;
             }
+            trackingCount.set( t.getTrackingCount() );
             return t.copyEntries(map);
 		}
 	}
@@ -1132,7 +1141,7 @@
                 trackAdding(item, related);
             } else {
                 /* Call customizer outside of synchronized region */
-                customizerModified(item, related, object);
+                customizerModified(item, related, object, trackingCount );
                 /*
                  * If the customizer throws an unchecked exception, it is safe to
                  * let it propagate
@@ -1156,7 +1165,7 @@
             boolean becameUntracked = false;
             /* Call customizer outside of synchronized region */
             try {
-                object = customizerAdding(item, related);
+                object = customizerAdding(item, related, trackingCount );
                 /*
                  * If the customizer throws an unchecked exception, it will
                  * propagate after the finally
@@ -1184,13 +1193,13 @@
                     System.out.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
                 }
                 /* Call customizer outside of synchronized region */
-                customizerRemoved(item, related, object);
+                customizerRemoved(item, related, object, trackingCount );
                 /*
                  * If the customizer throws an unchecked exception, it is safe to
                  * let it propagate
                  */
             } else {
-                customizerAdded( item, related, object );
+                customizerAdded( item, related, object, trackingCount );
             }
         }
 
@@ -1238,7 +1247,7 @@
                 System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
             }
             /* Call customizer outside of synchronized region */
-            customizerRemoved(item, related, object);
+            customizerRemoved(item, related, object, trackingCount );
             /*
              * If the customizer throws an unchecked exception, it is safe to let it
              * propagate
@@ -1277,7 +1286,7 @@
          * @GuardedBy this
          */
         T getCustomizedObject(final S item) {
-            return tracked.get(item);
+            return tracked.get( item );
         }
 
         /**
@@ -1337,14 +1346,16 @@
          * Call the specific customizer adding method. This method must not be
          * 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);
+        abstract T customizerAdding( final S item, final R related, int trackingCount );
 
-        abstract void customizerAdded(final S item, final R related, final T object);
+        abstract void customizerAdded( final S item, final R related, final T object, int trackingCount );
 
         /**
          * Call the specific customizer modified method. This method must not be
@@ -1353,8 +1364,9 @@
          * @param item Tracked item.
          * @param related Action related object.
          * @param object Customized object for the tracked item.
+         * @param trackingCount
          */
-        abstract void customizerModified(final S item, final R related, final T object);
+        abstract void customizerModified( final S item, final R related, final T object, int trackingCount );
 
         /**
          * Call the specific customizer removed method. This method must not be
@@ -1363,8 +1375,9 @@
          * @param item Tracked item.
          * @param related Action related object.
          * @param object Customized object for the tracked item.
+         * @param trackingCount
          */
-        abstract void customizerRemoved(final S item, final R related, final T object);
+        abstract void customizerRemoved( final S item, final R related, final T object, int trackingCount );
     }
 
 
@@ -1436,41 +1449,45 @@
 		 * Call the specific customizer adding method. This method must not be
 		 * called while synchronized on this object.
 		 * 
-		 * @param item Item to be tracked.
-		 * @param related Action related object.
-		 * @return Customized object for the tracked item or {@code null} if the
+		 *
+         * @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) {
-			return customizer.addingService( item );
+		final T customizerAdding( final ServiceReference<S> item, final ServiceEvent related, int trackingCount ) {
+			return customizer.addingService( item, trackingCount );
 		}
 
-		final void customizerAdded(final ServiceReference<S> item, final ServiceEvent related, final T object) {
-		    customizer.addedService( item, object );
+		final void customizerAdded( final ServiceReference<S> item, final ServiceEvent related, final T object, int trackingCount ) {
+		    customizer.addedService( item, object, trackingCount );
 		}
 
 		/**
 		 * Call the specific customizer modified method. This method must not be
 		 * called while synchronized on this object.
-		 * 
-		 * @param item Tracked item.
-		 * @param related Action related object.
-		 * @param object Customized object for the tracked item.
-		 */
-		final void customizerModified(final ServiceReference<S> item, final ServiceEvent related, final T object) {
-			customizer.modifiedService(item, object);
+		 *
+         * @param item Tracked item.
+         * @param related Action related object.
+         * @param object Customized object for the tracked item.
+         * @param trackingCount
+         */
+		final void customizerModified( final ServiceReference<S> item, final ServiceEvent related, final T object, int trackingCount ) {
+			customizer.modifiedService( item, object, trackingCount );
 		}
 
         /**
 		 * Call the specific customizer removed method. This method must not be
 		 * called while synchronized on this object.
-		 * 
-		 * @param item Tracked item.
-		 * @param related Action related object.
-		 * @param object Customized object for the tracked item.
-		 */
-		final void customizerRemoved(final ServiceReference<S> item, final ServiceEvent related, final T object) {
-			customizer.removedService(item, object);
+		 *
+         * @param item Tracked item.
+         * @param related Action related object.
+         * @param object Customized object for the tracked item.
+         * @param trackingCount
+         */
+		final void customizerRemoved( final ServiceReference<S> item, final ServiceEvent related, final T object, int trackingCount ) {
+			customizer.removedService(item, object, 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 2868106..77dff79 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
@@ -59,15 +59,17 @@
 	 * service object is stored in the {@code ServiceTracker} and is available
 	 * from the {@code getService} and {@code getServices} methods.
 	 * 
-	 * @param reference The reference to the service being added to the
-	 *        {@code ServiceTracker}.
-	 * @return The service object to be tracked for the specified referenced
+	 *
+     * @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);
+	public T addingService( ServiceReference<S> reference, int trackingCount );
 
-    public void addedService(ServiceReference<S> reference, T service);
+    public void addedService( ServiceReference<S> reference, T service, int trackingCount );
 
 	/**
 	 * A service tracked by the {@code ServiceTracker} has been modified.
@@ -75,11 +77,12 @@
 	 * <p>
 	 * This method is called when a service being tracked by the
 	 * {@code ServiceTracker} has had it properties modified.
-	 * 
-	 * @param reference The reference to the service that has been modified.
-	 * @param service The service object for the specified referenced service.
-	 */
-	public void modifiedService(ServiceReference<S> reference, T service);
+	 *
+     * @param reference The reference to the service that has been modified.
+     * @param service The service object for the specified referenced service.
+     * @param trackingCount
+     */
+	public void modifiedService( ServiceReference<S> reference, T service, int trackingCount );
 
 	/**
 	 * A service tracked by the {@code ServiceTracker} has been removed.
@@ -87,10 +90,11 @@
 	 * <p>
 	 * This method is called after a service is no longer being tracked by the
 	 * {@code ServiceTracker}.
-	 * 
-	 * @param reference The reference to the service that has been removed.
-	 * @param service The service object for the specified referenced service.
-	 */
-	public void removedService(ServiceReference<S> reference, T service);
+	 *
+     * @param reference The reference to the service that has been removed.
+     * @param service The service object for the specified referenced service.
+     * @param trackingCount
+     */
+	public void removedService( ServiceReference<S> reference, T service, int trackingCount );
 
 }