private static Step createTerminalFromCollector(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));
  }
private static Step createTerminalFromCollector(PsiMethodCallExpression call)