@Override
	protected void run() throws Exception {
		searchNonExecutableBlocks = true;
		maxFalsePositives = 20;
		File askDirectory = askDirectory("Result Directory", "Save");
		if (!askDirectory.isDirectory()) {
			println("Result directory does not exist: " + askDirectory.getAbsolutePath());
			return;
		}
		ResourceFile[] fileList = null;
		boolean localPattern = askYesNo("Local Pattern", "Use a local pattern file?");
		if (localPattern) {
			File patFile = askFile("Pattern File", "OK");
			fileList = new ResourceFile[1];
			fileList[0] = new ResourceFile(patFile);
		}
		if (!this.isRunningHeadless()) {
			if (askYesNo("DoSummary", "Would you like to summarize results?")) {
				runSummary(askDirectory);
				return;
			}
		}
		functionManager = currentProgram.getFunctionManager();
		listing = currentProgram.getListing();
		String fileName = "pat_" + currentProgram.getExecutableMD5();
		File resFile = new File(askDirectory, fileName);
		if (resFile.exists()) {
			println("Accumulation file already exists, skipping: " + resFile.getAbsolutePath());
			return;
		}
		ProgramDecisionTree patternDecisionTree = Patterns.getPatternDecisionTree();
		if (fileList == null) {
			fileList = Patterns.findPatternFiles(currentProgram, patternDecisionTree);
		}
		ArrayList<Pattern> patternlist = new ArrayList<>();
		for (ResourceFile element : fileList) {
			Pattern.readPatterns(element, patternlist, this);
		}
		if (patternlist.size() == 0) {
			return;
		}
		root = SequenceSearchState.buildStateMachine(patternlist);
		accumList = new ArrayList<>();
		for (int i = 0; i < patternlist.size(); ++i) {
			accumList.add(new PatternAccumulate(patternlist.get(i)));
		}
		MemoryBlock[] blocks = currentProgram.getMemory().getBlocks();
		for (MemoryBlock block2 : blocks) {
			MemoryBlock block = block2;
			if (!block.isInitialized()) {
				continue;
			}
			if (!searchNonExecutableBlocks && !block.isExecute()) {
				continue;
			}
			searchBlock(currentProgram, block, monitor);
		}
		FileWriter out = new FileWriter(resFile);
		out.write("<accumlist>\n");
		for (int i = 0; i < accumList.size(); ++i) {
			StringBuffer buf = new StringBuffer();
			accumList.get(i).saveXml(buf);
			out.write(buf.toString());
		}
		out.write("</accumlist>\n");
		out.close();
	}
Run patterns over all memory blocks, accumulate stats for
   1) hits for each pattern
   2) false positives for each pattern

 Produce an xml file output of stats for each pattern
Ghidra/Features/BytePatterns/ghidra_scripts/PatternStats.java