docs: <T> InternalProviderImpl<? extends T> lookupProvider(Class<T> clazz, String bindingName) {
      if (clazz == null) {
        throw new IllegalArgumentException("TP can't get an instance of a null class.");
      }
      InternalProviderImpl<? extends T> scopedProvider = getBoundProvider(clazz, bindingName);
      if (scopedProvider != null) {
        return scopedProvider;
      }
      Iterator<ScopeNode> iterator = parentScopes.iterator();
      while (iterator.hasNext()) {
        Scope parentScope = iterator.next();
        ScopeImpl parentScopeImpl = (ScopeImpl) parentScope;
        InternalProviderImpl<? extends T> parentScopedProvider = parentScopeImpl.getBoundProvider(clazz, bindingName);
        if (parentScopedProvider != null) {
          return parentScopedProvider;
        }
      }
  
      //if the binding is named
      //we couldn't find it in any scope, we must fail
      //as only unnamed bindings can be created dynamically
      if (bindingName != null) {
        throw new RuntimeException(format("No binding was defined for class %s and name %s " //
            + "in scope %s and its parents %s", clazz.getName(), bindingName, getName(), getParentScopesNames()));
      }
  
      //we now look for an unnamed binding
      //bindingName = null;  <-- valid but fails checkstyle as we use null directly
  
      //check if we have a cached un-scoped provider
      InternalProviderImpl unScopedProviderInPool = getUnBoundProvider(clazz, null);
      if (unScopedProviderInPool != null) {
        return unScopedProviderInPool;
      }
  
      //classes discovered at runtime, not bound by any module
      //they will be a bit slower as we need to get the factory first
      //we need to know whether they are scoped or not, if so we scope them
      //if not, they are place in the pool
      Factory<T> factory = FactoryLocator.getFactory(clazz);
  
      if (factory.hasScopeAnnotation()) {
        //the new provider will have to work in the current scope
        Scope targetScope = factory.getTargetScope(this);
        ScopedProviderImpl<? extends T> newProvider = new ScopedProviderImpl<>(targetScope, factory, false);
        //it is bound to its target scope only if it has a scope annotation.
        //lock free installing a provider means there could have been one set concurrently since last testing
        //its value. We allow to return it here
        ScopeImpl targetScopeImpl = (ScopeImpl) targetScope;
        return targetScopeImpl.installScopedProvider(clazz, null, newProvider, false);
      } else {
        //the provider is but in a pool of unbound providers for later reuse
        final InternalProviderImpl<T> newProvider = new InternalProviderImpl<>(factory,
            false);
        //the pool is static as it is accessible from all scopes
        //lock free installing a provider means there could have been one set concurrently since last testing
        //its value. We allow to return it here
        return installUnBoundProvider(clazz, null, newProvider);
      }
    }