private void createStringIfValid(FoundString foundString, Program program,
			AddressSetView addressSet, TaskMonitor monitor) {

		if (monitor.isCancelled()) {
			return;
		}

		Memory memory = program.getMemory();
		StringAndScores candidate =
			new StringAndScores(foundString.getString(memory), isLowerCaseModel);

		int scoredLength = candidate.getScoredStringLength();
		if (scoredLength < ABSOLUTE_MIN_STR_LENGTH) {
			return;
		}

		NGramUtils.scoreString(candidate);

		if (!candidate.isScoreAboveThreshold()) {
			return;
		}

		Address start = foundString.getAddress();
		Address end = foundString.getEndAddress();

		DataType dataType = foundString.getDataType();
		Listing listing = program.getListing();
		if (!DataUtilities.isUndefinedRange(program, start, end)) {
			if (allowStringCreationWithExistringSubstring) {
				// Check for single string with a common end address which be consumed
				Data definedData = listing.getDefinedDataContaining(end);
				if (definedData == null || definedData.getAddress().compareTo(start) <= 0 ||
					!dataType.isEquivalent(definedData.getDataType()) ||
					!DataUtilities.isUndefinedRange(program, start,
						definedData.getAddress().previous())) {
					return; // conflict data can not be consumed
				}
			}
			else {
				return; // data conflict
			}
		}

		boolean hasOffcutReferences = false;
		if (!allowStringCreationWithOffcutReferences) {
			hasOffcutReferences = hasOffcut(start, end, program);
		}

		// Only make a string if no offcut references or there are offcut references, 
		// but user says so
		if (hasOffcutReferences && !allowStringCreationWithOffcutReferences) {
			return;
		}

		try {

			int length = foundString.getLength();

			if (requireNullEnd && endAlignment > 1) {
				int padLength = getStringPadLength(program, end);

				// Check to make sure extra padding doesn't go over memory
				// boundaries or allow writing over defined data/instructions
				if (padLength > 0) {
					length += getValidPadLength(program, end, padLength);
				}
			}

			// Need to pass length into command for when (requireNullEnd == false).
			// Using the CreateDataCmd (which doesn't allow you to pass in a length)
			// creates a string at the starting address up to the length of the next
			// "00".
			DataUtilities.createData(program, start, foundString.getDataType(), length,
				DataUtilities.ClearDataMode.CLEAR_ALL_CONFLICT_DATA);

			Msg.trace(this, "Created string '" + candidate.getOriginalString() + "' at " + start);

			monitor.setMessage("Creating String at " + start);
		}
		catch (Exception e) {
			throw new AssertException("Unexpected exception", e);
		}
	}
Takes a FoundString, determines if it is a "valid" sequence of ASCII characters or not
(determined by the model).  If so, the string is created if the following criteria are
met:
		- The string does not overlap existing instructions
		- The exact string doesn't already exist
		- Any existing defined data within the potential string is:
			- wholly contained within the potential string
			- does not share the same starting address as the potential string
			- shares the same ending address as the potential string
			- has the same datatype as the potential string
		  Note: existing data will be cleared when the string is created

@param foundString  A string identified by the StringSearcher
@param program  the current program
@param addressSet the addresses to check for conflicts
@param monitor the task monitor
@throws CancelledException
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/StringsAnalyzer.java