private final void writeDoubleNoDebug(double value) {
    if (interrupted()) resume();

    if ((getFlags() & CompileTimeSettings.SERIALIZATION_BINARY_FLOAT_AND_DOUBLE) == 0) {
      writeString(PlatformAdapter.doubleToString(value), 0, false);

      if (interrupted()) {
        interrupt(null);
        return;
      }
    } else {
      if (remaining() < LONG_LENGTH) {
        interrupt(null);
        return;
      }

      writeLongToBuffer(PlatformAdapter.doubleToLong(value));
    }
  }
  private final void writeFloatNoDebug(float value) {
    if (interrupted()) resume();

    if ((getFlags() & CompileTimeSettings.SERIALIZATION_BINARY_FLOAT_AND_DOUBLE) == 0) {
      writeString(PlatformAdapter.floatToString(value), 0, false);

      if (interrupted()) {
        interrupt(null);
        return;
      }
    } else {
      if (remaining() < INTEGER_LENGTH) {
        interrupt(null);
        return;
      }

      int i = PlatformAdapter.floatToInt(value);
      writeIntegerToBuffer(i);
    }
  }
  public final void writeDecimal(java.math.BigDecimal value) {
    if (value == null) // Marker
    writeBinary(null, ImmutableClass.DECIMAL_INDEX);
    else {
      byte[] array;

      if (interrupted()) array = (byte[]) resume();
      else {
        byte[] t = value.unscaledValue().toByteArray();
        array = new byte[t.length + 4];
        PlatformAdapter.arraycopy(t, 0, array, 0, t.length);
        int scale = value.scale();
        array[array.length - 4] = (byte) (scale & 0xff);
        array[array.length - 3] = (byte) ((scale >>> 8) & 0xff);
        array[array.length - 2] = (byte) ((scale >>> 16) & 0xff);
        array[array.length - 1] = (byte) ((scale >>> 24) & 0xff);
      }

      writeBinary(array, ImmutableClass.DECIMAL_INDEX);

      if (interrupted()) interrupt(array);
    }
  }
  @Override
  public TObject.Version merge(TObject.Version target, TObject.Version next, int flags) {
    TListVersion source = (TListVersion) next;
    Object[] initialArray = _array;
    Object[] array = initialArray;

    if (source.getCleared()) {
      if (Debug.ENABLED) {
        Debug.assertion(source.getRemovals() == null);
        Debug.assertion(source.getRemovalsCount() == 0);
      }

      if (array != null) {
        if (array.length < source.size()) array = new Object[Utils.nextPowerOf2(source.size())];
        else for (int i = array.length - 1; i >= 0; i--) array[i] = null; // for GC
      }

      getReference().clearUserReferences();
      _size = 0;
    } else {
      if (array != null && array.length < source.size()) {
        Object[] temp = new Object[Utils.nextPowerOf2(source.size())];
        PlatformAdapter.arraycopy(array, 0, temp, 0, _size);
        array = temp;
      }
    }

    if (array == null) array = new Object[Utils.nextPowerOf2(source.size())];

    int copiedStart = Integer.MAX_VALUE;

    if (source.getCopied() != null) {
      copiedStart = source.getCopiedStart();
      int length = Math.min(source.getCopied().length, source.size() - copiedStart);

      if (Debug.ENABLED)
        for (int i = length; i < source.getCopied().length; i++)
          Debug.assertion(source.getCopied()[i] == null);

      for (int i = 0; i < length; i++) updateArray(array, copiedStart + i, source.getCopied()[i]);
    }

    if (source.getBits() != null) {
      for (int i = source.getBits().length - 1; i >= 0; i--) {
        if (source.getBits()[i] != null) {
          int firstWrite = source.getBits()[i].IntIndex << Bits.BITS_PER_UNIT_SHIFT;

          if (firstWrite < copiedStart) {
            for (int b = 0; b < Bits.BITS_PER_UNIT; b++) {
              if (Bits.get(source.getBits()[i].Value, b)) {
                int index = firstWrite + b;
                updateArray(array, index, source.get(index));
              }
            }
          }
        }
      }
    }

    if (array != initialArray) _array = array;

    if (Debug.ENABLED) Debug.assertion(_size + source.getSizeDelta() == source.size());

    for (int i = source.size(); i < _size; i++) updateArray(array, i, null);

    _size = source.size();

    return this;
  }