code: public boolean nextKey() throws IOException
  	{
  		// first element
  		if (this.next == null) {
  			this.next = this.serializer.createInstance();
  			if ((this.next = this.iterator.next(this.next)) != null) {
  				this.comparator.setReference(this.next);
  				this.nextIsFresh = false;
  				this.valuesIterator = new ValuesIterator();
  				this.valuesIterator.nextIsUnconsumed = true;
  				return true;
  			} else {
  				// empty input, set everything null
  				this.valuesIterator = null;
  				return false;
  			}
  		}
  
  		// Whole value-iterator was read and a new key is available.
  		if (this.nextIsFresh) {
  			this.nextIsFresh = false;
  			this.comparator.setReference(this.next);
  			this.valuesIterator.nextIsUnconsumed = true;
  			return true;
  		}
  
  		// try to move to next key.
  		// Required if user code / reduce() method did not read the whole value iterator.
  		while (true) {
  			if ((this.next = this.iterator.next(this.next)) != null) {
  				if (!this.comparator.equalToReference(this.next)) {
  					// the keys do not match, so we have a new group. store the current keys
  					this.comparator.setReference(this.next);						
  					this.nextIsFresh = false;
  					this.valuesIterator.nextIsUnconsumed = true;
  					return true;
  				}
  			}
  			else {
  				this.valuesIterator = null;
  				return false;
  			}
  		}
  	}
docs: Moves the iterator to the next key. This method may skip any values that have not yet been returned by the
  iterator created by the {@link #getValues()} method. Hence, if called multiple times it "removes" pairs.
  
  @return true if the input iterator has an other group of key-value pairs that share the same key.