also includes arrAltBranchRootUnits
770246
function createListOfBestChildrenIncludedByLaterUnits(arrAltBranchRootUnits, handleBestChildrenList){
					if (arrAltBranchRootUnits.length === 0)
						return handleBestChildrenList([]);
					var arrBestChildren = [];
					var arrTips = [];
					var arrNotIncludedTips = [];
					var arrRemovedBestChildren = [];

					function goDownAndCollectBestChildrenOld(arrStartUnits, cb){
						conn.query("SELECT unit, is_free, main_chain_index FROM units WHERE best_parent_unit IN(?)", [arrStartUnits], function(rows){
							if (rows.length === 0)
								return cb();
							async.eachSeries(
								rows, 
								function(row, cb2){
									
									function addUnit(){
										arrBestChildren.push(row.unit);
										if (row.is_free === 1 || arrLaterUnits.indexOf(row.unit) >= 0)
											cb2();
										else
											goDownAndCollectBestChildrenOld([row.unit], cb2);
									}
									
									if (row.main_chain_index !== null && row.main_chain_index <= max_later_limci)
										addUnit();
									else
										graph.determineIfIncludedOrEqual(conn, row.unit, arrLaterUnits, function(bIncluded){
											bIncluded ? addUnit() : cb2();
										});
								},
								cb
							);
						});
					}

					function goDownAndCollectBestChildrenFast(arrStartUnits, cb){
						readBestChildrenProps(conn, arrStartUnits, function(rows){
							if (rows.length === 0){
								arrStartUnits.forEach(function(start_unit){
									arrTips.push(start_unit);
								});
								return cb();
							}
							async.eachSeries(
								rows, 
								function(row, cb2){
									arrBestChildren.push(row.unit);
									if (arrLaterUnits.indexOf(row.unit) >= 0)
										cb2();
									else if (
										row.is_free === 1
										|| row.level >= max_later_level
										|| row.witnessed_level > max_later_witnessed_level && first_unstable_mc_index >= constants.witnessedLevelMustNotRetreatFromAllParentsUpgradeMci
										|| row.latest_included_mc_index > max_later_limci
										|| row.is_on_main_chain && row.main_chain_index > max_later_limci
									){
										arrTips.push(row.unit);
										arrNotIncludedTips.push(row.unit);
										cb2();
									}
									else
										goDownAndCollectBestChildrenFast([row.unit], cb2);
								},
								cb
							);
						});
					}
					
					function findBestChildrenNotIncludedInLaterUnits(arrUnits, cb){
						var arrUnitsToRemove = [];
						async.eachSeries(
							arrUnits, 
							function(unit, cb2){
								if (arrRemovedBestChildren.indexOf(unit) >= 0)
									return cb2();
								if (arrNotIncludedTips.indexOf(unit) >= 0){
									arrUnitsToRemove.push(unit);
									return cb2();
								}
								graph.determineIfIncludedOrEqual(conn, unit, arrLaterUnits, function(bIncluded){
									if (!bIncluded)
										arrUnitsToRemove.push(unit);
									cb2();
								});
							},
							function(){
								if (arrUnitsToRemove.length === 0)
									return cb();
								arrRemovedBestChildren = arrRemovedBestChildren.concat(arrUnitsToRemove);
								goUp(arrUnitsToRemove, cb);
							}
						);
					}
					
					function goUp(arrCurrentTips, cb){
						var arrUnits = [];
						async.eachSeries(
							arrCurrentTips,
							function(unit, cb2){
								storage.readStaticUnitProps(conn, unit, function(props){
									if (arrUnits.indexOf(props.best_parent_unit) === -1)
										arrUnits.push(props.best_parent_unit);
									cb2();
								});
							},
							function(){
								findBestChildrenNotIncludedInLaterUnits(arrUnits, cb);
							}
						);
					}
					
					function collectBestChildren(arrFilteredAltBranchRootUnits, cb){
						goDownAndCollectBestChildrenFast(arrFilteredAltBranchRootUnits, function(){
							if (arrTips.length === 0)
								return cb();
							var start_time = Date.now();
							findBestChildrenNotIncludedInLaterUnits(arrTips, function(){
								console.log("findBestChildrenNotIncludedInLaterUnits took "+(Date.now()-start_time)+"ms");
								arrBestChildren = _.difference(arrBestChildren, arrRemovedBestChildren);
								cb();
							});
						});
					}

					// leaves only those roots that are included by later units
					function filterAltBranchRootUnits(cb){
						//console.log('===== before filtering:', arrAltBranchRootUnits);
						var arrFilteredAltBranchRootUnits = [];
						conn.query("SELECT unit, is_free, main_chain_index FROM units WHERE unit IN(?)", [arrAltBranchRootUnits], function(rows){
							if (rows.length === 0)
								throw Error("no alt branch root units?");
							async.eachSeries(
								rows, 
								function(row, cb2){
									
									function addUnit(){
										arrBestChildren.push(row.unit);
									//	if (row.is_free === 0) // seems no reason to exclude
											arrFilteredAltBranchRootUnits.push(row.unit);
										cb2();
									}
									
									if (row.main_chain_index !== null && row.main_chain_index <= max_later_limci)
										addUnit();
									else
										graph.determineIfIncludedOrEqual(conn, row.unit, arrLaterUnits, function(bIncluded){
											bIncluded ? addUnit() : cb2();
										});
								},
								function(){
									//console.log('filtered:', arrFilteredAltBranchRootUnits);
									if (arrFilteredAltBranchRootUnits.length === 0)
										return handleBestChildrenList([]);
									var arrInitialBestChildren = _.clone(arrBestChildren);
									var start_time = Date.now();
									if (conf.bFaster)
										return collectBestChildren(arrFilteredAltBranchRootUnits, function(){
											console.log("collectBestChildren took "+(Date.now()-start_time)+"ms");
											cb();
										});
									goDownAndCollectBestChildrenOld(arrFilteredAltBranchRootUnits, function(){
										console.log("goDownAndCollectBestChildrenOld took "+(Date.now()-start_time)+"ms");
										var arrBestChildren1 = _.clone(arrBestChildren.sort());
										arrBestChildren = arrInitialBestChildren;
										start_time = Date.now();
										collectBestChildren(arrFilteredAltBranchRootUnits, function(){
											console.log("collectBestChildren took "+(Date.now()-start_time)+"ms");
											arrBestChildren.sort();
											if (!_.isEqual(arrBestChildren, arrBestChildren1)){
												throwError("different best children, old "+arrBestChildren1.join(', ')+'; new '+arrBestChildren.join(', ')+', later '+arrLaterUnits.join(', ')+', earlier '+earlier_unit+", global db? = "+(conn === db));
												arrBestChildren = arrBestChildren1;
											}
											cb();
										});
									});
								}
							);
						});
					}

					filterAltBranchRootUnits(function(){
						//console.log('best children:', arrBestChildren);
						handleBestChildrenList(arrBestChildren);
					});
				}
