private void populateLibraryFromProgram(Program program) throws CancelledException {

		FidHasher hasher = service.getHasher(program);
		ArrayList<Function> theFunctions = new ArrayList<>();
		Map<Function, FunctionRow> recordMap = new HashMap<>();

		// 1) hash all the functions, create function rows for them
		hashAllTheFunctions(program, hasher, theFunctions, recordMap);

		// 3) add all the forward (child) call relatives
		for (Entry<Function, FunctionRow> entry : recordMap.entrySet()) {
			monitor.checkCancelled();
			Function function = entry.getKey();
			FunctionRow functionRow = entry.getValue();
			if (functionRow != null) {
				functionRow.children = new ArrayList<>();
				addChildRelations(function, hasher, recordMap, functionRow.children);
				Collections.sort(functionRow.children);
				long hash = functionRow.generateHash();
				if (globalUniqueFunction.add(hash)) {
					functionRow.commit(fidDb, library); // Create the database record
				}
				else {
					exclude(program.getDomainFile(), function,
						FidPopulateResult.Disposition.DUPLICATE_INFO);
				}
			}
		}

		for (Entry<Function, FunctionRow> entry : recordMap.entrySet()) {
			monitor.checkCancelled();
			FunctionRow functionRow = entry.getValue();
			FunctionRecord functionRecord = functionRow.functionRecord;
			if (functionRecord == null) {
				continue; // Function exists but was excluded as a duplicate
			}
			for (ChildRow childRow : functionRow.children) {
				if (childRow.isVeryCommon) {
					continue; // So common, don't use parent/child as distinguisher
				}
				if (childRow.toRow == null) {
					if (childRow.symbolName != null) {
						addUnresolvedSymbol(functionRecord, childRow.symbolName, null);
					}
				}
				else if (childRow.toRow.functionRecord == null) { // This child was removed locally as a duplicate
					// We need to convert this to unresolved symbol, but in this case we know the hash
					addUnresolvedSymbol(functionRecord, childRow.toRow.name,
						childRow.toRow.hashQuad);
				}
				else {
					fidDb.createRelation(functionRecord, childRow.toRow.functionRecord,
						RelationType.DIRECT_CALL);
				}
			}
		}
	}
Processes a single program, adding it to the library.
@param result the populate result
@param program the program
@throws CancelledException if the user cancels
Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java