GrSignature (@NotNull GrSignature signature1, @NotNull GrSignature signature2, @NotNull PsiManager manager) { GrClosureParameter[] parameters1 = signature1.getParameters(); GrClosureParameter[] parameters2 = signature2.getParameters(); if (parameters1.length == parameters2.length) { GrClosureParameter[] params = new GrClosureParameter[parameters1.length]; for (int i = 0; i < params.length; i++) { final PsiType type = GenericsUtil.getGreatestLowerBound(parameters1[i].getType(), parameters2[i].getType()); boolean opt = parameters1[i].isOptional() && parameters2[i].isOptional(); String name = StringUtil.equals(parameters1[i].getName(), parameters2[i].getName()) ? parameters1[i].getName() : null; params[i] = new GrImmediateClosureParameterImpl(type, name, opt, null); } final PsiType s1type = signature1.getReturnType(); final PsiType s2type = signature2.getReturnType(); PsiType returnType = null; if (s1type != null && s2type != null) { returnType = TypesUtil.getLeastUpperBound(s1type, s2type, manager); } boolean isVarArgs = signature1.isVarargs() && signature2.isVarargs(); return new GrImmediateClosureSignatureImpl(params, returnType, isVarArgs, false); } return null; //todo }