docs: @SuppressWarnings("CompareToUsesNonFinalVariable")
    @Override
    public int compareTo(IntSet o)
    {
      // empty set cases
      if (this.isEmpty() && o.isEmpty()) {
        return 0;
      }
      if (this.isEmpty()) {
        return -1;
      }
      if (o.isEmpty()) {
        return 1;
      }
  
      final ConciseSet other = convert(o);
  
      // the word at the end must be the same
      int res = Integer.compare(this.last, other.last);
      if (res != 0) {
        return res;
      }
  
      // scan words from MSB to LSB
      int thisIndex = this.lastWordIndex;
      int otherIndex = other.lastWordIndex;
      int thisWord = this.words[thisIndex];
      int otherWord = other.words[otherIndex];
      while (thisIndex >= 0 && otherIndex >= 0) {
        if (!isLiteral(thisWord)) {
          if (!isLiteral(otherWord)) {
            // compare two sequences
            // note that they are made up of at least two blocks, and we
            // start comparing from the end, that is at blocks with no
            // (un)set bits
            if (isZeroSequence(thisWord)) {
              if (isOneSequence(otherWord)) {
                // zeros < ones
                return -1;
              }
              // compare two sequences of zeros
              res = Integer.compare(getSequenceCount(otherWord), getSequenceCount(thisWord));
              if (res != 0) {
                return res;
              }
            } else {
              if (isZeroSequence(otherWord)) {
                // ones > zeros
                return 1;
              }
              // compare two sequences of ones
              res = Integer.compare(getSequenceCount(thisWord), getSequenceCount(otherWord));
              if (res != 0) {
                return res;
              }
            }
            // if the sequences are the same (both zeros or both ones)
            // and have the same length, compare the first blocks in the
            // next loop since such blocks might contain (un)set bits
            thisWord = getLiteral(thisWord);
            otherWord = getLiteral(otherWord);
          } else {
            // zeros < literal --> -1
            // ones > literal --> +1
            // note that the sequence is made up of at least two blocks,
            // and we start comparing from the end, that is at a block
            // with no (un)set bits
            if (isZeroSequence(thisWord)) {
              if (otherWord != ConciseSetUtils.ALL_ZEROS_LITERAL) {
                return -1;
              }
            } else {
              if (otherWord != ConciseSetUtils.ALL_ONES_LITERAL) {
                return 1;
              }
            }
            if (getSequenceCount(thisWord) == 1) {
              thisWord = getLiteral(thisWord);
            } else {
              thisWord--;
            }
            if (--otherIndex >= 0) {
              otherWord = other.words[otherIndex];
            }
          }
        } else if (!isLiteral(otherWord)) {
          // literal > zeros --> +1
          // literal < ones --> -1
          // note that the sequence is made up of at least two blocks,
          // and we start comparing from the end, that is at a block
          // with no (un)set bits
          if (isZeroSequence(otherWord)) {
            if (thisWord != ConciseSetUtils.ALL_ZEROS_LITERAL) {
              return 1;
            }
          } else {
            if (thisWord != ConciseSetUtils.ALL_ONES_LITERAL) {
              return -1;
            }
          }
          if (--thisIndex >= 0) {
            thisWord = this.words[thisIndex];
          }
          if (getSequenceCount(otherWord) == 1) {
            otherWord = getLiteral(otherWord);
          } else {
            otherWord--;
          }
        } else {
          // equals compare(getLiteralBits(thisWord), getLiteralBits(otherWord))
          res = Integer.compare(thisWord, otherWord);
          if (res != 0) {
            return res;
          }
          if (--thisIndex >= 0) {
            thisWord = this.words[thisIndex];
          }
          if (--otherIndex >= 0) {
            otherWord = other.words[otherIndex];
          }
        }
      }
      return thisIndex >= 0 ? 1 : (otherIndex >= 0 ? -1 : 0);
    }