private void Link([CanBeNull] NodeRow parentNodeRow, [CanBeNull] NodeRow previousSiblingRow, [CanBeNull] NodeRow nextSiblingRow)
 {
     using (this.GetScope())
     {
         Unlink();
         ParentNodeRow = parentNodeRow;
         if (parentNodeRow == null)
         {
             RootControlRow = Table.DataSet.ControlRow;
         }
         PreviousSiblingRow = previousSiblingRow;
         if (nextSiblingRow != null)
         {
             nextSiblingRow.PreviousSiblingRow = this;
         }
         ControlRow = Table.DataSet.ControlRow;
     }
 }
        public void SetAs(NodeTargetMode mode, [CanBeNull] NodeRow target)
        {
            using (this.GetScope())
            {
                if (target == null)
                {
                    var currentControlRow = Table.DataSet.ControlRow;
                    var firstRootNode     = Table.DataSet.NodesTable.FirstOrDefault(n => n.ParentNodeRow == null && n.ControlRow == currentControlRow)?.FirstSibling;
                    if (mode == NodeTargetMode.FirstChild)
                    {
                        Link(null, null, firstRootNode);
                    }
                    else
                    {
                        Link(null, firstRootNode?.LastSibling, null);
                    }
                }
                else
                {
                    switch (mode)
                    {
                    case NodeTargetMode.LastChild:
                        Link(target, target.ChildNodeRows.FirstOrDefault()?.LastSibling, null);
                        break;

                    case NodeTargetMode.FirstChild:
                        Link(target, null, target.ChildNodeRows.FirstOrDefault()?.FirstSibling);
                        break;

                    case NodeTargetMode.PreviousSibling:
                        Link(target.ParentNodeRow, target.PreviousSiblingRow, target);
                        break;

                    case NodeTargetMode.NextSibling:
                        Link(target.ParentNodeRow, target, target.NextSiblingRow);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
                    }
                }
            }
        }