Revert: Search for scope first in parent locator. PR #1166
diff --git a/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java b/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
index a6ecdf2..5dd241e 100755
--- a/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
+++ b/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
@@ -113,9 +113,9 @@
         public String run() {
             return System.getProperty(BIND_TRACING_PATTERN_PROPERTY);
         }
-
+            
     });
-
+    
     private final static String BIND_TRACING_STACKS_PROPERTY = "org.jvnet.hk2.properties.bind.tracing.stacks";
     private static final boolean BIND_TRACING_STACKS = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
         @Override
@@ -123,7 +123,7 @@
             return Boolean.parseBoolean(
                 System.getProperty(BIND_TRACING_STACKS_PROPERTY, "false"));
         }
-
+            
     });
 
     private final static int CACHE_SIZE = 20000;
@@ -152,7 +152,7 @@
     private final LinkedHashSet<ValidationService> allValidators = new LinkedHashSet<>();
     private final LinkedList<ErrorService> errorHandlers = new LinkedList<>(Collections.singletonList(new RethrowErrorService()));
     private final LinkedList<ServiceHandle<?>> configListeners = new LinkedList<>();
-
+    
     private volatile boolean hasInterceptionServices = false;
     private final LinkedList<InterceptionService> interceptionServices =
             new LinkedList<InterceptionService>();
@@ -176,14 +176,14 @@
     private final ReentrantLock allResolversLock = new ReentrantLock();
     private ConcurrentHashMap<Class<? extends Annotation>, InjectionResolver<?>> allResolvers =
             new ConcurrentHashMap<Class<? extends Annotation>, InjectionResolver<?>>();
-    private final Cache<SystemInjecteeImpl, InjectionResolver<?>> injecteeToResolverCache =
+    private final Cache<SystemInjecteeImpl, InjectionResolver<?>> injecteeToResolverCache = 
             new Cache<SystemInjecteeImpl, InjectionResolver<?>>(new Computable<SystemInjecteeImpl, InjectionResolver<?>>() {
 
         @Override
         public InjectionResolver<?> compute(SystemInjecteeImpl key) {
             return perLocatorUtilities.getInjectionResolver(getMe(), key);
         }
-
+        
     });
 
     private ServiceLocatorState state = ServiceLocatorState.RUNNING;
@@ -218,10 +218,10 @@
                     " with stacks " + BIND_TRACING_STACKS + " in " + this);
         }
     }
-
+    
     /**
      * Must have read lock held
-     *
+     * 
      * @param vi The non-null validation
      * @return
      */
@@ -231,7 +231,7 @@
         }
         catch (Throwable th) {
             List<ErrorService> localErrorServices = new LinkedList<ErrorService>(errorHandlers);
-
+            
             MultiException useException;
             if (th instanceof MultiException) {
                 useException = (MultiException) th;
@@ -239,13 +239,13 @@
             else {
                 useException = new MultiException(th);
             }
-
+            
             ErrorInformationImpl ei = new ErrorInformationImpl(
                     ErrorType.VALIDATE_FAILURE,
                     vi.getCandidate(),
                     vi.getInjectee(),
                     useException);
-
+            
             for (ErrorService errorService : localErrorServices) {
                 try {
                     errorService.onFailure(ei);
@@ -254,9 +254,9 @@
                     Logger.getLogger().debug("ServiceLocatorImpl", "callValidate", th2);
                 }
             }
-
+            
         }
-
+        
         return false;
     }
 
@@ -534,7 +534,7 @@
 
         if (Provider.class.equals(rawType) || Iterable.class.equals(rawType) || IterableProvider.class.equals(rawType) ) {
             boolean isIterable = (IterableProvider.class.equals(rawType));
-
+            
             IterableProviderImpl<?> value = new IterableProviderImpl<Object>(this,
                     (ReflectionHelper.getFirstTypeArgument(requiredType)),
                     injectee.getRequiredQualifiers(),
@@ -562,12 +562,12 @@
             }
             return descriptor;
         }
