public RootNode ReadFile()
        {
            if (!FileExists)
            {
                return(null);
            }
            RootNode    rootNode       = new RootNode();
            CommandNode currentCommand = null;
            RefsNode    currentNode    = null;
            string      depsFile       = File.ReadAllText(_refsFilePath);
            var         lineNo         = 0;
            int         currentLevel;
            int         nextLevel;

            string[] allLines = depsFile.Split(new[] { Environment.NewLine, "\n", "\r" }, StringSplitOptions.None);

            string currentLine = allLines[0];
            string nextLine;

            for (int i = 0; i < allLines.Length; i++)
            {
                if (i + 1 < allLines.Length)
                {
                    nextLine = allLines[i + 1];
                }
                else
                {
                    nextLine = string.Empty;
                }
                var currentParts = currentLine.Split('"');
                var nextParts    = nextLine?.Split('"') ?? Array.Empty <string>();
                var path         = currentParts.Last();
                currentLevel = currentParts.Length - 2;
                nextLevel    = Math.Max(nextParts.Length - 2, 0);
                if (path.StartsWith("::") || path == string.Empty)
                { // pseudo-command
                    if (currentNode is CommandNode currentCmd && currentCmd.Command == CommandNode.CommandType.OptionalBlock)
                    {
                        currentNode = new CommandNode(currentLine);
                        currentCommand.Add(currentNode);
                    }
                    else if (path.StartsWith("::endopt"))
                    {
                        while (currentNode.Parent != null)
                        {
                            currentNode = currentNode.Parent;
                            if (currentNode is CommandNode commandNode && commandNode.Command == CommandNode.CommandType.OptionalBlock)
                            {
                                currentNode = currentNode.Parent;
                                break;
                            }
                        }
                    }
                    else
                    {
                        currentCommand = new CommandNode(currentLine);
                        currentNode    = currentCommand;
                        rootNode.Add(currentCommand);
                    }
                    currentLine = nextLine;
                    continue;
                }

                if (currentLevel < nextLevel)
                {
                    LeafNode toAdd = new LeafNode(currentLine);
                    currentNode.Add(toAdd);
                    currentNode = toAdd;
                }
                else if (currentLevel == nextLevel)
                {
                    currentNode.Add(new FileNode(currentLine));
                }
                else if (currentLevel > nextLevel)
                {
                    currentNode.Add(new FileNode(currentLine));
                    while (currentNode.NodeDepth > nextLevel)
                    {
                        currentNode = currentNode.Parent;
                    }
                }

                lineNo++;
                currentLine = nextLine;
            }
        public virtual bool InsertReference(FileEntry fileEntry, bool optional = false)
        {
            LeafNode[] matches = FindAll <LeafNode>(l =>
            {
                if (l.NodeType == RefsNodesType.File ||
                    l.InOptionalBlock() != optional ||
                    l.GetPathSource() != fileEntry.PathSource)
                {
                    return(false);
                }
                string relativePath = l.GetRelativePath();
                if (fileEntry.Fullname.StartsWith(relativePath))
                {
                    return(true);
                }
                return(false);
            });
            LeafNode bestMatch = matches.OrderByDescending(l => l.GetRelativePath().Length).FirstOrDefault();

            if (bestMatch != null)
            {
                for (int i = 0; i < bestMatch.Count; i++)
                {
                    if (bestMatch[i].Count > 0)
                    {
                        bestMatch.AddFile(fileEntry);
                        return(true);
                    }
                }
            }
            else
            {
                RootNode    rootNode           = this as RootNode;
                CommandNode matchedCommandNode = this as CommandNode;
                if (rootNode != null)
                {
                    matchedCommandNode = rootNode.FindAll <CommandNode>(c => c.GetPathSource() == fileEntry.PathSource && c.InOptionalBlock() == optional, 2).FirstOrDefault();
                    if (matchedCommandNode == null)
                    {
                        return(false);
                    }
                }
                string[] pathParts = fileEntry.Fullname.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                if (pathParts.Length == 1)
                {
                    matchedCommandNode.Insert(0, new FileNode(fileEntry.Fullname, fileEntry));
                    return(true);
                }
                RefsNode current = matchedCommandNode;
                for (int i = 0; i < pathParts.Length - 1; i++)
                {
                    LeafNode newLeaf = new LeafNode(pathParts[i] + "/");
                    current.Add(newLeaf);
                    current = newLeaf;
                }
                if (current is LeafNode leaf)
                {
                    leaf.AddFile(fileEntry);
                    return(true);
                }
            }
            return(false);
        }