private bool HandleUndoOperation(GraphCommand command)
        {
            DeltaNodes deltaNodes = new DeltaNodes();

            // Start tracking variables being undefined in this process.
            {
                RuntimeStates runtimeStates = this.GetRuntimeStates();
                runtimeStates.BeginDefinitionMonitor();
                this.undoRedoRecorder.Undo(deltaNodes);

                Dictionary <uint, List <string> > undefinedVariables = null;
                runtimeStates.EndDefinitionMonitor(out undefinedVariables);
                deltaNodes.AppendUndefinedVariables(undefinedVariables);
            }

            this.ValidateNodesSyntax(this.nodeCollection.Values.ToList <IVisualNode>());
            this.ValidateDefinedAndReferencedVariables();
            if (false == deltaNodes.IsEmpty)
            {
                this.SynchronizeToLiveRunner(deltaNodes);
            }

            this.UpdateDirtyNodes();
            this.edgeController.UpdateDirtyEdges(deltaNodes.ModifiedNodes);
            selectionBox.UpdateSelectionBox(GetSelectedNodes());
            return(true);
        }
        private bool HandleDeleteComponents(GraphCommand command)
        {
            if (currentDragState != DragState.None)
            {
                currentDragState = DragState.None;
                edgeController.ResetParameters();
            }

            DeltaNodes deltaNodes = new DeltaNodes();

            foreach (VisualNode node in nodeCollection.Values)
            {
                if (node.Selected)
                {
                    deltaNodes.AppendToRemovedNodes(node);
                }
            }

            if ((null == deltaNodes.RemovedNodes) && edgeController.SelectedEdgeCount() == 0)
            {
                return(true);
            }

            if (null != deltaNodes.RemovedNodes && (deltaNodes.RemovedNodes.Count > 0))
            {
                deltaNodes.AppendToModifiedNodes(FindAssociatedNodesFromNodes(deltaNodes.RemovedNodes));
            }
            List <IVisualNode> nodesConnectToEdge = edgeController.GetNodesFromSelectedEdges();

            foreach (IVisualNode node in nodesConnectToEdge)
            {
                bool inDeleteList = (null != deltaNodes.RemovedNodes && (deltaNodes.RemovedNodes.Contains(node)));
                bool inModifyList = (null != deltaNodes.ModifiedNodes && (deltaNodes.ModifiedNodes.Contains(node)));

                if (!inDeleteList && !inModifyList)
                {
                    deltaNodes.AppendToModifiedNodes(node);
                }
            }

            // Begin tracking variables being undefined in this process.
            {
                RuntimeStates runtimeStates = this.GetRuntimeStates();
                runtimeStates.BeginDefinitionMonitor();

                this.undoRedoRecorder.BeginGroup();
                this.undoRedoRecorder.RecordRuntimeStatesForUndo(this.graphProperties.RuntimeStates);
                this.undoRedoRecorder.RecordNodeDeletionForUndo(deltaNodes.RemovedNodes);
                this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                this.edgeController.DeleteSelectedEdges();
                this.DeleteNodes(deltaNodes.RemovedNodes);
                this.ValidateDefinedAndReferencedVariables();
                this.UpdateSlotsVisiblity();
                EstablishImplicitConnections(this.nodeCollection.Values.ToList());
                this.undoRedoRecorder.EndGroup();

                // Gather the data of variables being undefined.
                Dictionary <uint, List <string> > undefinedVariables = null;
                runtimeStates.EndDefinitionMonitor(out undefinedVariables);
                deltaNodes.AppendUndefinedVariables(undefinedVariables);
            }

            //After DeleteSelectedEdges() and DeleteNodes() are executed, the nodes in the nodeToModify would already be modified
            if (false == deltaNodes.IsEmpty)
            {
                this.SynchronizeToLiveRunner(deltaNodes);
            }

            this.UpdateDirtyNodes();

            //If the node is selected for deletion by clicking on the preview, the lastHoveredNode should be reset
            lastHoveredNodeId = uint.MaxValue;

            selectionBox.UpdateSelectionBox(GetSelectedNodes());
            return(true);
        }
        private bool HandleEndDrag(GraphCommand command)
        {
            MouseButton  button    = ((MouseButton)command.GetArgument(0));
            uint         compId    = ((uint)command.GetArgument(1));
            NodePart     nodePart  = ((NodePart)command.GetArgument(2));
            int          slotIndex = ((int)command.GetArgument(3));
            ModifierKeys modifiers = ((ModifierKeys)command.GetArgument(4));
            double       mouseX    = ((double)command.GetArgument(5));
            double       mouseY    = ((double)command.GetArgument(6));

            switch (currentDragState)
            {
            case DragState.NodeRepositioning:
                foreach (DraggedNode draggedNode in dragSet)
                {
                    ((VisualNode)draggedNode.node).X = mouseX - draggedNode.DeltaX;
                    ((VisualNode)draggedNode.node).Y = mouseY - draggedNode.DeltaY;
                }

                // both node that the edge is connected to should be bring to back
                //
                foreach (VisualNode connectingNode in edgeController.GetNodesFromSelectedEdges())
                {
                    if (!connectingNode.Selected)
                    {
                        RearrangeNodeAndBubbleVisual(connectingNode, false);
                    }
                }

                dragSet.Clear();
                edgeController.ResetAllEdges();
                break;

            case DragState.CurveDrawing:
            case DragState.EdgeReconnection:
                edgeConnection = EdgeConnectionFlag.None;

                VisualNode node = GetVisualNode(edgeController.GetConnectNodeId());
                if (null != node)
                {
                    node.PreviewSelected = node.Selected;
                    node.Compose();     // Optionally redraw the node.
                }
                node = GetVisualNode(edgeController.GetCurrentlySelectedNodeId());
                if (null != node)
                {
                    node.Selected = false;
                    node.Compose();     // reset highlighted node
                }

                node = GetVisualNode(compId);
                List <IVisualNode> modifiedNodes = null;
                edgeConnection = edgeController.AttemptConnectEdge(node, nodePart, slotIndex, out modifiedNodes);

                DeltaNodes deltaNodes = new DeltaNodes();
                deltaNodes.AppendToModifiedNodes(modifiedNodes.Distinct().ToList());

                //reset highlighted node
                foreach (IVisualNode visualNode in deltaNodes.ModifiedNodes)
                {
                    ((VisualNode)visualNode).Selected = false;
                }

                // Start tracking variables being undefined in this process.
                {
                    RuntimeStates runtimeStates = graphProperties.RuntimeStates;
                    runtimeStates.BeginDefinitionMonitor();

                    undoRedoRecorder.BeginGroup();
                    undoRedoRecorder.RecordRuntimeStatesForUndo(runtimeStates);
                    undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                    edgeController.CreateEdge();

                    modifiedNodes.Clear();
                    this.EstablishImplicitConnections(modifiedNodes);
                    undoRedoRecorder.EndGroup();

                    Dictionary <uint, List <string> > undefinedVariables = null;
                    runtimeStates.EndDefinitionMonitor(out undefinedVariables);
                    deltaNodes.AppendUndefinedVariables(undefinedVariables);
                }

                deltaNodes.AppendToModifiedNodes(modifiedNodes);
                if (deltaNodes.ModifiedNodes.Count > 0)      //modification have been done
                {
                    SynchronizeToLiveRunner(deltaNodes);
                }
                else
                {
                    undoRedoRecorder.PopRecordFromUndoStorage();
                }

                edgeController.ResetParameters();
                edgeController.ResetAllEdges();
                currentDragState = DragState.None;
                edgeConnection   = EdgeConnectionFlag.None;
                break;

            case DragState.RegionSelection:
                if (visualHost != null)
                {
                    visualHost.EndDragSelection();
                }
                break;
            }
            //currentDragState = DragState.None;
            selectionBox.UpdateSelectionBox(GetSelectedNodes());
            return(true);
        }