-
+        
         if (Topic.class.equals(rawType)) {
             TopicImpl<?> value = new TopicImpl<Object>(this,
                     ReflectionHelper.getFirstTypeArgument(requiredType),
                     injectee.getRequiredQualifiers());
-
+            
             return new ConstantActiveDescriptor<Object>(value, this);
         }
 
@@ -601,28 +601,28 @@
                 throw new IllegalArgumentException("The descriptor passed to getServiceHandle must have been bound into a ServiceLocator.  " +
                     "The descriptor is of type " + activeDescriptor.getClass().getName());
             }
-
+            
             Long sdLocator = activeDescriptor.getLocatorId();
             if (sdLocator == null) {
                 throw new IllegalArgumentException("The descriptor passed to getServiceHandle is not associated with any ServiceLocator");
             }
-
+            
             if (sdLocator != id) {
                 if (parent != null) {
                     return parent.getServiceHandle(activeDescriptor, injectee);
                 }
-
+                
                 throw new IllegalArgumentException("The descriptor passed to getServiceHandle is not associated with this ServiceLocator (id=" +
                     id + ").  It is associated ServiceLocator id=" + sdLocator);
             }
-
+            
            Long sdSID = activeDescriptor.getServiceId();
            if ((activeDescriptor instanceof SystemDescriptor) && (sdSID == null)) {
                throw new IllegalArgumentException("The descriptor passed to getServiceHandle was never added to this ServiceLocator (id=" +
                    id + ")");
            }
         }
-
+        
         return getServiceHandleImpl(activeDescriptor, injectee);
     }
 
@@ -682,7 +682,7 @@
             ServiceHandleImpl<T> tmpRoot = new ServiceHandleImpl<T>(this, activeDescriptor, originalRequest);
             return Utilities.createService(activeDescriptor, originalRequest, this, tmpRoot, rawClass);
         }
-
+        
         ServiceHandleImpl<?> rootImpl = (ServiceHandleImpl<?>) root;
 
         ServiceHandleImpl<T> subHandle = internalGetServiceHandle(activeDescriptor, contractOrImpl, originalRequest);
@@ -733,38 +733,38 @@
             throws MultiException {
         return internalGetService(contractOrImpl, name, null, qualifiers);
     }
-
+    
     private <T> T internalGetService(Type contractOrImpl, String name, Unqualified unqualified, Annotation... qualifiers) {
         return internalGetService(contractOrImpl, name, unqualified, false, qualifiers);
-
+        
     }
 
     @SuppressWarnings("unchecked")
     private <T> T internalGetService(Type contractOrImpl, String name, Unqualified unqualified, boolean calledFromSecondChanceResolveMethod, Annotation... qualifiers) {
         checkState();
-
+        
         Class<?> rawType = ReflectionHelper.getRawClass(contractOrImpl);
         if (rawType != null &&
                 (Provider.class.equals(rawType) || IterableProvider.class.equals(rawType)) ) {
             boolean isIterable = IterableProvider.class.equals(rawType);
-
+            
             Type requiredType = ReflectionHelper.getFirstTypeArgument(contractOrImpl);
             HashSet<Annotation> requiredQualifiers = new HashSet<Annotation>();
             for (Annotation qualifier : qualifiers) {
                 requiredQualifiers.add(qualifier);
             }
-
+            
             InjecteeImpl injectee = new InjecteeImpl(requiredType);
             injectee.setRequiredQualifiers(requiredQualifiers);
             injectee.setUnqualified(unqualified);
-
+            
             IterableProviderImpl<?> retVal = new IterableProviderImpl<Object>(this,
                     requiredType,
                     requiredQualifiers,
                     unqualified,
                     injectee,
                     isIterable);
-
+            
             return (T) retVal;
         }
 
@@ -878,7 +878,7 @@
             rLock.unlock();
         }
     }
