private void EstablishImplicitConnections(List<IVisualNode> modifiedNodes)
        {
            //Get all exsting implicit edges
            List<KeyValuePair<uint, uint>> existingImplicitEdges = edgeController.GetImplicitlyConnectedSlots();

            // This dictionary contains a string-list pair, where the "string" represents a referenced variable
            // name, and the "list" represents the list of visual nodes that reference the referenced variable.
            Dictionary<string, List<VisualNode>> referencedVarToNodes = new Dictionary<string, List<VisualNode>>();
            foreach (VisualNode node in nodeCollection.Values)
            {
                List<string> referencedVariableList = node.GetReferencedVariables(false);
                if (null == referencedVariableList)
                    continue;

                foreach (string referenceVariable in referencedVariableList)
                {
                    if (!referencedVarToNodes.ContainsKey(referenceVariable))
                        referencedVarToNodes.Add(referenceVariable, new List<VisualNode>());
                    referencedVarToNodes[referenceVariable].Add(node);
                }
            }

            //For each RefVar get the node that the variable define in: Dict < var, node >
            foreach (string referencedVariable in referencedVarToNodes.Keys)
            {
                uint definingNodeId = this.graphProperties.RuntimeStates.GetDefiningNode(referencedVariable);
                if (definingNodeId == uint.MaxValue) // A variable that is not defined anywhere.
                    continue;

                //Connect the nodes together by GC.ConnectNodesImplicitly
                VisualNode definingNode = this.GetVisualNode(definingNodeId);
                if (definingNode.Error) // We don't connect to/from erroneous nodes.
                    continue;

                foreach (VisualNode referencedNode in referencedVarToNodes[referencedVariable])
                {
                    if (referencedNode.Error) // We don't connect to/from erroneous nodes.
                        continue;

                    if (definingNode.NodeId != referencedNode.NodeId)
                    {
                        ImplicitConnectionRequest request = new ImplicitConnectionRequest();
                        request.variable = referencedVariable;
                        request.definingNode = definingNode;
                        request.referencedNode = referencedNode;
                        request.existingImplicitEdges = existingImplicitEdges;
                        request.modifiedNodes = modifiedNodes;
                        this.ConnectNodeImplicitly(request);
                    }
                }
            }

            //Remove edge that no longer exist
            this.RemoveEdgeList(existingImplicitEdges, modifiedNodes);
            edgeController.DeleteUnnecessaryEdges();
        }
        private void ConnectNodeImplicitly(ImplicitConnectionRequest request)
        {
            string variable = request.variable;
            VisualNode definingNode = request.definingNode;
            VisualNode referencedNode = request.referencedNode;
            List<IVisualNode> modifiedNodes = request.modifiedNodes;
            List<KeyValuePair<uint, uint>> existingImplicitEdges = request.existingImplicitEdges;

            List<uint> outputSlotIds = definingNode.GetSlotIdsByName(SlotType.Output, variable);
            uint outputSlotID = outputSlotIds[outputSlotIds.Count - 1];

            List<uint> inputSlotIds = referencedNode.GetSlotIdsByName(SlotType.Input, variable);
            uint inputSlotID = inputSlotIds[0];

            KeyValuePair<uint, uint> outputInputSlotID = new KeyValuePair<uint, uint>(outputSlotID, inputSlotID);

            if (existingImplicitEdges.Contains(outputInputSlotID))
                existingImplicitEdges.Remove(outputInputSlotID);
            else
            {
                Slot outputSlot = slotCollection[outputSlotID] as Slot;
                uint outputNodeId = outputSlot.Owners[0];
                VisualNode outputNode = GetVisualNode(outputNodeId);

                Slot inputSlot = slotCollection[inputSlotID] as Slot;
                uint inputNodeId = inputSlot.Owners[0];
                VisualNode inputNode = GetVisualNode(inputNodeId);

                List<IVisualNode> nodeList = new List<IVisualNode>();
                nodeList.Add(outputNode);
                nodeList.Add(inputNode);
                undoRedoRecorder.RecordNodeModificationForUndo(nodeList);

                edgeController.CreateImplicitEdge(outputSlot, inputSlot);

                // Mark these nodes as being modified.
                request.modifiedNodes.Add(outputNode);
                request.modifiedNodes.Add(inputNode);
            }
        }