UnmodifiableTerminal (@NotNull CollectTerminal terminal, @NotNull PsiElement element) { if (PsiUtil.getLanguageLevel(element).isLessThan(LanguageLevel.JDK_10)) return null; if (terminal.getStatus() == ControlFlowUtils.InitializerUsageStatus.UNKNOWN) return null; WrapperCandidate candidate = WrapperCandidate.tryExtract(terminal, element); if (candidate == null) return null; if (!(candidate.myCandidate instanceof PsiMethodCallExpression wrapCall)) return null; if (!UNMODIFIABLE_WRAPPER.test(wrapCall)) return null; PsiExpression arg = wrapCall.getArgumentList().getExpressions()[0]; if (!terminal.isTargetReference(arg)) return null; if (terminal.getTargetVariable() != null) { arg = terminal.getTargetVariable().getInitializer(); } if (arg == null) return null; PsiClassType targetType = tryCast(arg.getType(), PsiClassType.class); if (targetType == null) return null; String collector = TYPE_TO_UNMODIFIABLE_WRAPPER.get(targetType.rawType().getCanonicalText()); if (collector == null) { if (!(arg instanceof PsiMethodCallExpression argCall)) return null; if (!STREAM_COLLECT.test(argCall)) return null; PsiExpression previousCollector = argCall.getArgumentList().getExpressions()[0]; if (TO_LIST.matches(previousCollector)) { collector = "toUnmodifiableList"; } else if (TO_SET.matches(previousCollector)) { collector = "toUnmodifiableSet"; } else { return null; } } if (terminal instanceof AddingTerminal) { if (terminal instanceof AddingAllTerminal) return null; Nullability nullability = NullabilityUtil.getExpressionNullability(((AddingTerminal)terminal).getMapping(), true); // Null is not allowed in unmodifiable list/set if (nullability == Nullability.NULLABLE) return null; } return new UnmodifiableTerminal(terminal, candidate.myVar, wrapCall, collector); }