-
+    
     @Override
     public boolean isShutdown() {
         return state.equals(ServiceLocatorState.SHUTDOWN);
@@ -889,8 +889,8 @@
      */
     @Override
     public void shutdown() {
-
-
+        
+        
         wLock.lock();
         try {
             if (state.equals(ServiceLocatorState.SHUTDOWN)) return;
@@ -914,7 +914,7 @@
         finally {
             wLock.unlock();
         }
-
+        
         // These things must be done OUTSIDE the lock
         List<ServiceHandle<?>> handles = getAllServiceHandles(new IndexedFilter() {
 
@@ -932,7 +932,7 @@
             public String getName() {
                 return null;
             }
-
+            
         });
 
         for (ServiceHandle<?> handle : handles) {
@@ -960,7 +960,7 @@
             classReflectionHelper.dispose();
             contextCache.clear();
             perLocatorUtilities.shutdown();
-
+            
             childrenLock.lock();
             try {
                 children.clear();
@@ -1003,16 +1003,16 @@
     public void inject(Object injectMe) {
         inject(injectMe, null);
     }
-
+    
     @Override
     public Object assistedInject(Object injectMe, Method method, MethodParameter... params) {
         return assistedInject(injectMe, method, null, params);
     }
-
+    
     @Override
     public Object assistedInject(Object injectMe, Method method, ServiceHandle<?> root, MethodParameter... params) {
         checkState();
-
+        
         return Utilities.justAssistedInject(injectMe, method, this, root, params);
     }
 
@@ -1171,7 +1171,7 @@
             }
             return true;
         }
-
+        
         @Override
         public String toString() {
             return "IgdCacheKey(" + cacheKey + "," + name + "," + onBehalfOf + "," +
@@ -1198,7 +1198,7 @@
                     return igdCacheCompute(key);
                 }
             }, CACHE_SIZE, false);
-
+    
     private IgdValue igdCacheCompute(final IgdCacheKey key) {
         final List<SystemDescriptor<?>> candidates = getDescriptors(key.filter, key.onBehalfOf, true, false, true);
         final ImmediateResults immediate = narrow(ServiceLocatorImpl.this, // locator
@@ -1211,21 +1211,21 @@
                 null, // cachedResults
                 key.filter, // filter
                 key.qualifiers); // qualifiers
-
+        
         final NarrowResults results = immediate.getTimelessResults();
         if (!results.getErrors().isEmpty()) {
             Utilities.handleErrors(results, new LinkedList<ErrorService>(errorHandlers));
             throw new ComputationErrorException(new IgdValue(results, immediate));
         }
-
+        
         return new IgdValue(results, immediate);
     }
-
+    
     private Unqualified getEffectiveUnqualified(Unqualified givenUnqualified, boolean isIterable, Annotation qualifiers[]) {
         if (givenUnqualified != null) return givenUnqualified;
         if (qualifiers.length > 0) return null;
         if (isIterable) return null;
-
+        
         // Given unqualified is null and there are no qualifiers
         return defaultUnqualified;
     }
@@ -1237,7 +1237,7 @@
             Annotation... qualifiers) throws MultiException {
       return internalGetDescriptor(onBehalfOf, contractOrImpl, name, unqualified, isIterable, false, qualifiers);
     }
-
+  
     @SuppressWarnings("unchecked")
     private <T> ActiveDescriptor<T> internalGetDescriptor(Injectee onBehalfOf, Type contractOrImpl,
             String name,
@@ -1260,7 +1260,7 @@
         LinkedList<ErrorService> currentErrorHandlers = null;
 
         ImmediateResults immediate = null;
-
+        
         unqualified = getEffectiveUnqualified(unqualified, isIterable, qualifiers);
 
         final CacheKey cacheKey = new CacheKey(contractOrImpl, name, unqualified, qualifiers);
@@ -1331,7 +1331,7 @@
             }
             postValidateResult = (ActiveDescriptor<T>)secondChanceResolve(injectee);
         }
-
+        
         return postValidateResult;
     }
 
