private static Throwable createThrowableWithStackOlderThan(List<String> patterns,
			StackElementMatcher matcher) {

		if (patterns.isEmpty()) {
			// always ignore our class.  We get this for free if the client passes in any classes
			patterns = new ArrayList<>();
			patterns.add(ReflectionUtilities.class.getName());
		}

		Throwable t = new Throwable();
		StackTraceElement[] trace = t.getStackTrace();
		int lastIgnoreIndex = -1;
		for (int i = 0; i < trace.length; i++) {
			StackTraceElement element = trace[i];
			if (matchesAnyPattern(element, patterns, matcher)) {
				lastIgnoreIndex = i;
			}
			else {
				// not a class of interest; if we have already seen our muse, then we are done
				if (lastIgnoreIndex != -1) {
					break;
				}
			}
		}

		if (lastIgnoreIndex == -1) {
			Msg.error(ReflectionUtilities.class,
				"Change call to ReflectionUtils.  Did not find the " +
					"following patterns in the call stack: " + patterns);
		}

		if (lastIgnoreIndex == trace.length - 1) {
			Msg.error(ReflectionUtilities.class,
				"Change call to ReflectionUtils. Call stack contains only ignored patterns: " +
					patterns);
		}

		int startIndex = lastIgnoreIndex + 1;
		StackTraceElement[] updatedTrace = Arrays.copyOfRange(trace, startIndex, trace.length);
		t.setStackTrace(updatedTrace);
		return t;
	}
Creates a throwable whose stack trace is based upon the current call stack, with any
information coming before, and including, the given patterns removed.

@param patterns the strings to ignore (e.g., class or package names)
@return the new throwable
@see #createThrowableWithStackOlderThan(Class...)
Ghidra/Framework/Utility/src/main/java/utilities/util/reflection/ReflectionUtilities.java