public void createShortenedTemplateNamesForClasses(List<RecoveredClass> recoveredClasses)
			throws CancelledException {

		List<RecoveredClass> classesWithTemplates = new ArrayList<RecoveredClass>();

		// create list with only classes that have templates in name and add completely stripped
		// template name to class var
		Iterator<RecoveredClass> recoveredClassesIterator = recoveredClasses.iterator();
		while (recoveredClassesIterator.hasNext()) {
			monitor.checkCancelled();
			RecoveredClass recoveredClass = recoveredClassesIterator.next();

			String className = recoveredClass.getName();

			if (containsTemplate(className)) {
				String shortenedName = removeTemplate(className) + "<...>";
				recoveredClass.addShortenedTemplatedName(shortenedName);
				classesWithTemplates.add(recoveredClass);
			}
		}

		// iterate over map and remove entries that already have unique shortened names on map and 
		// add those unique names to class as shorted name
		// for those with non-unique names, process them as a group of matched names
		List<RecoveredClass> classesToProcess = new ArrayList<RecoveredClass>(classesWithTemplates);

		Iterator<RecoveredClass> classWithTemplatesIterator = classesWithTemplates.iterator();

		while (classWithTemplatesIterator.hasNext()) {
			monitor.checkCancelled();
			RecoveredClass currentClass = classWithTemplatesIterator.next();

			// skip if already processed
			if (!classesToProcess.contains(currentClass)) {
				continue;
			}

			String currentShortenedName = currentClass.getShortenedTemplateName();

			// if removing the middle of template results in unique name then keep that name and
			// remove class from list to process
			List<RecoveredClass> classesWithSameShortenedName =
				getClassesWithSameShortenedName(classesToProcess, currentShortenedName);

			if (classesWithSameShortenedName.size() == 1) {
				classesToProcess.remove(currentClass);
				continue;
			}

			Iterator<RecoveredClass> classesWithSameShortnameIterator =
				classesWithSameShortenedName.iterator();
			while (classesWithSameShortnameIterator.hasNext()) {
				monitor.checkCancelled();

				RecoveredClass classWithSameShortName = classesWithSameShortnameIterator.next();

				// if removing the middle of template results in duplicate names then
				// check for a simple internal to the template (ie just one item in it
				// if that is the case then just keep the original name 
				if (containsSimpleTemplate(classWithSameShortName.getName())) {
					classWithSameShortName.addShortenedTemplatedName(new String());
					classesWithSameShortnameIterator.remove();
					classesToProcess.remove(classWithSameShortName);
				}
			}

			// if none left after removing simple ones then continue processing next class
			if (classesWithSameShortenedName.isEmpty()) {
				continue;
			}

			// if only one left after removing the simple templates then use it with first part of 
			// template internal
			if (classesWithSameShortenedName.size() == 1) {
				RecoveredClass classWithSameShortName = classesWithSameShortenedName.get(0);
				String newName = getNewShortenedTemplateName(classWithSameShortName, 1);
				classWithSameShortName.addShortenedTemplatedName(newName);
				classesToProcess.remove(classWithSameShortName);
				continue;
			}

			// if more than one complex left over after all the removals above, then keep trying to
			// get unique name
			int commaIndex = 1;
			while (!classesWithSameShortenedName.isEmpty()) {

				List<RecoveredClass> leftoversWithSameShortName =
					new ArrayList<RecoveredClass>(classesWithSameShortenedName);

				// update all their shorted names to include up to the n'th comma
				Iterator<RecoveredClass> leftoversIterator = leftoversWithSameShortName.iterator();

				while (leftoversIterator.hasNext()) {

					monitor.checkCancelled();
					RecoveredClass currentClassWithSameShortName = leftoversIterator.next();
					currentClassWithSameShortName.addShortenedTemplatedName(
						getNewShortenedTemplateName(currentClassWithSameShortName, commaIndex));
				}

				// now iterate and see if any are unique and if so remove from list
				// if not, add up to next comma and so on until all are unique
				List<RecoveredClass> leftovers2WithSameShortName =
					new ArrayList<RecoveredClass>(classesWithSameShortenedName);
				Iterator<RecoveredClass> leftovers2Iterator =
					leftovers2WithSameShortName.iterator();

				while (leftovers2Iterator.hasNext()) {

					monitor.checkCancelled();
					RecoveredClass currentClassWithSameShortName = leftovers2Iterator.next();

					String shortenedTemplateName =
						currentClassWithSameShortName.getShortenedTemplateName();

					List<RecoveredClass> classesWithSameShortName =
						getClassesWithSameShortenedName(classesToProcess, shortenedTemplateName);

					if (classesWithSameShortName.size() == 1) {
						classesToProcess.remove(classesWithSameShortName.get(0));
						classesWithSameShortenedName.remove(classesWithSameShortName.get(0));
					}
				}

				commaIndex++;
			}

		}

	}
Method to generate unique shorted names for classes with templates
@param recoveredClasses the list of classes in the program
@throws CancelledException if cancelled
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/ExtendedFlatProgramAPI.java