@Override
	protected void run() throws Exception {

		funcsToQuery = getFunctionsToQuery(currentProgram);
		queryService = new SimilarFunctionQueryService(currentProgram);
		queryInfo = new SFQueryInfo(funcsToQuery);
		bsimFilter = queryInfo.getBsimFilter();

		// Add threshold filters.
		queryInfo.setMaximumResults(MAX_NUM_FUNCTIONS);
		queryInfo.setSimilarityThreshold(SIMILARITY_BOUND);
		queryInfo.setSignificanceThreshold(SIGNIFICANCE_BOUND);

		// Add prefilters.
		setPrefilters();

		// Add a simple date filter.
		addBsimFilter(new DateLaterBSimFilterType(""), "01/01/1776");

		// Demonstration of a filter that allows for multiple entries. All filters but the 
		// DateEarlier and DateLater allow this. The effect is that each filter will be OR'd 
		// with the others. This is effectively the same as creating three distinct ArchEquals filters.
		//
		// ie: 	"The architecture can equal x86:LE:64:default OR the architecture can equal
		// 		ARM:LE_32:v4 OR ...."
		addBsimFilter(new ArchitectureBSimFilterType(),
			"x86:LE:64:default, x86:LE:32:default, ARM:LE:32:v4");

		// Another filter with multiple entries, but in this case since it is a "NotEqual" filter,
		// the items are "AND'd together.
		// 
		// ie: "The compiler cannot equal windows AND the compiler cannot equal foo_compiler".
		addBsimFilter(new NotCompilerBSimFilterType(), "windows, foo_compiler");

		//connect to the database
		try {
			String dbUrl =
				askString("", "Enter the URL of the BSim database:", "ghidra://localhost/bsimDb");
			queryService.initializeDatabase(dbUrl);
			FunctionDatabase.BSimError error = queryService.getLastError();
			if (error != null && error.category == ErrorCategory.Nodatabase) {
				println("Database [" + dbUrl + "] cannot be found (does it exist?)");
				return;
			}
		}
		catch (QueryDatabaseException e) {
			println(e.getMessage());
			return;
		}

		// Execute query and print results.
		List<BSimMatchResult> resultRows = executeQuery(queryInfo);
		printFunctionQueryResults(resultRows, "\nFunction-level results before filtering");

		// Add some simple post-query filters. These filters will only be applied to the result
		// set returned from the previous query.
		addBsimFilter(new Md5BSimFilterType(), currentProgram.getExecutableMD5());
		addBsimFilter(new CompilerBSimFilterType(), "gcc");
		//addBsimFilter(new FunctionTagBSimFilterType("KNOWN_LIBRARY", queryService), "false");

		// Apply the filters and print results.
		List<BSimMatchResult> filteredRows =
			BSimMatchResult.filterMatchRows(bsimFilter, resultRows);
		printFunctionQueryResults(filteredRows, "\nFunction-level results after filtering");
		printExecutableInformation(filteredRows);
	}
Script showing how to apply filters to a BSim query. Currently we support three types
of filters, described below:

	1. 	QUERY THRESHOLDS
		These are the items at the top of the BSim query dialog:
			Similarity
			Confidence
			Matches per Function
		These are server-side filters that will be applied when the db is queried. 
		
2. 	PREFILTERS
		Allows users to identify functions that meet certain criteria by specifying 
		{@link BiPredicate}s. Any functions matching the predicate(s) will be included
		in the result set.

3. 	EXECUTABLE FILTERS
		These are predefined filters that can be applied on the server or on the 
		client (applied only to the results of a query). On the BSim query
		dialog these are the items in the filter pulldown menu.
		@see BSimFilterType
 
 SCRIPT FLOW
 	This example script does the following:
 
 	1) Set threshold filters
 	2) Set prefilters
 	3) Set executable filters
 	4) Query the database & print results
 	5) Set new executable filters
 	6) Print results
 
 NOTES:	1. 	You will be queried for the location of the BSim database. This URL
 			will take the form "ghidra://<ip address>/<database name>
 
 		2. 	This script is only an example - the specific filters demonstrated 
 			here will not necessarily apply to what's in your BSim database.
Ghidra/Features/BSim/ghidra_scripts/QueryWithFiltersScript.java