/// <summary>
 /// Returns an <see cref="IEnumerable{T}"/> of Dequeued Items from the Back of the
 /// <paramref name="deque"/>. The returned items will be in
 /// <see cref="Generic.IDeque{T}.DequeueBack"/> order and there may be as many as
 /// up to <paramref name="count"/> items.
 /// </summary>
 /// <param name="deque"></param>
 /// <param name="count"></param>
 /// <returns></returns>
 public static IEnumerable <object> DequeueBackMany(this IDeque deque, int count = 1)
 {
     while (count-- > 0 && deque.Count > 0)
     {
         yield return(deque.DequeueBack());
     }
 }
        /// <summary>
        /// Tries to Dequeue as Many <see cref="object"/> Items as possible. May return with
        /// a <paramref name="result"/> that contains up to <paramref name="count"/> number of
        /// them. The returned <paramref name="result"/> will be in
        /// <see cref="Generic.IDeque{T}.DequeueBack"/> order.
        /// </summary>
        /// <param name="deque"></param>
        /// <param name="result"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static bool TryDequeueBackMany(this IDeque deque, out IEnumerable <object> result, int count = 1)
        {
            result = new List <object>();

            while (count-- > 0 && deque.Count > 0)
            {
                ((IList <object>)result).Add(deque.DequeueBack());
            }

            return(result.Any());
        }
        public void DoUndo(IGraphProcessingEnvironment procEnv)
        {
            String attrName = _attrType.Name;
            LGSPGraphProcessingEnvironment procEnv_ = (LGSPGraphProcessingEnvironment)procEnv;

            if (_undoOperation == UndoOperation.PutElement)
            {
                if (_attrType.Kind == AttributeKind.SetAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDictionary dict = (IDictionary)_elem.GetAttribute(_attrType.Name);
                    dict.Add(_value, null);
                }
                else if (_attrType.Kind == AttributeKind.MapAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDictionary dict = (IDictionary)_elem.GetAttribute(_attrType.Name);
                    dict.Add(_keyOfValue, _value);
                }
                else if (_attrType.Kind == AttributeKind.ArrayAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IList array = (IList)_elem.GetAttribute(_attrType.Name);
                    if (_keyOfValue == null)
                    {
                        array.Add(_value);
                    }
                    else
                    {
                        array.Insert((int)_keyOfValue, _value);
                    }
                }
                else //if(_attrType.Kind == AttributeKind.DequeAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDeque deque = (IDeque)_elem.GetAttribute(_attrType.Name);
                    if (_keyOfValue == null)
                    {
                        deque.EnqueueFront(_value);
                    }
                    else
                    {
                        deque.EnqueueAt((int)_keyOfValue, _value);
                    }
                }
            }
            else if (_undoOperation == UndoOperation.RemoveElement)
            {
                if (_attrType.Kind == AttributeKind.SetAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDictionary dict = (IDictionary)_elem.GetAttribute(_attrType.Name);
                    dict.Remove(_value);
                }
                else if (_attrType.Kind == AttributeKind.MapAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDictionary dict = (IDictionary)_elem.GetAttribute(_attrType.Name);
                    dict.Remove(_keyOfValue);
                }
                else if (_attrType.Kind == AttributeKind.ArrayAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IList array = (IList)_elem.GetAttribute(_attrType.Name);
                    if (_keyOfValue == null)
                    {
                        array.RemoveAt(array.Count - 1);
                    }
                    else
                    {
                        array.RemoveAt((int)_keyOfValue);
                    }
                }
                else //if(_attrType.Kind == AttributeKind.DequeAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDeque deque = (IDeque)_elem.GetAttribute(_attrType.Name);
                    if (_keyOfValue == null)
                    {
                        deque.DequeueBack();
                    }
                    else
                    {
                        deque.DequeueAt((int)_keyOfValue);
                    }
                }
            }
            else if (_undoOperation == UndoOperation.AssignElement)
            {
                if (_attrType.Kind == AttributeKind.ArrayAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IList array = (IList)_elem.GetAttribute(_attrType.Name);
                    array[(int)_keyOfValue] = _value;
                }
                else if (_attrType.Kind == AttributeKind.DequeAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDeque deque = (IDeque)_elem.GetAttribute(_attrType.Name);
                    deque[(int)_keyOfValue] = _value;
                }
                else //if(_attrType.Kind == AttributeKind.MapAttr)
                {
                    ChangingElementAttribute(procEnv_);
                    IDictionary dict = (IDictionary)_elem.GetAttribute(_attrType.Name);
                    dict[_keyOfValue] = _value;
                }
            }
            else if (_undoOperation == UndoOperation.Assign)
            {
                ChangingElementAttribute(procEnv_);
                _elem.SetAttribute(attrName, _value);
            }
            // otherwise UndoOperation.None
        }