function createRegularControls(node, oClass, pRequireContext, oClosestBinding, oConfig) {
			var ns = node.namespaceURI,
				mSettings = {},
				mAggregationsWithExtensionPoints = {},
				sStyleClasses = "",
				aCustomData = [],
				mCustomSettings = null,
				sSupportData = null,
				// for stashed nodes we need to ignore the following type of attributes:
				// 1. Aggregations
				//    -> might lead to the creation of bindings; also the aggregation template is removed anyway
				// 2. Associations
				//    -> might refer to controls inside the node, which have been removed earlier when the StashedControl was created
				// 3. Events
				bStashedControl = node.getAttribute("stashed") === "true",
				bRootArea = oConfig && oConfig.rootArea,
				bViewRootNode = oConfig && oConfig.rootNode,
				oRequireContext;

			// remove stashed attribute as it is an unknown property.
			if (!bEnrichFullIds) {
				node.removeAttribute("stashed");
			}

			if (!oClass) {
				return SyncPromise.resolve([]);
			}

			if (bViewRootNode) {
				// although the 'id' isn't needed for mSettings object because the view instance is already created,
				// it's still needed for the closestBinding info object
				mSettings.id = oView.getId();
			}

			var oMetadata = oClass.getMetadata();
			var mKnownSettings = oMetadata.getAllSettings();

			var pSelfRequireContext = !bRootArea ? parseAndLoadRequireContext(node, bAsync) : undefined;

			// create new promise only when the current node has core:require defined
			if (pSelfRequireContext) {
				pRequireContext = SyncPromise.all([pRequireContext, pSelfRequireContext])
					.then(function(aRequiredModules) {
						return Object.assign({}, aRequiredModules[0], aRequiredModules[1]);
					});
			}

			pRequireContext = pRequireContext.then(function(oRequireModules) {
				if (isEmptyObject(oRequireModules)) {
					oRequireModules = null;
				}

				oRequireContext = oRequireModules;

				// [ASYNC only]: In async mode we instruct the BindingParser to resolve the Types asynchronously.
				//               The function "parseScalarType()" will then collect the Promises from the BindingParser,
				//               so that we can then wait for them later on here.
				var aTypePromises = bAsync ? [] : undefined;

				if (!bEnrichFullIds) {
					for (var i = 0; i < node.attributes.length; i++) {
						var attr = node.attributes[i],
							sName = attr.name,
							sNamespace = attr.namespaceURI,
							oInfo = mKnownSettings[sName],
							sValue = attr.value;

						if (bViewRootNode && VIEW_SPECIAL_ATTRIBUTES.includes(sName)) {
							continue;
						}

						// apply the value of the attribute to a
						//   * property,
						//   * association (id of the control),
						//   * event (name of the function in the controller) or
						//   * CustomData element (namespace-prefixed attribute)

						if (sName === "id" && !bViewRootNode) { // "id" attribute on View's root node isn't supported
							// special handling for ID
							mSettings[sName] = getId(oView, node, sValue);

						} else if (sName === "class") {
							// special handling for CSS classes, which will be added via addStyleClass()
							sStyleClasses += sValue;

						} else if (sName === "viewName") {
							mSettings[sName] = sValue;

						} else if (sName === "fragmentName") {
							mSettings[sName] = sValue;
							mSettings['containingView'] = oView._oContainingView;

						} else if ((sName === "binding" && !oInfo) || sName === 'objectBindings' ) {
							if (!bStashedControl) {
								var oBindingInfo = BindingInfo.parse(sValue, oView._oContainingView.oController);
								// TODO reject complex bindings, types, formatters; enable 'parameters'?
								if (oBindingInfo) {
									mSettings.objectBindings = mSettings.objectBindings || {};
									mSettings.objectBindings[oBindingInfo.model || undefined] = oBindingInfo;
								}
							}
						} else if (sName === 'metadataContexts') {
							if (!bStashedControl) {
								var mMetaContextsInfo = null;

								try {
									mMetaContextsInfo = XMLTemplateProcessor._calculatedModelMapping(sValue, oView._oContainingView.oController, true);
								} catch (e) {
									future.errorThrows(`Failed to parse metadataContexts in view "${oView}"`,  { cause: e });
								}

								if (mMetaContextsInfo) {
									mSettings.metadataContexts = mMetaContextsInfo;

									if (XMLTemplateProcessor._preprocessMetadataContexts) {
										XMLTemplateProcessor._preprocessMetadataContexts(oClass.getMetadata().getName(), mSettings, oView._oContainingView.oController);
									}
								}
							}
						} else if (sName.indexOf(":") > -1) {  // namespace-prefixed attribute found
							sNamespace = attr.namespaceURI;
							if (sNamespace === CUSTOM_DATA_NAMESPACE) {  // CustomData attribute found
								var sLocalName = localName(attr);
								aCustomData.push(new CustomData({
									key: sLocalName,
									value: parseScalarType("any", sValue, sLocalName, oView._oContainingView.oController, oRequireModules, aTypePromises)
								}));
							} else if (sNamespace === SUPPORT_INFO_NAMESPACE) {
								sSupportData = sValue;
							} else if (sNamespace && sNamespace.startsWith(PREPROCESSOR_NAMESPACE_PREFIX)) {
								Log.debug(oView + ": XMLView parser ignored preprocessor attribute '" + sName + "' (value: '" + sValue + "')");
							} else if (sNamespace === UI5_INTERNAL_NAMESPACE && localName(attr) === "invisible") {
								oInfo = mKnownSettings.visible;
								if (oInfo && oInfo._iKind === 0 && oInfo.type === "boolean") {
									mSettings.visible = false;
								}
							} else if (sNamespace === CORE_NAMESPACE
									   || sNamespace === UI5_INTERNAL_NAMESPACE
									   || sName.startsWith("xmlns:") ) {
								// ignore namespaced attributes that are handled by the XMLTP itself
							} else {
								// all other namespaced attributes are kept as custom settings
								if (!mCustomSettings) {
									mCustomSettings = {};
								}
								if (!mCustomSettings.hasOwnProperty(attr.namespaceURI)) {
									mCustomSettings[attr.namespaceURI] = {};
								}
								mCustomSettings[attr.namespaceURI][localName(attr)] = attr.nodeValue;
								Log.debug(oView + ": XMLView parser encountered unknown attribute '" + sName + "' (value: '" + sValue + "') with unknown namespace, stored as sap-ui-custom-settings of customData");
								// TODO: here XMLView could check for namespace handlers registered by the application for this namespace which could modify mSettings according to their interpretation of the attribute
							}

						} else if (oInfo && oInfo._iKind === 0 /* PROPERTY */ ) {
							// other PROPERTY
							mSettings[sName] = parseScalarType(oInfo.type, sValue, sName, oView._oContainingView.oController, oRequireModules, aTypePromises, mAdditionalBindableValues);
							// FIXME: ._oContainingView might be the original Fragment for an extension fragment or a fragment in a fragment - so it has no controller bit ITS containingView.

						} else if (oInfo && oInfo._iKind === 1 /* SINGLE_AGGREGATION */ && oInfo.altTypes ) {
							// AGGREGATION with scalar type (altType)
							if (!bStashedControl) {
								mSettings[sName] = parseScalarType(oInfo.altTypes[0], sValue, sName, oView._oContainingView.oController, oRequireModules, null, mAdditionalBindableValues);
							}
							} else if (oInfo && oInfo._iKind === 2 /* MULTIPLE_AGGREGATION */ ) {
							if (!bStashedControl) {
								var oBindingInfo = BindingInfo.parse(sValue, oView._oContainingView.oController, false, false, false, false, oRequireModules);
								if ( oBindingInfo ) {
									mSettings[sName] = oBindingInfo;
								} else {
									future.errorThrows("" + oView + ": aggregations with cardinality 0..n specifies a non valid BindingInfo (wrong value: " + sName + "='" + sValue + "')");
								}
							}

						} else if (oInfo && oInfo._iKind === 3 /* SINGLE_ASSOCIATION */ ) {
							// ASSOCIATION
							if (!bStashedControl) {
								mSettings[sName] = createId(sValue); // use the value as ID
							}

						} else if (oInfo && oInfo._iKind === 4 /* MULTIPLE_ASSOCIATION */ ) {
							// we support "," and " " to separate IDs and filter out empty IDs
							if (!bStashedControl) {
								mSettings[sName] = sValue.split(/[\s,]+/g).filter(identity).map(createId);
							}

						} else if (oInfo && oInfo._iKind === 5 /* EVENT */ ) {
							// EVENT
							if (!bStashedControl) {
								var aEventHandlers = [];

								EventHandlerResolver.parse(sValue).forEach(function (sEventHandler) { // eslint-disable-line no-loop-func
									var vEventHandler = EventHandlerResolver.resolveEventHandler(sEventHandler, oView._oContainingView.oController, oRequireModules); // TODO: can this be made async? (to avoid the hard resolver dependency)
									if (vEventHandler) {
										aEventHandlers.push(vEventHandler);
									} else  {
										future.warningThrows("" + oView + ": event handler function \"" + sEventHandler + "\" is not a function or does not exist in the controller.");
									}
								});

								if (aEventHandlers.length) {
									mSettings[sName] = aEventHandlers;
								}
							}
						} else if (oInfo && oInfo._iKind === -1) {
							// SPECIAL SETTING - currently only allowed for:
							// - "async"
							// - "type" (value must be in the ViewType enum)
							if (oMetadata.isA("sap.ui.core.mvc.View") && (sName == "async" || (sName == "type" && ViewType[sValue]))) {
								mSettings[sName] = parseScalarType(oInfo.type, sValue, sName, oView._oContainingView.oController, oRequireModules);
							} else {
								future.warningThrows("" + oView + ": setting '" + sName + "' for class " + oMetadata.getName() + " (value:'" + sValue + "') is not supported");
							}
						} else {
							future.assertThrows(sName === 'xmlns', oView + ": encountered unknown setting '" + sName + "' for class " + oMetadata.getName() + " (value:'" + sValue + "')");
							/** @deprecated since 1.120.0 */
							if (XMLTemplateProcessor._supportInfo) {
								XMLTemplateProcessor._supportInfo({
									context : node,
									env : {
										caller:"createRegularControls",
										error: true,
										info: "unknown setting '" + sName + "' for class " + oMetadata.getName()
									}
								});
							}
						}
					}
					//add custom settings as custom data "sap-ui-custom-settings"
					if (mCustomSettings) {
						aCustomData.push(new CustomData({
							key:"sap-ui-custom-settings",
							value: mCustomSettings
						}));
					}
					if (aCustomData.length > 0) {
						mSettings.customData = aCustomData;
					}
				}

				// aTypePromises is only filled when we run in async mode, so we don't need to use SyncPromise here
				if (Array.isArray(aTypePromises)) {
					return Promise.all(aTypePromises).then(function() { return oRequireModules; });
				}

				return oRequireModules;
			}).catch(function(oError) {
				// Errors caught here are expected UI5 issues, e.g. DataType errors, broken BindingSyntax, missing event handler functions etc.
				// we enrich the error message with XML information, e.g. the node causing the issue
				if (!oError.isEnriched) {
					// Logging the error like this cuts away the stack trace,
					// but provides better information for applications.
					// For Framework debugging, we would have to look at the error object anyway.
					oError = new Error(createErrorInfo(node, oError));
					oError.isEnriched = true;

					// TODO: Can be enriched with additional info for a support rule (not yet implemented)
					Log.error(oError);
				}

				/**
				 * @ui5-transform-hint replace-local false
				 */
				const bSequentialLegacyMode = oView._sProcessingMode === XMLProcessingMode.SequentialLegacy;

				// [COMPATIBILITY]
				// sync: we just log the error and keep on processing
				// asnyc: throw the error, so the parseTemplate Promise will reject
				if (bAsync && !bSequentialLegacyMode) {
					throw oError;
				}
			});

			/**
			 * The way how handleChildren works determines parallel or sequential processing
			 *
			 * @return {Promise} resolving to an array with 0..n controls created from a node
			 * @private
			 */
			// the actual handleChildren function depends on the processing mode
			var handleChildren = getHandleChildrenStrategy(handleChild, bAsync);

			/**
			 * @return {Promise} resolving to an array with 0..n controls created from a node
			 * @private
			 */
			function handleChild(node, childNode, mOptions) {
				var oAggregation = mOptions.aggregation,
					mAggregations = mOptions.allAggregations,
					pRequireContext = mOptions.chain,
					oClosestBinding = mOptions.closestBinding,
					oConfig = mOptions.config,
					oNamedAggregation,
					fnCreateStashedControl;

				// inspect only element nodes
				if (childNode.nodeType === 1 /* ELEMENT_NODE */) {

					if (childNode.namespaceURI === XML_COMPOSITE_NAMESPACE) {
						mSettings[localName(childNode)] = childNode.querySelector("*");
						return undefined;
					}
					// check for a named aggregation (must have the same namespace as the parent and an aggregation with the same name must exist)
					oNamedAggregation = childNode.namespaceURI === ns && mAggregations && mAggregations[localName(childNode)];

					if (oNamedAggregation) {
						// the children of the current childNode are aggregated controls (or HTML) below the named aggregation
						return handleChildren(childNode, {
							aggregation: oNamedAggregation,
							allAggregations: null,
							chain: pRequireContext,
							closestBinding: oClosestBinding,
							config: oConfig
						});
					} else if (oAggregation) {
						// TODO consider moving this to a place where HTML and SVG nodes can be handled properly
						// create a StashedControl for inactive controls, which is not placed in an aggregation
						if (childNode.getAttribute("stashed") === "true" && !bEnrichFullIds) {
							var oStashedNode = childNode;
							// clone the node and remove all descendants
							childNode = childNode.cloneNode();
							// remove stashed attribute as it is an unknown property.
							oStashedNode.removeAttribute("stashed");
							fnCreateStashedControl = function() {
								var sControlId = getId(oView, childNode);

								StashedControlSupport.createStashedControl({
									wrapperId: sControlId,
									fnCreate: function(bSync) {
										var bPrevAsync = bAsync;

										/**
										 * To stay compatible with legacy factories in 1.x, if the view was originally created sync,
										 * we don't switch to async processing here, even if the unstash() is called async.
										 * @deprecated
										 */
										if (bAsync === false) {
											bSync = true;
										}

										// temporarily switch the stashed subtree to async=false in case the unstash() operation is triggered sync.
										// the scoped var bAsync applies to everything contained in this view, the original value is restored after the unstash operation
										bAsync = !bSync;

										try {
											setUI5Attribute(oStashedNode, "unstash");
											let vUnstashedControl = handleChild(node, oStashedNode, {
												aggregation: oAggregation,
												allAggregations: mAggregations,
												chain: SyncPromise.resolve(oRequireContext),
												closestBinding: oClosestBinding
											});
											/**
											 * @deprecated
											 */
											if (bSync) {
												vUnstashedControl = vUnstashedControl.unwrap();
											}
											return vUnstashedControl;
										} finally {
											bAsync = bPrevAsync;
										}
									}
								});
							};

							scopedRunWithOwner(fnCreateStashedControl);

							// ...and mark the stashed node as invisible.
							// The original visibility value is still scoped in the clone (visible could be bound, yet stashed controls are never visible)
							childNode.removeAttribute("visible");
							setUI5Attribute(childNode, "invisible");
						}

						if ( mSettings[oAggregation.name] &&
							// whether the created controls will be the template for a list binding
							typeof mSettings[oAggregation.name].path === "string") {
							oClosestBinding = {
								aggregation: oAggregation.name,
								id: mSettings.id
							};

							// mark that the content aggregation of the View node is bound
							if (bViewRootNode && oAggregation.name === "content") {
								oConfig = oConfig || {};
								oConfig.contentBound = true;
							}
						}

						// child node name does not equal an aggregation name,
						// so this child must be a control (or HTML) which is aggregated below the DEFAULT aggregation
						return createControls(childNode, pRequireContext, oClosestBinding, oAggregation, oConfig).then(function(aControls) {
							for (var j = 0; j < aControls.length; j++) {
								var oControl = aControls[j];
								// append the child to the aggregation
								var name = oAggregation.name;

								// oControl is an ExtensionPoint placeholder
								// only in Flexibility scenario if an ExtensionProvider is given!
								if (oControl._isExtensionPoint) {
									if (!mSettings[name]) {
										mSettings[name] = [];
									}

									var aExtensionPointList = mAggregationsWithExtensionPoints[name];
									if (!aExtensionPointList) {
										aExtensionPointList = mAggregationsWithExtensionPoints[name] = [];
									}
									// if the aggregation already exists we get the
									oControl.index = mSettings[name].length;
									oControl.aggregationName = name;
									oControl.closestAggregationBindingCarrier = oClosestBinding && oClosestBinding.id; // TODO can we safely assume that this has an "id"?
									oControl.closestAggregationBinding = oClosestBinding && oClosestBinding.aggregation;

									// connect extension points
									var oLast = aExtensionPointList[aExtensionPointList.length - 1];
									if (oLast) {
										oLast._nextSibling = oControl;
									}

									aExtensionPointList.push(oControl);
								} else if (oAggregation.multiple) {
									// 1..n AGGREGATION
									if (!mSettings[name]) {
										mSettings[name] = [];
									}
									if (typeof mSettings[name].path === "string") {
										assert(!mSettings[name].template, "list bindings support only a single template object");
										mSettings[name].template = oControl;
									} else {
										mSettings[name].push(oControl);
									}
								} else {
									// 0..1 AGGREGATION
									assert(!mSettings[name], "multiple aggregates defined for aggregation " + name + " with cardinality 0..1");
									mSettings[name] = oControl;
								}
							}
							return aControls;
						});
					} else {
						throw new Error(createErrorInfo(childNode, "Cannot add direct child without default aggregation defined for control " + oMetadata.getElementName()));
					}
				} else if (childNode.nodeType === 3 /* TEXT_NODE */) {
					if (oConfig && oConfig.rootArea) {
						createControls(childNode, pRequireContext, oClosestBinding, oAggregation, oConfig);
					} else {
						var sTextContent = childNode.textContent || childNode.text;
						if (sTextContent && sTextContent.trim()) { // whitespace would be okay
							throw new Error(createErrorInfo(childNode, "Cannot add text nodes as direct child of an aggregation. For adding text to an aggregation, a surrounding html tag is needed."));
						}
					}
				} // other nodes types are silently ignored

			}

			// loop child nodes and handle all AGGREGATIONS
			var oAggregation = oMetadata.getDefaultAggregation();
			var mAggregations = oMetadata.getAllAggregations();

			return handleChildren(node, {
				aggregation: oAggregation,
				allAggregations: mAggregations,
				chain: pRequireContext,
				closestBinding: oClosestBinding,
				config: oConfig
			}).then(function() {
				// apply the settings to the control
				var vNewControlInstance;
				var pProvider = SyncPromise.resolve();
				var pInstanceCreated = SyncPromise.resolve();
				var sType = node.getAttribute("type");

				var oOwnerComponent = Component.getOwnerComponentFor(oView);
				var bIsAsyncComponent = oOwnerComponent?.getManifestObject()?._getSchemaVersion() === 2 ||
										oOwnerComponent?.isA("sap.ui.core.IAsyncContentCreation");

				if (bEnrichFullIds) {
					if (!bRootArea && node.hasAttribute("id")) {
						setId(oView, node);
					}
				} else if (!bViewRootNode && oClass.getMetadata().isA("sap.ui.core.mvc.View")) {
					if (!oClass._sType && !mSettings.viewName) {
						// Add module view name
						mSettings.viewName = "module:" + oClass.getMetadata().getName().replace(/\./g, "/");
					}

					mSettings.type = oClass._sType || sType;

					if (bAsync) {
						// legacy check: async=false is not supported with an async-component
						if (bIsAsyncComponent && mSettings.async === false) {
							throw new Error(
								"A nested view contained in a Component that uses manifest version 2 or implements 'sap.ui.core.IAsyncContentCreation' is processed asynchronously by default and cannot be processed synchronously.\n" +
								"Affected Component '" + oOwnerComponent.getMetadata().getComponentName() + "' and View '" + mSettings.viewName + "'."
							);
						}

						pInstanceCreated = scopedRunWithOwner(function() {
							return View.create(mSettings);
						});
					} else {
						/**
						 * @deprecated because the 'Sequential' Mode is used by default and it's the only mode that will be supported
						 * in the next major release
						 *
						 * Pass processingMode to nested XMLViews
						 */
						if (oClass.getMetadata().isA("sap.ui.core.mvc.XMLView") && oView._sProcessingMode) {
							mSettings.processingMode = oView._sProcessingMode;
						}

						vNewControlInstance = scopedRunWithOwner(function() {
							return _ViewFactory.create(mSettings);
						});
					}
				} else if (oClass.getMetadata().isA("sap.ui.core.Fragment") && bAsync) {
					/**
					 * @deprecated because the 'Sequential' Mode is used by default and it's the only mode that will be supported
					 * in the next major release
					 *
					 * Pass processingMode to any fragments except JS
					 * XML / HTML fragments: might include nested views / fragments,
					 *  which are processed asynchronously. Therefore the processingMode is needed
					 * JS fragments: might include synchronously or asynchronously created content. Nevertheless, the execution of the
					 *  content creation is not in the scope of the xml template processor, therefore the processing mode is not needed
					 */
					if (sType !== ViewType.JS) {
						mSettings.processingMode = oView._sProcessingMode;
					}

					var sFragmentPath = "sap/ui/core/Fragment";
					var Fragment = sap.ui.require(sFragmentPath);

					// call Fragment.load with mSettings.name
					mSettings.name = mSettings.name || mSettings.fragmentName;

					if (Fragment) {
						pInstanceCreated = Fragment.load(mSettings);
					} else {
						pInstanceCreated = new Promise(function (resolve, reject) {
							sap.ui.require([sFragmentPath], function (Fragment) {
								Fragment.load(mSettings).then(function (oFragmentContent) {
									resolve(oFragmentContent);
								});
							}, reject);
						});
					}
				} else {
					// call the control constructor with the according owner in scope
					var fnCreateInstance = function() {
						var oInstance;

						if (bViewRootNode) {
							oInstance = oView;
							if (!bAsync) {
								// oParseConfig.settings: the settings object that is given to the factory method
								// mSettings: the settings object that contains the properties parsed from View tag
								//
								// In sync case, mSettings is applied before the oParseConfig.settings. In order to make
								// the mSettings win against the oParseConfig.settings, the properties that exist in
								// both objects are merged into the oParseConfig.settings with the value taken from
								// mSettings and they are then deleted from mSettings.
								if (oParseConfig && oParseConfig.settings) {
									Object.keys(mSettings).forEach(function(sKey) {
										if (oParseConfig.settings.hasOwnProperty(sKey)) {
											oParseConfig.settings[sKey] = mSettings[sKey];
											delete mSettings[sKey];
										}
									});
								}
							}
							oView.applySettings(mSettings);
						} else {
							// the scoped runWithOwner function is only during ASYNC processing!
							oInstance = scopedRunWithOwner(function () {
								var oInstance;
								if (node.getAttributeNS(UI5_INTERNAL_NAMESPACE, "unstash") === "true") {
									oInstance = ElementRegistry.get(mSettings.id);
									// If the placeholder has a visible property we set it to false to hide the placeholder.
									// We must reset the setting to true to make it visible again or reflect the new settings.
									if (oInstance.setVisible) {
										oInstance.setVisible(true);
									}
									oInstance.applySettings(mSettings);
								} else {
									oInstance = new oClass(mSettings);
								}
								return oInstance;
							});
						}

						// check if we need to hand the ExtensionPoint info to the ExtensionProvider
						pProvider = fnTriggerExtensionPointProvider(oInstance, mAggregationsWithExtensionPoints, bAsync);

						return oInstance;
					};

					if (oParseConfig && oParseConfig.fnRunWithPreprocessor) {
						vNewControlInstance = oParseConfig.fnRunWithPreprocessor(fnCreateInstance);
					} else {
						vNewControlInstance = fnCreateInstance();
					}
				}

				return pInstanceCreated.then(function (vContent) {
					return vContent || vNewControlInstance;
				}).then(function (vFinalInstance) {
					if (sStyleClasses && vFinalInstance.addStyleClass) {
						// Elements do not have a style class!
						vFinalInstance.addStyleClass(sStyleClasses);
					}

					if (!vFinalInstance) {
						vFinalInstance = [];
					} else if (!Array.isArray(vFinalInstance)) {
						vFinalInstance = [vFinalInstance];
					}

					//apply support info if needed
					/** @deprecated since 1.120.0 */
					if (XMLTemplateProcessor._supportInfo && vFinalInstance) {
						for (var i = 0, iLength = vFinalInstance.length; i < iLength; i++) {
							var oInstance = vFinalInstance[i];
							if (oInstance && oInstance.getId()) {
								//create a support info for id creation and add it to the support data
								var iSupportIndex = XMLTemplateProcessor._supportInfo({ context: node, env: { caller: "createRegularControls", nodeid: node.getAttribute("id"), controlid: oInstance.getId() } }),
									sData = sSupportData ? sSupportData + "," : "";
								sData += iSupportIndex;
								//add the controls support data to the indexed map of support info control instance map
								XMLTemplateProcessor._supportInfo.addSupportInfo(oInstance.getId(), sData);
							}
						}
					}

					if (bDesignMode) {
						vFinalInstance.forEach(function (oInstance) {
							if (oMetadata.getCompositeAggregationName) {
								var aNodes = node.getElementsByTagName(oInstance.getMetadata().getCompositeAggregationName());
								for (var i = 0; i < aNodes.length; i++) {
									node.removeChild(aNodes[0]);
								}
							}
							oInstance._sapui_declarativeSourceInfo = {
								xmlNode: node,
								xmlRootNode: oView._sapui_declarativeSourceInfo.xmlRootNode,
								fragmentName: oMetadata.getName() === 'sap.ui.core.Fragment' ? mSettings['fragmentName'] : null
							};
						});
					}

					return pProvider.then(function () {
						// either resolve with fragment or control instance
						return vFinalInstance;
					});
				});
			});

		}
Creates 0..n UI5 controls from an XML node.
One control for regular controls, zero for ExtensionPoints without configured extension and
n controls for multi-root Fragments.

@param {Element} node The current XMLNode which is being processed
@param {function} oClass The constructor of the control that is currently being processed
@param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
@param {object} [oClosestBinding] Information on the binding that is closest to currently processed control
 node. Used by the flex extension-point provider to correctly trigger aggregation updates. This is necessary
 for extension-points that are inside a template control of an aggregation.
@param {object} [oConfig] The config object that contains information which is forwarded during the recursive processing
@param {boolean} [oConfig.rootArea=false] Indicates whether it's processing the root area of an XMLView
@param {boolean} [oConfig.rootNode=false] Indicates whether the <code>node</code> is the root node of an XMLView's content

@return {Promise} resolving to an array with 0..n controls created from a node
@private