public void Replace(ObjectValueNode node, ObjectValueNode[] replacementNodes)
        {
            if (!TryGetValue(node, out var item))
            {
                return;
            }

            var parent = item.Parent;
            int index  = -1;

            if (parent == null)
            {
                return;
            }

            for (int i = 0; i < parent.Children.Count; i++)
            {
                if (parent.Children[i] == item)
                {
                    index = i;
                    break;
                }
            }

            if (index == -1)
            {
                return;
            }

            parent.Children.RemoveAt(index);
            mapping.Remove(item.Target);
            item.Dispose();

            treeView.BeginUpdates();

            var indexes = new NSIndexSet(index);

            if (parent.Target is RootObjectValueNode)
            {
                treeView.RemoveItems(indexes, null, NSTableViewAnimation.None);
            }
            else
            {
                treeView.RemoveItems(indexes, parent, NSTableViewAnimation.None);
            }

            if (replacementNodes.Length > 0)
            {
                for (int i = 0; i < replacementNodes.Length; i++)
                {
                    Insert(parent, index + i, replacementNodes [i]);
                }

                var range = new NSRange(index, replacementNodes.Length);
                indexes = NSIndexSet.FromNSRange(range);

                if (parent.Target is RootObjectValueNode)
                {
                    treeView.InsertItems(indexes, null, NSTableViewAnimation.None);
                }
                else
                {
                    treeView.InsertItems(indexes, parent, NSTableViewAnimation.None);
                }

                foreach (var n in replacementNodes)
                {
                    if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint(n))
                    {
                        if (TryGetValue(n, out MacObjectValueNode x))
                        {
                            treeView.ExpandItem(x);
                        }
                    }
                }
            }

            treeView.EndUpdates();
        }
        public void Replace(ObjectValueNode node, ObjectValueNode[] replacementNodes)
        {
            if (!TryGetValue(node, out var item))
            {
                return;
            }

            var parent = item.Parent;
            int index  = -1;

            if (parent == null)
            {
                return;
            }

            for (int i = 0; i < parent.Children.Count; i++)
            {
                if (parent.Children[i] == item)
                {
                    index = i;
                    break;
                }
            }

            if (index == -1)
            {
                return;
            }

            var removed = new List <MacObjectValueNode> ();

            parent.Children.RemoveAt(index);
            Remove(item, removed);

            treeView.BeginUpdates();

            try {
                var indexes = new NSIndexSet(index);

                if (parent.Target is RootObjectValueNode)
                {
                    treeView.RemoveItems(indexes, null, NSTableViewAnimation.None);
                }
                else
                {
                    treeView.RemoveItems(indexes, parent, NSTableViewAnimation.None);
                }

                if (replacementNodes.Length > 0)
                {
                    for (int i = 0; i < replacementNodes.Length; i++)
                    {
                        Insert(parent, index + i, replacementNodes[i]);
                    }

                    var range = new NSRange(index, replacementNodes.Length);
                    indexes = NSIndexSet.FromNSRange(range);

                    if (parent.Target is RootObjectValueNode)
                    {
                        treeView.InsertItems(indexes, null, NSTableViewAnimation.None);
                    }
                    else
                    {
                        treeView.InsertItems(indexes, parent, NSTableViewAnimation.None);
                    }

                    RestoreExpandedState(replacementNodes);
                }
            } finally {
                treeView.EndUpdates();
            }

            for (int i = 0; i < removed.Count; i++)
            {
                removed[i].Dispose();
            }
        }