function topLevels(iMaxDistanceFromRoot, oExpandLevels = new Map()) {
		const oNodeID2EffectiveExpandLevels = new Map();

		function limitedDescendantCount(oNode) {
			const aChildren = oNodeID2EffectiveExpandLevels.get(oNode.ID) > 0
				? mChildrenByParentId[oNode.ID] || [] // "expanded"
				: [];

			return aChildren.reduce((iCount, oChild) => {
				return iCount + limitedDescendantCount(oChild);
			}, aChildren.length);
		}

		return aAllNodes
			.filter((oNode) => {
				const oParent = mNodeById[oNode.MANAGER_ID];
				// Note: the parent has been visited before
				let iExpandLevels = oParent
					? oNodeID2EffectiveExpandLevels.get(oParent.ID) - 1
					: iMaxDistanceFromRoot;
				if (iExpandLevels >= 0 && oExpandLevels.has(oNode.ID)) {
					iExpandLevels = oExpandLevels.get(oNode.ID);
				}
				oNodeID2EffectiveExpandLevels.set(oNode.ID, iExpandLevels);
				return iExpandLevels >= 0;
			})
			.map((oNode) => {
				oNode = {...oNode, DescendantCount : limitedDescendantCount(oNode)};
				const bIsExpanded = oNodeID2EffectiveExpandLevels.get(oNode.ID) > 0;
				if (oNode.DrillState === "collapsed" && bIsExpanded) {
					oNode.DrillState = "expanded";
				} else if (oNode.DrillState === "expanded" && !bIsExpanded) {
					oNode.DrillState = "collapsed";
				}
				return oNode;
			});
	}
Returns the hierarchy's top levels in preorder.

@param {number} iMaxDistanceFromRoot - Maximum distance from root to include
@param {Map} [oExpandLevels] - Mapping of NodeID to Levels to be expanded
@returns {object[]} - List of node objects in preorder