private static FinishMarker defineFinishMarker(PsiCodeBlock block, List<? extends PsiReturnStatement> returns, PsiType returnType,
                                                 boolean mayNeedMarker, PsiElementFactory factory) {
    if (PsiTypes.voidType().equals(returnType)) {
      return new FinishMarker(FinishMarkerType.SEPARATE_VAR, null);
    }
    PsiReturnStatement terminalReturn = tryCast(ArrayUtil.getLastElement(block.getStatements()), PsiReturnStatement.class);
    List<PsiExpression> nonTerminalReturns = StreamEx.<PsiReturnStatement>of(returns).without(terminalReturn)
      .map(PsiReturnStatement::getReturnValue)
      .map(PsiUtil::skipParenthesizedExprDown).toList();
    if (nonTerminalReturns.size() == 0) {
      return new FinishMarker(FinishMarkerType.SEPARATE_VAR, null);
    }
    Set<Object> nonTerminalReturnValues = StreamEx.of(nonTerminalReturns)
      .map(val -> val instanceof PsiLiteralExpression ? ((PsiLiteralExpression)val).getValue() : NULL)
      .toSet();
    if (!mayNeedMarker) {
      PsiExpression initValue = findBestExpression(terminalReturn, nonTerminalReturns, false);
      if (initValue == null && nonTerminalReturnValues.size() == 1 && nonTerminalReturnValues.iterator().next() != NULL) {
        initValue = nonTerminalReturns.iterator().next();
      }
      return new FinishMarker(FinishMarkerType.SEPARATE_VAR, initValue);
    }
    if (PsiTypes.booleanType().equals(returnType)) {
      if (nonTerminalReturnValues.size() == 1) {
        Object value = nonTerminalReturnValues.iterator().next();
        if (value instanceof Boolean) {
          boolean boolReturn = (boolean)value;
          FinishMarkerType markerType = boolReturn ? FinishMarkerType.BOOLEAN_TRUE : FinishMarkerType.BOOLEAN_FALSE;
          return new FinishMarker(markerType, factory.createExpressionFromText(String.valueOf(!boolReturn), null));
        }
      }
    }
    if (PsiTypes.intType().equals(returnType) || PsiTypes.longType().equals(returnType)) {
      return getMarkerForIntegral(nonTerminalReturns, terminalReturn, returnType, factory);
    }
    if (!(returnType instanceof PsiPrimitiveType)) {
      if (StreamEx.of(nonTerminalReturns).map(ret -> NullabilityUtil.getExpressionNullability(ret, true))
        .allMatch(Nullability.NOT_NULL::equals)) {
        return new FinishMarker(FinishMarkerType.VALUE_NON_EQUAL, factory.createExpressionFromText("null", null));
      }
    }
    if (terminalReturn != null) {
      PsiExpression value = terminalReturn.getReturnValue();
      if (canMoveToStart(value)) {
        return new FinishMarker(FinishMarkerType.SEPARATE_VAR, value);
      }
    }
    return new FinishMarker(FinishMarkerType.SEPARATE_VAR, findBestExpression(terminalReturn, nonTerminalReturns, true));
  }
private static FinishMarker defineFinishMarker(PsiCodeBlock block, List<? extends PsiReturnStatement> returns, PsiType returnType,
                                                 boolean mayNeedMarker, PsiElementFactory factory)