docs: public static Type createParameterizedType(final Type ownerType0, final Type rawType0, final Type... actualTypeArguments0) {
          if (ownerType0 == null && rawType0 instanceof Class) {
              int count = 0;
              for (Type t : actualTypeArguments0) {
                  if (isClassType(t)) count++;
              }
              if (count == actualTypeArguments0.length) return createParameterizedType((Class) rawType0, actualTypeArguments0);
          }
          return new ParameterizedType() {
              private final Class<?> rawType = (Class<?>) rawType0;
  
              private final Type ownerType = ownerType0;
  
              private final Type[] actualTypeArguments = actualTypeArguments0;
  
              @Override
              public Type[] getActualTypeArguments() {
                  return actualTypeArguments.clone();
              }
  
              @Override
              public Type getRawType() {
                  return rawType;
              }
  
              @Override
              public Type getOwnerType() {
                  return ownerType;
              }
  
              @Override
              public int hashCode() {
                  return Arrays.hashCode(actualTypeArguments) ^ Objects.hashCode(rawType) ^ Objects.hashCode(ownerType);
              }
  
              @Override
              public boolean equals(Object o) {
                  if (!(o instanceof ParameterizedType)) return false;
                  final ParameterizedType that = (ParameterizedType) o;
                  if (this == that) return true;
                  return Objects.equals(ownerType, that.getOwnerType())
                      && Objects.equals(rawType, that.getRawType())
                      && Arrays.equals(actualTypeArguments, that.getActualTypeArguments());
              }
  
              @Override
              public String toString() {
                  StringBuilder sb = new StringBuilder();
                  if (ownerType != null) sb.append((ownerType instanceof Class) ? (((Class) ownerType).getName()) : ownerType.toString()).append(".");
                  sb.append(rawType.getName());
  
                  if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                      sb.append("<");
                      boolean first = true;
                      for (Type t : actualTypeArguments) {
                          if (!first) sb.append(", ");
                          sb.append(t);
                          first = false;
                      }
                      sb.append(">");
                  }
                  return sb.toString();
              }
          };
      }