@PreDestroy
	private void save() {
		// Skip persisting in test environments
		if (TestEnvironment.isTestEnv())
			return;

		Gson gson = gsonProvider.getGson();
		for (ConfigContainer container : containers.values()) {
			// Skip writing empty containers
			if (container.getValues().isEmpty())
				continue;

			// Model the vales into a single object.
			JsonObject json = new JsonObject();
			for (ConfigValue<?> configValue : container.getValues().values()) {
				try {
					json.add(configValue.getId(), gson.toJsonTree(configValue.getValue()));
				} catch (IllegalArgumentException e) {
					logger.error("Could not find adapter for type: {}", configValue.getType(), e);
				} catch (Exception e) {
					logger.error("Failed to save config value: {}", configValue.getId(), e);
				}
			}

			// Write the appropriate path based on the container id.
			String key = container.getGroupAndId();
			Path containerPath = fileConfig.getConfigDirectory().resolve(key + ".json");
			try (JsonWriter writer = gson.newJsonWriter(Files.newBufferedWriter(containerPath))) {
				gson.toJson(json, writer);
			} catch (IOException e) {
				logger.error("Failed to save config container: {}", key, e);
			}
		}
	}
Tracker for all {@link ConfigContainer} instances.

@author Matt Coley
recaf-core/src/main/java/software/coley/recaf/services/config/ConfigManager.java