public static @Nullable Type extractCollectionElementType(Type returnType) {
    if (!(returnType instanceof ParameterizedType parameterizedType)) {
      return null;
    }

    Type rawType = parameterizedType.getRawType();
    if (!(rawType instanceof Class<?> rawClass)) {
      return null;
    }

    if (!List.class.equals(rawClass) && !Collection.class.equals(rawClass)) {
      return null;
    }

    final Type[] arguments = parameterizedType.getActualTypeArguments();
    if (arguments.length == 1) {
      final Type argument = arguments[0];
      if (argument instanceof WildcardType) {
        final Type[] upperBounds = ((WildcardType)argument).getUpperBounds();
        if (upperBounds.length == 1) {
          return upperBounds[0];
        }
      }
      else if (argument instanceof ParameterizedType) {
        if (DomUtil.getGenericValueParameter(argument) != null) {
          return argument;
        }
      }
      else if (argument instanceof Class) {
        return argument;
      }
    }
    return null;
  }
public static @Nullable Type extractCollectionElementType(Type returnType)