@@ -1425,7 +1425,7 @@
                 Utilities.handleErrors(results, new LinkedList<ErrorService>(errorHandlers));
                 throw new ComputationErrorException(new IgdValue(results, immediate)) ;
             }
-
+            
             return new IgdValue(results, immediate);
         }
     }, CACHE_SIZE, false);
@@ -1452,7 +1452,7 @@
         LinkedList<ErrorService> currentErrorHandlers = null;
 
         ImmediateResults immediate = null;
-
+        
         unqualified = getEffectiveUnqualified(unqualified, isIterable, qualifiers);
 
         final CacheKey cacheKey = new CacheKey(contractOrImpl, null, unqualified, qualifiers);
@@ -1604,10 +1604,10 @@
 
         });
     }
-
+    
     /* package */ List<InterceptionService> getInterceptionServices() {
         if (!hasInterceptionServices) return null;
-
+        
         rLock.lock();
         try {
             return new LinkedList<InterceptionService>(interceptionServices);
@@ -1676,7 +1676,7 @@
 
         for (SystemDescriptor<?> sd : dci.getAllDescriptors()) {
             transactionData.toAdd(sd);
-
+            
             affectedContracts.addAll(getAllContracts(sd));
 
             boolean checkScope = false;
@@ -1714,13 +1714,13 @@
 
                 addOrRemoveOfInjectionResolver = true;
             }
-
+            
             if (sd.getAdvertisedContracts().contains(DynamicConfigurationListener.class.getName())) {
                 // This gets reified right away
                 reifyDescriptor(sd);
-
+                
                 checkScope = true;
-
+                
                 addOrRemoveOfConfigListener = true;
             }
 
@@ -1754,29 +1754,29 @@
                 }
             }
         }
-
+        
         List<Filter> idempotentFilters = dci.getIdempotentFilters();
         if (!idempotentFilters.isEmpty()) {
             List<ActiveDescriptor<?>> allValidatedDescriptors = getDescriptors(BuilderHelper.allFilter());
-
+            
             List<Throwable> idempotentFailures = new LinkedList<>();
             for (ActiveDescriptor<?> aValidatedDescriptor : allValidatedDescriptors) {
                 for (Filter idempotentFilter : idempotentFilters) {
                     if (BuilderHelper.filterMatches(aValidatedDescriptor, idempotentFilter)) {
                         idempotentFailures.add(new DuplicateServiceException(aValidatedDescriptor, locatorName));
                     }
-
+                    
                 }
             }
-
+            
             if (!idempotentFailures.isEmpty()) {
                 throw new MultiException(idempotentFailures);
             }
         }
-
+        
         LinkedList<TwoPhaseResource> resources = dci.getResources();
         List<TwoPhaseResource> completedPrepares = new LinkedList<TwoPhaseResource>();
-
+        
         for (TwoPhaseResource resource : resources) {
             try {
                 resource.prepareDynamicConfiguration(transactionData);
@@ -1791,11 +1791,11 @@
                         Logger.getLogger().debug("Rollback of TwoPhaseResource " + resource + " failed with exception", ignore);
                     }
                 }
-
+                
                 if (th instanceof RuntimeException) {
                     throw (RuntimeException) th;
                 }
-
+                
                 throw new RuntimeException(th);
             }
         }
@@ -1856,18 +1856,18 @@
                 ValidationService vs = handle.getService();
                 allValidators.remove(vs);
             }
-
+            
             if (unbind.isReified()) {
                 for (Injectee injectee : unbind.getInjectees()) {
                     if (injectee instanceof SystemInjecteeImpl) {
                         injecteeToResolverCache.remove((SystemInjecteeImpl) injectee);
                     }
                 }
-
+                
                 classReflectionHelper.clean(unbind.getImplementationClass());
             }
         }
-
+        
         boolean hasOneUnbind = false;
         for (SystemDescriptor<?> unbind : unbinds) {
             hasOneUnbind = true;
@@ -1876,7 +1876,7 @@
             // as the validation service while we are unbinding
             unbind.close();
         }
