void (GenericDeclaration owner, Type type, StringBuilder sb, Map<Class<?>, Collection<Class<?>>> classes) { if (type instanceof Class<?> aClass) { final Class<?> enclosingClass = aClass.getEnclosingClass(); if (enclosingClass != null) { sb.append(enclosingClass.getSimpleName()).append("_"); } else if (!aClass.isArray() && !aClass.isPrimitive() && !aClass.getName().startsWith("java.") && !classes.containsKey(aClass)) { classes.get(Object.class).add(aClass); } sb.append(aClass.getSimpleName()); if (owner == aClass) { dumpTypeParametersArray(owner, aClass.getTypeParameters(), sb, "<", ">", classes); } } else if (type instanceof TypeVariable<?> typeVariable) { sb.append(typeVariable.getName()); if (typeVariable.getGenericDeclaration() == owner) { dumpTypeParametersArray(null, typeVariable.getBounds(), sb, " extends ", "", classes); } } else if (type instanceof WildcardType wildcardType) { sb.append("?"); dumpTypeParametersArray(owner, wildcardType.getUpperBounds(), sb, " extends ", "", classes); dumpTypeParametersArray(owner, wildcardType.getLowerBounds(), sb, " super ", "", classes); } else if (type instanceof ParameterizedType parameterizedType) { final Type raw = parameterizedType.getRawType(); dumpType(null, raw, sb, classes); dumpTypeParametersArray(owner, parameterizedType.getActualTypeArguments(), sb, "<", ">", classes); } else if (type instanceof GenericArrayType) { dumpType(owner, ((GenericArrayType)type).getGenericComponentType(), sb, classes); sb.append("[]"); } }