fnSuccess = function (oData) {
			// all nodes on root level -> save in this.oKeys[null] = [] (?)
			if (oData.results && oData.results.length > 0) {
				iNodesReceived += oData.results.length;
				aResultPages.push(oData.results);
				if (oData.__next || oData.results.length === that.iMaximumTopValue) {
					delete that.mRequestHandles[sRequestKey];
					that._loadCompleteTreeWithAnnotations(aOriginalURLParameters, aResultPages, iNodesReceived);

					return;
				}
			}
			let aCompleteResults;
			if (iNodesReceived > 0) {
				aCompleteResults = Array.prototype.concat.apply([], aResultPages);
				//collect mapping table between parent node id and actual OData-Key
				var mParentIds = {};
				var oDataObj;
				for (var k = 0; k < aCompleteResults.length; k++) {
					oDataObj = aCompleteResults[k];
					var sDataKey = oDataObj[that.oTreeProperties["hierarchy-node-for"]];
					// sanity check: if we have duplicate keys, the data is messed up. Has already happened...
					if (mParentIds[sDataKey]) {
						Log.warning("ODataTreeBinding - Duplicate data entry for key: " + sDataKey + "!");
					}
					mParentIds[sDataKey] = that.oModel._getKey(oDataObj);
				}

				// process data and built tree
				for (var i = 0; i < aCompleteResults.length; i++) {
					oDataObj = aCompleteResults[i];
					var sParentNodeId = oDataObj[that.oTreeProperties["hierarchy-parent-node-for"]];
					var sParentKey = mParentIds[sParentNodeId]; //oDataObj[that.oTreeProperties["hierarchy-parent-node-for"]];

					// the parentNodeID for root nodes (node level == iRootLevel) is "null"
					if (parseInt(oDataObj[that.oTreeProperties["hierarchy-level-for"]]) === that.iRootLevel) {
						sParentKey = "null";
					}

					// make sure the parent node is already present in the key map
					that.oKeys[sParentKey] = that.oKeys[sParentKey] || [];

					// add the current entry key to the key map, as a child of its parent node
					var sKey = that.oModel._getKey(oDataObj);
					that.oKeys[sParentKey].push(sKey);

					// update the length of the parent node
					that.oLengths[sParentKey] = that.oLengths[sParentKey] || 0;
					that.oLengths[sParentKey]++;
					that.oFinalLengths[sParentKey] = true;

					// keep up with the loaded sections
					that._mLoadedSections[sParentKey] = that._mLoadedSections[sParentKey] || [];
					that._mLoadedSections[sParentKey][0] = that._mLoadedSections[sParentKey][0] || {startIndex: 0, length: 0};
					that._mLoadedSections[sParentKey][0].length++;
				}

			} else {
				// no data received -> empty tree
				aCompleteResults = [];
				that.oKeys["null"] = [];
				that.oLengths["null"] = 0;
				that.oFinalLengths["null"] = true;
			}

			that.oAllKeys = deepExtend({}, that.oKeys);
			that.oAllLengths = deepExtend({}, that.oLengths);
			that.oAllFinalLengths = deepExtend({}, that.oFinalLengths);

			delete that.mRequestHandles[sRequestKey];
			that.bNeedsUpdate = true;

			// apply clientside filters, if any
			if ((that.aApplicationFilters && that.aApplicationFilters.length > 0) ||
				(that.aFilters && that.aFilters.length > 0)) {
				that._applyFilter();
			}

			// apply clientside sorters
			if (that.aSorters && that.aSorters.length > 0) {
				that._applySort();
			}

			that.oModel.callAfterUpdate(function() {
				that.fireDataReceived({data: {results: aCompleteResults}});
			});
		}
Loads the complete collection from the given binding path. The tree is then reconstructed
from the response entries based on the properties with hierarchy annotations.
Adds additional URL parameters.

@param {string[]} aURLParams Additional URL parameters
@param {array} aResultPages=[] An array containing the result arrays with previously read data
@param {int} iNodesReceived=0 The number of previously read data

@private