static PrimitiveIterator.OfInt intersection(PrimitiveIterator.OfInt lhs, PrimitiveIterator.OfInt rhs) {
    return new PrimitiveIterator.OfInt() {
      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 (!lhs.hasNext() || !rhs.hasNext()) {
          return -1;
        }

        // Since we know both iterators are in sorted order, we can iterate linearly through until
        // we find the next value that belongs to both iterators, or terminate if none exist
        int nextL = lhs.next();
        int nextR = rhs.next();

        while (true) {
          // Try to iterate LHS and RHS to the next intersecting value
          while (nextL < nextR && lhs.hasNext()) {
            nextL = lhs.next();
          }
          while (nextR < nextL && rhs.hasNext()) {
            nextR = rhs.next();
          }
          if (nextL == nextR) {
            return nextL;
          }

          // No intersection found; advance LHS to the next element and retry loop
          if (nextL < nextR && lhs.hasNext()) {
            nextL = lhs.next();
          } else {
            break;
          }
        }

        return -1;
      }
    };
  }
@Test
  public void testIntersection() {
    // Case 1: some overlap between LHS and RHS
    // LHS: [0, 1, 2, 3, 4, 5, 6, 7], RHS: [4, 5, 6, 7, 8, 9, 10]
    assertEquals(
        IndexIterator.intersection(
            IndexIterator.rangeTranslate(0, 7, i -> i), IndexIterator.rangeTranslate(4, 10, i -> i)),
        4,
        5,
        6,
        7);

    // Test inversion of LHS and RHS
    assertEquals(
        IndexIterator.intersection(
            IndexIterator.rangeTranslate(4, 10, i -> i), IndexIterator.rangeTranslate(0, 7, i -> i)),
        4,
        5,
        6,
        7);

    // Case 2: Single point of overlap at end of iterator
    // LHS: [1, 3, 5, 7], RHS: [0, 2, 4, 6, 7]
    assertEquals(
        IndexIterator.intersection(
            IndexIterator.filter(8, i -> i % 2 == 1), IndexIterator.filter(8, i -> i % 2 == 0 || i == 7)),
        7);

    // Test inversion of LHS and RHS
    assertEquals(
        IndexIterator.intersection(
            IndexIterator.filter(8, i -> i % 2 == 0 || i == 7), IndexIterator.filter(8, i -> i % 2 == 1)),
        7);

    // Test no intersection between ranges
    // LHS: [2, 3, 4, 5], RHS: [8, 9, 10]
    assertEquals(IndexIterator.intersection(
        IndexIterator.rangeTranslate(2, 5, i -> i), IndexIterator.rangeTranslate(8, 10, i -> i)));

    // Test inversion of LHS and RHS
    assertEquals(IndexIterator.intersection(
        IndexIterator.rangeTranslate(8, 10, i -> i), IndexIterator.rangeTranslate(2, 5, i -> i)));
  }