@SuppressWarnings("unchecked")
	private <S> ServiceProviderInfo<S> findProviderInfo(Class<S> serviceClass) {

		ServiceProviderInfo<S> result;

		// Try to avoid synchronization by looking in our thread-local cache,
		// which is just a (potential) subset of the global service provider
		// class cache. If not found here, proceed

		if (threadServiceProviderInfoCache.get()!=null) {
			result=threadServiceProviderInfoCache.get().get(serviceClass);
			if (result!=null) {
				return result;
			}
		}

		synchronized (SERVICE_PROVIDER_INFO) {

			result=SERVICE_PROVIDER_INFO.get(serviceClass);
			if (result!=null) {
				updateThreadServiceProviderClassCache();
				return result;
			}

			// TODO: Do we want to think about using Thread's context class
			// loader for those cases where the Services instance may be
			// instantiated more than once? Right now, there is only a single
			// global instance, so our own class loader should be sufficient.
			// Also, consider that the context class loader would only be
			// appropriate for request-scoped services.
			List<Class<? extends S>> providerClasses=
				findProviders(serviceClass,getClass().getClassLoader());

			// We have a bit of a problem here, since there is no guarantee
			// that the one provider that we choose to return will be
			// instantiatable. Take a chance for now and solve this problem
			// later. (We might want to introduce an annotation of the priority
			// so that we can look for providers in a particular order.)
			for (Class<? extends S> providerClass: providerClasses) {
				ServiceProvider annotation=
					providerClass.getAnnotation(ServiceProvider.class);

				if (annotation!=null) {

					result=new ServiceProviderInfo<S>(
						serviceClass,providerClass);

					// Cache the provider class so we can create more
					// instances later
					SERVICE_PROVIDER_INFO.put(serviceClass,result);

					updateThreadServiceProviderClassCache();

					// Put a copy on the local thread's cache
					break;
				}
				else {
					// Ignore implementation class because it's not annotated
					System.out.println("Ignoring service provider class "+
						providerClass.getName()+" for service "+
						serviceClass.getName()+" because it has not been "+
						"annotated as a provider. See "+
						ServiceProvider.class.getName()+".");
				}
			}

			return result;
		}
	}