@Nullable
 public static PsiExpression stripParentheses(@Nullable PsiExpression expression) {
   while (expression instanceof PsiParenthesizedExpression) {
     final PsiParenthesizedExpression parenthesizedExpression =
         (PsiParenthesizedExpression) expression;
     expression = parenthesizedExpression.getExpression();
   }
   return expression;
 }
 public static boolean areParenthesesNeeded(
     PsiParenthesizedExpression expression, boolean ignoreClarifyingParentheses) {
   final PsiElement parent = expression.getParent();
   if (!(parent instanceof PsiExpression)) {
     return false;
   }
   final PsiExpression child = expression.getExpression();
   if (child == null) {
     return true;
   }
   if (parent instanceof PsiArrayAccessExpression) {
     final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression) parent;
     final PsiExpression indexExpression = arrayAccessExpression.getIndexExpression();
     if (expression == indexExpression) {
       return false;
     }
   }
   return areParenthesesNeeded(child, (PsiExpression) parent, ignoreClarifyingParentheses);
 }
 @Nullable
 private static PsiReferenceExpression getReferenceFromInstanceofExpression(
     PsiExpression expression) {
   if (expression instanceof PsiParenthesizedExpression) {
     final PsiParenthesizedExpression parenthesizedExpression =
         (PsiParenthesizedExpression) expression;
     return getReferenceFromInstanceofExpression(parenthesizedExpression.getExpression());
   } else if (expression instanceof PsiInstanceOfExpression) {
     final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) expression;
     final PsiExpression operand =
         ParenthesesUtils.stripParentheses(instanceOfExpression.getOperand());
     if (!(operand instanceof PsiReferenceExpression)) {
       return null;
     }
     return (PsiReferenceExpression) operand;
   } else if (expression instanceof PsiPolyadicExpression) {
     final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression) expression;
     final IElementType tokenType = polyadicExpression.getOperationTokenType();
     if (JavaTokenType.OROR != tokenType) {
       return null;
     }
     final PsiExpression[] operands = polyadicExpression.getOperands();
     final PsiReferenceExpression referenceExpression =
         getReferenceFromInstanceofExpression(operands[0]);
     if (referenceExpression == null) {
       return null;
     }
     for (int i = 1, operandsLength = operands.length; i < operandsLength; i++) {
       if (!referencesEqual(
           referenceExpression, getReferenceFromInstanceofExpression(operands[i]))) {
         return null;
       }
     }
     return referenceExpression;
   } else {
     return null;
   }
 }
 private static void removeParensFromParenthesizedExpression(
     @NotNull PsiParenthesizedExpression parenthesizedExpression,
     boolean ignoreClarifyingParentheses) {
   final PsiExpression body = parenthesizedExpression.getExpression();
   if (body == null) {
     parenthesizedExpression.delete();
     return;
   }
   final PsiElement parent = parenthesizedExpression.getParent();
   if (!(parent instanceof PsiExpression)
       || parent instanceof PsiParenthesizedExpression
       || parent instanceof PsiArrayInitializerExpression) {
     final PsiExpression newExpression = (PsiExpression) parenthesizedExpression.replace(body);
     removeParentheses(newExpression, ignoreClarifyingParentheses);
     return;
   } else if (parent instanceof PsiArrayAccessExpression) {
     final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression) parent;
     if (parenthesizedExpression == arrayAccessExpression.getIndexExpression()) {
       // use addAfter() + delete() instead of replace() to
       // workaround automatic insertion of parentheses by psi
       final PsiExpression newExpression =
           (PsiExpression) parent.addAfter(body, parenthesizedExpression);
       parenthesizedExpression.delete();
       removeParentheses(newExpression, ignoreClarifyingParentheses);
       return;
     }
   }
   final PsiExpression parentExpression = (PsiExpression) parent;
   final int parentPrecedence = getPrecedence(parentExpression);
   final int childPrecedence = getPrecedence(body);
   if (parentPrecedence < childPrecedence) {
     final PsiElement bodyParent = body.getParent();
     final PsiParenthesizedExpression newParenthesizedExpression =
         (PsiParenthesizedExpression) parenthesizedExpression.replace(bodyParent);
     final PsiExpression expression = newParenthesizedExpression.getExpression();
     if (expression != null) {
       removeParentheses(expression, ignoreClarifyingParentheses);
     }
   } else if (parentPrecedence == childPrecedence) {
     if (parentExpression instanceof PsiPolyadicExpression
         && body instanceof PsiPolyadicExpression) {
       final PsiPolyadicExpression parentPolyadicExpression =
           (PsiPolyadicExpression) parentExpression;
       final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType();
       final PsiPolyadicExpression bodyPolyadicExpression = (PsiPolyadicExpression) body;
       final IElementType bodyOperator = bodyPolyadicExpression.getOperationTokenType();
       final PsiType parentType = parentPolyadicExpression.getType();
       final PsiType bodyType = body.getType();
       if (parentType != null
           && parentType.equals(bodyType)
           && parentOperator.equals(bodyOperator)) {
         final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands();
         if (PsiTreeUtil.isAncestor(parentOperands[0], body, true)
             || isCommutativeOperator(bodyOperator)) {
           // use addAfter() + delete() instead of replace() to
           // workaround automatic insertion of parentheses by psi
           final PsiExpression newExpression =
               (PsiExpression) parent.addAfter(body, parenthesizedExpression);
           parenthesizedExpression.delete();
           removeParentheses(newExpression, ignoreClarifyingParentheses);
           return;
         }
       }
       if (ignoreClarifyingParentheses) {
         if (parentOperator.equals(bodyOperator)) {
           removeParentheses(body, ignoreClarifyingParentheses);
         }
       } else {
         final PsiExpression newExpression = (PsiExpression) parenthesizedExpression.replace(body);
         removeParentheses(newExpression, ignoreClarifyingParentheses);
       }
     } else {
       final PsiExpression newExpression = (PsiExpression) parenthesizedExpression.replace(body);
       removeParentheses(newExpression, ignoreClarifyingParentheses);
     }
   } else {
     if (ignoreClarifyingParentheses
         && parent instanceof PsiPolyadicExpression
         && (body instanceof PsiPolyadicExpression || body instanceof PsiInstanceOfExpression)) {
       removeParentheses(body, ignoreClarifyingParentheses);
     } else {
       final PsiExpression newExpression = (PsiExpression) parenthesizedExpression.replace(body);
       removeParentheses(newExpression, ignoreClarifyingParentheses);
     }
   }
 }