/// <summary>
        /// Adds a dependant to this node.
        /// </summary>
        /// <param name="node">The node.</param>
        internal void AddDependant(PluginDependencyTreeNode node)
        {
            if (_dependants.Contains(node))
            {
                return;
            }

            _dependants.Add(node);
        }
        /// <summary>
        /// Adds a dependency branch to the tree.
        /// </summary>
        /// <param name="branch">The branch.</param>
        internal void AddBranch(PluginDependencyTreeNode branch)
        {
            if (_branches.Contains(branch))
            {
                return;
            }

            _branches.Add(branch);
        }
        private async Task <IEnumerable <TResult> > WalkNodeAsync <TResult>
        (
            PluginDependencyTreeNode node,
            Func <PluginDependencyTreeNode, Exception?, TResult> errorFactory,
            Func <PluginDependencyTreeNode, Task <TResult> > preOperation,
            Func <PluginDependencyTreeNode, Task <TResult> >?postOperation = null
        )
            where TResult : IResult
        {
            var results = new List <TResult>();

            try
            {
                var result = await preOperation(node);

                results.Add(result);

                if (!result.IsSuccess)
                {
                    results.AddRange(node.GetAllDependants().Select(d => errorFactory(d, null)));
                    return(results);
                }
            }
            catch (Exception e)
            {
                results.Add(errorFactory(node, e));
                results.AddRange(node.GetAllDependants().Select(d => errorFactory(d, null)));
                return(results);
            }

            foreach (var dependant in node.Dependants)
            {
                results.AddRange(await WalkNodeAsync(dependant, errorFactory, preOperation, postOperation));
            }

            if (postOperation is null)
            {
                return(results);
            }

            try
            {
                var result = await postOperation(node);

                results.Add(result);

                if (!result.IsSuccess)
                {
                    results.AddRange(node.GetAllDependants().Select(d => errorFactory(d, null)));
                    return(results);
                }
            }
            catch (Exception e)
            {
                results.Add(errorFactory(node, e));
                results.AddRange(node.GetAllDependants().Select(d => errorFactory(d, null)));
                return(results);
            }

            return(results);
        }