async function adaptationStarter(mOptions, fnLoadPlugins, fnOnStart, fnOnFailed, fnOnStop) {
		const oRtaResourceBundle = Lib.getResourceBundleFor("sap.ui.rta");

		try {
			if (!(mOptions.rootControl?.isA("sap.ui.core.Control")) && !(mOptions.rootControl?.isA("sap.ui.core.UIComponent"))) {
				const oError = Error("An invalid root control was passed");
				oError.reason = "rootControl";
				throw oError;
			}
			mOptions.rootControl = FlexUtils.getAppComponentForControl(mOptions.rootControl);

			await checkKeyUser(mOptions.flexSettings.layer);
			checkFlexEnabled(mOptions.rootControl);
			checkPseudoAppVariant(mOptions.rootControl);

			const oRta = new RuntimeAuthoring(mOptions);
			if (fnOnStart) {
				oRta.attachEvent("start", fnOnStart);
			}
			if (fnOnFailed) {
				oRta.attachEvent("failed", fnOnFailed);
			}
			oRta.attachEvent("stop", fnOnStop || function() {
				oRta.destroy();
			});

			if (fnLoadPlugins) {
				await fnLoadPlugins(oRta);
			}
			await oRta.start();

			if (mOptions.flexSettings.layer === "CUSTOMER") {
				const mPropertyBag = {
					oComponent: mOptions.rootControl,
					selector: mOptions.rootControl,
					invalidateCache: false,
					includeCtrlVariants: true,
					currentLayer: Layer.CUSTOMER
				};

				const oWarningMessage = await PersistenceWriteAPI.getChangesWarning(mPropertyBag);
				if (oWarningMessage.showWarning) {
					const oMessageProps = oWarningMessage.warningType === "mixedChangesWarning"
						? {
							text: "MSG_ADAPTATION_STARTER_MIXED_CHANGES_WARNING",
							title: "TIT_ADAPTATION_STARTER_MIXED_CHANGES_TITLE"
						}
						: {
							text: "MSG_ADAPTATION_STARTER_NO_CHANGES_IN_P_WARNING",
							title: "TIT_ADAPTATION_STARTER_NO_CHANGES_IN_P_TITLE"
						};

					showMessageBox(
						oRtaResourceBundle.getText(oMessageProps.text),
						{
							title: oRtaResourceBundle.getText(oMessageProps.title)
						},
						"warning"
					);
				}
			}
			return oRta;
		} catch (vError) {
			if (
				vError.message !== "Reload triggered"
				&& !(FlexUtils.getUshellContainer() && vError.reason === "flexEnabled") // FLP Plugin already handles this error
			) {
				if (vError.reason === "isKeyUser" || vError.reason === "pseudoAppVariant") {
					showMessageBox(
						vError.message,
						{title: oRtaResourceBundle.getText("MSG_ADAPTATION_COULD_NOT_START")},
						"error"
					);
				} else {
					showMessageBox(
						oRtaResourceBundle.getText("MSG_GENERIC_ERROR_MESSAGE", [vError.message]),
						{title: oRtaResourceBundle.getText("MSG_ADAPTATION_COULD_NOT_START")},
						"error"
					);
				}
				Log.error("UI Adaptation could not be started", vError.message);
			}
			throw vError;
		}
	}
Starter util for UI adaptation.
With this API you are also able to modify the UI adaptation plugins list and or add some event handler functions
to be called on start, failed and stop events.
The function also checks for the Key User authorization and the <code>flexEnabled</code> flag in the manifest.
If either check is not passed successfully the function returns a rejected Promise.

@param {object} mOptions - Object with properties
@param {sap.ui.core.Control|sap.ui.core.UIComponent} mOptions.rootControl - Control instance to get the AppComponent. This then is used to start UI adaptation.
@param {function} [fnLoadPlugins] - Callback function that enables the modification of the default plugin list of UI adaptation. UI adaptation is passed to this function and it should return a promise
@param {function} [fnOnStart] - Event handler function called on start event
@param {function} [fnOnFailed] - Event handler function called on failed event
@param {function} [fnOnStop] - Event handler function called on stop event
@returns {Promise} Resolves when UI adaptation was successfully started with adaptation instance.
@private