function loadComponent(oConfig, mOptions) {
		var aActiveTerminologies = mOptions.activeTerminologies,
			sName = oConfig.name,
			sUrl = oConfig.url,
			bComponentPreload = /^(sync|async)$/.test(Component.getComponentPreloadMode()),
			vManifest = oConfig.manifest,
			bManifestFirst,
			sManifestUrl,
			oManifest,
			mModels,
			mPreloadModelConfigs,
			fnCallLoadComponentCallback;

		// The loading Promise of the FL library, need to orchestrate the execution of the manifest
		// preprocessing hook in case the FL library is part of the async hints
		const { promise: pFlLibLoading, resolve: flLibResolve, reject: flLibReject } = Promise.withResolvers();
		const sFlLibId = "sap.ui.fl";

		function createSanitizedManifest( oRawManifestJSON, mOptions ) {
			var oManifestCopy = JSON.parse(JSON.stringify(oRawManifestJSON));

			if (oConfig.async) {
				return preprocessManifestJSON(oManifestCopy).then(function(oFinalJSON) {
					// oFinalJSON might be modified by the flex-hook
					return new Manifest(oFinalJSON, mOptions);
				});
			} else {
				return new Manifest(oManifestCopy, mOptions);
			}
		}

		async function preprocessManifestJSON(oRawJson) {

			await pFlLibLoading; // flex lib can be part of the async hints!

			// the preprocessing flex-hook is only called if a manifest.json was loaded or an object was given via config
			if (ComponentHooks.onPreprocessManifest.isRegistered() && oRawJson != null) {
				try {
					// secure configuration from manipulation
					var oConfigCopy = deepExtend({}, oConfig);
					return ComponentHooks.onPreprocessManifest.execute(oRawJson, oConfigCopy);
				} catch (oError) {
					// in case the hook itself crashes without 'safely' rejecting, we log the error and reject directly
					Log.error("Failed to execute flexibility hook for manifest preprocessing.", oError);
					return Promise.reject(oError);
				}
			} else {
				return Promise.resolve(oRawJson);
			}
		}

		// url must be a string, although registerModulePath would also accept an object
		assert(!sUrl || typeof sUrl === 'string', "sUrl must be a string or undefined");

		// if a component name and a URL is given, we register this URL for the name of the component:
		// the name is the package in which the component is located (dot separated)
		if (sName && typeof sUrl === 'string') {
			registerModulePath(sName, sUrl);
		}

		// set the name of this newly loaded component at the interaction measurement,
		// as otherwise this would be the outer component from where it was called,
		// which is not true - this component causes the load
		Interaction.setStepComponent(sName);

		/**
		 * With Component.create() the manifest option cannot be undefined (default is <true>, other options see API doc for Component.create)
		 * @deprecated since 1.120
		 */
		if ( vManifest === undefined ) {
			// no manifest property set, evaluate legacy properties
			bManifestFirst = oConfig.manifestFirst === undefined ? BaseConfig.get({name: "sapUiManifestFirst", type: BaseConfig.Type.Boolean, external: true}) : !!oConfig.manifestFirst;
			sManifestUrl = oConfig.manifestUrl;
			// oManifest = undefined;
		}

		if (vManifest !== undefined) {
			// in case of manifest property is set, by default we load async
			if ( oConfig.async === undefined ) {
				oConfig.async = true;
			}
			// determine the semantic of the manifest property
			bManifestFirst = !!vManifest;
			sManifestUrl = vManifest && typeof vManifest === 'string' ? vManifest : undefined;
			oManifest = vManifest && typeof vManifest === 'object' ? createSanitizedManifest(vManifest, {url: oConfig && oConfig.altManifestUrl, activeTerminologies: aActiveTerminologies, process: !oConfig.async}) : undefined;
		}

		// if we find a manifest URL in the configuration
		// we will load the manifest from the specified URL (sync or async)
		if (!oManifest && sManifestUrl) {
			oManifest = Manifest.load({
				activeTerminologies: aActiveTerminologies,
				manifestUrl: sManifestUrl,
				componentName: sName,
				processJson: preprocessManifestJSON,
				async: oConfig.async,
				// If a dedicated manifest URL is given, e.g. for a Variant
				// we expect that the Manifest can be loaded successfully
				// If not, the manifest loading promise rejects and the further Component creation is stopped
				failOnError: true
			});
		}

		// once the manifest is available we extract the controller name
		if (oManifest && !oConfig.async) {
			sName = oManifest.getComponentName();

			// if a component name and a URL is given, we register this URL for the name of the component:
			// the name is the package in which the component is located (dot separated)
			if (sName && typeof sUrl === 'string') {
				registerModulePath(sName, sUrl);
			}
		}

		// Only if loading a manifest is done asynchronously we will skip the
		// name check because this will be done once the manifest is loaded!
		if (!(oManifest && oConfig.async)) {

			// check for an existing name
			if (!sName) {
				throw new Error("The name of the component is undefined.");
			}

			// check the type of the name
			assert(typeof sName === 'string', "sName must be a string");

		}

		// in case of loading the manifest first by configuration we need to
		// wait until the registration of the module path is done if needed and
		// then we can use the standard capabilities of the framework to resolve
		// the Components' modules namespace
		if (bManifestFirst && !oManifest) {
			oManifest = Manifest.load({
				activeTerminologies: aActiveTerminologies,
				manifestUrl: getManifestUrl(sName),
				componentName: sName,
				async: oConfig.async,
				processJson: preprocessManifestJSON,
				// Legacy components might not have a manifest.json but use the Component metadata instead.
				// For compatibility reasons we don't want to break the Component creation in these cases.
				failOnError: false
			});
		}

		function getControllerModuleName() {
			return (sName + ".Component").replace(/\./g, "/");
		}

		function prepareControllerClass(oClass) {

			var sController = sName + '.Component';

			if (!oClass) {
				var sMsg = "The specified component controller '" + sController + "' could not be found!";
				if (mOptions.failOnError) {
					throw new Error(sMsg);
				} else {
					future.warningThrows(sMsg);
				}
			}

			if (oManifest) {
				// create the proxy metadata object
				var oMetadataProxy = createMetadataProxy(oClass.getMetadata(), oManifest);
				// create the proxy class for passing the manifest
				var oClassProxy = function() {

					// create a copy of arguments for local modification
					// and later handover to Component constructor
					var args = Array.prototype.slice.call(arguments);

					// inject the manifest to the settings object
					var mSettings;
					if (args.length === 0 || typeof args[0] === "object") {
						mSettings = args[0] = args[0] || {};
					} else if (typeof args[0] === "string") {
						mSettings = args[1] = args[1] || {};
					}
					mSettings._metadataProxy = oMetadataProxy;

					// mixin created "models" into "mSettings"
					if (mModels) {
						mSettings._manifestModels = mModels;
					}

					// call the original constructor of the component class
					var oInstance = Object.create(oClass.prototype);
					oClass.apply(oInstance, args);
					return oInstance;

				};

				oMetadataProxy.getClass = function() {
					return oClassProxy;
				};

				oClassProxy[Symbol("isProxy")] = true;

				// overload the getMetadata function
				oClassProxy.getMetadata = function() {
					return oMetadataProxy;
				};
				// overload the extend function
				oClassProxy.extend = function() {
					throw new Error("Extending Components created by Manifest is not supported!");
				};
				return oClassProxy;
			} else {
				return oClass;
			}
		}

		/*
		 * Process .url and .lazy options.
		 * For preloadBundles, lazy will be ignored
		 */
		function processOptions(vObj, bIgnoreLazy) {

			assert(
				(typeof vObj === 'string' && vObj) ||
				(typeof vObj === 'object' && typeof vObj.name === 'string' && vObj.name),
				"reference either must be a non-empty string or an object with a non-empty 'name' and an optional 'url' property");

			if ( typeof vObj === 'object' ) {
				if ( vObj.url ) {
					registerModulePath(vObj.name, vObj.url);
				}
				return (vObj.lazy && bIgnoreLazy !== true) ? undefined : vObj.name; // expl. check for true to allow usage in Array.prototype.map below
			}

			return vObj;
		}

		/**
		 * @private
		 * @ui5-transform-hint replace-param bAsync true
		 */
		function preload(sComponentName, bAsync) {

			var sController = sComponentName + '.Component',
				http2 = Library.isDepCacheEnabled(),
				sPreloadName,
				oTransitiveDependencies,
				aLibs,
				errorLogging = function (sPreloadName, bAsync) {
					return function (e) {
						var sErrorMessage = "Component-preload for this component does not exist.";
						Log.warning(
							"Couldn't preload component from " + sPreloadName + ": " + ((e && e.message) || e),
							!bAsync ? sErrorMessage : sErrorMessage + " If the component is part of a library or another component, the configuration 'sap.app/embeddedBy' is not maintained. " +
							" The 'sap.app/embeddedBy' property must be relative path inside the deployment unit (library or component).",
							"sap.ui.core.Component#preload"
						);
					};
				};

			// only load the Component-preload file if the Component module is not yet available
			if ( bComponentPreload && sComponentName != null && !sap.ui.loader._.getModuleState(sController.replace(/\./g, "/") + ".js") ) {

				if ( bAsync ) {
					// check whether component controller is included in a library preload
					oTransitiveDependencies = VersionInfo._getTransitiveDependencyForComponent(sComponentName);

					if (oTransitiveDependencies && !oTransitiveDependencies.hasOwnPreload) {
						aLibs = [oTransitiveDependencies.library];
						// add all dependencies to aLibs
						Array.prototype.push.apply(aLibs, oTransitiveDependencies.dependencies);

						// load library preload for every transitive dependency
						return Library._load( aLibs, { preloadOnly: true } ).catch(errorLogging(oTransitiveDependencies.library, true));
					} else {
						sPreloadName = sController.replace(/\./g, "/") + (http2 ? '-h2-preload.js' : '-preload.js'); // URN
						return sap.ui.loader._.loadJSResourceAsync(sPreloadName).catch(errorLogging(sPreloadName, true));
					}
				} else {
					try {
						sPreloadName = sController + '-preload'; // Module name
						sap.ui.requireSync(sPreloadName.replace(/\./g, "/")); // legacy-relevant: Sync path
					} catch (e) {
						errorLogging(sPreloadName, false)(e);
					}
				}
			} else if (bAsync) {
				return Promise.resolve();
			}
		}

		/**
		 * @private
		 * @ui5-transform-hint replace-param bAsync true
		 */
		function preloadDependencies(sComponentName, oManifest, bAsync) {

			var aPromises = [];
			var fnCollect = bAsync ? function(oPromise) {
				aPromises.push(oPromise);
			} : function() {};

			// lookup the required libraries
			var mLibs = oManifest.getEntry("/sap.ui5/dependencies/libs");
			if (mLibs) {
				var aLibs = [];
				// filter the lazy libs
				for (var sLibName in mLibs) {
					if (!mLibs[sLibName].lazy) {
						aLibs.push(sLibName);
					}
				}
				if (aLibs.length > 0) {
					Log.info("Component \"" + sComponentName + "\" is loading libraries: \"" + aLibs.join(", ") + "\"");
					fnCollect(Library._load(aLibs, {
						sync: !bAsync
					}));
				}
			}

			// lookup the extended component and preload it
			var sExtendedComponent = oManifest.getEntry("/sap.ui5/extends/component");
			if (sExtendedComponent) {
				fnCollect(preload(sExtendedComponent, bAsync));
			}

			// lookup the non-lazy components from component dependencies
			var aComponents = [];
			var mComponents = oManifest.getEntry("/sap.ui5/dependencies/components");
			if (mComponents) {
				for (var sCompName in mComponents) {
					// filter the lazy components
					if (!mComponents[sCompName].lazy) {
						aComponents.push(sCompName);
					}
				}
			}

			// lookup the non-lazy components from component usages
			var mUsages = oManifest.getEntry("/sap.ui5/componentUsages");
			if (mUsages) {
				// filter the lazy usages
				for (var sUsage in mUsages) {
					// default value is true, so explicit check for false
					if (mUsages[sUsage].lazy === false && aComponents.indexOf(mUsages[sUsage].name) === -1) {
						aComponents.push(mUsages[sUsage].name);
					}
				}
			}

			// preload the collected components
			if (aComponents.length > 0) {
				aComponents.forEach(function(sComponentName) {
					fnCollect(preload(sComponentName, bAsync));
				});
			}

			return bAsync ? Promise.all(aPromises) : undefined;

		}

		if ( oConfig.async ) {

			// trigger loading of libraries and component preloads and collect the given promises
			var hints = oConfig.asyncHints || {},
				promises = [],
				reflect = function(oPromise) {
					// In order to make the error handling of the Promise.all() happen after all Promises finish, we catch all rejected Promises and make them resolve with an marked object.
					oPromise = oPromise.then(
						function(v) {
							return {
								result: v,
								rejected: false
							};
						},
						function(v) {
							return {
								result: v,
								rejected: true
							};
						}
					);
					return oPromise;
				},
				collect = function(oPromise) {
					if ( oPromise ) {
						promises.push(reflect(oPromise));
					}
				},
				identity = function($) { return $; },
				phase1Preloads,
				libs;

			phase1Preloads = [];

			// load any required preload bundles
			if ( Array.isArray(hints.preloadBundles) ) {
				hints.preloadBundles.forEach(function(vBundle) {
					phase1Preloads.push(
						sap.ui.loader._.loadJSResourceAsync(processOptions(vBundle, /* ignoreLazy */ true), /* ignoreErrors */ true) );
				});
			}

			// preload any libraries
			if ( Array.isArray(hints.libs) ) {
				libs = hints.libs.map(processOptions).filter(identity);

				// try if FL lib is part of async hints and needs separate preloading
				// we do this in order to orchestrate the manifest preprocessing hook to the loading of the lib
				if (!libs.includes(sFlLibId) || mOptions.preloadOnly) {
					flLibResolve();
				}

				phase1Preloads.push(
					Library._load( libs, { preloadOnly: true } )
				);
			} else {
				flLibResolve();
			}

			// sync preloadBundles and preloads of libraries first before requiring the libs
			// Note: component preloads are assumed to be always independent from libs
			// therefore those requests are not synchronized with the require calls for the libs
			phase1Preloads = Promise.all( phase1Preloads );
			if ( libs && !mOptions.preloadOnly ) {
				phase1Preloads = phase1Preloads.then( function() {
					let pFlLib = Promise.resolve();
					if (libs.includes(sFlLibId)) {
						libs = libs.filter((libId) => libId !== sFlLibId);
						pFlLib = Library._load([sFlLibId]).then(flLibResolve).catch(flLibReject);
					}

					return Promise.all([pFlLib, Library._load( libs )]);
				});
			}
			collect( phase1Preloads );

			// if a hint about "used" components is given, preload those components
			if ( hints.components ) {
				Object.keys(hints.components).forEach(function(sComp) {
					collect(preload(processOptions(hints.components[sComp]), true));
				});
			}

			// preload the component itself
			if (!oManifest) {
				collect(preload(sName, true));
			} else {
				var aI18nProperties = [];
				// // we have a manifest, so we can register the module path for the component
				// // and resolve any "ui5://" pseudo-protocol URLs inside.
				// // This needs to be done before we create the "afterPreload" models.
				oManifest = oManifest.then(async function(oManifest) {
					// if a URL is given we register this URL for the name of the component:
					// the name is the package in which the component is located (dot separated)
					var sComponentName = oManifest.getComponentName();

					if (typeof sUrl === 'string') {
						registerModulePath(sComponentName, sUrl);
					}

					// define resource roots, so they can be respected for "ui5://..." URL resolution
					oManifest.defineResourceRoots();

					// Resolve command descriptions
					await _resolveCommandsInManifest(oManifest);

					oManifest._preprocess({
						resolveUI5Urls: true,
						i18nProperties: aI18nProperties
					});

					return oManifest;
				});

				// create "afterPreload" models in parallel to loading the component preload (below)
				if (mOptions.createModels) {
					collect(oManifest.then(async function(oManifest) {
						var sComponentName = oManifest.getComponentName();
						// Calculate configurations of preloaded models once the manifest is available
						mPreloadModelConfigs = getPreloadModelConfigsFromManifest(oManifest);

						// Create preloaded models directly after the manifest has been loaded
						if (Object.keys(mPreloadModelConfigs.afterManifest).length > 0) {
							await _loadManifestModelClasses(mPreloadModelConfigs.afterManifest, sComponentName);

							// deep clone is needed as manifest only returns a read-only copy (frozen object)
							var oManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources"));
							var mAllModelConfigurations = _createManifestModelConfigurations({
								models: mPreloadModelConfigs.afterManifest,
								dataSources: oManifestDataSources,
								manifest: oManifest,
								componentData: oConfig.componentData,
								cacheTokens: hints.cacheTokens,
								activeTerminologies: aActiveTerminologies
							});

							mModels = _createManifestModels(mAllModelConfigurations, oConfig, oManifest);
						}

						return oManifest;
					}));
				}

				// in case of manifest first we need to load the manifest
				// to know the component name and then preload the component itself
				collect(oManifest.then(function(oManifest) {

					// preload the component only if not embedded in a library
					// If the Component controller is not preloaded, the Component.js file is loaded as a single request later on.
					// This situation should be fixed by the factory caller, so we log it as a warning.
					var pPreload = Promise.resolve();
					var sEmbeddedBy = oManifest.getEntry("/sap.app/embeddedBy");
					var sComponentName = oManifest.getComponentName();
					if (!sEmbeddedBy) {
						pPreload = preload(sComponentName, true);
					} else if (!sap.ui.loader._.getModuleState(getControllerModuleName() + ".js")) {
						Log.warning(
							"Component '" + sComponentName + "' is defined to be embedded in a library or another component" +
							"The relatively given preload for the embedding resource was not loaded before hand. " +
							"Please make sure to load the embedding resource containing this Component before instantiating.",
							undefined,
							"sap.ui.core.Component#embeddedBy"
						);
					}

					return pPreload.then(function() {
						// after preload is finished, load the i18n resource and process the placeholder texts
						return oManifest._processI18n(true, aI18nProperties);
					}).then(function() {
						// after i18n resource is finished, the resource models from the manifest are loaded

						if (!mOptions.createModels) {
							return null;
						}

						var aResourceModelNames = Object.keys(mPreloadModelConfigs.afterPreload);

						if (aResourceModelNames.length === 0) {
							return null;
						}

						// if there are resource models to be loaded, load the resource bundle async first.
						// a promise is returned which resolves after all resource models are loaded
						return new Promise(function(resolve, reject) {
							// load the sap.ui.model/resource/ResourceModel class async if it's not loaded yet
							sap.ui.require(["sap/ui/model/resource/ResourceModel"], function(ResourceModel) {
								// Directly resolve as otherwise uncaught exceptions can't be handled
								resolve(ResourceModel);
							}, reject);
						}).then(function(ResourceModel) {

							// deep clone is needed as manifest only returns a read-only copy (frozen object)
							var oManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources"));
							var mAfterPreloadModelConfigurations = _createManifestModelConfigurations({
								models: mPreloadModelConfigs.afterPreload,
								dataSources: oManifestDataSources,
								manifest: oManifest,
								componentData: oConfig.componentData,
								cacheTokens: hints.cacheTokens,
								activeTerminologies: aActiveTerminologies
							});

							function loadResourceBundle(sModelName) {
								var mModelConfig = mAfterPreloadModelConfigurations[sModelName];
								if (Array.isArray(mModelConfig.settings) && mModelConfig.settings.length > 0) {
									var mModelSettings = mModelConfig.settings[0]; // first argument is the config map

									// in order to load the whole ResourceBundle/terminologies closure upfront
									// we need pass the active terminologies to the ResourceModel/-Bundle.
									mModelSettings.activeTerminologies = mOptions.activeTerminologies;

									return ResourceModel.loadResourceBundle(mModelSettings, true).then(function(oResourceBundle) {
										// Extend the model settings with the preloaded bundle so that no sync request
										// is triggered once the model gets created
										mModelSettings.bundle = oResourceBundle;

										/*
										 * Compatibility concerning ResourceModel API:
										 * If active terminologies were given we need to remove the "enhanceWith", "terminologies" and "activeTerminologies"
										 * parameters from the model settings. The ResourceModel's constructor does not accept a mixed scenario
										 * where a constructed bundle, as well as additional enhance bundles with terminologies, are given.
										 */
										delete mModelSettings.terminologies;
										delete mModelSettings.activeTerminologies;
										delete mModelSettings.enhanceWith;

									}, function(err) {
										Log.error("Component Manifest: Could not preload ResourceBundle for ResourceModel. " +
											"The model will be skipped here and tried to be created on Component initialization.",
											"[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", oManifest.getComponentName());
										Log.error(err);

										// If the resource bundle can't be loaded, the resource model will be skipped.
										// But once the component instance gets created, the model will be tried to created again.
										delete mAfterPreloadModelConfigurations[sModelName];
									});
								} else {
									// Can't load bundle as no settings are defined.
									// Should not happen as those models won't be part of "afterPreload"
									return Promise.resolve();
								}
							}

							// Load all ResourceBundles for all models in parallel
							return Promise.all(aResourceModelNames.map(loadResourceBundle)).then(function() {
								if (Object.keys(mAfterPreloadModelConfigurations).length > 0) {
									var mResourceModels = _createManifestModels(mAfterPreloadModelConfigurations);
									if (!mModels) {
										mModels = {};
									}
									for (var sKey in mResourceModels) {
										mModels[sKey] = mResourceModels[sKey];
									}
								}
							});
						});
					});
				}));

				fnCallLoadComponentCallback = function(oLoadedManifest) {
					// if a callback is registered to the component load, call it with the configuration
					if (ComponentHooks.onComponentLoaded.isRegistered()) {
						// secure configuration from manipulation, manifest can be adjusted by late changes
						var oConfigCopy = deepExtend({}, oConfig);
						// trigger the callback with a copy of its required data
						// do not await any result from the callback nor stop component loading on an occurring error
						try {
							return ComponentHooks.onComponentLoaded.execute(oConfigCopy, oLoadedManifest);
						} catch (oError) {
							future.errorThrows("sap.ui.core.Component: Callback for loading the component \"" + oLoadedManifest.getComponentName() +
								"\" run into an error.", { cause: oError , suffix: "The callback was skipped and the component loading resumed." });
						}
					}
				};
			}

			// combine given promises
			return Promise.all(promises).then(function(v) {
				// If any promise is rejected, a new rejected Promise is forwarded on the chain which leads to the catch clause
				var aResults = [],
					bErrorFound = false,
					vError;

				bErrorFound = v.some(function(oResult) {
					if (oResult && oResult.rejected) {
						vError = oResult.result;
						return true;
					}
					aResults.push(oResult.result);
					return false;
				});

				if (bErrorFound) {
					return Promise.reject(vError);
				}

				return aResults;
			}).then(function (v) {
				// after all promises including the loading of dependent libs have been resolved
				// pass the manifest to the callback function in case the manifest is present and a callback was set
				if (oManifest && fnCallLoadComponentCallback) {
					return oManifest.then(fnCallLoadComponentCallback).then(function() {
						return v;
					});
				}
				return v;
			}).then(function(v) {
				Log.debug("Component.load: all promises fulfilled, then " + v);
				if (oManifest) {
					return oManifest.then(function(oLoadedManifest) {
						if (!oLoadedManifest._bLoadManifestRequestFailed) {
							// store the loaded manifest in the oManifest variable
							// which is used for the scope constructor function
							oManifest = oLoadedManifest;
							// read the component name from the manifest and
							// preload the dependencies defined in the manifest
							sName = oManifest.getComponentName();
							return preloadDependencies(sName, oManifest, true);
						} else {
							// Set oManifest to undefined in case the loadManifest request failed
							// This should be only the case if manifestFirst is true but there was
							// no manifest.json
							oManifest = undefined;
							return oManifest;
						}
					});
				} else {
					return v;
				}
			}).then(function() {
				if ( mOptions.preloadOnly ) {
					return true;
				}

				return new Promise(function(resolve, reject) {
					// asynchronously require component controller class
					sap.ui.require( [ getControllerModuleName() ], function(oClass) {
						// Directly resolve as otherwise uncaught exceptions can't be handled
						resolve(oClass);
					}, reject);
				}).then(function(oClass) {
					var oMetadata = oClass.getMetadata();
					var sName = oMetadata.getComponentName();
					var sDefaultManifestUrl = getManifestUrl(sName);
					var aPromises = [];

					// Check if we loaded the manifest.json from the default location
					// In this case it can be directly passed to its metadata class to prevent an additional request
					if (oManifest && typeof vManifest !== "object" && (typeof sManifestUrl === "undefined" || sManifestUrl === sDefaultManifestUrl)) {
						// We could use oManifest.getJson() to avoid calling '_processI18n(true)' at the next line.
						// However, we have to use oManifest.getRawJson() instead of oManifest.getJson() because the
						//  urls start with "ui5://" are already resolved in the oManifest.getJson() and
						//  ComponentMetadata needs to keep them unresolved until the resource roots are set.
						oMetadata._applyManifest(JSON.parse(JSON.stringify(oManifest.getRawJson())), true /* skip processing */);

						// Resolve commands description
						const pI18n = _resolveCommandsInManifest(oMetadata.getManifestObject()).then(() => {
							return oMetadata.getManifestObject()._processI18n(true);
						});
						aPromises.push(pI18n);
					}

					aPromises.push(loadManifests(oMetadata));

					return Promise.all(aPromises).then(function() {

						// The following processing of the sap.app/i18n resources happens under two conditions:
						//    1. The manifest is defined in the component metadata (no Manifest object yet)
						//    2. We have instance specific information (activeTerminologies)
						// In case of a manifest-first approach (Manifest object exists already),
						// the i18n processing has already happened and we skip this part.

						// Why do we set the oManifest object here?
						// > If we have instance specific information like "activeTerminologies" (non-empty array), the resulting
						//   Manifest instance differs from the Manifest that is stored on the ComponentMetadata.
						//   The function prepareControllerClass() then creates a ComponentMetadata Proxy,
						//   which encapsulates this single instance specific Manifest object.
						var pProcessI18n = Promise.resolve();
						if (!oManifest && Array.isArray(mOptions.activeTerminologies) && mOptions.activeTerminologies.length > 0) {
							oManifest = new Manifest(oMetadata.getManifestObject().getRawJson(), {
								process: false,
								activeTerminologies: aActiveTerminologies
							});

							pProcessI18n = _resolveCommandsInManifest(oMetadata.getManifestObject()).then(() => {
								return oManifest._processI18n(true);
							});
						}

						// prepare the loaded class and resolve with it
						return pProcessI18n.then(prepareControllerClass.bind(undefined, oClass));
					});
				});
			}).then(function(oControllerClass) {
				if (!oManifest) {
					return oControllerClass;
				}

				// collect routing related class names for async loading
				const oClassMetadata = oControllerClass.getMetadata();
				const aModuleNames = findRoutingClasses(oClassMetadata);

				// lookup model classes
				var mManifestModels = merge({}, oManifest.getEntry("/sap.ui5/models"));
				var mManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources"));
				var mAllModelConfigurations = _findManifestModelClasses({
					models: mManifestModels,
					dataSources: mManifestDataSources,
					componentName: oManifest.getComponentName()
				});
				for (var mModelName in mAllModelConfigurations) {
					if (!mAllModelConfigurations.hasOwnProperty(mModelName)) {
						continue;
					}
					var oModelConfig = mAllModelConfigurations[mModelName];
					if (!oModelConfig.type) {
						continue;
					}
					var sModuleName = oModelConfig.type.replace(/\./g, "/");
					if (aModuleNames.indexOf(sModuleName) === -1) {
						aModuleNames.push(sModuleName);
					}
				}

				if (aModuleNames.length > 0) {
					const sComponentName = oManifest.getComponentName();
					return Promise.all(aModuleNames.map(function(sModuleName) {
						// All modules are required separately to have a better error logging.
						// Most of the classes collected here will be instantiated during the (UI)Component constructor.
						// The upfront async loading is done to prevent synchronous loading during instantiation.
						// If loading fails, the component should still be created which might fail once the required module is actually used / loaded.
						return loadModuleAndLog(sModuleName, sComponentName);
					})).then(function() {
						return oControllerClass;
					});
				} else {
					return oControllerClass;
				}
			}).then(function(oControllerClass) {
				var waitFor = mOptions.waitFor;
				if (waitFor) {
					// when waitFor Promises have been specified we also wait for
					// them before we call the component constructor
					var aPromises = Array.isArray(waitFor) ? waitFor : [ waitFor ];
					return Promise.all(aPromises).then(function() {
						return oControllerClass;
					});
				}
				return oControllerClass;
			}).catch(function(vError) {
				// handle preload errors

				// destroy "preloaded" models in case of any error to prevent memory leaks
				if (mModels) {
					for (var sName in mModels) {
						var oModel = mModels[sName];
						if (oModel && typeof oModel.destroy === "function") {
							oModel.destroy();
						}
					}
				}

				// re-throw error to hand it over to the application
				throw vError;

			});

		}

		/**
		 * Sync creation path
		 */
		if (oManifest) {

			// define resource roots, so they can be respected for "ui5://..." URL resolution
			oManifest.defineResourceRoots();

			/** @deprecated As of version 1.135 */
			_resolveCommandsInManifestSync(oManifest);

			oManifest._preprocess({
				resolveUI5Urls: true
			});

			preloadDependencies(sName, oManifest);
		}
		preload(sName);

		// synchronously load the controller class, prepare and return it
		return prepareControllerClass(
			sap.ui.requireSync( getControllerModuleName() ) // legacy-relevant: Sync path
		);
	}
Internal loading method used by the factory methods.

@param {object} oConfig
    Configuration options as provided to the calling factory, see e.g. {@link sap.ui.core.Component.create}
@param {object} [oConfig.async]
    Whether the Component loading should be done asynchronously
@param {object} mOptions Additional, internal loading configuration
@param {string[]} mOptions.activeTerminologies list of active terminologies.
                  See the public API documentation for more detail: {@link sap.ui.core.Component.create Component.create}
@param {boolean} mOptions.failOnError see <code>sap.ui.component.load</code>
@param {boolean} mOptions.createModels whether models from manifest should be created during
                                       component preload (should only be set via <code>sap.ui.component</code>)
@param {boolean} mOptions.preloadOnly see <code>sap.ui.component.load</code> (<code>vConfig.asyncHints.preloadOnly</code>)
@param {Promise|Promise[]} mOptions.waitFor see <code>sap.ui.component</code> (<code>vConfig.asyncHints.waitFor</code>)
@return {function|Promise<function>} the constructor of the Component class or a Promise that will be fulfilled with the same

@private
@ui5-transform-hint replace-param oConfig.async true