Step (PsiMethodCallExpression call) { PsiMethodCallExpression collectorCall = tryCast(PsiUtil.skipParenthesizedExprDown(call.getArgumentList().getExpressions()[0]), PsiMethodCallExpression.class); if (COUNTING_COLLECTOR.matches(collectorCall)) { return new SumTerminalStep(call); } if (COLLECTION_COLLECTOR.matches(collectorCall)) { String name = Objects.requireNonNull(collectorCall.getMethodExpression().getReferenceName()); return new ToCollectionStep(call, ArrayUtil.getFirstElement(collectorCall.getArgumentList().getExpressions()), name.startsWith("toUnmodifiable")); } if (MAP_COLLECTOR.matches(collectorCall)) { PsiExpression[] args = collectorCall.getArgumentList().getExpressions(); if (args.length >= 2 && args.length <= 4) { PsiExpression keyExtractor = args[0]; PsiExpression valueExtractor = args[1]; PsiExpression merger = args.length >= 3 ? args[2] : null; PsiExpression supplier = args.length >= 4 ? args[3] : null; return new ToMapStep(call, keyExtractor, valueExtractor, merger, supplier, "toUnmodifiableMap".equals(collectorCall.getMethodExpression().getReferenceName())); } } if (GROUPING_COLLECTOR.matches(collectorCall)) { PsiExpression[] args = collectorCall.getArgumentList().getExpressions(); if (args.length >= 1 && args.length <= 3) { PsiExpression keyExtractor = args[0]; PsiExpression downstream = args.length > 1 ? args[args.length - 1] : null; PsiExpression supplier = args.length == 3 ? args[1] : null; return new GroupingStep(call, keyExtractor, downstream, supplier); } } return new UnknownTerminalStep(call, NOT_NULL_COLLECTORS.test(collectorCall)); }