void WeightedTriangleLinkPredictor::computeDetailedNeighbors( const neighbor_set_t& inNeighbors, const neighbor_set_t& outNeighbors, DetailedNeighbors& result ) const {
	neighbor_set_t::const_iterator inIt = inNeighbors.begin();
	neighbor_set_t::const_iterator outIt = outNeighbors.begin();
	neighbor_set_t::const_iterator inEnd = inNeighbors.end();
	neighbor_set_t::const_iterator outEnd = outNeighbors.end();
	while( inIt != inEnd && outIt != outEnd ) {
		if( inIt->first < outIt->first ) {
			result.inOnly.push_back( *inIt );
			result.either.push_back( *inIt );
	    	++inIt;
		} else if( inIt->first > outIt->first ) {
			result.outOnly.push_back( *outIt );
			result.either.push_back( *outIt );
	    	++outIt;
		} else {
	    	result.both.push_back( *inIt );
	    	result.either.push_back( *inIt );
	    	++inIt;
	    	++outIt;
		}
	}
	while( inIt != inEnd ) {
		result.inOnly.push_back( *inIt );
		result.either.push_back( *inIt );
		++inIt;
	}
	while( outIt != outEnd ) {
		result.outOnly.push_back( *outIt );
		result.either.push_back( *outIt );
		++outIt;
	}
}
VCP3DirectedLinkPredictor::DetailedNeighbors VCP3DirectedLinkPredictor::computeDetailedNeighbors( const neighbor_set_t& inNeighbors, const neighbor_set_t& outNeighbors, vertex_t avoidance ) const {
	neighbor_set_t::const_iterator inIt = inNeighbors.begin();
	neighbor_set_t::const_iterator outIt = outNeighbors.begin();
	neighbor_set_t::const_iterator inEnd = inNeighbors.end();
	neighbor_set_t::const_iterator outEnd = outNeighbors.end();
	DetailedNeighbors result;
	while( inIt != inEnd && outIt != outEnd ) {
		if( inIt->first == avoidance ) {
			++inIt;
			continue;
		}
		if( outIt->first == avoidance ) {
			++outIt;
			continue;
		}
		if( inIt->first < outIt->first ) {
			result.inOnly.push_back( inIt->first );
			result.either.push_back( inIt->first );
	    	++inIt;
		} else if( inIt->first > outIt->first ) {
			result.outOnly.push_back( outIt->first );
			result.either.push_back( outIt->first );
	    	++outIt;
		} else {
	    	result.both.push_back( inIt->first );
	    	result.either.push_back( inIt->first );
	    	++inIt;
	    	++outIt;
		}
	}
	while( inIt != inEnd ) {
		if( inIt->first == avoidance ) {
			++inIt;
			continue;
		}
		result.inOnly.push_back( inIt->first );
		result.either.push_back( inIt->first );
		++inIt;
	}
	while( outIt != outEnd ) {
		if( outIt->first == avoidance ) {
			++outIt;
			continue;
		}
		result.outOnly.push_back( outIt->first );
		result.either.push_back( outIt->first );
		++outIt;
	}
	return result;
}