private NodeCursor FindInsertNodeCursorImpl(long index)
        {
            if (Count == 0 || ReferenceEquals(HeadNode.Next, TailNode))
            {
                return(HeadCursor);
            }

            if (TailCursor.Contains(index))
            {
                return(TailCursor);
            }

            var cursor = Cursor;

            if (cursor.Contains(index))
            {
                return(cursor);
            }

            if (index >= cursor.Index)
            {
                while (cursor.Node != null)
                {
                    var next = cursor.GetNext();

                    if (cursor.Contains(index, true))
                    {
                        return((next.Contains(index) ? next : cursor).WithIndex(index));
                    }

                    cursor = next;
                }
            }
            else
            {
                while (cursor.Node != null)
                {
                    var prev = cursor.GetPrev();

                    if (cursor.Contains(index, true))
                    {
                        return((prev.Contains(index) ? prev : cursor).WithIndex(index));
                    }

                    cursor = prev;
                }
            }

            return(NodeCursor.Empty);
        }
        private protected void InsertCleanRangeImpl(long index, long count)
        {
            try
            {
                EnterStructureChange();

                if (ReferenceEquals(HeadNode.Next, TailNode))
                {
                    HeadNode.Size += count;
                    LongCount     += count;

                    return;
                }

                if (index == 0 || HeadCursor.Contains(index))
                {
                    HeadNode.Size += count;
                    LongCount     += count;

                    return;
                }

                if (index == LongCount || TailCursor.Contains(index))
                {
                    TailNode.Size += count;
                    LongCount     += count;

                    return;
                }

                var cursor       = FindInsertNodeCursorImpl(index);
                var node         = cursor.Node;
                var realizedNode = node as RealizedNode;
                var prevNode     = node.Prev;
                var nextNode     = node.Next;

                if (prevNode is GapNode prevGapNode && cursor.GetPrev().NodeOffset == index)
                {
                    prevGapNode.Size += count;
                    LongCount        += count;

                    return;
                }

                if (realizedNode == null)
                {
                    node.Size += count;
                    LongCount += count;

                    return;
                }

                var splitIndex = (int)(index - cursor.NodeOffset);
                var splitCount = (int)(realizedNode.Size - splitIndex);

                if (count <= NodeCapacity - realizedNode.Size)
                {
                    //Array.Copy(realizedNode.Items, splitIndex, realizedNode.Items, splitIndex + count, splitCount);

                    var sourceSpan = realizedNode.Span.Slice(splitIndex, splitCount);
                    var targetSpan = realizedNode.Span.Slice((int)(splitIndex + count), splitCount);

                    sourceSpan.CopyTo(targetSpan);

                    //Array.Clear(realizedNode.Items, splitIndex, count);

                    var clearSpan = realizedNode.Span.Slice(splitIndex, (int)count);

                    clearSpan.Clear();

                    realizedNode.Size += count;

                    LongCount += count;

                    return;
                }

                var gapNode = Manager.GetGapNode();

                gapNode.Size = count;

                if (index == cursor.NodeOffset)
                {
                    gapNode.Prev = prevNode;
                    gapNode.Next = realizedNode;

                    prevNode.Next     = gapNode;
                    realizedNode.Prev = gapNode;
                }
                else
                {
                    var nextRealizedNode = Manager.GetRealizedNode();

                    node.Next = gapNode;

                    gapNode.Prev = node;
                    gapNode.Next = nextRealizedNode;

                    nextRealizedNode.Size = splitCount;
                    nextRealizedNode.Prev = gapNode;
                    nextRealizedNode.Next = nextNode;
                    nextNode.Prev         = nextRealizedNode;

                    realizedNode.Size = splitIndex;

                    //Array.Copy(realizedNode.ItemsPrivate, splitIndex, nextRealizedNode.ItemsPrivate, 0, splitCount);
                    var sourceSpan = realizedNode.Span.Slice(splitIndex, splitCount);
                    var targetSpan = nextRealizedNode.Span.Slice(0, splitCount);

                    sourceSpan.CopyTo(targetSpan);

                    //Array.Clear(realizedNode.ItemsPrivate, splitIndex, splitCount);
                    sourceSpan.Clear();
                }

                LongCount += count;
            }
            finally
            {
                LeaveStructureChange();
            }
        }