public void splitVertex(FGController controller, FGVertex vertexToSplit,
			Address newVertexMinAddress) {

		// For now we do not handle splitting when the vertex to split is a group vertex, which
		// means that the real vertex is inside of the grouped vertex.  The work to update
		// everything does not seem worth the result at this time (the result being an updated
		// group vertex display and proper ungrouping).  For now, the user will just have to
		// hit refresh to see the new vertices, but, they will no longer be grouped.
		if (vertexToSplit instanceof GroupedFunctionGraphVertex) {
			return;
		}

		stopAllAnimation();

		FGView view = controller.getView();
		VisualizationServer<FGVertex, FGEdge> primaryViewer = view.getPrimaryGraphViewer();

		//
		// First: create the new parent and child vertices from the given vertex
		//
		Layout<FGVertex, FGEdge> graphLayout = primaryViewer.getGraphLayout();
		Graph<FGVertex, FGEdge> graph = graphLayout.getGraph();

		boolean isOldVertexAnEntry = vertexToSplit.isEntry();
		FlowType oldFlowType = vertexToSplit.getFlowType();
		FGVertexType oldVertexType = vertexToSplit.getVertexType();
		AddressSetView oldAddresses = vertexToSplit.getAddresses();

		AddressSet newParentAddresses = new AddressSet();
		AddressSet newChildAddresses = new AddressSet();

		// grab the addresses for the new child node first, then we can subtract those for the
		// parent set
		AddressIterator iterator = oldAddresses.getAddresses(newVertexMinAddress, true);
		while (iterator.hasNext()) {
			Address address = iterator.next();
			newChildAddresses.addRange(address, address);
		}

		newParentAddresses = oldAddresses.subtract(newChildAddresses);

		FGVertex parentVertex = new ListingFunctionGraphVertex(controller, newParentAddresses,
			oldFlowType, isOldVertexAnEntry);
		FGVertex childVertex = new ListingFunctionGraphVertex(controller, newChildAddresses,
			RefType.FALL_THROUGH, false);

		if (oldVertexType == FGVertexType.SINGLETON) {
			parentVertex.setVertexType(FGVertexType.ENTRY);
			childVertex.setVertexType(FGVertexType.EXIT);
		}
		else if (oldVertexType.isEntry()) {
			parentVertex.setVertexType(oldVertexType);
			childVertex.setVertexType(FGVertexType.BODY);
		}
		else if (oldVertexType.isExit()) {
			parentVertex.setVertexType(FGVertexType.BODY);
			childVertex.setVertexType(oldVertexType);
		}
		else {
			parentVertex.setVertexType(oldVertexType);
			childVertex.setVertexType(oldVertexType);
		}
		graph.addVertex(parentVertex);
		graph.addVertex(childVertex);

		FunctionGraph fg = (FunctionGraph) graph;
		if (vertexToSplit == fg.getRootVertex()) {
			fg.setRootVertex(parentVertex);
		}
		//
		// Second: add the edges from the original vertices to the new vertices
		//
		// To do this, we have to:
		// -move the edge(s) coming into the old vertex to the new parent vertex
		// -move the edge(s) coming out of the old vertex to the new child vertex
		// -add a fallthrough edge between the two new vertices
		//
		Collection<FGEdge> oldInEdges = graph.getInEdges(vertexToSplit);
		Collection<FGEdge> oldOutEdges = graph.getOutEdges(vertexToSplit);

		// copy to keep a reference, as given collection is backed by the graph's state
		oldInEdges = new ArrayList<>(oldInEdges);
		oldOutEdges = new ArrayList<>(oldOutEdges);

		// ...now move the edges to the new parent vertex
		for (FGEdge edge : oldInEdges) {
			FGVertex oldStartVertex = edge.getStart();
			FGEdge newEdge = edge.cloneEdge(oldStartVertex, parentVertex);
			graph.addEdge(newEdge, oldStartVertex, parentVertex);
		}

		// ...now move the edges to the new child vertex
		for (FGEdge edge : oldOutEdges) {
			FGVertex oldDestinationVertex = edge.getEnd();
			graph.addEdge(edge.cloneEdge(childVertex, oldDestinationVertex), childVertex,
				oldDestinationVertex);
		}

		// ...now connect the two new vertices
		FGEdge edge = new FGEdgeImpl(parentVertex, childVertex, RefType.FALL_THROUGH,
			controller.getFunctionGraphOptions());
		graph.addEdge(edge, parentVertex, childVertex);

		//
		// Third: Create the animator to smooth the process.  The animator will not
		//        animate if animation is disabled.
		//
		SplitVertexFunctionGraphJob job = new SplitVertexFunctionGraphJob(controller, primaryViewer,
			vertexToSplit, parentVertex, childVertex, isAnimationEnabled());
		scheduleViewChangeJob(job);
	}
Install the given grouped vertex into the graph, optionally animating the process.

@param controller the controller of the graph to be ungrouped
@param groupVertex The group vertex to be ungrouped
@param groupVertexLocation The default groupVertex location (only used if not
							  performing a relayout).
@param relayoutOverride true signals to always relayout the graph after grouping; false
                        indicates to use the tool's options to decide
@param animate whether to animate
@return true if the given group was added to the graph
Ghidra/Features/FunctionGraph/src/main/java/ghidra/graph/viewer/FGViewUpdater.java