1174391
def active(extended=False):
    '''
    
    '''
    ret = {}
    if __grains__['os'] == 'FreeBSD':
        _active_mounts_freebsd(ret)
    elif 'AIX' in __grains__['kernel']:
        _active_mounts_aix(ret)
    elif __grains__['kernel'] == 'SunOS':
        _active_mounts_solaris(ret)
    elif __grains__['os'] == 'OpenBSD':
        _active_mounts_openbsd(ret)
    elif __grains__['os'] in ['MacOS', 'Darwin']:
        _active_mounts_darwin(ret)
    else:
        if extended:
            try:
                _active_mountinfo(ret)
            except CommandExecutionError:
                _active_mounts(ret)
        else:
            _active_mounts(ret)
    return ret
1008487
private function findSimilarAggregateRoot(AggregateRoot $aggregateRoot)
    {
        foreach ($this->aggregateRoots as $registeredAggregateRoot) {
            if ($registeredAggregateRoot->sameIdentityAs($aggregateRoot)) {
                return $registeredAggregateRoot;
            }
        }

        return;
    }
560524
function flagBundlesIncludedByCommonParentModule(modules,bundles) {
	var
		 bundleToModule = extractBundleToModuleMap(modules),
		 bundleMap = extractBundleMap(bundles.bundlesArray),
		 moduleAncestors = {},
		 modulesArray, x, commonAncestor;
	
	for( x in bundleToModule ) {
		if( !bundleToModule.hasOwnProperty(x) ) continue;
		modulesArray = bundleToModule[x];
		commonAncestor = extractCommonAncestor(modulesArray);
		if( commonAncestor != null ) {
			includeBundleInModule(bundleMap[x], commonAncestor);
		}
	}
	
	
	function extractBundleToModuleMap(modules) {
		var x, i, ret = {}, bundleDeps, dependentModules;
		for( x in modules ) {
			if( !modules.hasOwnProperty(x) ) continue;
			bundleDeps = modules[x].bundleDeps;
			for( i=0; i < bundleDeps.length; i++ ) {
				if( bundleDeps[i].exclusive ) continue;
				dependentModules = ret[bundleDeps[i].id];
				if( dependentModules == null ) {
					dependentModules = [];
					ret[bundleDeps[i].id] = dependentModules;
				}
				dependentModules.push(modules[x]);
			}
		}
		return ret;
	}
	
	function extractBundleMap(bundlesArray) {
		var i, ret = {};
		for( i=0; i < bundlesArray.length; i++ ) {
			ret[bundlesArray[i].id] = bundlesArray[i];
		}
		return ret;
	}
	
	function findAllAncestors(module) {
		var ret = moduleAncestors[module.name];
		if( ret == null ) {
			ret = [];
			moduleAncestors[module.name] = ret;
			addParents(ret, module);
		}
		return ret;
		
		function addParents(ret, module) {
			var i, j, grandParents;
			for( i=0; i < module.parents.length; i++ ) {
				if( ret.indexOf(module.parents[i]) < 0 ) {
					ret.push(module.parents[i]);
					grandParents = findAllAncestors(modules[module.parents[i]]);
					for( j=0; j < grandParents.length; j++ ) {
						if( ret.indexOf(grandParents[j]) < 0 ) ret.push(grandParents[j]);
					}
				}
				
			}
		}
	}
	
	function isAncestor(potentialAncestorModuleName, module) {
		if( typeof(module) === "string" ) module = modules[module];
		var a = findAllAncestors(module);
		return a.indexOf(potentialAncestorModuleName) >= 0;
	}
	
	function extractCommonAncestor(modulesArray) {
		var i, j, foundNonAncestor;
		for( i=0; i < modulesArray.length; i++ ) {
			foundNonAncestor = false;
			for( j=0; j < modulesArray.length; j++ ) {
				if( i !== j ) {
					if( !isAncestor(modulesArray[i].name, modulesArray[j]) ) {
						foundNonAncestor = true;
						break;
					}
				}
			}
			if( !foundNonAncestor ) {
				return modulesArray[i];
			}
		}
		return null;
	}
	
	function includeBundleInModule(bundle, module) {
		var i, index, newExcludedDeps = [];
		bundle.includedIn = module.name;
		// re-enable bundle deps in module
		for( i=0; i < bundle.deps.length; i++ ) {
			index = module.excludedDeps.indexOf(bundle.deps[i]);
			module.excludedDeps[index] = false
		}
		for( i=0; i < module.excludedDeps.length; i++ ) {
			if( module.excludedDeps[i] === false ) continue;
			newExcludedDeps.push(module.excludedDeps[i]);
		}
		module.excludedDeps = newExcludedDeps;
	}
}
415824
private function addCollectionToRoot(&$root, &$object, $fullPropertyPath)
    {
        // First determine if the $object is a resource or a
        // collection of resources
        $isResource = false;
        if (is_array($object)) {
            $copy = $object;
            $values = array_values($copy);
            $firstPropertyOrResource = array_shift($values);

            if (Utility::isPrimitive($firstPropertyOrResource)) {
                $isResource = true;
            }
        } elseif ($object instanceof EloquentModel) {
            $isResource = true;
        }

        $newCollection = $isResource ? [$object] : $object;

        // Does existing collections use arrays or Collections
        $copy = $root;
        $values = array_values($copy);
        $existingRootCollection = array_shift($values);

        $newCollection = $existingRootCollection instanceof Collection ?
                                new Collection($newCollection) : $newCollection;

        if (!array_key_exists($fullPropertyPath, $root)) {
            $root[$fullPropertyPath] = $newCollection;
        } else {
            $this->mergeRootCollection($root[$fullPropertyPath], $newCollection);
        }
    }
