function handleChild(node, oAggregation, mAggregations, childNode, bActivate, pRequireContext, oClosestBinding) {
				var oNamedAggregation,
					fnCreateStashedControl;

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

					if (childNode.namespaceURI === XML_COMPOSITE_NAMESPACE) {
						mSettings[localName(childNode)] = childNode.querySelector("*");
						return;
					}
					// 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, oNamedAggregation, false, pRequireContext, oClosestBinding);
					} 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 (!bActivate && childNode.getAttribute("stashed") === "true" && !bEnrichFullIds) {
							var oStashedNode = childNode;
							// remove child-nodes...
							childNode = childNode.cloneNode();
							// remove stashed attribute as it is an uknown property.
							oStashedNode.removeAttribute("stashed");

							fnCreateStashedControl = function() {
								var sControlId = getId(oView, childNode);

								StashedControlSupport.createStashedControl({
									wrapperId: sControlId,
									fnCreate: function() {
										// EVO-Todo: stashed control-support is still mandatory SYNC
										// this means we need to switch back the view processing to synchronous too
										// at this point everything is sync again
										var bPrevAsync = bAsync;
										bAsync = false;

										try {
											return handleChild(node, oAggregation, mAggregations, oStashedNode, true, pRequireContext, oClosestBinding).unwrap();
										} finally {
											// EVO-Todo:revert back to the original async/sync behavior
											// if we moved to the sync path for the stashed control, we might now go back to the async path.
											bAsync = bPrevAsync;
										}
									}
								});
							};

							if (oView.fnScopedRunWithOwner) {
								oView.fnScopedRunWithOwner(fnCreateStashedControl);
							} else {
								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");
						}

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

						// 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).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 {
									// 1..1 AGGREGATION
									assert(!mSettings[name], "multiple aggregates defined for aggregation with cardinality 0..1");
									mSettings[name] = oControl;
								}
							}
							return aControls;
						});
					} else if (localName(node) !== "FragmentDefinition" || node.namespaceURI !== CORE_NAMESPACE) { // children of FragmentDefinitions are ok, they need no aggregation
						throw new Error("Cannot add direct child without default aggregation defined for control " + oMetadata.getElementName());
					}

				} else if (childNode.nodeType === 3 /* TEXT_NODE */) {
					var sTextContent = childNode.textContent || childNode.text;
					if (sTextContent && sTextContent.trim()) { // whitespace would be okay
						throw new Error("Cannot add text nodes as direct child of an aggregation. For adding text to an aggregation, a surrounding html tag is needed: " + sTextContent.trim());
					}
				} // other nodes types are silently ignored

			}
/**
			 * @return {Promise} resolving to an array with 0..n controls created from a node
			 * @private
			 */
