public T get(GThemeValueMap values) {
		if (value != null) {
			return value;
		}

		Set<String> visitedKeys = new HashSet<>();
		visitedKeys.add(id);
		ThemeValue<T> referred = getReferredValue(values, referenceId);

		// loop resolving indirect references
		while (referred != null) {
			if (referred.value != null) {
				return referred.get(values);
			}
			visitedKeys.add(referred.id);
			if (visitedKeys.contains(referred.referenceId)) {
				Msg.warn(this, "Theme value reference loop detected for key: " + id);
				return getUnresolvedReferenceValue(id, referred.referenceId);
			}
			referred = getReferredValue(values, referred.referenceId);
		}
		return getUnresolvedReferenceValue(id, referenceId);
	}
Returns the T value for this instance, following references as needed. Uses the given
preferredValues map to resolve references. If the value can't be resolved by following
reference chains, an error stack trace will be generated and the default T value will
be returned. In rare situations where it is acceptable for the value to not be resolvable,
use the {@link #hasResolvableValue(GThemeValueMap)} method first.
@param values the {@link GThemeValueMap} used to resolve references if this
instance doesn't have an actual value.
@return the T value for this instance, following references as needed.
Ghidra/Framework/Gui/src/main/java/generic/theme/ThemeValue.java