docs: protected static boolean typeCheckMethodArgumentWithGenerics(ClassNode parameterType, ClassNode argumentType, boolean lastArg) {
          if (UNKNOWN_PARAMETER_TYPE == argumentType) {
              // called with null
              return !isPrimitiveType(parameterType);
          }
          if (!isAssignableTo(argumentType, parameterType) && !lastArg) {
              // incompatible assignment
              return false;
          }
          if (!isAssignableTo(argumentType, parameterType) && lastArg) {
              if (parameterType.isArray()) {
                  if (!isAssignableTo(argumentType, parameterType.getComponentType())) {
                      return false;
                  }
              } else {
                  return false;
              }
          }
          if (parameterType.isUsingGenerics() && argumentType.isUsingGenerics()) {
              GenericsType gt = GenericsUtils.buildWildcardType(parameterType);
              if (!gt.isCompatibleWith(argumentType)) {
                  boolean samCoercion = isSAMType(parameterType) && argumentType.equals(CLOSURE_TYPE);
                  if (!samCoercion) return false;
              }
          } else if (parameterType.isArray() && argumentType.isArray()) {
              // verify component type
              return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType.getComponentType(), lastArg);
          } else if (lastArg && parameterType.isArray()) {
              // verify component type, but if we reach that point, the only possibility is that the argument is
              // the last one of the call, so we're in the cast of a vargs call
              // (otherwise, we face a type checker bug)
              return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType, lastArg);
          }
          return true;
      }