docs: @Override
  	public boolean nextKey() throws IOException
  	{
  		// first element (or empty)
  		if (this.current == null) {
  			if (this.done) {
  				this.valuesIterator = null;
  				return false;
  			}
  			this.current = this.reuse;
  			if ((this.current = this.iterator.next(this.current)) != null) {
  				this.comparator.setReference(this.current);
  				this.lookAheadHasNext = false;
  				this.valuesIterator = new ValuesIterator();
  				this.valuesIterator.currentIsUnconsumed = true;
  				return true;
  			} else {
  				// empty input, set everything null
  				this.valuesIterator = null;
  				this.current = null;
  				this.done = true;
  				return false;
  			}
  		}
  		
  		this.valuesIterator.iteratorAvailable = true;
  
  		// Whole value-iterator was read and a new key is available.
  		if (this.lookAheadHasNext) {
  			this.lookAheadHasNext = false;
  			this.current = this.lookahead;
  			this.lookahead = null;
  			this.comparator.setReference(this.current);
  			this.valuesIterator.currentIsUnconsumed = 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.done && ((this.current = this.iterator.next(this.current)) != null)) {
  				if (!this.comparator.equalToReference(this.current)) {
  					// the keys do not match, so we have a new group. store the current keys
  					this.comparator.setReference(this.current);
  					this.lookAheadHasNext = false;
  					this.valuesIterator.currentIsUnconsumed = true;
  					return true;
  				}
  			}
  			else {
  				this.valuesIterator = null;
  				this.current = null;
  				this.done = true;
  				return false;
  			}
  		}
  	}