-
+        
         if (hasOneUnbind) {
             perLocatorUtilities.releaseCaches();
         }
@@ -1981,13 +1981,13 @@
         }
         injecteeToResolverCache.clear();
     }
-
+    
     private void reupInterceptionServices() {
         List<InterceptionService> allInterceptionServices = protectedGetAllServices(InterceptionService.class);
 
         interceptionServices.clear();
         interceptionServices.addAll(allInterceptionServices);
-
+        
         hasInterceptionServices = !interceptionServices.isEmpty();
     }
 
@@ -1997,7 +1997,7 @@
         errorHandlers.clear();
         errorHandlers.addAll(allErrorServices);
     }
-
+    
     private void reupConfigListeners() {
         List<ServiceHandle<?>> allConfigListeners = protectedGetAllServiceHandles(DynamicConfigurationListener.class);
 
@@ -2072,7 +2072,7 @@
         if (errorHandlersModified) {
             reupErrorHandlers();
         }
-
+        
         if (dynamicConfigurationListenersModified) {
             reupConfigListeners();
         }
@@ -2087,7 +2087,7 @@
         if (classAnalyzersModified) {
             reupClassAnalyzers();
         }
-
+        
         // Should be last in order to ensure none of the
         // things added in this update are intercepted
         if (interceptionServicesModified) {
@@ -2112,14 +2112,14 @@
             sli.getAllChildren(allMyChildren);
         }
     }
