internal static void Clear(TList list)
            {
                if (list == null)
                {
                    throw new ArgumentNullException("list");
                }
                list.InvokeInMonitorLock(() =>
                {
                    if (list._firstNode == null)
                    {
                        return;
                    }

                    WithAll(list.GetInChange(() =>
                    {
                        var r = list.Select((node, index) =>
                        {
                            RaiseRemovingItem(list, node, index);
                            return(new { Item = node, Index = index });
                        }).ToArray();
                        list._firstNode = list._lastNode = null;
                        list.Count      = 0L;
                        foreach (var i in r)
                        {
                            i.Item._nextNode  = null;
                            i.Item._container = null;
                        }
                        return(r);
                    }), a => RaiseItemRemoved(list, a.Item, a.Index));
                });
            }
 internal static void RemoveAt(TList list, long index)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (index < 0)
     {
         throw new ArgumentOutOfRangeException("index");
     }
     list.InvokeInMonitorLock(() =>
     {
         if (index >= list.Count)
         {
             throw new ArgumentOutOfRangeException("index");
         }
         TElement item         = list._firstNode;
         TElement previousItem = null;
         for (long i = 0L; i < index; i++)
         {
             previousItem = item;
             if ((item = item._nextNode) == null)
             {
                 throw new ArgumentOutOfRangeException("index");
             }
         }
         list.InvokeInChange(() =>
         {
             RaiseRemovingItem(list, item, index);
             if (index == 0)
             {
                 if (list.Count == 1)
                 {
                     list._firstNode = list._lastNode = null;
                     list.Count      = 0;
                 }
                 else if ((list._firstNode = item._nextNode)._nextNode == null)
                 {
                     list._lastNode = list._firstNode;
                     list.Count     = 1;
                 }
                 else
                 {
                     list.Count--;
                 }
             }
             else
             {
                 if ((previousItem._nextNode = item._nextNode)._nextNode == null)
                 {
                     list._lastNode = previousItem;
                 }
                 list.Count--;
             }
             item._container = null;
             item._nextNode  = null;
         });
         RaiseItemRemoved(list, item, index);
     });
 }
 internal static void Add(TList list, TElement item)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     list.InvokeInMonitorLock(() => RaiseItemAdded(list, item, item.GetInMonitorLock(() =>
     {
         ValidateItemOrphaned(list, item);
         return(list.GetInChange(() =>
         {
             long i = list.Count;
             RaiseAddingItem(list, item, i);
             if (list._firstNode == null)
             {
                 list._firstNode = list._lastNode = item;
                 list.Count = 1;
             }
             else
             {
                 list._lastNode._nextNode = item;
                 list._lastNode = item;
                 list.Count++;
             }
             item._container = list;
             return i;
         }));
     })));
 }
                /// <summary>
                ///
                /// </summary>
                /// <param name="disposing"></param>
                protected virtual void Dispose(bool disposing)
                {
                    TList list = _list;

                    if (list != null && disposing)
                    {
                        list.InvokeInMonitorLock(() => _list = null);
                    }
                }
 internal static void CopyTo(TList list, Array array, int arrayIndex)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (array == null)
     {
         throw new ArgumentNullException("array");
     }
     if (arrayIndex < 0)
     {
         throw new ArgumentOutOfRangeException("arrayIndex");
     }
     list.InvokeInMonitorLock(() =>
     {
         if (list.Count + (long)arrayIndex > array.LongLength)
         {
             throw new ArgumentException("Not enough room at end of array", "arrayIndex");
         }
         long index = (long)arrayIndex - 1L;
         for (TElement node = list._firstNode; node != null; node = node._nextNode)
         {
             try
             {
                 index++;
                 array.SetValue(node, index);
             }
             catch (InvalidCastException exception) { throw new ArgumentException(exception.Message, "array", exception); }
             catch (ArgumentException exception)
             {
                 if (list.Count + (long)arrayIndex > array.LongLength)
                 {
                     throw new ArgumentException("Not enough room at end of array", "arrayIndex", exception);
                 }
                 if (exception.ParamName != null && exception.ParamName == "index")
                 {
                     throw new ArgumentException(exception.Message, "arrayIndex", exception);
                 }
                 throw new ArgumentException(exception.Message, "array", exception);
             }
             catch (Exception exception)
             {
                 if (list.Count + (long)arrayIndex > array.LongLength)
                 {
                     throw new ArgumentException("Not enough room at end of array", "arrayIndex");
                 }
                 throw new ArgumentException(exception.Message, "array", exception);
             }
         }
     });
 }
 /// <summary>
 /// Initializes a new <see cref="Enumerator" /> to iterate over the elements of a <typeparamref name="TList" />.
 /// </summary>
 /// <param name="list">The <typeparamref name="TList" /> whose elements are to be iterated.</param>
 public Enumerator(TList list)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     Index = -1;
     _list = list;
     list.InvokeInMonitorLock(() =>
     {
         _firstNode = list._firstNode;
         _lastNode  = list._lastNode;
         _count     = list.Count;
     });
 }
                /// <summary>
                /// Sets the enumerator to its initial position, which is before the first element in the <typeparamref name="TList" />.
                /// </summary>
                /// <exception cref="ObjectDisposedException">The current enumerator or the <typeparamref name="TList" /> being iterated has been <sealso cref="Dispose" />d.</exception>
                public void Reset()
                {
                    TList list = _list;

                    if (list == null)
                    {
                        throw new ObjectDisposedException(typeof(Enumerator).FullName);
                    }
                    list.InvokeInMonitorLock(() =>
                    {
                        if (_list == null)
                        {
                            throw new ObjectDisposedException(typeof(Enumerator).FullName);
                        }
                        Current    = null;
                        Index      = -1;
                        _firstNode = _list._firstNode;
                        _lastNode  = _list._lastNode;
                        _count     = _list.Count;
                    });
                }
 internal static void Set(TList list, long index, TElement value)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (index < 0L)
     {
         throw new IndexOutOfRangeException();
     }
     if (value == null)
     {
         throw new ArgumentNullException();
     }
     list.InvokeInMonitorLock(() =>
     {
         if (index < list.Count)
         {
             TElement previousNode = null;
             TElement currentNode  = list._firstNode;
             for (long i = 0; i < index; i++)
             {
                 if (currentNode == null)
                 {
                     break;
                 }
                 previousNode = currentNode;
                 currentNode  = currentNode._nextNode;
             }
             if (currentNode != null)
             {
                 value.InvokeInMonitorLock(() =>
                 {
                     if (value._container != null)
                     {
                         if (ReferenceEquals(value._container, list))
                         {
                             if (ReferenceEquals(value, currentNode))
                             {
                                 return;
                             }
                             throw new ArgumentOutOfRangeException("value", ErrorMessage_ItemExistsInCurrent);
                         }
                         throw new ArgumentOutOfRangeException("value", ErrorMessage_ItemExistsInCurrent);
                     }
                     list.InvokeInChange(() =>
                     {
                         RaiseReplacingItem(list, currentNode, value, index);
                         value._nextNode = currentNode._nextNode;
                         if (previousNode == null)
                         {
                             list._firstNode = value;
                         }
                         else
                         {
                             previousNode._nextNode = value;
                         }
                         if (value._nextNode == null)
                         {
                             list._lastNode = value;
                         }
                         value._container       = list;
                         currentNode._container = null;
                     });
                 });
                 RaiseItemReplaced(list, currentNode, value, index);
                 return;
             }
         }
         throw new IndexOutOfRangeException();
     });
 }
 internal static void Insert(TList list, long index, TElement item)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (index < 0L)
     {
         throw new ArgumentOutOfRangeException("index");
     }
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     list.InvokeInMonitorLock(() =>
     {
         if (index > list.Count)
         {
             throw new ArgumentOutOfRangeException("index");
         }
         item.InvokeInMonitorLock(() =>
         {
             ValidateItemOrphaned(list, item);
             list.InvokeInChange(() =>
             {
                 RaiseAddingItem(list, item, index);
                 if (index == list.Count)
                 {
                     if (index == 0L)
                     {
                         list._firstNode = item;
                         list.Count      = 1L;
                     }
                     else
                     {
                         list._lastNode._nextNode = item;
                         list.Count++;
                     }
                     list._lastNode = item;
                 }
                 else if (index == 0L)
                 {
                     item._nextNode  = list._firstNode;
                     list._firstNode = item;
                 }
                 else if (index == list.Count - 1)
                 {
                     list._lastNode._nextNode = item;
                     list._lastNode           = item;
                 }
                 else
                 {
                     TElement previousItem = list._firstNode;
                     for (long i = 1L; i < index; i++)
                     {
                         if ((previousItem = previousItem._nextNode) == null)
                         {
                             throw new ArgumentOutOfRangeException("index");
                         }
                     }
                     item._nextNode         = previousItem._nextNode;
                     previousItem._nextNode = item;
                 }
                 item._container = list;
             });
         });
         RaiseItemAdded(list, item, index);
     });
 }