private void startGhidraIfNeeded(GhidraApplicationLayout layout)
			throws StopWaitingException, FailedToStartGhidraException {
		// if there is no listening Ghidra
		if (!sender.isGhidraListening()) {

			// attempt to start a Ghidra within a locked action
			// do not wait for the lock if another GhidraGo has been started.
			try {
				boolean success = sender.doLockedAction(false, () -> {
					try {
						Process ghidraProcess = startGhidra(layout);
						sender.waitForListener(ghidraProcess);
						return true;
					}
					catch (StopWaitingException e) {
						return true;
					}
					catch (StartedGhidraProcessExitedException | IOException e) {
						return false;
					}
				});
				if (!success) {
					// GhidraGo attempted to start ghidra and failed
					throw new FailedToStartGhidraException();
				}
			}
			catch (UnableToGetLockException e) {
				// When another GhidraGo has the lock,
				// wait for there to be a listener without starting the process
				sender.waitForListener();
			}
		}
	}
Initializes a new GhidraGoSender and processes the {@link GhidraURL}
@param layout the layout passed from main.Ghidra
@param args the CLI args passed to GhidraGo. args should contain a single {@link GhidraURL}.
@throws Exception in the event of an error
Ghidra/Features/GhidraGo/src/main/java/ghidra/GhidraGo.java