static PrimitiveIterator.OfInt union(PrimitiveIterator.OfInt lhs, PrimitiveIterator.OfInt rhs) {
    return new PrimitiveIterator.OfInt() {
      private int peekL = -1;
      private int peekR = -1;
      private int next = fetchNext();

      @Override
      public int nextInt() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        int result = next;
        next = fetchNext();
        return result;
      }

      @Override
      public boolean hasNext() {
        return next != -1;
      }

      private int fetchNext() {
        if ((peekL == -1 && peekR == -1) && (!lhs.hasNext() && !rhs.hasNext())) {
          return -1;
        }

        if (peekL == -1 && lhs.hasNext()) {
          peekL = lhs.next();
        }

        if (peekR == -1 && rhs.hasNext()) {
          peekR = rhs.next();
        }

        // Return the smaller of the two next iterator values
        int result;
        if (peekL != -1 && (peekL == peekR || peekR == -1)) {
          // If RHS is exhausted or intersects with LHS, return l and throw away r to avoid duplicates
          result = peekL;
          peekL = -1;
          peekR = -1;
        } else if (peekL == -1 && peekR != -1) {
          // If LHS is exhausted, return RHS
          result = peekR;
          peekR = -1;
        } else if (peekL < peekR) {
          // If LHS value is smaller than RHS value, return LHS
          result = peekL;
          peekL = -1;
        } else {
          // If RHS value is smaller than LHS value, return RHS
          result = peekR;
          peekR = -1;
        }
        return result;
      }
    };
  }
@Test
  public void testUnion() {
    // Test deduplication of intersecting ranges
    assertEquals(
        IndexIterator.union(
            IndexIterator.rangeTranslate(0, 7, i -> i), IndexIterator.rangeTranslate(4, 10, i -> i)),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10);

    // Test inversion of LHS and RHS
    assertEquals(
        IndexIterator.union(
            IndexIterator.rangeTranslate(4, 10, i -> i), IndexIterator.rangeTranslate(0, 7, i -> i)),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10);

    // Test non-intersecting ranges
    assertEquals(
        IndexIterator.union(
            IndexIterator.rangeTranslate(2, 5, i -> i), IndexIterator.rangeTranslate(8, 10, i -> i)),
        2,
        3,
        4,
        5,
        8,
        9,
        10);
  }