function loadComponent(oConfig, mOptions) {

		var sName = oConfig.name,
			sUrl = oConfig.url,
			oConfiguration = sap.ui.getCore().getConfiguration(),
			bComponentPreload = /^(sync|async)$/.test(oConfiguration.getComponentPreload()),
			vManifest = oConfig.manifest,
			bManifestFirst,
			sManifestUrl,
			oManifest,
			mModels,
			mModelConfigs,
			fnCallLoadComponentCallback;

		function createSanitizedManifest( oRawManifestJSON, mOptions ) {
			var oManifest = new Manifest( JSON.parse(JSON.stringify(oRawManifestJSON)), mOptions );
			return oConfig.async ? Promise.resolve(oManifest) : oManifest;
		}

		// 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);

		if ( vManifest === undefined ) {
			// no manifest property set, evaluate legacy properties
			bManifestFirst = oConfig.manifestFirst === undefined ? oConfiguration.getManifestFirst() : !!oConfig.manifestFirst;
			sManifestUrl = oConfig.manifestUrl;
			// oManifest = undefined;
		} else {
			// 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}) : 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({
				manifestUrl: sManifestUrl,
				componentName: sName,
				async: oConfig.async
			});
		}

		// 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({
				manifestUrl: getManifestUrl(sName),
				componentName: sName,
				async: oConfig.async,
				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 {
					Log.warning(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;

				};
				// 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;
		}

		function preload(sComponentName, bAsync) {

			var sController = sComponentName + '.Component',
				http2 = sap.ui.getCore().getConfiguration().getDepCache(),
				sPreloadName,
				oTransitiveDependencies,
				aLibs;

			// 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) {
						aLibs = [oTransitiveDependencies.library];
						// add all dependencies to aLibs
						Array.prototype.push.apply(aLibs, oTransitiveDependencies.dependencies);

						// load library preload for every transitive dependency
						return sap.ui.getCore().loadLibraries( aLibs, { preloadOnly: true } );
					} else {
						sPreloadName = sController.replace(/\./g, "/") + (http2 ? '-h2-preload.js' : '-preload.js'); // URN
						return sap.ui.loader._.loadJSResourceAsync(sPreloadName, true);
					}
				}

				try {
					sPreloadName = sController + '-preload'; // Module name
					sap.ui.requireSync(sPreloadName.replace(/\./g, "/"));
				} catch (e) {
					Log.warning("couldn't preload component from " + sPreloadName + ": " + ((e && e.message) || e));
				}
			} else if (bAsync) {
				return Promise.resolve();
			}
		}

		function preloadDependencies(sComponentName, oManifest, bAsync) {

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

			// lookup the resource roots and call the register API
			oManifest.defineResourceRoots();

			// 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(sap.ui.getCore().loadLibraries(aLibs, {
						async: 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 sComponentName in mComponents) {
					// filter the lazy components
					if (!mComponents[sComponentName].lazy) {
						aComponents.push(sComponentName);
					}
				}
			}

			// 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;

			if (oManifest && mOptions.createModels) {
				collect(oManifest.then(function(oManifest) {
					// Calculate configurations of preloaded models once the manifest is available
					mModelConfigs = getPreloadModelConfigsFromManifest(oManifest, oConfig.componentData, hints.cacheTokens);

					return oManifest;
				}).then(function(oManifest) {
					// Create preloaded models directly after the manifest has been loaded
					if (Object.keys(mModelConfigs.afterManifest).length > 0) {
						mModels = Component._createManifestModels(mModelConfigs.afterManifest, oManifest.getComponentName());
					}

					return oManifest;
				}));
			}

			phase1Preloads = [];

			// load any required preload bundles
			if ( Array.isArray(hints.preloadBundles) ) {
				hints.preloadBundles.forEach(function(vBundle) {
					//TODO: global jquery call found
					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);
				phase1Preloads.push(
					sap.ui.getCore().loadLibraries( libs, { preloadOnly: true } )
				);
			}

			// 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() {
					return sap.ui.getCore().loadLibraries( libs );
				});
			}
			collect( phase1Preloads );

			// preload the component itself
			if (!oManifest) {
				collect(preload(sName, true));
			} else {
				// in case of manifest first we need to load the manifest
				// to know the component name and preload the component itself
				collect(oManifest.then(function(oManifest) {
					var sComponentName = oManifest.getComponentName();

					// 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)
					if (typeof sUrl === 'string') {
						registerModulePath(sComponentName, sUrl);
					}

					// preload the component
					return preload(sComponentName, true).then(function() {
						// after preload is finished, load the i18n resource
						return oManifest._processI18n(true);
					}).then(function() {
						// after i18n resource is finished, the resource models from the manifest are loaded

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

						var aResourceModelNames = Object.keys(mModelConfigs.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) {
							function loadResourceBundle(sModelName) {
								var mModelConfig = mModelConfigs.afterPreload[sModelName];
								if (Array.isArray(mModelConfig.settings) && mModelConfig.settings.length > 0) {
									var mModelSettings = mModelConfig.settings[0]; // first argument is the config map
									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;
									}, 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 + "\"]", sComponentName);
										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 mModelConfigs.afterPreload[sModelName];
									});
								} else {
									// Can't load bundle as no settings are defined.
									// Should not happen as those models won't be part of "mModelConfigs.afterPreload"
									return Promise.resolve();
								}
							}

							// Load all ResourceBundles for all models in parallel
							return Promise.all(aResourceModelNames.map(loadResourceBundle)).then(function() {
								if (Object.keys(mModelConfigs.afterPreload).length > 0) {
									var mResourceModels = Component._createManifestModels(mModelConfigs.afterPreload, oManifest.getComponentName());
									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 (typeof Component._fnLoadComponentCallback === "function") {
						// secure configuration and manifest from manipulation
						var oConfigCopy = jQuery.extend(true, {}, oConfig);
						var oManifestCopy = jQuery.extend(true, {}, oLoadedManifest);
						// 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 {
							Component._fnLoadComponentCallback(oConfigCopy, oManifestCopy);
						} catch (oError) {
							Log.error("Callback for loading the component \"" + oManifest.getComponentName() +
								"\" run into an error. The callback was skipped and the component loading resumed.",
								oError, "sap.ui.core.Component");
						}
					}
				};
			}

			// if a hint about "used" components is given, preload those components
			if ( hints.components ) {
				jQuery.each(hints.components, function(i, vComp) {
					collect(preload(processOptions(vComp), true));
				});
			}

			// 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);
				});

				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) {
					oManifest.then(fnCallLoadComponentCallback);
				}
				return v;
			}).then(function(v) {
				Log.debug("Component.load: all promises fulfilled, then " + v);
				if (oManifest) {
					return oManifest.then(function(oLoadedManifest) {
						// 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 {
					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 pLoaded;

					// 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)) {
						pLoaded = loadManifests(oMetadata, oManifest);
					} else {
						pLoaded = loadManifests(oMetadata);
					}

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

				// Load all modules derived from "/sap.ui5" manifest entries asynchronously (if underlaying loader supports it)
				// Note: this does not load modules declared / derived from parent manifests (e.g. extension scenario)
				var aModuleNames = [];

				// lookup rootView class
				var sRootViewType;
				var oRootView = oManifest.getEntry("/sap.ui5/rootView");
				if (typeof oRootView === "string") {
					// String as rootView defaults to ViewType XML
					// See: UIComponent#createContent and UIComponentMetadata#_convertLegacyMetadata
					sRootViewType = "XML";
				} else if (oRootView && typeof oRootView === "object" && oRootView.type) {
					sRootViewType = oRootView.type;
				}
				if (sRootViewType && ViewType[sRootViewType]) {
					var sViewClass = "sap/ui/core/mvc/" + ViewType[sRootViewType] + "View";
					aModuleNames.push(sViewClass);
				}

				// lookup router class
				var oRouting = oManifest.getEntry("/sap.ui5/routing");
				if (oRouting && oRouting.routes) {
					var sRouterClass = oManifest.getEntry("/sap.ui5/routing/config/routerClass") || "sap.ui.core.routing.Router";
					var sRouterClassModule = sRouterClass.replace(/\./g, "/");
					aModuleNames.push(sRouterClassModule);
				}

				// lookup model classes
				var mManifestModels = jQuery.extend(true, {}, oManifest.getEntry("/sap.ui5/models"));
				var mManifestDataSources = jQuery.extend(true, {}, oManifest.getEntry("/sap.app/dataSources"));
				var mAllModelConfigurations = Component._createManifestModelConfigurations({
					models: mManifestModels,
					dataSources: mManifestDataSources,
					manifest: oManifest,
					cacheTokens: hints.cacheTokens
				});
				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) {
					return Promise.all(aModuleNames.map(function(sModuleName) {
						// All modules are required separately to have a better error logging.
						// This "preloading" is done for optimization to enable async loading
						// in case the underlaying loader supports it. If loading fails, the component
						// should still be created which might fail once the required module is actually used / loaded
						return new Promise(function(resolve, reject) {
							var bResolved = false;
							function logErrorAndResolve(err) {
								if (bResolved) {
									return;
								}
								Log.warning("Can not preload module \"" + sModuleName + "\". " +
									"This will most probably cause an error once the module is used later on.",
									oManifest.getComponentName(), "sap.ui.core.Component");
								Log.warning(err);

								bResolved = true;
								resolve();
							}
							sap.ui.require([sModuleName], resolve, logErrorAndResolve);
						});
					})).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;

			});

		}

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

		// synchronously load the controller class, prepare and return it
		return prepareControllerClass(
			sap.ui.requireSync( getControllerModuleName() )
		);
	}
