@Override
 public void advance() {
   int max = overlappingRangesCount == 0 ? myIterators.length : overlappingRangesCount;
   for (int i = 0; i < max; i++) {
     IteratorWrapper wrapper = myIterators[i];
     if (wrapper == null) {
       continue;
     }
     RangeIterator iterator = wrapper.iterator;
     if (overlappingRangesCount > 0 && iterator.getRangeEnd() > myCurrentEnd) {
       continue;
     }
     if (iterator.atEnd()) {
       iterator.dispose();
       myIterators[i] = null;
     } else {
       iterator.advance();
     }
   }
   Arrays.sort(myIterators, RANGE_SORTER);
   myCurrentStart = Math.max(myIterators[0].iterator.getRangeStart(), myCurrentEnd);
   myCurrentEnd = Integer.MAX_VALUE;
   //noinspection ForLoopReplaceableByForEach
   for (int i = 0; i < myIterators.length; i++) {
     IteratorWrapper wrapper = myIterators[i];
     if (wrapper == null) {
       break;
     }
     RangeIterator iterator = wrapper.iterator;
     int nearestBound;
     if (iterator.getRangeStart() > myCurrentStart) {
       nearestBound = iterator.getRangeStart();
     } else {
       nearestBound = iterator.getRangeEnd();
     }
     myCurrentEnd = Math.min(myCurrentEnd, nearestBound);
   }
   myCurrentEnd = getRangeEnd();
   for (overlappingRangesCount = 1;
       overlappingRangesCount < myIterators.length;
       overlappingRangesCount++) {
     IteratorWrapper wrapper = myIterators[overlappingRangesCount];
     if (wrapper == null || wrapper.iterator.getRangeStart() > myCurrentStart) {
       break;
     }
   }
 }
 public void dispose() {
   myRangeIterator.dispose();
 }