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 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 bool Remove(TList list, TElement item)
 {
     if (list == null)
     {
         throw new ArgumentNullException("list");
     }
     if (item == null)
     {
         return(false);
     }
     return(list.GetInMonitorLock(() =>
     {
         if (list.Count == 0)
         {
             return false;
         }
         if (item.GetInMonitorLock(() => item._container == null || !ReferenceEquals(item._container, list)))
         {
             return false;
         }
         if (ReferenceEquals(list._firstNode, item))
         {
             list.InvokeInChange(() =>
             {
                 RaiseRemovingItem(list, item, 0L);
                 list._firstNode = item._nextNode;
                 if (list._firstNode == null)
                 {
                     list.Count = 0L;
                     list._lastNode = null;
                 }
                 else if (list._firstNode._nextNode == null)
                 {
                     list.Count = 1L;
                     list._lastNode = list._firstNode;
                 }
                 else
                 {
                     list.Count--;
                 }
                 item._container = null;
                 item._nextNode = null;
             });
             RaiseItemRemoved(list, item, 0L);
             return true;
         }
         long index = 0L;
         TElement previousItem = list._firstNode;
         for (TElement node = previousItem._nextNode; node != null; node = node._nextNode)
         {
             index++;
             if (ReferenceEquals(node, item))
             {
                 list.InvokeInChange(() =>
                 {
                     RaiseRemovingItem(list, item, index);
                     previousItem._nextNode = item._nextNode;
                     if (previousItem._nextNode == null)
                     {
                         list._lastNode = previousItem;
                     }
                 });
                 RaiseItemRemoved(list, item, index);
                 return true;
             }
             previousItem = node;
         }
         return false;
     }));
 }
 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);
     });
 }