@Override
 public @NonNull IntegerValue addInteger(@NonNull IntegerValue right) {
   if (right instanceof IntIntegerValueImpl) {
     int thatValue = ((IntIntegerValueImpl) right).intValue();
     int sum = value + thatValue;
     if (value >= 0) {
       if ((thatValue >= 0) && (sum >= 0)) {
         return ValueUtil.integerValueOf(sum);
       }
     } else {
       if ((thatValue <= 0) && (sum <= 0)) {
         return ValueUtil.integerValueOf(sum);
       }
     }
     return ValueUtil.integerValueOf((long) value + (long) thatValue);
   } else if (right instanceof LongIntegerValueImpl) {
     long thatValue = ((LongIntegerValueImpl) right).longValue();
     return ValueUtil.integerValueOf(value + thatValue);
   } else {
     @SuppressWarnings("null")
     @NonNull
     BigInteger result = bigIntegerValue().add(right.bigIntegerValue());
     return ValueUtil.integerValueOf(result);
   }
 }
 @Override
 public @NonNull IntegerValue subtractInteger(@NonNull IntegerValue right) {
   if (right instanceof IntIntegerValueImpl) {
     int thatValue = ((IntIntegerValueImpl) right).intValue();
     int diff = value - thatValue;
     if (value >= 0) {
       if ((thatValue <= 0) && (diff >= 0)) {
         return ValueUtil.integerValueOf(diff);
       }
     } else {
       if ((thatValue >= 0) && (diff <= 0)) {
         return ValueUtil.integerValueOf(diff);
       }
     }
     return ValueUtil.integerValueOf((long) value - (long) thatValue);
   } else if (right instanceof LongIntegerValueImpl) {
     long thatValue = ((LongIntegerValueImpl) right).longValue();
     return ValueUtil.integerValueOf(value - thatValue);
   } else {
     @SuppressWarnings("null")
     @NonNull
     BigInteger result = bigIntegerValue().subtract(right.bigIntegerValue());
     return ValueUtil.integerValueOf(result);
   }
 }
 @Override
 public @NonNull IntegerValue negate() {
   if (value > Integer.MIN_VALUE) {
     return ValueUtil.integerValueOf(-value);
   } else {
     return ValueUtil.integerValueOf(1L << Integer.SIZE - 1);
   }
 }
 @Override
 public @NonNull IntegerValue multiplyInteger(@NonNull IntegerValue right) {
   if (right instanceof IntIntegerValueImpl) {
     long thatValue = ((IntIntegerValueImpl) right).intValue();
     return ValueUtil.integerValueOf(value * thatValue);
   } else {
     @SuppressWarnings("null")
     @NonNull
     BigInteger result = bigIntegerValue().multiply(right.bigIntegerValue());
     return ValueUtil.integerValueOf(result);
   }
 }
  /**
   * This default implementation asserts that the <tt>constraint</tt> is boolean-valued if it is an
   * invariant, pre-condition, or post-condition constraint and returns the value of its body
   * expression by delegation to {@link Visitable#accept(Visitor)}.
   */
  @Override
  public Object visitConstraint(@NonNull Constraint constraint) {
    LanguageExpression specification = constraint.getOwnedSpecification();
    if (!(specification instanceof ExpressionInOCL)) {
      return null;
    }
    OCLExpression body = ((ExpressionInOCL) specification).getOwnedBody();
    //		boolean isBoolean = BOOLEAN_CONSTRAINTS.contains(constraint.getStereotype());

    if (body == null) {
      throw new IllegalArgumentException("constraint has no body expression"); // $NON-NLS-1$
    }

    //		if (isBoolean && !(body.getType() != metamodelManager.getBooleanType())) {
    //			throw new IllegalArgumentException("constraint is not boolean"); //$NON-NLS-1$
    //		}

    Object result = body.accept(undecoratedVisitor);
    //		try {
    //			if (result == null) {
    //				return evaluationEnvironment.throwInvalidEvaluation("null constraint result");
    //			}
    return ValueUtil.asBoolean(result);
    //		} catch (InvalidValueException e) {
    //			return e.getValue();
    //		}
  }
 @Override
 public @NonNull IntegerValue modInteger(@NonNull IntegerValue right) {
   if (right.bigIntegerValue().signum() == 0) {
     throw new InvalidValueException("mod zero");
   }
   if (right instanceof IntIntegerValueImpl) {
     int thatValue = ((IntIntegerValueImpl) right).intValue();
     return ValueUtil.integerValueOf(value % thatValue);
   } else if (right instanceof LongIntegerValueImpl) {
     long thatValue = ((LongIntegerValueImpl) right).longValue();
     return ValueUtil.integerValueOf(value % thatValue);
   } else {
     @SuppressWarnings("null")
     @NonNull
     BigInteger result = bigIntegerValue().remainder(right.bigIntegerValue());
     return ValueUtil.integerValueOf(result);
   }
 }
 @Override
 public @NonNull IntegerValue divInteger(@NonNull IntegerValue right) {
   if (right.bigIntegerValue().signum() == 0) {
     throw new InvalidValueException("div zero");
   }
   @SuppressWarnings("null")
   @NonNull
   BigInteger result = bigIntegerValue().divide(right.bigIntegerValue());
   return ValueUtil.integerValueOf(result);
 }
 /** @deprecated use Executor */
 @Deprecated
 @Override
 public @NonNull Object createAccumulatorValue(
     @NonNull Evaluator evaluator, @NonNull TypeId accumulatorTypeId, @NonNull TypeId bodyTypeId) {
   return createAccumulatorValue(ValueUtil.getExecutor(evaluator), accumulatorTypeId, bodyTypeId);
 }