int changeWord(int bitIndex, @NotNull IntUnaryOperator changeWord) {
    assertNonNegative(bitIndex);
    int i = wordIndex(bitIndex);
    synchronized (this) {
      int[] newArray;
      int[] oldArray = array;
      int oldWord;
      boolean canReuseArray = i < oldArray.length;
      if (canReuseArray) {
        newArray = oldArray;
        oldWord = arrayRead(oldArray, i);
      }
      else {
        newArray = ArrayUtil.realloc(oldArray, Math.max(oldArray.length * 2, i + 1));
        oldWord = 0;
      }
      int newWord = changeWord.applyAsInt(oldWord);
      ARRAY_ELEMENT.setVolatile(newArray, i, newWord);
      if (!canReuseArray) {
        // reassign this.array only after newArray modification to avoid leaking empty newArray
        array = newArray;
      }
      return oldWord;
    }
  }
int changeWord(int bitIndex, @NotNull IntUnaryOperator changeWord)