@SuppressWarnings("unchecked")
	private void partitionGraph(TaskMonitor monitor) throws CancelledException {

		// make entry point list and set their source number attribute
		LinkedList<Vertex> entryList = new LinkedList<>();
		Vertex[] sources = g.getSources();

		for (Vertex source : sources) {
			entryList.addLast(source);
		}
		LinkedList<Vertex> todoStack = new LinkedList<>();

		boolean sourceListIsGrowing = true;

		while (sourceListIsGrowing) {

			sourceListIsGrowing = false;

			IntegerAttribute<Vertex> sourceNumber =
				(IntegerAttribute<Vertex>) vertexAttributes.createAttribute(SOURCE_NUMBER,
					attributeType);

			int cnt = entryList.size();
			for (int i = 0; i < cnt; i++) {
				todoStack.addLast(entryList.get(i)); // initialize stack with entry point
				while (!todoStack.isEmpty()) {  // traverse the graph from source

					if (monitor.isCancelled()) {
						throw new CancelledException();
					}

					Vertex v = todoStack.removeLast(); // pop vertex off todo stack

					sourceNumber.setValue(v, i + 1);
					Set<Vertex> children = g.getChildren(v);
					if (children.isEmpty()) {
						continue;
					}
					Iterator<Vertex> childIter = children.iterator();
					while (childIter.hasNext()) {
						Vertex child = childIter.next();

						// check to see if child has already been labeled
						//  if not, give it label of current source
						int sourceValue = 0;
						try {
							sourceValue = sourceNumber.getValue(child);
							if (sourceValue == i + 1) { // there's a cycle -- need to break out
								continue;
							}
						}
						catch (NoValueException nVE) {
							sourceValue = i + 1;
						}

						// If child's label is the same as the source, continue traversing graph
						// If child's label differs from source, we found a new entry point!
						//  In later case, don't traverse graph -- removing incoming edges
						//  and add to entryList
						if (sourceValue == i + 1) {
							todoStack.addLast(child);
						}
						else {
							// remove all edges going into child
							Set<Edge> incomingEdges = g.getIncomingEdges(child);
							Iterator<Edge> edgeIter = incomingEdges.iterator();
							while (edgeIter.hasNext()) {
								g.remove(edgeIter.next());
							}

							// add child to entryList
							entryList.addLast(child);

							// child has entry point
							entAttribute.setValue(child, 0);

							sourceListIsGrowing = true;
						}
					}
				}
			}
		}
	}
Partition the Model-M subroutine graph using the Model-P algorythm.
The method createBlockGraph() must first be called to generate the
initial Model-M graph.
@param monitor task monitor which allows user to cancel operation.
@throws CancelledException if the monitor cancels the operation.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/PartitionCodeSubModel.java