code: public CharRanges shift(int delta) {
      int n = ranges.length;
      if (delta == 0 || n == 0) { return this; }
      // Test overflow/underflow
      if (delta < 0) {
        long lmin = ranges[0] + delta;
        if (lmin < Integer.MIN_VALUE) { throw new IndexOutOfBoundsException(); }
      } else {
        long lmax = ranges[n - 1] + delta;
        if (lmax > Integer.MAX_VALUE) { throw new IndexOutOfBoundsException(); }
      }
      // Create a shifted range.
      int[] shiftedRanges = new int[n];
      for (int i = n; --i >= 0;) {
        shiftedRanges[i] = ranges[i] + delta;
      }
      return new CharRanges(shiftedRanges);
    }
docs: Shifts the bits matched by the given delta.
  So if this has the bits (a, b, c, ..., z) set then the result has the bits
  ((a - delta), (b - delta), (c - delta), ...., (z - delta)) set.
  
  @throws IndexOutOfBoundsException if shifting by delta would cause an
  overflow or underflow in a 32 bit {@code signed int} range boundary.
  Since the end boundaries of ranges are exclusive, even if there is no
  range containing {@link Integer#MAX_VALUE}, shifting by a delta of 1
  can cause an overflow.