public void findDeletingDestructors(List<RecoveredClass> recoveredClasses,
			List<Address> allVftables) throws Exception {

		if (recoveredClasses.isEmpty()) {
			return;
		}

		Set<Function> allPossibleCDs = getAllPossibleConstructorDestructors(allVftables);

		Set<Function> allFunctionsThatRefVftables = getAllClassFunctionsWithVtableRef(allVftables);

		if (operatorDeletes == null) {
			return;
		}

		// iterate over all class virtual functions to find the ones that are deleting destructors
		for (RecoveredClass recoveredClass : recoveredClasses) {
			monitor.checkCancelled();

			List<Function> vfunctions = recoveredClass.getAllVirtualFunctions();

			if (vfunctions.isEmpty()) {
				continue;
			}

			for (Function vfunction : vfunctions) {
				monitor.checkCancelled();

				// get the map of addresses in vfunction to the corresponding functions called
				// from those addresses
				Map<Address, Function> functionCallMap = getFunctionCallMap(vfunction, false);

				if (functionCallMap.isEmpty()) {
					continue;
				}

				List<Address> operatorDeleteCallingAddresses =
					getAddressesOfListedFunctionsInMap(operatorDeletes, functionCallMap);

				// only process vfunctions with at least one call to operator delete
				if (operatorDeleteCallingAddresses.size() == 0) {
					continue;
				}

				// get the first call to operator delete in the function 
				Collections.sort(operatorDeleteCallingAddresses);

				// get first vftable reference in vfuntion
				List<Address> vftableReferences = getVftableReferences(vfunction);
				Address firstVftableReference = null;
				if (vftableReferences != null) {
					Collections.sort(vftableReferences);
					firstVftableReference = vftableReferences.get(0);
				}

				List<Function> possibleCalledDestructors = getPossibleCalledDestructors(
					functionCallMap, operatorDeleteCallingAddresses, firstVftableReference);

				// process deleting destructors if type 1, 2 or 3
				boolean isDeletingDestructor =
					processDeletingDestructor(recoveredClass, vfunction, allVftables);
				if (isDeletingDestructor) {
					processPossibleDestructors(allPossibleCDs, possibleCalledDestructors, vfunction,
						allVftables);
					continue;
				}

				// process deleting destructors type 4 and 5
				// if function has only two calls and one is a vetted possible destructor (ie on 
				// list called after first vftable reference and  before operator delete) and the 
				// other is a call to operator delete, then it is one of these two types
				if (!allFunctionsThatRefVftables.contains(vfunction) &&
					operatorDeleteCallingAddresses.size() == 1 &&
					functionCallMap.keySet().size() == 2 && possibleCalledDestructors.size() == 1) {

					recoveredClass.addDeletingDestructor(vfunction);
					Function destructor = possibleCalledDestructors.get(0);

					// if the called destructor isn't on the possible constructor/destructor 
					// list then it is a vbase destructor
					if (firstVftableReference == null && !allPossibleCDs.contains(destructor)) {

						recoveredClass.setVBaseDestructor(destructor);
						continue;
					}

					// else, if the vfunction CALLS a function on the constructor/destructor list
					// it is a regular destructor for some class
					if (allPossibleCDs.contains(destructor)) {
						processFoundDestructor(destructor, vfunction);
					}
				}

			}
		}

	}
Method to find deleting destructors in the virtual functions of the given list of classes. 
Method finds the following use cases (Note that in all cases operator_delete is called after
 the called destructor or inlined destructor):
   1. deleting destructors that reference their own vftable (ie on own c/d list) which means
   function is both a deleting destructor and has an inlined class destructor.
   2. deleting destructors that references a parent vftable (ie on parent c/d list) which
   means function is a deleting destructor in the class and contains an inlined destructor
   for the parent class.
   3. deleting destructors that do not reference a vftable but call their own destructor
   4. deleting destructors that do not reference a vftable with only two calls and that calls
     a destructor from another class
   5. deleting destructors that do not reference a vftable with only two calls tand that 
     calls a vbase destructor
@param recoveredClasses the given classes to process for deleting destructors
@param allVftables all known vftables
@throws Exception  if an exception
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java