Added synchronization blocks to ServiceTracker and AspectFilterIndex to solve and prevent concurrency issues.
Fixed issue in AdapterServiceImpl which did not handle aspect services correctly.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1303396 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
index b9b39b2..260ef79 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
@@ -87,15 +87,24 @@
             ServiceReference ref = (ServiceReference) properties[0]; 
             Properties props = new Properties();
             String[] keys = ref.getPropertyKeys();
+            String serviceIdToTrack = null;
             for (int i = 0; i < keys.length; i++) {
                 String key = keys[i];
-                if (key.equals(Constants.SERVICE_ID) || key.equals(Constants.SERVICE_RANKING) || key.equals(DependencyManager.ASPECT) || key.equals(Constants.OBJECTCLASS)) {
-                    // do not copy these
+                if (key.equals(DependencyManager.ASPECT)) {
+                	// if we're handed an aspect fetch the aspect property as the service id to track, but do not copy it
+                	serviceIdToTrack = ref.getProperty(key).toString();
+                }
+                if (key.equals(Constants.SERVICE_ID) || key.equals(Constants.SERVICE_RANKING) || key.equals(Constants.OBJECTCLASS)) {
+                    // do not copy these either
                 }
                 else {
                     props.put(key, ref.getProperty(key));
                 }
             }
+            if (serviceIdToTrack == null) {
+            	// we're not handed an aspect so we can use the service id to track
+            	serviceIdToTrack = ref.getProperty(Constants.SERVICE_ID).toString();
+            }
             if (m_serviceProperties != null) {
                 Enumeration e = m_serviceProperties.keys();
                 while (e.hasMoreElements()) {
@@ -107,8 +116,8 @@
             dependencies.remove(0);
             ServiceDependency dependency = m_manager.createServiceDependency()
             	 // create a dependency on both the service id we're adapting and possible aspects for this given service id
-            	 .setService(m_adapteeInterface, "(|(" + Constants.SERVICE_ID + "=" + ref.getProperty(Constants.SERVICE_ID) 
-            			 	+ ")(" + DependencyManager.ASPECT + "=" + ref.getProperty(Constants.SERVICE_ID) + "))")
+            	 .setService(m_adapteeInterface, "(|(" + Constants.SERVICE_ID + "=" + serviceIdToTrack 
+            			 	+ ")(" + DependencyManager.ASPECT + "=" + serviceIdToTrack + "))")
                  .setRequired(true);
             if (m_autoConfig != null) {
                 dependency.setAutoConfig(m_autoConfig);
@@ -116,7 +125,7 @@
             if (m_add != null || m_change != null || m_remove != null || m_swap != null) {
                 dependency.setCallbacks(m_add, m_change, m_remove, m_swap);
             }
-            
+
             Component service = m_manager.createComponent()
                 .setInterface(m_serviceInterfaces, props)
                 .setImplementation(m_serviceImpl)
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
index 4bef15e..c16dada 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
@@ -129,7 +129,10 @@
         List /* <ServiceReference> */ result = new ArrayList();
         FilterData data = getFilterData(clazz, filter);
         if (data != null) {
-            SortedSet /* <ServiceReference> */ list = (SortedSet) m_sidToServiceReferencesMap.get(Long.valueOf(data.serviceId));
+        	SortedSet /* <ServiceReference> */ list = null;
+        	synchronized (m_sidToServiceReferencesMap) {
+        		list = (SortedSet) m_sidToServiceReferencesMap.get(Long.valueOf(data.serviceId));
+			}
             if (list != null) {
                 Iterator iterator = list.iterator();
                 while (iterator.hasNext()) {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java
index 21504a1..c7440fc 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java
@@ -928,64 +928,78 @@
         
         private ServiceReference highestTrackedCache(long serviceId) {
             Long sid = Long.valueOf(serviceId);
-            TreeSet services = (TreeSet) m_highestTrackedCache.get(sid);
-            if (services != null && services.size() > 0) {
-                ServiceReference result = (ServiceReference) services.last();
-                return result;
-            }
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestTrackedCache.get(sid);
+            	if (services != null && services.size() > 0) {
+            		ServiceReference result = (ServiceReference) services.last();
+            		return result;
+            	}
+			}
             return null;
         }
         
         private void addHighestTrackedCache(ServiceReference reference) {
             Long serviceId = ServiceUtil.getServiceIdObject(reference);
-            TreeSet services = (TreeSet) m_highestTrackedCache.get(serviceId);
-            if (services == null) {
-                services = new TreeSet();
-                m_highestTrackedCache.put(serviceId, services);
-            }
-            services.add(reference);
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestTrackedCache.get(serviceId);
+            	if (services == null) {
+            		services = new TreeSet();
+            		m_highestTrackedCache.put(serviceId, services);
+            	}
+            	services.add(reference);
+			}
         }
         
         private void removeHighestTrackedCache(ServiceReference reference) {
             Long serviceId = ServiceUtil.getServiceIdObject(reference);
-            TreeSet services = (TreeSet) m_highestTrackedCache.get(serviceId);
-            if (services != null) {
-                services.remove(reference);
-            }
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestTrackedCache.get(serviceId);
+            	if (services != null) {
+            		services.remove(reference);
+            	}
+			}
         }
         
         private void clearHighestTrackedCache() {
-            m_highestTrackedCache.clear();
+        	synchronized (this) {
+        		m_highestTrackedCache.clear();
+			}
         }
         
         private final HashMap m_highestHiddenCache = new HashMap();
         
         private ServiceReference highestHiddenCache(long serviceId) {
             Long sid = Long.valueOf(serviceId);
-            TreeSet services = (TreeSet) m_highestHiddenCache.get(sid);
-            if (services != null && services.size() > 0) {
-                ServiceReference result = (ServiceReference) services.last();
-                return result;
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestHiddenCache.get(sid);
+	            if (services != null && services.size() > 0) {
+	                ServiceReference result = (ServiceReference) services.last();
+	                return result;
+	            }
             }
             return null;
         }
         
         private void addHighestHiddenCache(ServiceReference reference) {
             Long serviceId = ServiceUtil.getServiceIdObject(reference);
-            TreeSet services = (TreeSet) m_highestHiddenCache.get(serviceId);
-            if (services == null) {
-                services = new TreeSet();
-                m_highestHiddenCache.put(serviceId, services);
-            }
-            services.add(reference);
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestHiddenCache.get(serviceId);
+            	if (services == null) {
+            		services = new TreeSet();
+            		m_highestHiddenCache.put(serviceId, services);
+            	}
+            	services.add(reference);
+			}
         }
         
         private void removeHighestHiddenCache(ServiceReference reference) {
             Long serviceId = ServiceUtil.getServiceIdObject(reference);
-            TreeSet services = (TreeSet) m_highestHiddenCache.get(serviceId);
-            if (services != null) {
-                services.remove(reference);
-            }
+            synchronized (this) {
+            	TreeSet services = (TreeSet) m_highestHiddenCache.get(serviceId);
+            	if (services != null) {
+            		services.remove(reference);
+            	}
+			}
         }
 
         /**