  @Test
  public void testReduce() throws Exception {

    // test input, input[*][0] is the key,
    // input[*][1..n] are the values passed in via
    // the iterator.
    Gram[][] input = {
        {new Gram("the", UNIGRAM), new Gram("the", UNIGRAM), new Gram("the", UNIGRAM)},
        {new Gram("the", HEAD), new Gram("the best", NGRAM), new Gram("the worst", NGRAM)},
        {new Gram("of", HEAD), new Gram("of times", NGRAM), new Gram("of times", NGRAM)},
        {new Gram("times", TAIL), new Gram("of times", NGRAM), new Gram("of times", NGRAM)}};
    
    // expected results.
    Gram[][] values = {{new Gram("the", 2, UNIGRAM), new Gram("the", 2, UNIGRAM)},
                                    {new Gram("the best", 1, NGRAM), new Gram("the", 2, HEAD)},
                                    {new Gram("the worst", 1, NGRAM), new Gram("the", 2, HEAD)},
                                    {new Gram("of times", 2, NGRAM), new Gram("of", 2, HEAD)},
                                    {new Gram("of times", 2, NGRAM), new Gram("times", 2, TAIL)}};

    // set up expectations
    for (Gram[] v : values) {
      output.collect(v[0], v[1]);
    }
    EasyMock.replay(reporter, output);
    
    // play back the input data.
    CollocReducer c = new CollocReducer();
    
    GramKey key = new GramKey();

    byte[] empty = new byte[0];
    for (Gram[] ii : input) {
      key.set(ii[0], empty);

      List<Gram> vv = new LinkedList<Gram>();
      vv.addAll(Arrays.asList(ii));
      c.reduce(key, vv.iterator(), output, reporter);
    }
    
    EasyMock.verify(reporter, output);
  }