@Override
	public void processWorkspace(@Nonnull Workspace workspace) {
		// Ensure future changes to workspace will process any new classes.
		ThrowablePropertyAssigningProcessor processor = this;
		workspace.addWorkspaceModificationListener(new WorkspaceModificationListener() {
			@Override
			public void onAddLibrary(@Nonnull Workspace workspace, @Nonnull WorkspaceResource library) {
				library.addListener(processor);
			}

			@Override
			public void onRemoveLibrary(@Nonnull Workspace workspace, @Nonnull WorkspaceResource library) {
				library.removeListener(processor);
			}
		});
		for (WorkspaceResource resource : workspace.getAllResources(false))
			resource.addListener(processor);

		// Provide a graph asynchronously, then process all classes in the workspace.
		CompletableFuture.supplyAsync(() -> graphService.getOrCreateInheritanceGraph(workspace), ThreadUtil.executor())
				.thenAccept(inheritanceGraph -> {
					this.inheritanceGraph = inheritanceGraph;
					workspace.findClasses(false, c -> true).forEach(path -> handle(path.getValue()));
				});
	}
Workspace processor that marks {@link ClassInfo} values that inherit from {@link Throwable}
as having a {@link ThrowableProperty}. This allows instant look-ups for if a class is throwable,
by bypassing repeated calls to {@link InheritanceGraph}.

@author Matt Coley
recaf-core/src/main/java/software/coley/recaf/services/workspace/processors/ThrowablePropertyAssigningProcessor.java