internal static T[] ToArray(ProducerConsumerQueue <T> target)
            {
                List <T> removed = new List <T>();

                Monitor.Enter(target.SyncRoot);
                try
                {
                    if (target._firstElement == null)
                    {
                        return(new T[0]);
                    }
                    for (QueueItem item = target._firstElement; item != null; item = item._followingElement)
                    {
                        removed.Add(item._value);
                    }
                    bool wasFull = target.Count == target.BoundedCapacity;
                    target.Count         = 0;
                    target._firstElement = target._lastElement = null;
                    target._notEmptyEvent.Reset();
                    if (target.IsAddingCompleted)
                    {
                        target.IsCompleted = true;
                    }
                    if (wasFull)
                    {
                        target._notFullEvent.Set();
                    }
                }
                finally { Monitor.Exit(target.SyncRoot); }
                if (removed.Count > 0)
                {
                    target.RaiseCollectionReset(removed.ToArray());
                }
                return(removed.ToArray());
            }
 internal static bool TryTake(ProducerConsumerQueue <T> target, out T item)
 {
     Monitor.Enter(target.SyncRoot);
     try
     {
         if (target._firstElement == null)
         {
             item = default(T);
             return(false);
         }
         item = target._firstElement._value;
         bool wasFull = target.Count == target.BoundedCapacity;
         target.Count--;
         if (target._firstElement._followingElement == null)
         {
             target._firstElement = target._lastElement = null;
             target._notEmptyEvent.Reset();
             if (target.IsAddingCompleted)
             {
                 target.IsCompleted = true;
             }
         }
         else
         {
             (target._firstElement = target._firstElement._followingElement)._precedingElement = null;
         }
         if (wasFull)
         {
             target._notFullEvent.Set();
         }
     }
     finally { Monitor.Exit(target.SyncRoot); }
     target.RaiseItemRemoved(0, item);
     return(true);
 }
 internal static bool TryPush(ProducerConsumerQueue <T> target, T item)
 {
     Monitor.Enter(target.SyncRoot);
     try
     {
         if (target.IsAddingCompleted || target.Count == target.BoundedCapacity)
         {
             return(false);
         }
         target.Count++;
         if (target._firstElement == null)
         {
             target._firstElement = target._lastElement = new QueueItem(item);
             target._notEmptyEvent.Set();
         }
         else
         {
             target._firstElement = target._firstElement._precedingElement = new QueueItem(item)
             {
                 _followingElement = target._firstElement
             }
         };
         if (target.Count == target.BoundedCapacity)
         {
             target._notFullEvent.Reset();
         }
     }
     finally { Monitor.Exit(target.SyncRoot); }
     target.RaiseItemAdded(0, item);
     return(true);
 }
            internal static void CopyTo(ProducerConsumerQueue <T> target, Array array, int index)
            {
                List <T> list = new List <T>();

                Monitor.Enter(target.SyncRoot);
                try
                {
                    for (QueueItem item = target._firstElement; item != null; item = item._followingElement)
                    {
                        list.Add(item._value);
                    }
                }
                finally { Monitor.Exit(target.SyncRoot); }
                list.ToArray().CopyTo(array, index);
            }
 internal static bool TryPeek(ProducerConsumerQueue <T> target, out T item)
 {
     Monitor.Enter(target.SyncRoot);
     try
     {
         if (target._firstElement == null)
         {
             item = default(T);
             return(false);
         }
         item = target._firstElement._value;
     }
     finally { Monitor.Exit(target.SyncRoot); }
     return(true);
 }
 internal static bool Contains(ProducerConsumerQueue <T> target, T item)
 {
     Monitor.Enter(target.SyncRoot);
     try
     {
         for (QueueItem q = target._firstElement; q != null; q = q._followingElement)
         {
             if (target._areEqual(q._value, item))
             {
                 return(true);
             }
         }
     }
     finally { Monitor.Exit(target.SyncRoot); }
     return(false);
 }
            internal static bool Remove(ProducerConsumerQueue <T> target, T item)
            {
                bool collectionChanged = false;

                Monitor.Enter(target.SyncRoot);
                try
                {
                    for (QueueItem q = target._firstElement; q != null; q = q._followingElement)
                    {
                        if (target._areEqual(q._value, item))
                        {
                            item = q._value;
                            target.Count--;
                            collectionChanged = true;
                            bool wasFull = target.Count == target.BoundedCapacity;
                            if (q._precedingElement == null)
                            {
                                if (q._followingElement == null)
                                {
                                    target._firstElement = target._lastElement = null;
                                    target._notEmptyEvent.Reset();
                                }
                                else
                                {
                                    (target._firstElement = q._followingElement)._precedingElement = null;
                                }
                            }
                            else if (q._followingElement == null)
                            {
                                (target._lastElement = q._precedingElement)._followingElement = null;
                            }
                            else
                            {
                                q._precedingElement._followingElement = q._followingElement;
                                q._followingElement._precedingElement = q._precedingElement;
                            }
                            break;
                        }
                    }
                }
                finally { Monitor.Exit(target.SyncRoot); }
                if (collectionChanged)
                {
                    target.RaiseItemRemoved(0, item);
                }
                return(collectionChanged);
            }
 internal ConsumingEnumerator(ProducerConsumerQueue <T> target, CancellationToken?cancellationToken)
 {
     _target                   = target;
     _cancellationToken        = cancellationToken;
     target.CollectionChanged += Target_CollectionChanged;
 }
 internal ConsumingEnumerable(ProducerConsumerQueue <T> target, CancellationToken?cancellationToken)
 {
     _target            = target;
     _cancellationToken = cancellationToken;
 }