function intersection( iterators, hashFcn, thisArg ) {
	var hash;
	var it;
	var hv;
	var v;
	var n;
	var j;

	// Create a new linked list for storing the intersection:
	hash = new LinkedList();

	// Find the intersection by first finding the unique values in the first iterator...
	it = iterators[ 0 ];
	while ( true ) {
		v = it.next();
		if ( v.done ) {
			break;
		}
		hv = hashFcn.call( thisArg, v.value );

		// Determine if we have seen this hash before...
		n = getNode( hash, hv );
		if ( n === null ) {
			// First time we have seen this hash, so add to our set of hashes:
			hash.push( [ hv, v.value, 1 ] );
		}
	}
	// Check whether we found any unique hashes:
	if ( hash.length === 0 ) {
		return hash;
	}
	// Now that we have found an initial set of unique hashes, we need to consume each subsequent iterator, updating the count indicating how many iterators have contained an iterated value mapping to a given hash and removing any hashes from our initial set which were not found in *all* iterators...
	for ( j = 1; j < iterators.length; j++ ) {
		it = iterators[ j ];
		while ( true ) {
			v = it.next();
			if ( v.done ) {
				break;
			}
			hv = hashFcn.call( thisArg, v.value );
			n = getNode( hash, hv );
			if ( n && n.value[ 2 ] === j ) {
				// Only increment a hash's counter the first time we see the hash per iterator...
				n.value[ 2 ] += 1;
			}
		}
		// Upon consuming an iterator, we need to remove any hashes whose count is less than the number of iterators seen thus far:
		clean( hash, j+1 );

		// Check whether we still have any unique hashes:
		if ( hash.length === 0 ) {
			return hash;
		}
		// Move on to the next iterator...
	}
	return hash;
}
Finds the intersection of two or more iterators according to a hash function.

@private
@param {Array<Iterator>} iterators - list of iterators
@param {Function} hashFcn - hash function
@param {*} thisArg - execution context
@returns {LinkedList} a linked list containing the intersection