@return {Promise} resolving to an array with 0..n controls created from a node
@private
@return { Promise } resolving to an array with 0 .. n controls created from a node @private
function handleChild(node, oAggregation, mAggregations, childNode, bActivate, pRequireContext, oClosestBinding) {
				var oNamedAggregation,
					fnCreateStashedControl;
				if (childNode.nodeType === 1 ) {
					if (childNode.namespaceURI === XML_COMPOSITE_NAMESPACE) {
						mSettings[localName(childNode)] = childNode.querySelector("*");
						return;
					}
					oNamedAggregation = childNode.namespaceURI === ns && mAggregations && mAggregations[localName(childNode)];
					if (oNamedAggregation) {
						return handleChildren(childNode, oNamedAggregation, false, pRequireContext, oClosestBinding);
					} else if (oAggregation) {
						if (!bActivate && childNode.getAttribute("stashed") === "true" && !bEnrichFullIds) {
							var oStashedNode = childNode;
							childNode = childNode.cloneNode();
							oStashedNode.removeAttribute("stashed");
							fnCreateStashedControl = function() {
								var sControlId = getId(oView, childNode);
								StashedControlSupport.createStashedControl({
									wrapperId: sControlId,
									fnCreate: function() {
										var bPrevAsync = bAsync;
										bAsync = false;
										try {
											return handleChild(node, oAggregation, mAggregations, oStashedNode, true, pRequireContext, oClosestBinding).unwrap();
										} finally {
											bAsync = bPrevAsync;
										}
									}
								});
							};
							if (oView.fnScopedRunWithOwner) {
								oView.fnScopedRunWithOwner(fnCreateStashedControl);
							} else {
								fnCreateStashedControl();
							}
							childNode.removeAttribute("visible");
							setUI5Attribute(childNode, "invisible");
						}
						if ( mSettings[oAggregation.name] &&
							mSettings[oAggregation.name].path &&
							typeof mSettings[oAggregation.name].path === "string") {
							oClosestBinding = {
								aggregation: oAggregation.name,
								id: mSettings.id
							};
						}
						return createControls(childNode, pRequireContext, oClosestBinding).then(function(aControls) {
							for (var j = 0; j < aControls.length; j++) {
								var oControl = aControls[j];
								var name = oAggregation.name;
								if (oControl._isExtensionPoint) {
									if (!mSettings[name]) {
										mSettings[name] = [];
									}
									var aExtensionPointList = mAggregationsWithExtensionPoints[name];
									if (!aExtensionPointList) {
										aExtensionPointList = mAggregationsWithExtensionPoints[name] = [];
									}
									oControl.index = mSettings[name].length;
									oControl.aggregationName = name;
									oControl.closestAggregationBindingCarrier = oClosestBinding && oClosestBinding.id; 
									oControl.closestAggregationBinding = oClosestBinding && oClosestBinding.aggregation;
									var oLast = aExtensionPointList[aExtensionPointList.length - 1];
									if (oLast) {
										oLast._nextSibling = oControl;
									}
									aExtensionPointList.push(oControl);
								} else if (oAggregation.multiple) {
									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 {
									assert(!mSettings[name], "multiple aggregates defined for aggregation with cardinality 0..1");
									mSettings[name] = oControl;
								}
							}
							return aControls;
						});
					} else if (localName(node) !== "FragmentDefinition" || node.namespaceURI !== CORE_NAMESPACE) { 
						throw new Error("Cannot add direct child without default aggregation defined for control " + oMetadata.getElementName());
					}
				} else if (childNode.nodeType === 3 ) {
					var sTextContent = childNode.textContent || childNode.text;
					if (sTextContent && sTextContent.trim()) { 
						throw new Error("Cannot add text nodes as direct child of an aggregation. For adding text to an aggregation, a surrounding html tag is needed: " + sTextContent.trim());
					}
				} 
			}
function handleChild ( node , oAggregation , mAggregations , childNode , bActivate , pRequireContext , oClosestBinding ) { var oNamedAggregation , fnCreateStashedControl ; if ( childNode . nodeType === 1 ) { if ( childNode . namespaceURI === XML_COMPOSITE_NAMESPACE ) { mSettings [ localName ( childNode ) ] = childNode . querySelector ( "*" ) ; return ; } oNamedAggregation = childNode . namespaceURI === ns && mAggregations && mAggregations [ localName ( childNode ) ] ; if ( oNamedAggregation ) { return handleChildren ( childNode , oNamedAggregation , false , pRequireContext , oClosestBinding ) ; } else if ( oAggregation ) { if ( ! bActivate && childNode . getAttribute ( "stashed" ) === "true" && ! bEnrichFullIds ) { var oStashedNode = childNode ; childNode = childNode . cloneNode ( ) ; oStashedNode . removeAttribute ( "stashed" ) ; fnCreateStashedControl = function ( ) { var sControlId = getId ( oView , childNode ) ; StashedControlSupport . createStashedControl ( { wrapperId : sControlId , fnCreate : function ( ) { var bPrevAsync = bAsync ; bAsync = false ; try { return handleChild ( node , oAggregation , mAggregations , oStashedNode , true , pRequireContext , oClosestBinding ) . unwrap ( ) ; } finally { bAsync = bPrevAsync ; } } } ) ; } ; if ( oView . fnScopedRunWithOwner ) { oView . fnScopedRunWithOwner ( fnCreateStashedControl ) ; } else { fnCreateStashedControl ( ) ; } childNode . removeAttribute ( "visible" ) ; setUI5Attribute ( childNode , "invisible" ) ; } if ( mSettings [ oAggregation . name ] && mSettings [ oAggregation . name ] . path && typeof mSettings [ oAggregation . name ] . path === "string" ) { oClosestBinding = { aggregation : oAggregation . name , id : mSettings . id } ; } return createControls ( childNode , pRequireContext , oClosestBinding ) . then ( function ( aControls ) { for ( var j = 0 ; j < aControls . length ; j ++ ) { var oControl = aControls [ j ] ; var name = oAggregation . name ; if ( oControl . _isExtensionPoint ) { if ( ! mSettings [ name ] ) { mSettings [ name ] = [ ] ; } var aExtensionPointList = mAggregationsWithExtensionPoints [ name ] ; if ( ! aExtensionPointList ) { aExtensionPointList = mAggregationsWithExtensionPoints [ name ] = [ ] ; } oControl . index = mSettings [ name ] . length ; oControl . aggregationName = name ; oControl . closestAggregationBindingCarrier = oClosestBinding && oClosestBinding . id ; oControl . closestAggregationBinding = oClosestBinding && oClosestBinding . aggregation ; var oLast = aExtensionPointList [ aExtensionPointList . length - 1 ] ; if ( oLast ) { oLast . _nextSibling = oControl ; } aExtensionPointList . push ( oControl ) ; } else if ( oAggregation . multiple ) { 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 { assert ( ! mSettings [ name ] , "multiple aggregates defined for aggregation with cardinality 0..1" ) ; mSettings [ name ] = oControl ; } } return aControls ; } ) ; } else if ( localName ( node ) !== "FragmentDefinition" || node . namespaceURI !== CORE_NAMESPACE ) { throw new Error ( "Cannot add direct child without default aggregation defined for control " + oMetadata . getElementName ( ) ) ; } } else if ( childNode . nodeType === 3 ) { var sTextContent = childNode . textContent || childNode . text ; if ( sTextContent && sTextContent . trim ( ) ) { throw new Error ( "Cannot add text nodes as direct child of an aggregation. For adding text to an aggregation, a surrounding html tag is needed: " + sTextContent . trim ( ) ) ; } } }
@return {Promise} resolving to an array with 0..n controls created from a node
 @private
@return { Promise } resolving to an array with 0 .. n controls created from a node @private
// inspect only element nodes /* ELEMENT_NODE */ // check for a named aggregation (must have the same namespace as the parent and an aggregation with the same name must exist) // the children of the current childNode are aggregated controls (or HTML) below the named aggregation // 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 // remove child-nodes... // remove stashed attribute as it is an uknown property. // EVO-Todo: stashed control-support is still mandatory SYNC // this means we need to switch back the view processing to synchronous too // at this point everything is sync again // EVO-Todo:revert back to the original async/sync behavior // if we moved to the sync path for the stashed control, we might now go back to the async path. // ...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) // whether the created controls will be the template for a list binding // 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 // append the child to the aggregation // oControl is an ExtensionPoint placeholder // only in Flexibility scenario if an ExtensionProvider is given! // if the aggregation already exists we get the // TODO can we safely assume that this has an "id"? // connect extension points // 1..n AGGREGATION // 1..1 AGGREGATION // children of FragmentDefinitions are ok, they need no aggregation /* TEXT_NODE */ // whitespace would be okay // other nodes types are silently ignored