code: public Mutations<S> extractRelativeMutationsForRange(int from, int to) {
          if (to < from)
              throw new IllegalArgumentException("Reversed ranges are not supported.");
  
          long indexRange = getIndexRange(from, to);
  
          // If range size is 0 return empty array
          if (indexRange == 0)
              return empty(alphabet);
  
          // Unpacking
          int fromIndex = (int) (indexRange >>> 32),
                  toIndex = (int) (indexRange & 0xFFFFFFFF);
  
          // Don't create new object if result will be equal to this
          if (from == 0 && fromIndex == 0 && toIndex == mutations.length)
              return this;
  
          // Creating result
          int[] result = new int[toIndex - fromIndex];
  
          // Constant to move positions in the output array
          int offset;
          if (from == -1)
              offset = 0;
          else
              offset = ((-from) << POSITION_OFFSET);
  
          // Copy and move mutations
          for (int i = result.length - 1, j = toIndex - 1; i >= 0; --i, --j)
              result[i] = mutations[j] + offset;
  
          return new Mutations<>(alphabet, result, true);
      }
docs: Extracts mutations for a range of positions in the original sequence and performs shift of corresponding
  positions (moves them to {@code -from}).
  
  <p>Insertions before {@code from} excluded. Insertions after {@code (to - 1)} included.</p>
  
  <p>
  <b>Important:</b> to extract leftmost insertions (trailing insertions) use {@code from = -1}. E.g.
  {@code extractRelativeMutationsForRange(mut, -1, seqLength) == mut}.
  </p>
  
  @param from left bound of range, inclusive. Use -1 to extract leftmost insertions.
  @param to   right bound of range, exclusive
  @return mutations for a range of positions