function loadComponent(oConfig, mOptions) {

		var sName = oConfig.name,
			sUrl = oConfig.url,
			oConfiguration = sap.ui.getCore().getConfiguration(),
			bComponentPreload = /^(sync|async)$/.test(oConfiguration.getComponentPreload()),
			vManifest = oConfig.manifest,
			bManifestFirst,
			sManifestUrl,
			oManifest,
			mModels,
			mModelConfigs,
			fnCallLoadComponentCallback;

		function createSanitizedManifest( oRawManifestJSON, mOptions ) {
			var oManifest = new Manifest( JSON.parse(JSON.stringify(oRawManifestJSON)), mOptions );
			return oConfig.async ? Promise.resolve(oManifest) : oManifest;
		}

		// 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);

		if ( vManifest === undefined ) {
			// no manifest property set, evaluate legacy properties
			bManifestFirst = oConfig.manifestFirst === undefined ? oConfiguration.getManifestFirst() : !!oConfig.manifestFirst;
			sManifestUrl = oConfig.manifestUrl;
			// oManifest = undefined;
		} else {
			// 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}) : 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({
				manifestUrl: sManifestUrl,
				componentName: sName,
				async: oConfig.async
			});
		}

		// 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({
				manifestUrl: getManifestUrl(sName),
				componentName: sName,
				async: oConfig.async,
				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 {
					Log.warning(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;

				};
				// 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;
		}

		function preload(sComponentName, bAsync) {

			var sController = sComponentName + '.Component',
				http2 = sap.ui.getCore().getConfiguration().getDepCache(),
				sPreloadName,
				oTransitiveDependencies,
				aLibs;

			// 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) {
						aLibs = [oTransitiveDependencies.library];
						// add all dependencies to aLibs
						Array.prototype.push.apply(aLibs, oTransitiveDependencies.dependencies);

						// load library preload for every transitive dependency
						return sap.ui.getCore().loadLibraries( aLibs, { preloadOnly: true } );
					} else {
						sPreloadName = sController.replace(/\./g, "/") + (http2 ? '-h2-preload.js' : '-preload.js'); // URN
						return sap.ui.loader._.loadJSResourceAsync(sPreloadName, true);
					}
				}

				try {
					sPreloadName = sController + '-preload'; // Module name
					sap.ui.requireSync(sPreloadName.replace(/\./g, "/"));
				} catch (e) {
					Log.warning("couldn't preload component from " + sPreloadName + ": " + ((e && e.message) || e));
				}
			} else if (bAsync) {
				return Promise.resolve();
			}
		}

		function preloadDependencies(sComponentName, oManifest, bAsync) {

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

			// lookup the resource roots and call the register API
			oManifest.defineResourceRoots();

			// 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(sap.ui.getCore().loadLibraries(aLibs, {
						async: 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 sComponentName in mComponents) {
					// filter the lazy components
					if (!mComponents[sComponentName].lazy) {
						aComponents.push(sComponentName);
					}
				}
			}

			// 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;

			if (oManifest && mOptions.createModels) {
				collect(oManifest.then(function(oManifest) {
					// Calculate configurations of preloaded models once the manifest is available
					mModelConfigs = getPreloadModelConfigsFromManifest(oManifest, oConfig.componentData, hints.cacheTokens);

					return oManifest;
				}).then(function(oManifest) {
					// Create preloaded models directly after the manifest has been loaded
					if (Object.keys(mModelConfigs.afterManifest).length > 0) {
						mModels = Component._createManifestModels(mModelConfigs.afterManifest, oManifest.getComponentName());
					}

					return oManifest;
				}));
			}

			phase1Preloads = [];

			// load any required preload bundles
			if ( Array.isArray(hints.preloadBundles) ) {
				hints.preloadBundles.forEach(function(vBundle) {
					//TODO: global jquery call found
					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);
				phase1Preloads.push(
					sap.ui.getCore().loadLibraries( libs, { preloadOnly: true } )
				);
			}

			// 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() {
					return sap.ui.getCore().loadLibraries( libs );
				});
			}
			collect( phase1Preloads );

			// preload the component itself
			if (!oManifest) {
				collect(preload(sName, true));
			} else {
				// in case of manifest first we need to load the manifest
				// to know the component name and preload the component itself
				collect(oManifest.then(function(oManifest) {
					var sComponentName = oManifest.getComponentName();

					// 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)
					if (typeof sUrl === 'string') {
						registerModulePath(sComponentName, sUrl);
					}

					// preload the component
					return preload(sComponentName, true).then(function() {
						// after preload is finished, load the i18n resource
						return oManifest._processI18n(true);
					}).then(function() {
						// after i18n resource is finished, the resource models from the manifest are loaded

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

						var aResourceModelNames = Object.keys(mModelConfigs.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) {
							function loadResourceBundle(sModelName) {
								var mModelConfig = mModelConfigs.afterPreload[sModelName];
								if (Array.isArray(mModelConfig.settings) && mModelConfig.settings.length > 0) {
									var mModelSettings = mModelConfig.settings[0]; // first argument is the config map
									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;
									}, 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 + "\"]", sComponentName);
										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 mModelConfigs.afterPreload[sModelName];
									});
								} else {
									// Can't load bundle as no settings are defined.
									// Should not happen as those models won't be part of "mModelConfigs.afterPreload"
									return Promise.resolve();
								}
							}

							// Load all ResourceBundles for all models in parallel
							return Promise.all(aResourceModelNames.map(loadResourceBundle)).then(function() {
								if (Object.keys(mModelConfigs.afterPreload).length > 0) {
									var mResourceModels = Component._createManifestModels(mModelConfigs.afterPreload, oManifest.getComponentName());
									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 (typeof Component._fnLoadComponentCallback === "function") {
						// secure configuration and manifest from manipulation
						var oConfigCopy = jQuery.extend(true, {}, oConfig);
						var oManifestCopy = jQuery.extend(true, {}, oLoadedManifest);
						// 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 {
							Component._fnLoadComponentCallback(oConfigCopy, oManifestCopy);
						} catch (oError) {
							Log.error("Callback for loading the component \"" + oManifest.getComponentName() +
								"\" run into an error. The callback was skipped and the component loading resumed.",
								oError, "sap.ui.core.Component");
						}
					}
				};
			}

			// if a hint about "used" components is given, preload those components
			if ( hints.components ) {
				jQuery.each(hints.components, function(i, vComp) {
					collect(preload(processOptions(vComp), true));
				});
			}

			// 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);
				});

				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) {
					oManifest.then(fnCallLoadComponentCallback);
				}
				return v;
			}).then(function(v) {
				Log.debug("Component.load: all promises fulfilled, then " + v);
				if (oManifest) {
					return oManifest.then(function(oLoadedManifest) {
						// 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 {
					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 pLoaded;

					// 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)) {
						pLoaded = loadManifests(oMetadata, oManifest);
					} else {
						pLoaded = loadManifests(oMetadata);
					}

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

				// Load all modules derived from "/sap.ui5" manifest entries asynchronously (if underlaying loader supports it)
				// Note: this does not load modules declared / derived from parent manifests (e.g. extension scenario)
				var aModuleNames = [];

				// lookup rootView class
				var sRootViewType;
				var oRootView = oManifest.getEntry("/sap.ui5/rootView");
				if (typeof oRootView === "string") {
					// String as rootView defaults to ViewType XML
					// See: UIComponent#createContent and UIComponentMetadata#_convertLegacyMetadata
					sRootViewType = "XML";
				} else if (oRootView && typeof oRootView === "object" && oRootView.type) {
					sRootViewType = oRootView.type;
				}
				if (sRootViewType && ViewType[sRootViewType]) {
					var sViewClass = "sap/ui/core/mvc/" + ViewType[sRootViewType] + "View";
					aModuleNames.push(sViewClass);
				}

				// lookup router class
				var oRouting = oManifest.getEntry("/sap.ui5/routing");
				if (oRouting && oRouting.routes) {
					var sRouterClass = oManifest.getEntry("/sap.ui5/routing/config/routerClass") || "sap.ui.core.routing.Router";
					var sRouterClassModule = sRouterClass.replace(/\./g, "/");
					aModuleNames.push(sRouterClassModule);
				}

				// lookup model classes
				var mManifestModels = jQuery.extend(true, {}, oManifest.getEntry("/sap.ui5/models"));
				var mManifestDataSources = jQuery.extend(true, {}, oManifest.getEntry("/sap.app/dataSources"));
				var mAllModelConfigurations = Component._createManifestModelConfigurations({
					models: mManifestModels,
					dataSources: mManifestDataSources,
					manifest: oManifest,
					cacheTokens: hints.cacheTokens
				});
				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) {
					return Promise.all(aModuleNames.map(function(sModuleName) {
						// All modules are required separately to have a better error logging.
						// This "preloading" is done for optimization to enable async loading
						// in case the underlaying loader supports it. If loading fails, the component
						// should still be created which might fail once the required module is actually used / loaded
						return new Promise(function(resolve, reject) {
							var bResolved = false;
							function logErrorAndResolve(err) {
								if (bResolved) {
									return;
								}
								Log.warning("Can not preload module \"" + sModuleName + "\". " +
									"This will most probably cause an error once the module is used later on.",
									oManifest.getComponentName(), "sap.ui.core.Component");
								Log.warning(err);

								bResolved = true;
								resolve();
							}
							sap.ui.require([sModuleName], resolve, logErrorAndResolve);
						});
					})).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;

			});

		}

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

		// synchronously load the controller class, prepare and return it
		return prepareControllerClass(
			sap.ui.requireSync( getControllerModuleName() )
		);
	}
