void nextNGramSource(int index) {
		int nextSize = 1;
		DataNGram zeroGram = ngrams.get(0);			// 0-gram for this node
		int finalHash;
		if (isCommutative()) {							// Commutative nodes have indistinguishable sources.
			finalHash = 0;
			for (DataVertex neighbor : sources) {
				DataNGram gram = neighbor.ngrams.get(index);	// Immediate neighbor (n-1)-gram
				finalHash += gram.hash;					// Combine hashes using a commutative operation
				nextSize += gram.weight;				// Running tally of number of nodes in hash
			}
			finalHash = Pinning.hashTwo(zeroGram.hash, finalHash);
		}
		else {
			finalHash = zeroGram.hash;
			for (DataVertex neighbor : sources) {
				DataNGram gram = neighbor.ngrams.get(index);	// Immedate neighbor (n-1)-gram
				finalHash = Pinning.hashTwo(finalHash, gram.hash);	// Hash in, in order
				nextSize += gram.weight;				// Running tally of number of nodes in hash
			}
		}

		ngrams.add(new DataNGram(this, nextSize, ngrams.size(), finalHash));
	}
Compute and store a new n-gram by combining existing (n-1)-grams from sources. 
@param index is the index of the current, already computed, (n-1)-gram to recurse on
Ghidra/Features/CodeCompare/src/main/java/ghidra/features/codecompare/graphanalysis/DataVertex.java