internal ExpandedPath.Action LocateNodeByExpandedPath(ExpandedPath ep, NodeProvider node, out NodeProvider?handlingNode)
        {
            var action = node.HandlePath(ep);

            switch (action)
            {
            case Unknown:
                throw new NotImplementedException($"handler for {node.GetType().ToString()} returned Unknown");

            case NotFound:
                // TODO
                handlingNode = null;
                return(ExpandedPath.Action.NotFound);

            case PassThrough:
                // TODO
                foreach (var child in node.Children)
                {
                    var res = LocateNodeByExpandedPath(ep.NextLevel(), child, out handlingNode);
                    if (res == ExpandedPath.Action.Handle)
                    {
                        return(ExpandedPath.Action.Handle);
                    }
                }
                handlingNode = null;
                return(ExpandedPath.Action.NotFound);

            case Handle:
                handlingNode = node;
                return(ExpandedPath.Action.Handle);
            }

            handlingNode = null;
            return(ExpandedPath.Action.Unknown);
        }
 private static void SetLevel(NodeProvider node, int level = 0)
 {
     node.Level = level;
     foreach (var child in node.Children)
     {
         SetLevel(child, level + 1);
     }
 }
 public NodeDispatcher(NodeProvider root)
 {
     Root = root;
     SetLevel(Root);
 }