/**
   * This method returns the input-value, casted to match the type. If the value matches the type,
   * it is returned unchanged. This method handles overflows and print warnings for the user.
   * Example: This method is called, when an value of type 'integer' is assigned to a variable of
   * type 'char'.
   *
   * @param value will be casted. If value is null, null is returned.
   * @param targetType value will be casted to targetType.
   * @param machineModel contains information about types
   */
  public static Region[] castCValue(
      @Nullable final Region[] value,
      final CType targetType,
      final BitvectorManager bvmgr,
      final MachineModel machineModel) {
    if (value == null) {
      return null;
    }

    final CType type = targetType.getCanonicalType();
    if (type instanceof CSimpleType) {
      final CSimpleType st = (CSimpleType) type;
      if (st.getType() == CBasicType.INT || st.getType() == CBasicType.CHAR) {
        final int bitPerByte = machineModel.getSizeofCharInBits();
        final int numBytes = machineModel.getSizeof(st);
        final int size = bitPerByte * numBytes;
        final Region[] result = bvmgr.toBitsize(size, st.isSigned(), value);
        return result;
      }
    }
    // currently we do not handle floats, doubles or voids, pointers, so lets ignore this case.
    return value;
  }