def __LocateRootDir(self, basicConfig: BasicConfig,
                     rootDirs: List[ToolConfigRootDirectory],
                     entryName: str,
                     projectRootDirectory: str) -> ToolConfigRootDirectory:
     if projectRootDirectory is None or not entryName.startswith(
             MagicStrings.ProjectRoot):
         for rootDir in rootDirs:
             if entryName.startswith(rootDir.Name):
                 return rootDir
     else:
         # Lets try to locate a root directory which the project is based in,
         # then use it to dynamically add a new allowed root directory based on the project file location
         for rootDir in rootDirs:
             if projectRootDirectory == rootDir.ResolvedPath:
                 return ToolConfigRootDirectory(basicConfig, None,
                                                rootDir.ProjectId, rootDir,
                                                MagicStrings.ProjectRoot,
                                                rootDir.DynamicName)
             elif projectRootDirectory.startswith(rootDir.ResolvedPathEx):
                 dynamicRootDir = projectRootDirectory[len(rootDir.
                                                           ResolvedPathEx):]
                 dynamicRootDir = "{0}/{1}".format(rootDir.Name,
                                                   dynamicRootDir)
                 return ToolConfigRootDirectory(basicConfig, None,
                                                rootDir.ProjectId, rootDir,
                                                MagicStrings.ProjectRoot,
                                                dynamicRootDir)
     raise Exception(
         "Path '{0}' is not based on one of the valid root directories {1}".
         format(entryName, ", ".join(Util.ExtractNames(rootDirs))))
 def __ResolveRootDirectories(
         self, basicConfig: BasicConfig,
         rootDirectories: List[XmlConfigFileAddRootDirectory],
         configFileName: str) -> List[ToolConfigRootDirectory]:
     uniqueNames = set()  # type: Set[str]
     rootDirs = []  # type: List[ToolConfigRootDirectory]
     for rootDir in rootDirectories:
         toolRootDir = ToolConfigRootDirectory(basicConfig, rootDir)
         if not toolRootDir.Name in uniqueNames:
             uniqueNames.add(toolRootDir.Name)
             rootDirs.append(toolRootDir)
         else:
             raise DuplicatedConfigRootPath(toolRootDir.Name,
                                            configFileName)
     # We sort it so that the longest paths come first meaning we will always find the most exact match first
     # if searching from the front to the end of the list and comparing to 'startswith'
     rootDirs.sort(key=lambda s: -len(s.ResolvedPathEx))
     return rootDirs