JoiningTerminal (@NotNull TerminalBlock terminalBlock, @Nullable List<PsiVariable> nonFinalVariables) { if (nonFinalVariables != null && nonFinalVariables.size() != 1) return null; SpecialFirstIterationLoop specialFirstIterationLoop = SpecialFirstIterationLoop.BoolFlagLoop.extract(terminalBlock); if (specialFirstIterationLoop == null) return null; PsiLocalVariable boolVar = specialFirstIterationLoop.getVariable(); if (boolVar == null) return null; if (nonFinalVariables != null && !nonFinalVariables.get(0).equals(boolVar)) return null; List<? extends PsiStatement> firstIterationStatements = specialFirstIterationLoop.getFirstIterationStatements(); List<? extends PsiStatement> otherIterationStatements = specialFirstIterationLoop.getOtherIterationStatements(); if (firstIterationStatements.isEmpty() || otherIterationStatements.isEmpty()) return null; List<PsiExpression> firstIterationJoinParts = extractJoinParts(firstIterationStatements); List<PsiExpression> otherIterationJoinParts = extractJoinParts(otherIterationStatements); if (firstIterationJoinParts == null || otherIterationJoinParts == null) return null; JoinData joinData = JoinData.extractLeftDelimiter(otherIterationJoinParts); if (!joinPartsAreEquivalent(joinData.getMainJoinParts(), firstIterationJoinParts)) return null; PsiVariable targetBuilder = extractStringBuilder(firstIterationStatements.get(0)); if (targetBuilder == null) return null; PsiStatement loop = terminalBlock.getStreamSourceStatement(); PrefixSuffixContext context = PrefixSuffixContext.extractAndVerifyRefs(loop, loop, targetBuilder, terminalBlock, singletonList(boolVar), new HashSet<>(emptyList())); if (context == null) return null; return new BoolFlagJoiningTerminal(targetBuilder, terminalBlock.getVariable(), firstIterationJoinParts, context, joinData.getDelimiterJoinParts(), boolVar, terminalBlock); }