@Override
  public boolean handleEquality(Project project, Editor editor, PsiFile file, int offsetBefore) {
    if (offsetBefore == 0) return false;
    Document doc = editor.getDocument();
    char prevChar = doc.getCharsSequence().charAt(offsetBefore - 1);
    if (prevChar != '=' && prevChar != '!') return false;

    HighlighterIterator it = editor.getHighlighter().createIterator(offsetBefore - 1);
    IElementType curToken = it.getTokenType();
    if (curToken != JavaTokenType.EQ && curToken != JavaTokenType.EXCL) return false;
    int lineStart = doc.getLineStartOffset(doc.getLineNumber(offsetBefore));
    do {
      it.retreat();
      if (it.atEnd()) return false;
      curToken = it.getTokenType();
    }
    while (curToken == TokenType.WHITE_SPACE || curToken == JavaTokenType.C_STYLE_COMMENT || curToken == JavaTokenType.END_OF_LINE_COMMENT);
    // ) == or ) != : definitely no need to add parentheses
    if (curToken == JavaTokenType.RPARENTH) return false;
    while (true) {
      if (it.getStart() < lineStart) return false;
      it.retreat();
      if (it.atEnd()) return false;
      curToken = it.getTokenType();
      if (curToken == JavaTokenType.AND || curToken == JavaTokenType.OR || curToken == JavaTokenType.XOR) break;
    }

    doc.insertString(offsetBefore, "=");
    editor.getCaretModel().moveToOffset(offsetBefore + 1);
    // a&b== => (a&b)==
    PsiDocumentManager.getInstance(project).commitDocument(doc);
    PsiJavaToken token = ObjectUtils.tryCast(file.findElementAt(offsetBefore), PsiJavaToken.class);
    if (token == null) return true;
    IElementType type = token.getTokenType();
    if (type != JavaTokenType.EQEQ && type != JavaTokenType.NE) return true;
    PsiBinaryExpression comparison = ObjectUtils.tryCast(token.getParent(), PsiBinaryExpression.class);
    if (comparison == null || comparison.getROperand() != null) return true;
    PsiBinaryExpression bitwiseOp = ObjectUtils.tryCast(comparison.getParent(), PsiBinaryExpression.class);
    if (bitwiseOp == null || bitwiseOp.getROperand() != comparison) return true;
    IElementType bitwiseOpType = bitwiseOp.getOperationTokenType();
    if (bitwiseOpType != JavaTokenType.AND && bitwiseOpType != JavaTokenType.OR && bitwiseOpType != JavaTokenType.XOR) return true;
    PsiExpression left = bitwiseOp.getLOperand();
    PsiExpression right = comparison.getLOperand();
    if (!TypeConversionUtil.isIntegralNumberType(left.getType()) || !TypeConversionUtil.isIntegralNumberType(right.getType())) {
      return true;
    }
    int openingOffset = left.getTextRange().getStartOffset();
    int closingOffset = right.getTextRange().getEndOffset();
    wrapWithParentheses(file, doc, openingOffset, closingOffset);
    return true;
  }
@Override
  public boolean handleEquality(Project project, Editor editor, PsiFile file, int offsetBefore)