@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);
      }
      assert myCurrentStart <= myCurrentEnd : "Unexpected range: " + myCurrentStart + ":" + myCurrentEnd +
                                              ", iterators: " + Arrays.toString(myIterators) +
                                              ", overlappingRanges: " + overlappingRangesCount;
      for (overlappingRangesCount = 1; overlappingRangesCount < myIterators.length; overlappingRangesCount++) {
        IteratorWrapper wrapper = myIterators[overlappingRangesCount];
        if (wrapper == null || wrapper.iterator.getRangeStart() > myCurrentStart) {
          break;
        }
      }
    }
@Override
    public void advance()