249712
private boolean isInRoots(String canonicalPath) {

        if (canonicalPath.startsWith(m_rootPath)) {
            return true;
        }
        if (m_additionalRoots != null) {
            for (String root : m_additionalRoots) {
                if (canonicalPath.startsWith(root)) {
                    return true;
                }

            }
        }
        return false;
    }
378307
private function reassembleWithoutRoot()
    {
        if (!$this->root) {
            return $this->reassemble();
        }

        /**
         * In some rare conditions the path in interpreted as the host when there is no domain.tld format given.
         * This is still considered a valid url, be it with only a tld as indication.
         */
        $path = (isset($this->parsed['path']) && $this->parsed['path'] != $this->root->host())
                    ? $this->parsed['path']
                    : '';

        return $path
            .((isset($this->parsed['query'])) ? '?'.$this->parsed['query'] : '')
            .((isset($this->parsed['fragment'])) ? '#'.$this->parsed['fragment'] : '');
    }
1276110
function() {

        var base = this.__base();
        return function() {

            var _this = this;
            return Q.when(base.call(this))
                .then(function() {

                    var arch = _this.ctx.arch,
                        o = {
                            root: _this.root,
                            level: _this.level,
                            item: _this.mergedBundleItem()
                        };

                    if (_this.buildMergedBundle() &&
                        _this.mergedBundleName() &&
                        !arch.hasNode(Bundle.MergedBundleNode.createId(o))) {

                        var levelNode = arch.getNode(_this.path),
                            bundles = arch.getChildren(levelNode)
                                .filter(function(b) {
                                        return arch.getNode(b) instanceof Bundle.BundleNode;
                                    }, _this);

                        arch.setNode(new Bundle.MergedBundleNode(o),
                            arch.getNode(_this.path).getId(),
                            bundles);

                        return _this.takeSnapshot('after BundlesLevelNode alterArch ' + _this.getId());
                    }

                });

        };

    }
