private void queryAssociatedSignatures(List<FunctionDescription> listFunctions,
			DescriptionManager manager) throws ElasticException {
		TreeMap<Long, VectorResult> vecMap = new TreeMap<>();
		for (FunctionDescription fdesc : listFunctions) {				// Collect (unique) vectorids across FunctionDescriptions
			if (fdesc.getSignatureRecord() != null) {
				continue;
			}
			Long key = Long.valueOf(fdesc.getVectorId());
			if (vecMap.containsKey(key)) {
				continue;
			}
			VectorResult vecRes = new VectorResult();
			vecRes.vectorid = key.longValue();
			vecMap.put(key, vecRes);
		}
		Iterator<VectorResult> iter1 = vecMap.values().iterator();
		Iterator<VectorResult> iter2 = vecMap.values().iterator();
		while (iter1.hasNext()) {
			fetchVectors(iter1, iter2, 50);						// Fetch vector associated with each vectorid
		}
		iter1 = vecMap.values().iterator();
		iter2 = vecMap.values().iterator();
		while (iter1.hasNext()) {
			fetchVectorCounts(iter1, iter2, MAX_VECTORCOUNT_WINDOW);	// Fetch hitcount of each vector
		}
		TreeMap<Long, SignatureRecord> sigMap = new TreeMap<>();
		for (Entry<Long, VectorResult> entry : vecMap.entrySet()) {		// Build SignatureRecord for each (id,vector,hitcount)
			SignatureRecord sigRec =
				manager.newSignature(entry.getValue().vec, entry.getValue().hitcount);
			manager.setSignatureId(sigRec, entry.getKey());
			sigMap.put(entry.getKey(), sigRec);
		}
		for (FunctionDescription fdesc : listFunctions) {						// Attach SignatureRecords to FunctionDescriptions
			if (fdesc.getSignatureRecord() != null) {
				continue;
			}
			SignatureRecord sigRec = sigMap.get(fdesc.getVectorId());
			manager.attachSignature(fdesc, sigRec);
		}
	}
Given a list of FunctionDescriptions, fill in the matching SignatureRecords
@param listFunctions is the list of functions
@param manager is the FunctionDescription container
@throws ElasticException for communication problems with the server
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java