// TODO:
        // 1) Move to Node extension method
        // 2) Use predicate which returns true as soon as we find graphElementModel that corresponds to node's graphElementModel
        public static bool IsNodeConnectedTo(Experimental.GraphView.Node node,
                                             Experimental.GraphView.Node otherNode)
        {
            if (node == null)
            {
                return(false);
            }

            var otherGraphElementModel = (otherNode as IHasGraphElementModel)?.GraphElementModel;

            if (otherGraphElementModel == null)
            {
                return(false);
            }

            // Fetch all nodes first
            HashSet <Experimental.GraphView.Node> visitedNodes =
                new HashSet <Experimental.GraphView.Node>();

            VisitNodes(node, ref visitedNodes);

            return(visitedNodes.Any(x =>
                                    x is IHasGraphElementModel hasGraphElementModel &&
                                    ReferenceEquals(hasGraphElementModel.GraphElementModel, otherGraphElementModel)));
        }
        static void VisitNodes(Experimental.GraphView.Node node, ref HashSet <Experimental.GraphView.Node> visitedGraphElements)
        {
            if (node == null || visitedGraphElements == null || visitedGraphElements.Contains(node))
            {
                return;
            }

            if (node is StackNode)
            {
                foreach (var visualElement in node.inputContainer.Children())
                {
                    var port = (Port)visualElement;
                    if (port?.connections == null)
                    {
                        continue;
                    }

                    foreach (Experimental.GraphView.Edge connection in port.connections)
                    {
                        Experimental.GraphView.Port otherConnection = connection.output;
                        Experimental.GraphView.Node otherNode       = otherConnection?.node;
                        if (otherNode == null)
                        {
                            continue;
                        }

                        visitedGraphElements.Add(otherNode);
                        VisitNodes(otherNode, ref visitedGraphElements);
                    }
                }
            }
            else
            {
                foreach (var visualElement in node.outputContainer.Children())
                {
                    var port = (Port)visualElement;
                    if (port?.connections == null)
                    {
                        continue;
                    }

                    foreach (Experimental.GraphView.Edge connection in port.connections)
                    {
                        Experimental.GraphView.Port otherConnection = connection.input;
                        Experimental.GraphView.Node otherNode       = otherConnection?.node;
                        if (otherNode == null)
                        {
                            continue;
                        }

                        visitedGraphElements.Add(otherNode);
                        VisitNodes(otherNode, ref visitedGraphElements);
                    }
                }
            }

            switch (node)
            {
            case FunctionNode functionNode:
                visitedGraphElements.Add(functionNode);
                break;

            case Node vsNode when vsNode.IsInStack:
                visitedGraphElements.Add(vsNode.Stack);
                break;
            }
        }