function loadControllerClass(sName, sViewId, bAsync) {
			if (typeof sName !== "string") {
				throw new Error("Controller name ('sName' parameter) is required and must be typeof 'string'");
			}

			/**
			 * @deprecated
			 */
			function resolveClass(ControllerClass) {
				if (ControllerClass) {
					return ControllerClass;
				} else if (mRegistry[sName]) {
					return Controller;
				} else {
					/** @deprecated since 1.120 */
					return ObjectPath.get(sName);
				}
			}

			let sControllerName;

			if (sName.startsWith("module:")) {
				sControllerName = sName.substring(7);
			} else {
				sControllerName = sName.replace(/\./g, "/") + ".controller";
			}

			let ControllerClass = sap.ui.require(sControllerName);
			/** @deprecated */
			ControllerClass ??= resolveClass(ControllerClass);

			/**
			 * @deprecated
			 * Sanity check: If the assumed Controller is actually a View we encountered a specific edge case.
			 *               A JSView that has been migrated to a Typed View can in theory have the same class name
			 *               as the Controller. While the file names might differ (e.g. sap/typed/Main.view.js and sap/typed/Main.controller.js),
			 *               the filename does not necessarily imply a class name. In this example the class names could both be "sap.typed.Main".
			 *               When sync loading, the classes are exposed in the global namespace under this class name.
			 *               At this time of loading the Controller class, the ObjectPath.get() call in resolveClass() might now retrieve the View class
			 *               that was previously written into the global namespace instead.
			 *               This causes a "Maximum call stack size exceeded" error. To prevent this we check specifically for a View class here.
			 */
			(() => {
				if (ControllerClass?.getMetadata?.().isA?.("sap.ui.core.mvc.View")) {
					throw new Error(`The controller '${sName}' define for the View with ID '${sViewId}' is not a valid Controller, but rather a View. ` +
					`This happens when the View and Controller classes have the same fully qualified class name. Please make sure that the class names in` +
					`Controller.extend("...") and the View.extend("...") call differ. If you migrated a 'JSView' to a 'Typed View' please refer to the documentation section under 'Typed View'`);
				}
			})();

			/**
			 * Sync class resolution
			 * @deprecated since 1.120
			 */
			if (!bAsync) {
				if (!ControllerClass) {
					ControllerClass = sap.ui.requireSync(sControllerName); // legacy-relevant: Sync path
					return resolveClass(ControllerClass);
				} else {
					return ControllerClass;
				}
			}

			return new Promise(function(resolve, reject) {
				if (!ControllerClass) {
					sap.ui.require([sControllerName], function (ControllerClass) {
						/** @deprecated */
						ControllerClass ??= resolveClass(ControllerClass);
						resolve(ControllerClass);
					}, reject);
				} else {
					resolve(ControllerClass);
				}
			});
		}
Loads a controller class or a controller-extension

@param {string} sName the controller name
@param {string} sViewId the ID of the View to which the loaded controller/extensions should be connected
@param {boolean} bAsync Load async or not
@return {sap.ui.core.mvc.Controller | Promise} oController <code>Promise</code> in case of asynchronous loading
          or <code>undefined</code> in case of synchronous loading
@ui5-transform-hint replace-param bAsync true