DelimiterRewriteJoiningTerminal (@NotNull TerminalBlock terminalBlock, @Nullable List<PsiVariable> nonFinalVariables) { if (nonFinalVariables != null && nonFinalVariables.size() != 1) return null; List<PsiStatement> statements = List.of(terminalBlock.getStatements()); if (statements.size() < 2) return null; // TODO maybe not just last, but check if delimiter not used after assignment? PsiAssignmentExpression assignment = extractAssignment(statements.get(statements.size() - 1)); if (assignment == null) return null; PsiLocalVariable delimiterVar = extractDelimiterVar(assignment); if (delimiterVar == null) return null; PsiExpression delimiter = extractDelimiter(assignment); if (delimiter == null) return null; List<PsiStatement> mainStatements = statements.subList(0, statements.size() - 1); List<PsiExpression> joinParts = extractJoinParts(mainStatements); if (joinParts == null || joinParts.isEmpty()) return null; if (isSeparator(delimiterVar, joinParts.get(0))) return null; joinParts.remove(0); if (ReferencesSearch.search(delimiterVar, new LocalSearchScope(terminalBlock.getStatements())).findAll().size() != 2) return null; PsiVariable targetBuilder = extractStringBuilder(mainStatements.get(0)); if (targetBuilder == null) return null; PsiStatement loop = terminalBlock.getStreamSourceStatement(); PrefixSuffixContext context = PrefixSuffixContext.extractAndVerifyRefs(loop, loop, targetBuilder, terminalBlock, singletonList(delimiterVar), new HashSet<>(emptyList())); if (context == null) return null; PsiVariable variable = terminalBlock.getVariable(); return new DelimiterRewriteJoiningTerminal(targetBuilder, variable, joinParts, context, singletonList(delimiter), delimiterVar, terminalBlock); }