PsiMethod (@NotNull PsiAnnotation psiAnnotation, @NotNull PsiClass parentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass builderClass, @NotNull String buildMethodName, List<BuilderInfo> builderInfos) { final PsiType builderType = getReturnTypeOfBuildMethod(parentClass, psiMethod); final PsiSubstitutor builderSubstitutor = getBuilderSubstitutor(parentClass, builderClass); final PsiType returnType = builderSubstitutor.substitute(builderType); final String buildMethodPrepare = builderInfos.stream() .map(BuilderInfo::renderBuildPrepare) .collect(Collectors.joining()); final String buildMethodParameters = builderInfos.stream() .map(BuilderInfo::renderBuildCall) .collect(Collectors.joining(",")); final LombokLightMethodBuilder methodBuilder = new LombokLightMethodBuilder(parentClass.getManager(), buildMethodName) .withMethodReturnType(returnType) .withContainingClass(builderClass) .withNavigationElement(parentClass) .withModifier(getBuilderInnerAccessVisibility(psiAnnotation)); final String codeBlockText = createBuildMethodCodeBlockText(psiMethod, builderClass, returnType, buildMethodPrepare, buildMethodParameters); methodBuilder.withBodyText(codeBlockText); if (!PsiTypes.voidType().equals(returnType)) { createRelevantNonNullAnnotation(builderClass, methodBuilder); } Optional<PsiMethod> definedConstructor = Optional.ofNullable(psiMethod); if (definedConstructor.isEmpty()) { definedConstructor = getExistingConstructorForParameters(parentClass, builderInfos); } definedConstructor.map(PsiMethod::getThrowsList).map(PsiReferenceList::getReferencedTypes).map(Arrays::stream) .ifPresent(stream -> stream.forEach(methodBuilder::withException)); return methodBuilder; }