code: public static int bounds(char source[], int start, int limit, int offset16) {
          offset16 += start;
          if (offset16 < start || offset16 >= limit) {
              throw new ArrayIndexOutOfBoundsException(offset16);
          }
          char ch = source[offset16];
          if (isSurrogate(ch)) {
              if (isLeadSurrogate(ch)) {
                  ++offset16;
                  if (offset16 < limit && isTrailSurrogate(source[offset16])) {
                      return LEAD_SURROGATE_BOUNDARY;
                  }
              } else { // isTrailSurrogate(ch), so
                  --offset16;
                  if (offset16 >= start && isLeadSurrogate(source[offset16])) {
                      return TRAIL_SURROGATE_BOUNDARY;
                  }
              }
          }
          return SINGLE_CHAR_BOUNDARY;
      }
docs: Returns the type of the boundaries around the char at offset16. Used for random access. Note
  that the boundaries are determined with respect to the subarray, hence the char array
  {0xD800, 0xDC00} has the result SINGLE_CHAR_BOUNDARY for start = offset16 = 0 and limit = 1.
  
  @param source Char array to analyse
  @param start Offset to substring in the source array for analyzing
  @param limit Offset to substring in the source array for analyzing
  @param offset16 UTF16 offset relative to start
  @return
  <ul>
  <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are
  <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds
  are [offset16, offset16 + 2]
  <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the
  bounds are [offset16 - 1, offset16 + 1]
  </ul>
  For bit-twiddlers, the boundary values for these are chosen so that the boundaries
  can be gotten by: [offset16 - (boundvalue &gt;&gt; 2), offset16 + (boundvalue &amp; 3)].
  @exception IndexOutOfBoundsException If offset16 is not within the range of start and limit.