public <V> Iterable<V> getAll(TupleTag<V> tag) {
    int index = schema.getIndex(tag);
    if (index < 0) {
      throw new IllegalArgumentException("TupleTag " + tag + " is not in the schema");
    }
    @SuppressWarnings("unchecked")
    Iterable<V> unions = (Iterable<V>) valueMap.get(index);
    return unions;
  }
@Test
  public void testLazyResults() {
    TestUnionValues values = new TestUnionValues(0, 0, 1, 1, 0, 1, 1);
    CoGbkResult result = new CoGbkResult(createSchema(5), values, 0, 2);
    // Nothing is read until we try to iterate.
    assertThat(values.maxPos(), equalTo(0));
    Iterable<?> tag0iterable = result.getAll("tag0");
    assertThat(values.maxPos(), equalTo(0));
    Iterator<?> ignored = tag0iterable.iterator();
    assertThat(values.maxPos(), equalTo(0));

    // Iterating reads (nearly) the minimal number of values.
    Iterator<?> tag0 = tag0iterable.iterator();
    tag0.next();
    assertThat(values.maxPos(), lessThanOrEqualTo(2));
    tag0.next();
    assertThat(values.maxPos(), equalTo(2));
    // Note that we're skipping over tag 1.
    tag0.next();
    assertThat(values.maxPos(), equalTo(5));

    // Iterating again does not cause more reads.
    Iterator<?> tag0iterAgain = tag0iterable.iterator();
    tag0iterAgain.next();
    tag0iterAgain.next();
    tag0iterAgain.next();
    assertThat(values.maxPos(), equalTo(5));

    // Iterating over other tags does not cause more reads for values we have seen.
    Iterator<?> tag1 = result.getAll("tag1").iterator();
    tag1.next();
    tag1.next();
    assertThat(values.maxPos(), equalTo(5));
    // However, finding the next tag1 value does require more reads.
    tag1.next();
    assertThat(values.maxPos(), equalTo(6));
  }