@Nullable
  protected Object evaluateBinary(@NotNull PyBinaryExpression expression) {
    final PyElementType op = expression.getOperator();
    final Object lhs = evaluate(expression.getLeftExpression());
    final Object rhs = evaluate(expression.getRightExpression());
    if (op == PyTokenTypes.PLUS && lhs != null && rhs != null) {
      return applyPlus(lhs, rhs);
    }
    else if (lhs instanceof Number && rhs instanceof Number) {
      final BigInteger first = toBigInteger((Number)lhs);
      final BigInteger second = toBigInteger((Number)rhs);
      if (op == PyTokenTypes.MINUS) {
        return fromBigInteger(first.subtract(second));
      }
      else if (op == PyTokenTypes.MULT) {
        return fromBigInteger(first.multiply(second));
      }
      else if (op == PyTokenTypes.FLOORDIV) {
        return fromBigInteger(first.divide(second));
      }
      else if (op == PyTokenTypes.LT) {
        return first.compareTo(second) < 0;
      }
      else if (op == PyTokenTypes.LE) {
        return first.compareTo(second) <= 0;
      }
      else if (op == PyTokenTypes.GT) {
        return first.compareTo(second) > 0;
      }
      else if (op == PyTokenTypes.GE) {
        return first.compareTo(second) >= 0;
      }
      else if (op == PyTokenTypes.EQEQ) {
        return first.compareTo(second) == 0;
      }
      else if (op == PyTokenTypes.NE) {
        return first.compareTo(second) != 0;
      }
    }
    else if (lhs instanceof Boolean first && rhs instanceof Boolean second) {
      if (op == PyTokenTypes.AND_KEYWORD) {
        return first && second;
      }
      else if (op == PyTokenTypes.OR_KEYWORD) {
        return first || second;
      }
    }

    return null;
  }
@Nullable
  protected Object evaluateBinary(@NotNull PyBinaryExpression expression)