docs: @Override
    public Container not(final int firstOfRange, final int lastOfRange) {
      // TODO: may need to convert to a RunContainer
      if (firstOfRange >= lastOfRange) {
        return clone(); // empty range
      }
  
      // determine the span of array indices to be affected
      int startIndex = Util.unsignedBinarySearch(content, 0, cardinality, (short) firstOfRange);
      if (startIndex < 0) {
        startIndex = -startIndex - 1;
      }
      int lastIndex = Util.unsignedBinarySearch(content, 0, cardinality, (short) (lastOfRange - 1));
      if (lastIndex < 0) {
        lastIndex = -lastIndex - 2;
      }
      final int currentValuesInRange = lastIndex - startIndex + 1;
      final int spanToBeFlipped = lastOfRange - firstOfRange;
      final int newValuesInRange = spanToBeFlipped - currentValuesInRange;
      final int cardinalityChange = newValuesInRange - currentValuesInRange;
      final int newCardinality = cardinality + cardinalityChange;
  
      if (newCardinality > DEFAULT_MAX_SIZE) {
        return toBitmapContainer().not(firstOfRange, lastOfRange);
      }
  
      ArrayContainer answer = new ArrayContainer(newCardinality);
  
      // copy stuff before the active area
      System.arraycopy(content, 0, answer.content, 0, startIndex);
  
      int outPos = startIndex;
      int inPos = startIndex; // item at inPos always >= valInRange
  
      int valInRange = firstOfRange;
      for (; valInRange < lastOfRange && inPos <= lastIndex; ++valInRange) {
        if ((short) valInRange != content[inPos]) {
          answer.content[outPos++] = (short) valInRange;
        } else {
          ++inPos;
        }
      }
  
      for (; valInRange < lastOfRange; ++valInRange) {
        answer.content[outPos++] = (short) valInRange;
      }
  
      // content after the active range
      for (int i = lastIndex + 1; i < cardinality; ++i) {
        answer.content[outPos++] = content[i];
      }
      answer.cardinality = newCardinality;
      return answer;
    }