Program: 88302
Project: 88302
Buggy source:
/** 
 * <p> Calls the <code>MatchStub#match()</code> method for all two key-value pairs that share the same key and come from different inputs. The output of the <code>match()</code> method is forwarded. <p> This method is called with a key and two iterator (one for each input) over all values that share this key. <p>
 * @param key A key.
 * @param values1 An iterator on values of the first input that were paired with the key.
 * @param values2 An iterator on values of the second input that were paired with the key.
 * @param out A collector that collects all output pairs.
 */
private void crossValues(Key key,final Iterator<Value> values1,final Iterator<Value> values2) throws RuntimeException {
  final Value firstV1=values1.next();
  final Value firstV2=values2.next();
  if (firstV1 == null || firstV2 == null) {
    return;
  }
  boolean v1HasNext=values1.hasNext();
  boolean v2HasNext=values2.hasNext();
  if (!v1HasNext && !v2HasNext) {
    matchStub.match(key,firstV1,firstV2,output);
    return;
  }
  Value v1;
  Value v2;
  keyCopier.setCopy(key);
  if (!v1HasNext) {
    this.v1Copier.setCopy(firstV1);
    matchStub.match(key,firstV1,firstV2,output);
    while (v2HasNext && !this.taskCanceled) {
      key=this.keySerialization.newInstance();
      this.keyCopier.getCopy(key);
      v1=this.v1Serialization.newInstance();
      this.v1Copier.getCopy(v1);
      v2=values2.next();
      v2HasNext=values2.hasNext();
      matchStub.match(key,v1,v2,output);
    }
  }
 else   if (!v2HasNext && !this.taskCanceled) {
    this.v2Copier.setCopy(firstV2);
    matchStub.match(key,firstV1,firstV2,output);
    while (v1HasNext) {
      key=this.keySerialization.newInstance();
      this.keyCopier.getCopy(key);
      v2=this.v2Serialization.newInstance();
      this.v2Copier.getCopy(v2);
      v1=values1.next();
      v1HasNext=values1.hasNext();
      matchStub.match(key,v1,v2,output);
    }
  }
 else {
    Reader<Value> v1Reader=new Reader<Value>(){
      boolean firstValue=true;
      @Override public List<AbstractInputChannel<Value>> getInputChannels(){
        throw new UnsupportedOperationException();
      }
      @Override public boolean hasNext(){
        if (firstValue)         return true;
        return values1.hasNext();
      }
      @Override public Value next() throws IOException, InterruptedException {
        if (firstValue) {
          firstValue=false;
          return firstV1;
        }
        return values1.next();
      }
    }
;
    SpillingResettableIterator<Value> v1ResettableIterator=null;
    try {
      ValueDeserializer<Value> v1Deserializer=new ValueDeserializer<Value>(matchStub.getFirstInValueType());
      v1ResettableIterator=new SpillingResettableIterator<Value>(getEnvironment().getMemoryManager(),getEnvironment().getIOManager(),v1Reader,((int)(MEMORY_IO * MEMORY_SHARE_RATIO)),v1Deserializer,this);
      v1ResettableIterator.open();
      this.v2Copier.setCopy(firstV2);
      while (v1ResettableIterator.hasNext() && !this.taskCanceled) {
        key=this.keySerialization.newInstance();
        this.keyCopier.getCopy(key);
        v2=this.v2Serialization.newInstance();
        this.v2Copier.getCopy(v2);
        v1=v1ResettableIterator.next();
        matchStub.match(key,v1,v2,output);
      }
      v1ResettableIterator.reset();
      while (values2.hasNext() && !this.taskCanceled) {
        v2=values2.next();
        this.v2Copier.setCopy(v2);
        while (v1ResettableIterator.hasNext() && !this.taskCanceled) {
          key=this.keySerialization.newInstance();
          this.keyCopier.getCopy(key);
          v2=this.v2Serialization.newInstance();
          this.v2Copier.getCopy(v2);
          v1=v1ResettableIterator.next();
          matchStub.match(key,v1,v2,output);
        }
        v1ResettableIterator.reset();
      }
      v1ResettableIterator.close();
    }
 catch (    Exception e) {
      throw new RuntimeException(e);
    }
 finally {
      if (v1ResettableIterator != null) {
        try {
          v1ResettableIterator.close();
        }
 catch (        ServiceException e) {
          LOG.warn(e);
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * <p> Calls the <code>MatchStub#match()</code> method for all two key-value pairs that share the same key and come from different inputs. The output of the <code>match()</code> method is forwarded. <p> This method is called with a key and two iterator (one for each input) over all values that share this key. <p>
 * @param key A key.
 * @param values1 An iterator on values of the first input that were paired with the key.
 * @param values2 An iterator on values of the second input that were paired with the key.
 * @param out A collector that collects all output pairs.
 */
private void crossValues(Key key,final Iterator<Value> values1,final Iterator<Value> values2) throws RuntimeException {
  final Value firstV1=values1.next();
  final Value firstV2=values2.next();
  if (firstV1 == null || firstV2 == null) {
    return;
  }
  boolean v1HasNext=values1.hasNext();
  boolean v2HasNext=values2.hasNext();
  if (!v1HasNext && !v2HasNext) {
    matchStub.match(key,firstV1,firstV2,output);
    return;
  }
  Value v1;
  Value v2;
  keyCopier.setCopy(key);
  if (!v1HasNext) {
    this.v1Copier.setCopy(firstV1);
    matchStub.match(key,firstV1,firstV2,output);
    while (v2HasNext && !this.taskCanceled) {
      key=this.keySerialization.newInstance();
      this.keyCopier.getCopy(key);
      v1=this.v1Serialization.newInstance();
      this.v1Copier.getCopy(v1);
      v2=values2.next();
      v2HasNext=values2.hasNext();
      matchStub.match(key,v1,v2,output);
    }
  }
 else   if (!v2HasNext && !this.taskCanceled) {
    this.v2Copier.setCopy(firstV2);
    matchStub.match(key,firstV1,firstV2,output);
    while (v1HasNext) {
      key=this.keySerialization.newInstance();
      this.keyCopier.getCopy(key);
      v2=this.v2Serialization.newInstance();
      this.v2Copier.getCopy(v2);
      v1=values1.next();
      v1HasNext=values1.hasNext();
      matchStub.match(key,v1,v2,output);
    }
  }
 else {
    Reader<Value> v1Reader=new Reader<Value>(){
      boolean firstValue=true;
      @Override public List<AbstractInputChannel<Value>> getInputChannels(){
        throw new UnsupportedOperationException();
      }
      @Override public boolean hasNext(){
        if (firstValue)         return true;
        return values1.hasNext();
      }
      @Override public Value next() throws IOException, InterruptedException {
        if (firstValue) {
          firstValue=false;
          return firstV1;
        }
        return values1.next();
      }
    }
;
    SpillingResettableIterator<Value> v1ResettableIterator=null;
    try {
      ValueDeserializer<Value> v1Deserializer=new ValueDeserializer<Value>(matchStub.getFirstInValueType());
      v1ResettableIterator=new SpillingResettableIterator<Value>(getEnvironment().getMemoryManager(),getEnvironment().getIOManager(),v1Reader,((int)(MEMORY_IO * MEMORY_SHARE_RATIO)),v1Deserializer,this);
      v1ResettableIterator.open();
      this.v2Copier.setCopy(firstV2);
      while (v1ResettableIterator.hasNext() && !this.taskCanceled) {
        key=this.keySerialization.newInstance();
        this.keyCopier.getCopy(key);
        v2=this.v2Serialization.newInstance();
        this.v2Copier.getCopy(v2);
        v1=v1ResettableIterator.next();
        matchStub.match(key,v1,v2,output);
      }
      v1ResettableIterator.reset();
      while (values2.hasNext() && !this.taskCanceled) {
        v2=values2.next();
        this.v2Copier.setCopy(v2);
        while (v1ResettableIterator.hasNext() && !this.taskCanceled) {
          key=this.keySerialization.newInstance();
          this.keyCopier.getCopy(key);
          v2=this.v2Serialization.newInstance();
          this.v2Copier.getCopy(v2);
          v1=v1ResettableIterator.next();
          matchStub.match(key,v1,v2,output);
        }
        v1ResettableIterator.reset();
      }
    }
 catch (    Exception e) {
      throw new RuntimeException(e);
    }
 finally {
      if (v1ResettableIterator != null) {
        try {
          v1ResettableIterator.close();
        }
 catch (        ServiceException e) {
          LOG.warn(e);
        }
      }
    }
  }
}