private List<CompositeBlobInfo.ChunkMetadata> getChunkMetadataForRange(long start, long end,
      List<Pair<StoreKey, Long>> keysAndContentSizes) {
    Objects.nonNull(keysAndContentSizes);
    long totalSize = 0;
    for (Pair<StoreKey, Long> keyAndContentSize : keysAndContentSizes) {
      totalSize += keyAndContentSize.getSecond();
    }
    if (end < start || start < 0L || end >= totalSize) {
      throw new IllegalArgumentException(
          "Bad input parameters, start=" + start + " end=" + end + " totalSize=" + totalSize);
    }
    List<CompositeBlobInfo.ChunkMetadata> ans = new ArrayList<>();
    long seenSoFar = -1;
    int idx = 0;
    while (seenSoFar < end) {
      Pair<StoreKey, Long> keyAndContentSize = keysAndContentSizes.get(idx++);
      seenSoFar += keyAndContentSize.getSecond();
      if (seenSoFar >= start) {
        ans.add(new CompositeBlobInfo.ChunkMetadata(keyAndContentSize.getFirst(),
            seenSoFar - keyAndContentSize.getSecond() + 1, keyAndContentSize.getSecond()));
      }
    }
    return ans;
  }
Creates a list of pairs of StoreKeys and content sizes, where each pair is of a random size
@param keySize size of the actual store key
@param lowerBound the smallest random content size value allowed
@param higherBound the largest random content size value allowed
@param numKeys number of keys to populate the list
@return a list of pairs of StoreKeys and content sizes, where each pair is of a random size
ambry-messageformat/src/test/java/com/github/ambry/messageformat/CompositeBlobInfoTest.java