@Override
  public Region[] visit(final CUnaryExpression unaryExpression) {
    final UnaryOperator unaryOperator = unaryExpression.getOperator();
    final CExpression unaryOperand = unaryExpression.getOperand();

    if (unaryOperator == UnaryOperator.SIZEOF) {
      return getSizeof(unaryOperand.getExpressionType());
    }

    final Region[] value = unaryOperand.accept(this);

    if (value == null) {
      return null;
    }

    switch (unaryOperator) {
      case MINUS: // -X == (0-X)
        return bvmgr.makeSub(bvmgr.makeNumber(BigInteger.ZERO, value.length), value);

      case SIZEOF:
        throw new AssertionError("SIZEOF should be handled before!");

      case AMPER: // valid expression, but it's a pointer value
        // TODO Not precise enough
        return getSizeof(unaryOperand.getExpressionType());
      case TILDE:
      default:
        // TODO handle unimplemented operators
        return null;
    }
  }
  @Override
  public Region[] visit(CIdExpression idExp) {
    if (idExp.getDeclaration() instanceof CEnumerator) {
      CEnumerator enumerator = (CEnumerator) idExp.getDeclaration();
      if (enumerator.hasValue()) {
        return bvmgr.makeNumber(enumerator.getValue(), getSize(idExp.getExpressionType()));
      } else {
        return null;
      }
    }

    return predMgr.createPredicate(
        idExp.getDeclaration().getQualifiedName(),
        idExp.getExpressionType(),
        location,
        getSize(idExp.getExpressionType()),
        precision);
  }
 private Region[] getSizeof(CType pType) {
   return bvmgr.makeNumber(machineModel.getSizeof(pType), machineModel.getSizeofInt());
 }
 @Override
 public Region[] visit(CIntegerLiteralExpression pE) {
   return bvmgr.makeNumber(pE.asLong(), getSize(pE.getExpressionType()));
 }
 @Override
 public Region[] visit(CCharLiteralExpression pE) {
   return bvmgr.makeNumber(pE.getCharacter(), getSize(pE.getExpressionType()));
 }