Result (@NotNull TypeEvalContext context) { if (myStubComputation == null) { throw new IllegalStateException("Over-stub computation must be provided"); } Function<Psi, Result> overNewStubComputation = myStubBuilder != null ? myStubBuilder.andThen(myStubComputation) : null; Function<Psi, Result> astComputation = ObjectUtils.chooseNotNull(myAstComputation, overNewStubComputation); if (astComputation == null) { throw new IllegalStateException("Either over-AST computation or a stub builder must be provided"); } Function<Psi, Result> astStubLikeComputation = ObjectUtils.chooseNotNull(myAstStubLikeComputation, overNewStubComputation); if (astStubLikeComputation == null) { throw new IllegalStateException("Either over-AST-stub-like computation or a stub builder must be provided"); } Psi psi = myConversion.myElement; if (context.maySwitchToAST(psi)) { return astComputation.apply(psi); } else if (myConversion.getPsiStub() != null) { return myStubComputation.apply(myConversion.getCustomStub()); } else { return astStubLikeComputation.apply(psi); } }