502661
NodeBuilder ascendToRoot()
    {
        NodeBuilder current = this;
        while (!current.isRoot())
            current = current.ascend();
        return current;
    }
254535
protected function loadNodeDataBranch($nID = -3)
    {
        $this->sessData->setCoreID($GLOBALS["SL"]->coreTbl, $this->coreID); // not sure why this is needed
        $nIDtmp = $nID;
        $parents = [$nID];
        while ($this->hasNode($nIDtmp)) {
            $nIDtmp = $this->allNodes[$nIDtmp]->getParent();
            if (intVal($nIDtmp) > 0) {
                $parents[] = $nIDtmp;
            }
        }
        $this->sessData->dataBranches = [ [
            "branch" => $GLOBALS["SL"]->coreTbl, 
            "loop"   => '', 
            "itemID" => $this->coreID 
        ] ];
        if (sizeof($parents) > 1) {
            for ($i = (sizeof($parents)-2); $i >= 0; $i--) {
                if ($this->allNodes[$parents[$i]]->nodeType == 'Data Manip: New') {
                    $this->loadManipBranch($parents[$i], true);
                } elseif (trim($this->allNodes[$parents[$i]]->dataBranch) != '') {
                    $nBranch = $this->allNodes[$parents[$i]]->dataBranch;
                    $addBranch = $addLoop = '';
                    $itemID = -3;
                    if ($this->allNodes[$parents[$i]]->isLoopRoot()) {
                        $addBranch = $GLOBALS["SL"]->dataLoops[$nBranch]->DataLoopTable;
                        $addLoop = $nBranch;
                        $itemID = $GLOBALS["SL"]->getSessLoopID($nBranch);
                    } else {
                        $addBranch = $nBranch;
                        list($itemInd, $itemID) = $this->sessData->currSessDataPos($nBranch, 
                            $this->allNodes[$parents[$i]]->isDataManip());
                        if ($itemID <= 0) {
                            if (isset($GLOBALS["SL"]->tblAbbr[$nBranch])) {
                                $lastInd = sizeof($this->sessData->dataBranches)-1;
                                $parBranch = $this->sessData->dataBranches[$lastInd]["branch"];
                                $lnkFld = $GLOBALS["SL"]->getForeignLnk($GLOBALS["SL"]->tblI[$parBranch],
                                    $GLOBALS["SL"]->tblI[$nBranch]);
                                if ($lnkFld != '') {
                                    $lnkFld = $GLOBALS["SL"]->tblAbbr[$parBranch] . $lnkFld;
                                    $row = $this->sessData->getRowById($parBranch, 
                                        $this->sessData->dataBranches[$lastInd]["itemID"]);
                                    if ($row && isset($row->{ $lnkFld })) {
                                        $itemID = $row->{ $lnkFld };
                                    }
                                }
                                if ($lnkFld == '' || $itemID <= 0) {
                                    $lnkFld = $GLOBALS["SL"]->getForeignLnk($GLOBALS["SL"]->tblI[$nBranch], 
                                        $GLOBALS["SL"]->tblI[$parBranch]);
                                    if ($lnkFld != '') {
                                        $lnkFld = $GLOBALS["SL"]->tblAbbr[$nBranch] . $lnkFld;
                                        $row = $this->sessData->getRowById($nBranch, 
                                            $this->sessData->dataBranches[$lastInd]["itemID"]);
                                        if ($row && isset($row->{ $lnkFld })) {
                                            $itemID = $row->{ $lnkFld };
                                        }
                                    }
                                }
                                if ($lnkFld == '' || $itemID <= 0) {
                                    $lnkFld = $GLOBALS["SL"]->getForeignLnk($GLOBALS["SL"]->tblI[$nBranch], 
                                        $GLOBALS["SL"]->tblI[$parBranch]);
                                    if ($parBranch == 'users' && $lnkFld == 'UserID' 
                                        && isset($this->sessData->dataSets[$nBranch]) 
                                        && sizeof($this->sessData->dataSets[$nBranch]) > 0) {
                                        $lnkFld = $GLOBALS["SL"]->tblAbbr[$nBranch] . $lnkFld;
                                        foreach ($this->sessData->dataSets[$nBranch] as $row) {
                                            if (isset($row->{ $lnkFld }) && $row->{ $lnkFld } 
                                                == $this->sessData->dataBranches[$lastInd]["itemID"] ) {
                                                $itemID = $row->getKey();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    $foundBranch = false; // $this->sessData->chkDataBranch($addBranch, $dataBranch);
                    if (!$foundBranch) {
                        $this->sessData->dataBranches[] = [
                            "branch" => $addBranch,
                            "loop"   => $addLoop,
                            "itemID" => $itemID
                        ];
                    }
                }
            }
        }
        return $this->sessData->dataBranches;
    }
424492
public function getAncestors($includeSelf = false)
    {
        $ancestors = new ArrayList();
        $object = $this->owner;

        if ($includeSelf) {
            $ancestors->push($object);
        }
        while ($object = $object->getParent()) {
            $ancestors->push($object);
        }

        return $ancestors;
    }
1179370
function readDescendantUnitsBeforeLandingOnMc(conn, objEarlierUnitProps, arrLaterUnitProps, handleUnits){
	
	var max_later_limci = Math.max.apply(null, arrLaterUnitProps.map(function(objLaterUnitProps){ return objLaterUnitProps.latest_included_mc_index; }));
	var max_later_level = Math.max.apply(null, arrLaterUnitProps.map(function(objLaterUnitProps){ return objLaterUnitProps.level; }));
	var arrLandedUnits = []; // units that landed on MC before max_later_limci, they are already included in at least one of later units
	var arrUnlandedUnits = []; // direct shoots to later units, without touching the MC
	
	function goDown(arrStartUnits){
		conn.query(
			"SELECT unit, level, latest_included_mc_index, main_chain_index, is_on_main_chain \n\
			FROM parenthoods JOIN units ON child_unit=unit \n\
			WHERE parent_unit IN(?) AND latest_included_mc_index<? AND level<=?",
			[arrStartUnits, objEarlierUnitProps.main_chain_index, max_later_level],
			function(rows){
				var arrNewStartUnits = [];
				for (var i=0; i<rows.length; i++){
					var objUnitProps = rows[i];
					//if (objUnitProps.latest_included_mc_index >= objEarlierUnitProps.main_chain_index)
					//    continue;
					//if (objUnitProps.level > max_later_level)
					//    continue;
					arrNewStartUnits.push(objUnitProps.unit);
					if (objUnitProps.main_chain_index !== null && objUnitProps.main_chain_index <= max_later_limci) // exclude free balls!
						arrLandedUnits.push(objUnitProps.unit);
					else
						arrUnlandedUnits.push(objUnitProps.unit);
				}
				(arrNewStartUnits.length > 0) ? goDown(arrNewStartUnits) : handleUnits(arrLandedUnits, arrUnlandedUnits);
			}
		);
	}
	
	goDown([objEarlierUnitProps.unit]);
}
925307
function(node, ufNameArr) {
			var context = this,
				out = {
					'root': [],
					'properties': []
				},
				classNames,
				key,
				items,
				item,
				i,
				x,
				z,
				y,
				map,
				prop,
				propName,
				v2Name,
				impiedRel,
				ufName;

			// don't get classes from excluded list of tags
			if(modules.domUtils.hasTagName(node, this.excludeTags) === false){

				// find classes for node
				classNames = modules.domUtils.getAttribute(node, 'class');
				if(classNames) {
					items = classNames.split(' ');
					x = 0;
					i = items.length;
					while(x < i) {

						item = modules.utils.trim(items[x]);

						// test for root prefix - v2
						if(modules.utils.startWith(item, context.rootPrefix) && modules.utils.isLowerCase(item)) {
							if(out.root.indexOf(item) === -1){
								out.root.push(item);
							}
							out.typeVersion = 'v2';
						}

						// test for property prefix - v2
						z = context.propertyPrefixes.length;
						while(z--) {
							if(modules.utils.startWith(item, context.propertyPrefixes[z]) && modules.utils.isLowerCase(item)) {
								out.properties.push([item,'v2']);
							}
						}

						// test for mapped root classnames v1
						for(key in modules.maps) {
							if(modules.maps.hasOwnProperty(key)) {
								// only add a root once
								if(modules.maps[key].root === item && out.root.indexOf(key) === -1) {
									// if root map has subTree set to true
									// test to see if we should create a property or root
									if(modules.maps[key].subTree) {
										out.properties.push(['p-' + modules.maps[key].root, 'v1']);
									} else {
										out.root.push(key);
										if(!out.typeVersion){
											out.typeVersion = 'v1';
										}
									}
								}
							}
						}


						// test for mapped property classnames v1
						if(ufNameArr){
							for (var a = 0; a < ufNameArr.length; a++) {
								ufName = ufNameArr[a];
								// get mapped property v1 microformat
								map = context.getMapping(ufName);
								if(map) {
									for(key in map.properties) {
										if (map.properties.hasOwnProperty(key)) {

											prop = map.properties[key];
											propName = (prop.map) ? prop.map : 'p-' + key;

											if(key === item) {
												if(prop.uf) {
													// loop all the classList make sure
													//   1. this property is a root
													//   2. that there is not already an equivalent v2 property i.e. url and u-url on the same element
													y = 0;
													while(y < i) {
														v2Name = context.getV2RootName(items[y]);
														// add new root
														if(prop.uf.indexOf(v2Name) > -1 && out.root.indexOf(v2Name) === -1) {
															out.root.push(v2Name);
															out.typeVersion = 'v1';
														}
														y++;
													}
													//only add property once
													if(out.properties.indexOf(propName) === -1) {
														out.properties.push([propName,'v1']);
													}
												} else {
													if(out.properties.indexOf(propName) === -1) {
														out.properties.push([propName,'v1']);
													}
												}
											}
										}

									}
								}
							}

						}

						x++;

					}
				}
			}


			// finds any alt rel=* mappings for a given node/microformat
			if(ufNameArr && this.findRelImpied){
				for (var b = 0; b < ufNameArr.length; b++) {
					ufName = ufNameArr[b];
					impiedRel = this.findRelImpied(node, ufName);
					if(impiedRel && out.properties.indexOf(impiedRel) === -1) {
						out.properties.push([impiedRel, 'v1']);
					}
				}
			}


			//if(out.root.length === 1 && out.properties.length === 1) {
			//	if(out.root[0].replace('h-','') === this.removePropPrefix(out.properties[0][0])) {
			//		out.typeVersion = 'v2';
			//	}
			//}

			return out;
		}
340372
public function save(AggregateRoot $aggregateRoot) : void
    {
        $this->getProperRepository($aggregateRoot->className())->save($aggregateRoot);
    }
1019798
public static List<ResourceRoot> allResourceRoots(DeploymentUnit deploymentUnit) {
        List<ResourceRoot> roots = new ArrayList<ResourceRoot>();
        // not all deployment units have a deployment root
        final ResourceRoot deploymentRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT);
        if (deploymentRoot != null)
            roots.add(deploymentRoot);
        roots.addAll(deploymentUnit.getAttachmentList(Attachments.RESOURCE_ROOTS));
        return roots;
    }
925504
private Set<DagNode<T>> getAncestorNodes(Set<DagNode<T>> dagNodes) {
    Set<DagNode<T>> ancestorNodes = new HashSet<>();
    for (DagNode<T> dagNode : dagNodes) {
      LinkedList<DagNode<T>> nodesToExpand = Lists.newLinkedList(this.getParents(dagNode));
      while (!nodesToExpand.isEmpty()) {
        DagNode<T> nextNode = nodesToExpand.poll();
        ancestorNodes.add(nextNode);
        nodesToExpand.addAll(this.getParents(nextNode));
      }
    }
    return ancestorNodes;
  }
548118
private function allAncestors($xref1, $xref2, $tree_id): array
    {
        $ancestors = [
            $xref1,
            $xref2,
        ];

        $queue = [
            $xref1,
            $xref2,
        ];
        while (!empty($queue)) {
            $parents = DB::table('link AS l1')
                ->join('link AS l2', static function (JoinClause $join): void {
                    $join
                        ->on('l1.l_to', '=', 'l2.l_to')
                        ->on('l1.l_file', '=', 'l2.l_file');
                })
                ->where('l1.l_file', '=', $tree_id)
                ->where('l1.l_type', '=', 'FAMC')
                ->where('l2.l_type', '=', 'FAMS')
                ->whereIn('l1.l_from', $queue)
                ->pluck('l2.l_from');

            $queue = [];
            foreach ($parents as $parent) {
                if (!in_array($parent, $ancestors, true)) {
                    $ancestors[] = $parent;
                    $queue[]     = $parent;
                }
            }
        }

        return $ancestors;
    }