docs: @Override
      @FFDCIgnore(InterruptedException.class)
      /* re-thrown as an IllegalStateException and FFDC'd later */
      public ThreadContextClassLoader createThreadContextClassLoader(final ClassLoader applicationClassLoader) {
          final String methodName = "createThreadContextClassLoader(): ";
          if (applicationClassLoader == null) {
              throw new IllegalArgumentException("ClassLoader argument is null");
          }
  
          final String key;
          if (applicationClassLoader instanceof AppClassLoader) {
              key = ((AppClassLoader) applicationClassLoader).getKey().toString();
              if (tc.isDebugEnabled())
                  Tr.debug(tc, methodName + "Instance of LibertyClassLoader, key = " + key);
          } else if (applicationClassLoader instanceof BundleReference) {
              key = Long.toString(((BundleReference) applicationClassLoader).getBundle().getBundleId());
              if (tc.isDebugEnabled())
                  Tr.debug(tc, methodName + "Instance of BundleReference, key = " + key);
          } else {
              throw new IllegalArgumentException(applicationClassLoader.toString() + " + is an unexpected ClassLoader type");
          }
  
          ThreadContextClassLoader result;
          try {
              if (tcclStoreLock.tryLock(TCCL_LOCK_WAIT, TimeUnit.MILLISECONDS)) {
                  do {
                      result = this.tcclStore.retrieveOrCreate(key, new Factory<ThreadContextClassLoader>() {
                          @Override
                          public ThreadContextClassLoader createInstance() {
                              return ClassLoadingServiceImpl.this.createTCCL(applicationClassLoader, key);
                          }
                      }); // using an anonymous inner class here for clarity - the object should be GCable as soon as the method call returns
                      if (!!!result.isFor(applicationClassLoader)) {
                          // this is a stale entry for a previous ClassLoader that had the same key
                          this.tcclStore.remove(result);
                          result = null;
                      }
                  } while (result == null);
  
                  result.incrementRefCount();
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      leakDetectionMap.put(result, Thread.currentThread().getStackTrace());
                  }
              } else {
                  // could not acquire the tcclStoreLock
                  throw new IllegalStateException("Unable to acquire TCCL store lock");
              }
          } catch (InterruptedException e) {
              throw new IllegalStateException("Thread interrupted while acquiring TCCL store lock");
          } finally {
              if (tcclStoreLock.isHeldByCurrentThread()) {
                  tcclStoreLock.unlock();
              }
          }
          return result;
      }