### Question:
TypeUtils { @Nullable public static ArgType replaceClassGenerics(RootNode root, ArgType instanceType, ArgType typeWithGeneric) { if (typeWithGeneric == null) { return null; } if (instanceType.isGeneric()) { List<GenericInfo> generics = root.getClassGenerics(instanceType); if (generics.isEmpty()) { return null; } ArgType[] actualTypes = instanceType.getGenericTypes(); if (actualTypes == null) { return null; } int genericParamsCount = actualTypes.length; if (genericParamsCount != generics.size()) { return null; } Map<ArgType, ArgType> replaceMap = new HashMap<>(genericParamsCount); for (int i = 0; i < genericParamsCount; i++) { ArgType actualType = actualTypes[i]; ArgType genericType = generics.get(i).getGenericType(); replaceMap.put(genericType, actualType); } return replaceGenericUsingTypeMap(typeWithGeneric, replaceMap); } return null; } private  TypeUtils(); @Nullable static ArgType replaceClassGenerics(RootNode root, ArgType instanceType, ArgType typeWithGeneric); @Nullable static ArgType replaceMethodGenerics(RootNode root, InsnNode invokeInsn, ArgType typeWithGeneric);  }### Answer:
@Test public void testReplaceGenericsWithWildcards() { List<GenericInfo> classGenerics = root.getClassGenerics(ArgType.object("java.util.ArrayList")); assertThat(classGenerics, hasSize(1)); GenericInfo genericInfo = classGenerics.get(0); assertThat(genericInfo.getGenericType(), is(ArgType.genericType("E"))); assertThat(genericInfo.getExtendsList(), hasSize(0)); ArgType instanceType = ArgType.generic("java.util.ArrayList", ArgType.OBJECT); LOG.debug("instanceType: {}", instanceType); ArgType generic = ArgType.generic("java.util.List", ArgType.wildcard(ArgType.genericType("E"), ArgType.WildcardBound.SUPER)); LOG.debug("generic: {}", generic); ArgType result = TypeUtils.replaceClassGenerics(root, instanceType, generic); LOG.debug("result: {}", result); ArgType expected = ArgType.generic("java.util.List", ArgType.wildcard(ArgType.OBJECT, ArgType.WildcardBound.SUPER)); assertThat(result, is(expected)); }