code: public static ClassLoader getClassLoader(TypeToken<?> type) {
      Set<ClassLoader> classLoaders = Sets.newIdentityHashSet();
  
      // Breath first traversal into the Type.
      Queue<TypeToken<?>> queue = Lists.newLinkedList();
      queue.add(type);
      while (!queue.isEmpty()) {
        type = queue.remove();
        ClassLoader classLoader = type.getRawType().getClassLoader();
        if (classLoader != null) {
          classLoaders.add(classLoader);
        }
  
        if (type.getType() instanceof ParameterizedType) {
          for (Type typeArg : ((ParameterizedType) type.getType()).getActualTypeArguments()) {
            queue.add(TypeToken.of(typeArg));
          }
        }
      }
  
      // Determine the parent classloader
      ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
      ClassLoader parent = (contextClassLoader == null) ? ClassLoader.getSystemClassLoader() : contextClassLoader;
  
      if (classLoaders.isEmpty()) {
        return parent;
      }
      return new CombineClassLoader(parent, classLoaders);
    }
docs: Returns the ClassLoader of the given type. If the given type is a {@link java.lang.reflect.ParameterizedType},
  it returns a {@link CombineClassLoader} of all types. The context ClassLoader or System ClassLoader would be used
  as the parent of the CombineClassLoader.
  
  @return A new CombineClassLoader. If no ClassLoader is found from the type,
  it returns the current thread context ClassLoader if it's not null, otherwise, return system ClassLoader.