public static boolean isNeedParenthesis(@NotNull ASTNode oldExpr, ASTNode newExpr) {
    final ASTNode oldParent = oldExpr.getTreeParent();
    if (!ElementType.EXPRESSION_BIT_SET.contains(oldParent.getElementType())) return false;
    int priority = getExpressionPriority(newExpr);
    int parentPriority = getExpressionPriority(oldParent);
    if (priority == -1 || parentPriority == -1) {
      // Unknown element types: enclose with parentheses just in case
      return true;
    }
    if (priority > parentPriority) return false;
    IElementType i = oldParent.getElementType();
    if (i == JavaElementType.ASSIGNMENT_EXPRESSION) {
      return priority < parentPriority || ((CompositeElement)oldParent).getChildRole(oldExpr) == ChildRole.LOPERAND;
    }
    if (i == JavaElementType.CONDITIONAL_EXPRESSION) {
      int role = ((CompositeElement)oldParent).getChildRole(oldExpr);
      if (role == ChildRole.THEN_EXPRESSION) return false;
      return priority < parentPriority || role != ChildRole.ELSE_EXPRESSION;
    }
    if (i == JavaElementType.BINARY_EXPRESSION || i == JavaElementType.POLYADIC_EXPRESSION) {
      if (priority < parentPriority) return true;
      PsiElement element = SourceTreeToPsiMap.treeElementToPsi(oldParent);
      assert element != null;
      IElementType opType = ((PsiPolyadicExpression)element).getOperationTokenType();
      IElementType newI = newExpr.getElementType();
      if (((CompositeElement)oldParent).getChildRole(oldExpr) == ChildRole.LOPERAND) return false;
      if (newI == JavaElementType.BINARY_EXPRESSION || newI == JavaElementType.POLYADIC_EXPRESSION) {
        IElementType newType = ((PsiPolyadicExpression)newExpr).getOperationTokenType();
        if (newType == JavaTokenType.DIV || newType == JavaTokenType.PERC) return true;
      }
      return opType != JavaTokenType.PLUS &&
             opType != JavaTokenType.ASTERISK &&
             opType != JavaTokenType.ANDAND &&
             opType != JavaTokenType.OROR;
    }
    if (i == JavaElementType.POSTFIX_EXPRESSION) {
      return true;
    }
    if (i == JavaElementType.INSTANCE_OF_EXPRESSION ||
             i == JavaElementType.PREFIX_EXPRESSION ||
             i == JavaElementType.TYPE_CAST_EXPRESSION ||
             i == JavaElementType.REFERENCE_EXPRESSION ||
             i == JavaElementType.METHOD_REF_EXPRESSION) {
      return priority < parentPriority;
    }
    if (i == JavaElementType.ARRAY_ACCESS_EXPRESSION) {
      int role = ((CompositeElement)oldParent).getChildRole(oldExpr);
      return role != ChildRole.ARRAY_DIMENSION && role != ChildRole.INDEX && priority < parentPriority;
    }
    if (i == JavaElementType.METHOD_CALL_EXPRESSION ||
             i == JavaElementType.NEW_EXPRESSION ||
             i == JavaElementType.ARRAY_INITIALIZER_EXPRESSION ||
             i == JavaElementType.PARENTH_EXPRESSION ||
             i == JavaElementType.LITERAL_EXPRESSION ||
             i == JavaElementType.THIS_EXPRESSION ||
             i == JavaElementType.SUPER_EXPRESSION ||
             i == JavaElementType.CLASS_OBJECT_ACCESS_EXPRESSION ||
             i == JavaElementType.LAMBDA_EXPRESSION ||
             i == JavaElementType.SWITCH_EXPRESSION ||
             i == JavaElementType.TEMPLATE_EXPRESSION) {
      return false;
    }

    LOG.assertTrue(false);
    return false;
  }
public static boolean isNeedParenthesis(@NotNull ASTNode oldExpr, ASTNode newExpr)