code: protected void inferClosureParameterTypes(final ClassNode receiver, final Expression arguments, final ClosureExpression expression, final Parameter param, final MethodNode selectedMethod) {
          List<AnnotationNode> annotations = param.getAnnotations(CLOSUREPARAMS_CLASSNODE);
          if (annotations != null && !annotations.isEmpty()) {
              for (AnnotationNode annotation : annotations) {
                  Expression hintClass = annotation.getMember("value");
                  Expression options = annotation.getMember("options");
                  Expression resolverClass = annotation.getMember("conflictResolutionStrategy");
                  if (hintClass instanceof ClassExpression) {
                      doInferClosureParameterTypes(receiver, arguments, expression, selectedMethod, hintClass, resolverClass, options);
                  }
              }
          } else if (isSAMType(param.getOriginType())) {
              // SAM coercion
              inferSAMType(param, receiver, selectedMethod, InvocationWriter.makeArgumentList(arguments), expression);
          }
      }
docs: This method is responsible for performing type inference on closure argument types whenever code like this is
  found: <code>foo.collect { it.toUpperCase() }</code>.
  In this case, the type checker tries to find if the <code>collect</code> method has its {@link Closure} argument
  annotated with {@link groovy.transform.stc.ClosureParams}. If yes, then additional type inference can be performed
  and the type of <code>it</code> may be inferred.
  
  @param receiver
  @param arguments
  @param expression     a closure expression for which the argument types should be inferred
  @param param          the parameter where to look for a {@link groovy.transform.stc.ClosureParams} annotation.
  @param selectedMethod the method accepting a closure