code: @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
      public static Map<Class<?>, LinkedHashMap<String, Type>> trackRootVariables(
              final Class<?> type,
              final List<Class<?>> ignoreClasses) {
          // leave type variables to track where would they go
          final LinkedHashMap<String, Type> rootGenerics = new LinkedHashMap<String, Type>();
          for (TypeVariable var : type.getTypeParameters()) {
              // special variables type, known by resolver (no exceptions for unknown generics will be thrown)
              rootGenerics.put(var.getName(), new ExplicitTypeVariable(var));
          }
          return GenericsResolutionUtils.resolve(type,
                  rootGenerics,
                  Collections.<Class<?>, LinkedHashMap<String, Type>>emptyMap(),
                  ignoreClasses == null ? Collections.<Class<?>>emptyList() : ignoreClasses);
      }
docs: Used when it is important to track when root type generics will go. For example:
  {@code  class Root<T> implements Base<List<T>>}. When resolution applied, unknown root type T
  will be replaced with special type {@link ExplicitTypeVariable}, which does not cause exceptions on type
  resolution, but allows to preserve root type variables. After resolution actual types could be constructed
  depending on root type parametrization (dynamic calculation).
  
  @param type          class to analyze
  @param ignoreClasses classes to ignore during analysis (may be null)
  @return resolved generics for all types in class hierarchy with root variables preserved