private PsiType @NotNull [] inferMethodParameters(@NotNull GrMethod method) {
    PsiType[] psiTypes = inferredTypes.get(method);
    if (psiTypes != null) return psiTypes;

    final GrParameter[] parameters = method.getParameters();

    final IntList paramInds = new IntArrayList(parameters.length);
    final PsiType[] types = PsiType.createArray(parameters.length);
    for (int i = 0; i < parameters.length; i++) {
      if (parameters[i].getTypeElementGroovy() == null) {
        paramInds.add(i);
      } else {
        types[i] = parameters[i].getType();
      }
    }

    if (!paramInds.isEmpty()) {
      final GrSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY);
      MethodReferencesSearch.search(method, true).forEach(psiReference -> {
        final PsiElement element = psiReference.getElement();
        final PsiManager manager = element.getManager();
        final GlobalSearchScope resolveScope = element.getResolveScope();

        if (element instanceof GrReferenceExpression) {
          final GrCall call = (GrCall)element.getParent();
          final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);

          if (argInfos == null) return true;
          paramInds.forEach((IntConsumer)i -> {
            PsiType type = GrClosureSignatureUtil.getTypeByArg(argInfos[i], manager, resolveScope);
            types[i] = TypesUtil.getLeastUpperBoundNullable(type, types[i], manager);
          });
        }
        return true;
      });
    }
    paramInds.forEach((IntConsumer)i -> {
      if (types[i] == null || types[i] == PsiTypes.nullType()) {
        types[i] = parameters[i].getType();
      }
    });
    inferredTypes.put(method, types);
    return types;
  }
private PsiType @NotNull [] inferMethodParameters(@NotNull GrMethod method)