code: private void joinAndCollect(Object[] tags, ResetableIterator[] values,
                                int pos, Object[] partialList, Object key,
                                OutputCollector output, Reporter reporter) throws IOException {
  
      if (values.length == pos) {
        // get a value from each source. Combine them
        TaggedMapOutput combined = combine(tags, partialList);
        collect(key, combined, output, reporter);
        return;
      }
      ResetableIterator nextValues = values[pos];
      nextValues.reset();
      while (nextValues.hasNext()) {
        Object v = nextValues.next();
        partialList[pos] = v;
        joinAndCollect(tags, values, pos + 1, partialList, key, output, reporter);
      }
    }
docs: Perform the actual join recursively.
  
  @param tags
  a list of input tags
  @param values
  a list of value lists, each corresponding to one input source
  @param pos
  indicating the next value list to be joined
  @param partialList
  a list of values, each from one value list considered so far.
  @param key
  @param output
  @throws IOException