private Map<Integer, RecoveredClass> getParentOrderMap(RecoveredClass recoveredClass,
			List<RecoveredClass> allowedAncestors, boolean useConstructors)
			throws CancelledException {

		Map<Integer, RecoveredClass> parentOrderMap = new HashMap<Integer, RecoveredClass>();

		int numVftables = recoveredClass.getVftableAddresses().size();

		List<Function> functionList = new ArrayList<Function>();
		if (useConstructors) {
			functionList.addAll(recoveredClass.getConstructorList());
			functionList.addAll(recoveredClass.getInlinedConstructorList());
		}
		else {
			functionList.addAll(recoveredClass.getDestructorList());
			functionList.addAll(recoveredClass.getInlinedDestructorList());
		}

		// return empty map
		if (functionList.isEmpty()) {
			return parentOrderMap;
		}

		for (Function function : functionList) {

			monitor.checkCancelled();

			parentOrderMap = new HashMap<Integer, RecoveredClass>();

			Map<Address, RecoveredClass> referenceToParentMap =
				getReferenceToClassMap(recoveredClass, function);

			Map<Address, RecoveredClass> allowedReferncesToParentMap =
				new HashMap<Address, RecoveredClass>();

			List<Address> classReferences = new ArrayList<Address>(referenceToParentMap.keySet());
			for (Address classReferenceAddress : classReferences) {

				monitor.checkCancelled();
				// if the address refers to a vftable and that vftable is in the current class then it is not a parent class so do not add to map
				Address possibleVftable = getVftableAddress(classReferenceAddress);

				// if not a vftable then it is a function call
				if (possibleVftable == null) {

					Function referencedFunction =
						extendedFlatAPI.getReferencedFunction(classReferenceAddress, true);

					if (referencedFunction == null) {
						continue;
					}

				}
				if (possibleVftable != null &&
					recoveredClass.getVftableAddresses().contains(possibleVftable)) {
					continue;
				}

				RecoveredClass ancestorClass = referenceToParentMap.get(classReferenceAddress);
				if (allowedAncestors.contains(ancestorClass)) {
					allowedReferncesToParentMap.put(classReferenceAddress, ancestorClass);
				}
			}

			// now order the addresses in the map one direction for constructors and the other for destructors
			int order = 0;
			List<Address> parentReferences =
				new ArrayList<Address>(allowedReferncesToParentMap.keySet());

			if (useConstructors) {
				Collections.sort(parentReferences);
			}
			else {
				Collections.sort(parentReferences, Collections.reverseOrder());
			}

			// iterate over the ordered parents and add the order to the parent map
			for (Address refAddress : parentReferences) {
				monitor.checkCancelled();
				RecoveredClass parentClass = referenceToParentMap.get(refAddress);
				parentOrderMap.put(order, parentClass);
				order++;
			}

			// the size of the resulting ref to parent map should equal the number of vftables in the class
			// if not, continue to iterate over more functions 
			// if so, return the map
			if (parentOrderMap.size() == numVftables) {
				return parentOrderMap;
			}
		}

		// return empty map if none of the construtor/destructor functions create the correctly sized map
		return parentOrderMap;
	}
Method to create an order/ancestor map for the given class (usually will be parents but in some cases will be ancestors)
@param recoveredClass the given class
@param allowedAncestors List of ancestors (usually parents) that can be added to the map
@param useConstructors if true, use constructor functions to determine order, if false, use destructor functions
@return the order/ancestor map of the same size as the number of vftables in the class or an empty map if the correctly sized map cannot be determined
@throws CancelledException if cancelled
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java