async function fnRecurse(oCurrentNode, bIsAggregation) {
				let oMetadata;
				if (!bIsAggregation) {
					oMetadata = await this._getControlMetadataInXml(oCurrentNode, true);
				}
				const aAggregations = oMetadata && await oMetadata.getAllAggregations();
				const aChildren = this._getElementNodeChildren(oCurrentNode);
				let oPromiseChain = Promise.resolve();
				aChildren.forEach(function(oChild) {
					const bIsCurrentNodeAggregation = aAggregations && aAggregations[oChild.localName];
					oPromiseChain = oPromiseChain.then(function() {
						return fnRecurse.call(this, oChild, bIsCurrentNodeAggregation)
						.then(function() {
							// if it's an aggregation, we don't call the callback function
							if (!bIsCurrentNodeAggregation) {
								fnCallback(oChild);
							}
						});
					}.bind(this));
				}.bind(this));

				return oPromiseChain;
			}
Recursively goes through an XML tree and calls a callback function for every control inside.
Does not call the callback function for aggregations.

@param {function} fnCallback - Function that will be called for every control with the following arguments: <code>fnCallback(&lt;Element>)</code>
@param {Element} oRootNode - Root node from which we start traversing the tree
@returns {Promise} resolves when async processing is done