public bool Remove(IEnumerable <ConversationNode> nodes, IEnumerable <NodeGroup> groups, ILocalizationEngine localization) { nodes = nodes.ToList(); groups = groups.ToList(); bool removeNodes = nodes.Any(); bool removeGroups = groups.Any(); List <Action> undoActions = new List <Action>(); List <Action> redoActions = new List <Action>(); if (nodes.Any(n => !CanRemoveFromData(n, () => false))) { if (!PromptNodeDeletion()) { return(false); } } if (removeNodes) { //Make sure all the nodes are added before trying to link them foreach (var node in nodes) { var n = node; undoActions.Add(() => { m_nodes.Add(n); }); } foreach (var node in nodes) { var n = node; var actions = n.GetNodeRemoveActions(); //Ensure that the localization engine is up to date in terms of usage of localized data foreach (var parameter in n.Data.Parameters.OfType <ILocalizedStringParameter>()) { SimpleUndoPair clearLocalization = localization.ClearLocalizationAction(Id <LocalizedStringType> .ConvertFrom(parameter.TypeId), parameter.Value); undoActions.Add(clearLocalization.Undo); redoActions.Add(clearLocalization.Redo); } var containingGroups = m_groups.Where(g => g.Contents.Contains(n.Data.NodeId)).Evaluate(); undoActions.Add(() => { actions.Undo(); //Connect after adding the node foreach (var group in containingGroups) { group.Contents.Add(n.Data.NodeId); } m_audioProvider.UpdateUsage(n); }); redoActions.Add(() => { actions.Redo(); //Disconnect before removing the node m_nodes.Remove(n); foreach (var group in containingGroups) { group.Contents.Remove(n.Data.NodeId); } NodesDeleted.Execute(); }); } } if (removeGroups) { List <NodeGroup> toAdd = new List <NodeGroup>(groups); undoActions.Add(() => { m_groups.AddRange(toAdd); }); redoActions.Add(() => { m_groups.RemoveRange(toAdd); }); } Action undo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in undoActions) { action(); } }; Action redo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in redoActions) { action(); } }; string message; if (removeNodes && removeGroups) { message = "Deleted elements"; } else if (removeNodes) { message = "Deleted nodes"; } else if (removeGroups) { message = "Removed groupings"; } else { throw new InternalLogicException("Something went wrong :("); } UndoableFile.Change(new GenericUndoAction(undo, redo, message)); return(true); }