function loadComponent ( oConfig , mOptions ) { var sName = oConfig . name , sUrl = oConfig . url , oConfiguration = sap . ui . getCore ( ) . getConfiguration ( ) , bComponentPreload = / ^(sync|async)$ / . test ( oConfiguration . getComponentPreload ( ) ) , vManifest = oConfig . manifest , bManifestFirst , sManifestUrl , oManifest , mModels , mModelConfigs , fnCallLoadComponentCallback ; function createSanitizedManifest ( oRawManifestJSON , mOptions ) { var oManifest = new Manifest ( JSON . parse ( JSON . stringify ( oRawManifestJSON ) ) , mOptions ) ; return oConfig . async ? Promise . resolve ( oManifest ) : oManifest ; } // 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 ) ; if ( vManifest === undefined ) { // no manifest property set, evaluate legacy properties bManifestFirst = oConfig . manifestFirst === undefined ? oConfiguration . getManifestFirst ( ) : ! ! oConfig . manifestFirst ; sManifestUrl = oConfig . manifestUrl ; // oManifest = undefined; } else { // 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 } ) : 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 ( { manifestUrl : sManifestUrl , componentName : sName , async : oConfig . async } ) ; } // 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 ( { manifestUrl : getManifestUrl ( sName ) , componentName : sName , async : oConfig . async , 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 { Log . warning ( 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 ; } ; // 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 ; } function preload ( sComponentName , bAsync ) { var sController = sComponentName + '.Component' , http2 = sap . ui . getCore ( ) . getConfiguration ( ) . getDepCache ( ) , sPreloadName , oTransitiveDependencies , aLibs ; // 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 ) { aLibs = [ oTransitiveDependencies . library ] ; // add all dependencies to aLibs Array . prototype . push . apply ( aLibs , oTransitiveDependencies . dependencies ) ; // load library preload for every transitive dependency return sap . ui . getCore ( ) . loadLibraries ( aLibs , { preloadOnly : true } ) ; } else { sPreloadName = sController . replace ( / \. / g , "/" ) + ( http2 ? '-h2-preload.js' : '-preload.js' ) ; // URN return sap . ui . loader . _ . loadJSResourceAsync ( sPreloadName , true ) ; } } try { sPreloadName = sController + '-preload' ; // Module name sap . ui . requireSync ( sPreloadName . replace ( / \. / g , "/" ) ) ; } catch ( e ) { Log . warning ( "couldn't preload component from " + sPreloadName + ": " + ( ( e && e . message ) || e ) ) ; } } else if ( bAsync ) { return Promise . resolve ( ) ; } } function preloadDependencies ( sComponentName , oManifest , bAsync ) { var aPromises = [ ] ; var fnCollect = bAsync ? function ( oPromise ) { aPromises . push ( oPromise ) ; } : function ( ) { } ; // lookup the resource roots and call the register API oManifest . defineResourceRoots ( ) ; // 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 ( sap . ui . getCore ( ) . loadLibraries ( aLibs , { async : 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 sComponentName in mComponents ) { // filter the lazy components if ( ! mComponents [ sComponentName ] . lazy ) { aComponents . push ( sComponentName ) ; } } } // 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 ; if ( oManifest && mOptions . createModels ) { collect ( oManifest . then ( function ( oManifest ) { // Calculate configurations of preloaded models once the manifest is available mModelConfigs = getPreloadModelConfigsFromManifest ( oManifest , oConfig . componentData , hints . cacheTokens ) ; return oManifest ; } ) . then ( function ( oManifest ) { // Create preloaded models directly after the manifest has been loaded if ( Object . keys ( mModelConfigs . afterManifest ) . length > 0 ) { mModels = Component . _createManifestModels ( mModelConfigs . afterManifest , oManifest . getComponentName ( ) ) ; } return oManifest ; } ) ) ; } phase1Preloads = [ ] ; // load any required preload bundles if ( Array . isArray ( hints . preloadBundles ) ) { hints . preloadBundles . forEach ( function ( vBundle ) { //TODO: global jquery call found 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 ) ; phase1Preloads . push ( sap . ui . getCore ( ) . loadLibraries ( libs , { preloadOnly : true } ) ) ; } // 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 ( ) { return sap . ui . getCore ( ) . loadLibraries ( libs ) ; } ) ; } collect ( phase1Preloads ) ; // preload the component itself if ( ! oManifest ) { collect ( preload ( sName , true ) ) ; } else { // in case of manifest first we need to load the manifest // to know the component name and preload the component itself collect ( oManifest . then ( function ( oManifest ) { var sComponentName = oManifest . getComponentName ( ) ; // 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) if ( typeof sUrl === 'string' ) { registerModulePath ( sComponentName , sUrl ) ; } // preload the component return preload ( sComponentName , true ) . then ( function ( ) { // after preload is finished, load the i18n resource return oManifest . _processI18n ( true ) ; } ) . then ( function ( ) { // after i18n resource is finished, the resource models from the manifest are loaded if ( ! mOptions . createModels ) { return null ; } var aResourceModelNames = Object . keys ( mModelConfigs . 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 ) { function loadResourceBundle ( sModelName ) { var mModelConfig = mModelConfigs . afterPreload [ sModelName ] ; if ( Array . isArray ( mModelConfig . settings ) && mModelConfig . settings . length > 0 ) { var mModelSettings = mModelConfig . settings [ 0 ] ; // first argument is the config map 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 ; } , 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 + "\"]" , sComponentName ) ; 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 mModelConfigs . afterPreload [ sModelName ] ; } ) ; } else { // Can't load bundle as no settings are defined. // Should not happen as those models won't be part of "mModelConfigs.afterPreload" return Promise . resolve ( ) ; } } // Load all ResourceBundles for all models in parallel return Promise . all ( aResourceModelNames . map ( loadResourceBundle ) ) . then ( function ( ) { if ( Object . keys ( mModelConfigs . afterPreload ) . length > 0 ) { var mResourceModels = Component . _createManifestModels ( mModelConfigs . afterPreload , oManifest . getComponentName ( ) ) ; 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 ( typeof Component . _fnLoadComponentCallback === "function" ) { // secure configuration and manifest from manipulation var oConfigCopy = jQuery . extend ( true , { } , oConfig ) ; var oManifestCopy = jQuery . extend ( true , { } , oLoadedManifest ) ; // 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 { Component . _fnLoadComponentCallback ( oConfigCopy , oManifestCopy ) ; } catch ( oError ) { Log . error ( "Callback for loading the component \"" + oManifest . getComponentName ( ) + "\" run into an error. The callback was skipped and the component loading resumed." , oError , "sap.ui.core.Component" ) ; } } } ; } // if a hint about "used" components is given, preload those components if ( hints . components ) { jQuery . each ( hints . components , function ( i , vComp ) { collect ( preload ( processOptions ( vComp ) , true ) ) ; } ) ; } // 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 ) ; } ) ; 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 ) { oManifest . then ( fnCallLoadComponentCallback ) ; } return v ; } ) . then ( function ( v ) { Log . debug ( "Component.load: all promises fulfilled, then " + v ) ; if ( oManifest ) { return oManifest . then ( function ( oLoadedManifest ) { // 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 { 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 pLoaded ; // 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 ) ) { pLoaded = loadManifests ( oMetadata , oManifest ) ; } else { pLoaded = loadManifests ( oMetadata ) ; } return pLoaded . then ( function ( ) { // prepare the loaded class and resolve with it return prepareControllerClass ( oClass ) ; } ) ; } ) ; } ) . then ( function ( oControllerClass ) { if ( ! oManifest ) { return oControllerClass ; } // Load all modules derived from "/sap.ui5" manifest entries asynchronously (if underlaying loader supports it) // Note: this does not load modules declared / derived from parent manifests (e.g. extension scenario) var aModuleNames = [ ] ; // lookup rootView class var sRootViewType ; var oRootView = oManifest . getEntry ( "/sap.ui5/rootView" ) ; if ( typeof oRootView === "string" ) { // String as rootView defaults to ViewType XML // See: UIComponent#createContent and UIComponentMetadata#_convertLegacyMetadata sRootViewType = "XML" ; } else if ( oRootView && typeof oRootView === "object" && oRootView . type ) { sRootViewType = oRootView . type ; } if ( sRootViewType && ViewType [ sRootViewType ] ) { var sViewClass = "sap/ui/core/mvc/" + ViewType [ sRootViewType ] + "View" ; aModuleNames . push ( sViewClass ) ; } // lookup router class var oRouting = oManifest . getEntry ( "/sap.ui5/routing" ) ; if ( oRouting && oRouting . routes ) { var sRouterClass = oManifest . getEntry ( "/sap.ui5/routing/config/routerClass" ) || "sap.ui.core.routing.Router" ; var sRouterClassModule = sRouterClass . replace ( / \. / g , "/" ) ; aModuleNames . push ( sRouterClassModule ) ; } // lookup model classes var mManifestModels = jQuery . extend ( true , { } , oManifest . getEntry ( "/sap.ui5/models" ) ) ; var mManifestDataSources = jQuery . extend ( true , { } , oManifest . getEntry ( "/sap.app/dataSources" ) ) ; var mAllModelConfigurations = Component . _createManifestModelConfigurations ( { models : mManifestModels , dataSources : mManifestDataSources , manifest : oManifest , cacheTokens : hints . cacheTokens } ) ; 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 ) { return Promise . all ( aModuleNames . map ( function ( sModuleName ) { // All modules are required separately to have a better error logging. // This "preloading" is done for optimization to enable async loading // in case the underlaying loader supports it. If loading fails, the component // should still be created which might fail once the required module is actually used / loaded return new Promise ( function ( resolve , reject ) { var bResolved = false ; function logErrorAndResolve ( err ) { if ( bResolved ) { return ; } Log . warning ( "Can not preload module \"" + sModuleName + "\". " + "This will most probably cause an error once the module is used later on." , oManifest . getComponentName ( ) , "sap.ui.core.Component" ) ; Log . warning ( err ) ; bResolved = true ; resolve ( ) ; } sap . ui . require ( [ sModuleName ] , resolve , logErrorAndResolve ) ; } ) ; } ) ) . 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 ; } ) ; } if ( oManifest ) { preloadDependencies ( sName , oManifest ) ; } preload ( sName ) ; // synchronously load the controller class, prepare and return it return prepareControllerClass ( sap . ui . requireSync ( getControllerModuleName ( ) ) ) ; }
Internal loading method to decouple "sap.ui.component" / "sap.ui.component.load".

@param {object} oConfig see <code>sap.ui.component</code> / <code>sap.ui.component.load</code>
@param {object} mOptions internal loading configurations
@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} the constructor of the Component class or a Promise that will be fulfilled with the same

@private
Internal loading method to decouple sap . ui . component / sap . ui . component . load .
Loads a component from the given manifest