private ConstantValue evaluateBinaryExpr(
        Expression lhs, Expression rhs, Type resultType, ArithmeticBinaryOperation operation) {
      // Evaluate subexpressions
      ConstantValue valueLhs = lhs.accept(this, null);
      ConstantValue valueRhs = rhs.accept(this, null);

      // Convert to type implied by usual arithmetic conversions
      final ArithmeticType commonType =
          TypeUtils.doUsualArithmeticConversions(
              (ArithmeticType) lhs.getType().get(), (ArithmeticType) rhs.getType().get());
      final ConstantType commonConstantType = typeFactory.newConstantType(commonType);
      final ConstantType resultConstantType = typeFactory.newConstantType(resultType);
      valueLhs = valueLhs.castTo(commonConstantType);
      valueRhs = valueRhs.castTo(commonConstantType);

      // Perform the operation
      switch (operation) {
        case ADDITION:
          return valueLhs.add(valueRhs);
        case SUBTRACTION:
          return valueLhs.subtract(valueRhs);
        case MULTIPLICATION:
          return valueLhs.multiply(valueRhs);
        case DIVISION:
          return valueLhs.divide(valueRhs);
        case REMAINDER:
          return valueLhs.remainder(valueRhs);
        case BITWISE_AND:
          return valueLhs.bitwiseAnd(valueRhs);
        case BITWISE_OR:
          return valueLhs.bitwiseOr(valueRhs);
        case BITWISE_XOR:
          return valueLhs.bitwiseXor(valueRhs);
        case LESS:
          return valueLhs.less(valueRhs).castTo(resultConstantType);
        case LESS_OR_EQUAL:
          return valueLhs.lessOrEqual(valueRhs).castTo(resultConstantType);
        case GREATER:
          return valueLhs.greater(valueRhs).castTo(resultConstantType);
        case GREATER_OR_EQUAL:
          return valueLhs.greaterOrEqual(valueRhs).castTo(resultConstantType);
        case EQUAL:
          return valueLhs.equalTo(valueRhs).castTo(resultConstantType);
        case NOT_EQUAL:
          return valueLhs.notEqualTo(valueRhs).castTo(resultConstantType);
        default:
          throw new RuntimeException("unexpected arithmetic binary operation '" + operation + "'");
      }
    }