private void createActions() {

		new ActionBuilder("Graph Block Flow", getName()).menuPath(MENU_GRAPH, "&Block Flow")
				.menuGroup(MENU_GRAPH, "A")
				.onAction(c -> graphBlockFlow())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		new ActionBuilder("Graph Code Flow", getName()).menuPath(MENU_GRAPH, "C&ode Flow")
				.menuGroup(MENU_GRAPH, "B")
				.onAction(c -> graphCodeFlow())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		new ActionBuilder("Graph Calls Using Default Model", getName())
				.menuPath(MENU_GRAPH, "&Calls")
				.menuGroup(MENU_GRAPH, "C")
				.onAction(c -> createDefaultCallGraph())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		tool.setMenuGroup(new String[] { MENU_GRAPH, "Data" }, "Graph", "Data");
		HelpLocation helpLoc = new HelpLocation(getName(), "Data_Reference_Graph");

		new ActionBuilder("Graph To/From Data References", getName())
				.menuPath(MENU_GRAPH, "Data", "To/From &References")
				.menuGroup(MENU_GRAPH, "Data")
				.helpLocation(helpLoc)
				.onAction(c -> graphDataReferences())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		new ActionBuilder("Graph To Data References", getName())
				.menuPath(MENU_GRAPH, "Data", "&To References")
				.menuGroup(MENU_GRAPH, "Data")
				.helpLocation(helpLoc)
				.onAction(c -> graphToDataReferences())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		new ActionBuilder("Graph From Data References", getName())
				.menuPath(MENU_GRAPH, "Data", "&From References")
				.menuGroup(MENU_GRAPH, "Data")
				.helpLocation(helpLoc)
				.onAction(c -> graphFromDataReferences())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		reuseGraphAction =
			new ToggleActionBuilder("Reuse Graph", getName()).menuPath(MENU_GRAPH, "Reuse Graph")
					.menuGroup("Graph Options")
					.selected(reuseGraph)
					.onAction(c -> reuseGraph = reuseGraphAction.isSelected())
					.enabledWhen(this::canGraph)
					.buildAndInstall(tool);

		appendGraphAction =
			new ToggleActionBuilder("Append Graph", getName()).menuPath(MENU_GRAPH, "Append Graph")
					.menuGroup("Graph Options")
					.selected(false)
					.onAction(c -> updateAppendAndReuseGraph())
					.enabledWhen(this::canGraph)
					.buildAndInstall(tool);

		forceLocationVisibleAction = new ToggleActionBuilder("Show Location in Graph", getName())
				.menuPath(MENU_GRAPH, "Show Location")
				.description("Tell the graph to pan/scale as need to keep location changes visible")
				.menuGroup("Graph Options")
				.onAction(c -> toggleForceLocationVisible())
				.enabledWhen(this::canGraph)
				.buildAndInstall(tool);

		updateSubroutineActions();
	}
Plugin for generating program graphs. It uses the GraphServiceBroker to consume/display
the graphs that it generates. This plugin generates several different types of program graphs.
Both the "block flow" and "code flow" actions will generate a graph of basic block flows. The only
difference is that the "code flow" action generates a graph that
displays the assembly for each basic block, whereas the "block flow" action generates a graph
that displays the symbol or address at the start of the basic block.  This plugin also
generates call graphs, using either the default subroutine model or one that the user chooses.
Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/ProgramGraphPlugin.java