-
+    
     private void callAllConfigurationListeners(List<ServiceHandle<?>> allListeners) {
         if (allListeners == null) return;
-
+        
         for (ServiceHandle<?> listener : allListeners) {
             ActiveDescriptor<?> listenerDescriptor = listener.getActiveDescriptor();
             if (listenerDescriptor.getLocatorId() != id) continue;
-
+            
             try {
                 ((DynamicConfigurationListener) listener.getService()).configurationChanged();
             }
@@ -2131,7 +2131,7 @@
 
     /* package */ void addConfiguration(DynamicConfigurationImpl dci) {
         CheckConfigurationData checkData;
-
+        
         List<ServiceHandle<?>> allConfigurationListeners = null;
         MultiException configurationError = null;
 
@@ -2151,7 +2151,7 @@
                     checkData.getDynamicConfigurationListenerModificationMade(),
                     checkData.getAffectedContracts(),
                     checkData.getInterceptionServiceModificationMade());
-
+            
             allConfigurationListeners = new LinkedList<ServiceHandle<?>>(configListeners);
         } catch (MultiException me) {
             configurationError = me;
@@ -2161,9 +2161,9 @@
             if (configurationError != null) {
                 errorServices = new LinkedList<ErrorService>(errorHandlers);
             }
-
+            
             wLock.unlock();
-
+            
             if (errorServices != null && !errorServices.isEmpty()) {
                 for (ErrorService errorService : errorServices) {
                     try {
@@ -2177,7 +2177,7 @@
                         // Ignore
                     }
                 }
-
+                
             }
         }
 
@@ -2187,9 +2187,9 @@
         for (ServiceLocatorImpl sli : allMyChildren) {
             sli.reupCache(checkData.getAffectedContracts());
         }
-
+        
         callAllConfigurationListeners(allConfigurationListeners);
-
+        
         LinkedList<TwoPhaseResource> resources = dci.getResources();
         for (TwoPhaseResource resource : resources) {
             try {
@@ -2224,12 +2224,6 @@
 
     private Context<?> _resolveContext(final Class<? extends Annotation> scope) throws IllegalStateException {
         Context<?> retVal = null;
-        if (parent != null) {
-            retVal = parent._resolveContext(scope);
-            if (retVal != null) {
-                return retVal;
-            }
-        }
         Type actuals[] = new Type[1];
         actuals[0] = scope;
         ParameterizedType findContext = new ParameterizedTypeImpl(Context.class, actuals);
@@ -2257,7 +2251,7 @@
         if (scope.equals(PerLookup.class)) return perLookupContext;
         Context<?> retVal = contextCache.compute(scope);
         if (retVal.isActive()) return retVal;
-
+        
         // Not active anymore, maybe there is another.  But first, clear the cache!
         contextCache.remove(scope);
         return contextCache.compute(scope);
@@ -2464,7 +2458,7 @@
             wLock.unlock();
         }
     }
-
+    
     @Override
     public Unqualified getDefaultUnqualified() {
         rLock.lock();
@@ -2475,7 +2469,7 @@
             rLock.unlock();
         }
     }
-
+    
     @Override
     public void setDefaultUnqualified(Unqualified unqualified) {
         wLock.lock();
@@ -2485,7 +2479,7 @@
         finally {
             wLock.unlock();
         }
-
+        
     }
 
     /* package */ ClassAnalyzer getAnalyzer(String name, Collector collector) {
@@ -2562,7 +2556,7 @@
         private boolean getClassAnalyzerModificationMade() {
             return classAnalyzerModificationMade;
         }
-
+        
         private boolean getDynamicConfigurationListenerModificationMade() {
             return dynamicConfigurationListenerModificationMade;
         }
@@ -2570,11 +2564,11 @@
         private HashSet<String> getAffectedContracts() {
             return affectedContracts;
         }
-
+        
         private boolean getInterceptionServiceModificationMade() {
             return interceptionServiceModificationMade;
         }
-
+        
         private TwoPhaseTransactionData getTransactionData() {
             return transactionData;
         }
@@ -2594,7 +2588,7 @@
         @Override
         public boolean matches(Descriptor d) {
             if (unqualified == null) return true;
-
+            
             Class<? extends Annotation> unqualifiedAnnos[] = unqualified.value();
 
             if (unqualifiedAnnos.length <= 0) {
@@ -2622,7 +2616,7 @@
         public String getName() {
             return name;
         }
-
+        
         @Override
         public String toString() {
             return "UnqualifiedIndexFilter(" + contract + "," + name + "," + unqualified + "," + System.identityHashCode(this) + ")";
@@ -2651,28 +2645,28 @@
         }
 
     }
-
+    
     /**
      * Used to get the ServiceLocatorImpl in inner classes
-     *
+     * 
      * @return This current object
      */
     private ServiceLocatorImpl getMe() {
         return this;
     }
-
+    
     /* package */ boolean hasInjectAnnotation(AnnotatedElement annotated) {
         return perLocatorUtilities.hasInjectAnnotation(annotated);
     }
-
+    
     /* package */ InjectionResolver<?> getInjectionResolverForInjectee(SystemInjecteeImpl injectee) {
-        return injecteeToResolverCache.compute(injectee);
+        return injecteeToResolverCache.compute(injectee);  
     }
-
+    
     /* package */ ClassReflectionHelper getClassReflectionHelper() {
         return classReflectionHelper;
     }
-
+    
     /* package */ LinkedList<ErrorService> getErrorHandlers() {
         rLock.lock();
         try {
@@ -2682,7 +2676,7 @@
             rLock.unlock();
         }
     }
-
+    
     /* package */ PerLocatorUtilities getPerLocatorUtilities() {
         return perLocatorUtilities;
     }
@@ -2711,7 +2705,7 @@
 
     /* package */ void clearServiceCache() {
         igdCache.clear();
-
+        
     }
 
     /* package */ int getReflectionCacheSize() {
@@ -2727,22 +2721,22 @@
             wLock.unlock();
         }
     }
-
+    
     /* package */ int unsortIndexes(int newRank, SystemDescriptor<?> desc, Set<IndexedListData> myLists) {
         wLock.lock();
         try {
             int retVal = desc.setRankWithLock(newRank);
-
+            
             for (IndexedListData myList : myLists) {
                 myList.unSort();
             }
-
+            
             return retVal;
         }
         finally {
             wLock.unlock();
         }
-
+        
     }
 
     @Override