public int CompareTo(DLinkedListNode <T> other)
        {
            if (other == null)
            {
                return(-1);
            }

            return(this.Data.CompareTo(other.Data));
        }
            public bool MovePrevious()
            {
                if (_current.Previous != null)
                {
                    _current = _current.Previous;
                }
                else
                {
                    return(false);
                }

                return(true);
            }
            public bool MoveNext()
            {
                if (_current.Next != null)
                {
                    _current = _current.Next;
                }
                else
                {
                    return(false);
                }

                return(true);
            }
        public virtual void Append(T dataItem)
        {
            DLinkedListNode <T> newNode = new DLinkedListNode <T>(dataItem);

            if (_firstNode == null)
            {
                _firstNode = _lastNode = newNode;
            }
            else
            {
                var currentNode = _lastNode;
                currentNode.Next = newNode;
                newNode.Previous = currentNode;
                _lastNode        = newNode;
            }

            _count++;
        }
        public virtual DLinkedList <T> GetRange(int index, int countOfElements)
        {
            DLinkedListNode <T> currentNode = null;
            DLinkedList <T>     newList     = new DLinkedList <T>();


            if (Count == 0)
            {
                return(newList);
            }

            if (index < 0 || index > Count)
            {
                throw new IndexOutOfRangeException();
            }
            if (index > (Count / 2))
            {
                currentNode = this._lastNode;
                for (int i = (Count - 1); i > index; --i)
                {
                    currentNode = currentNode.Previous;
                }
            }
            else
            {
                currentNode = this._firstNode;
                for (int i = 0; i < index; ++i)
                {
                    currentNode = currentNode.Next;
                }
            }

            // Append the elements to the new list using the currentNode reference
            while (currentNode != null && newList.Count <= countOfElements)
            {
                newList.Append(currentNode.Data);
                currentNode = currentNode.Next;
            }

            return(newList);
        }
        /// <summary>
        /// Inserts the dataItem at the specified index.
        /// </summary>
        /// <param name="dataItem">Data item.</param>
        /// <param name="index">Index.</param>
        public virtual void InsertAt(T dataItem, int index)
        {
            if (index < 0 || index > Count)
            {
                throw new IndexOutOfRangeException();
            }

            if (index == 0)
            {
                Prepend(dataItem);
            }
            else if (index == Count)
            {
                Append(dataItem);
            }
            else
            {
                DLinkedListNode <T> currentNode = null;
                DLinkedListNode <T> newNode     = new DLinkedListNode <T>(dataItem);

                currentNode = this._firstNode;
                for (int i = 0; i < index - 1; ++i)
                {
                    currentNode = currentNode.Next;
                }

                var oldNext = currentNode.Next;

                if (oldNext != null)
                {
                    currentNode.Next.Previous = newNode;
                }

                newNode.Next     = oldNext;
                currentNode.Next = newNode;
                newNode.Previous = currentNode;

                _count++;
            }
        }
        protected virtual T _getElementAt(int index)
        {
            if (IsEmpty() || index < 0 || index >= Count)
            {
                throw new IndexOutOfRangeException("List is empty.");
            }

            if (index == 0)
            {
                return(First);
            }

            if (index == (Count - 1))
            {
                return(Last);
            }

            DLinkedListNode <T> currentNode = null;

            if (index > (Count / 2))
            {
                currentNode = this._lastNode;
                for (int i = (Count - 1); i > index; --i)
                {
                    currentNode = currentNode.Previous;
                }
            }
            else
            {
                currentNode = this._firstNode;
                for (int i = 0; i < index; ++i)
                {
                    currentNode = currentNode.Next;
                }
            }

            return(currentNode.Data);
        }
        protected virtual void _setElementAt(int index, T value)
        {
            if (IsEmpty() || index < 0 || index >= Count)
            {
                throw new IndexOutOfRangeException("List is empty.");
            }

            if (index == 0)
            {
                _firstNode.Data = value;
            }
            else if (index == (Count - 1))
            {
                _lastNode.Data = value;
            }
            else
            {
                DLinkedListNode <T> currentNode = null;
                if (index > (Count / 2))
                {
                    currentNode = this._lastNode;
                    for (int i = (Count - 1); i > index; --i)
                    {
                        currentNode = currentNode.Previous;
                    }
                }
                else
                {
                    currentNode = this._firstNode;
                    for (int i = 0; i < index; ++i)
                    {
                        currentNode = currentNode.Next;
                    }
                }

                currentNode.Data = value;
            }
        }
 public void Dispose()
 {
     _current          = null;
     _doublyLinkedList = null;
 }
 public void Reset()
 {
     _current = _doublyLinkedList.Head;
 }
 public DLinkedListEnumerator(DLinkedList <T> list)
 {
     this._current          = list.Head;
     this._doublyLinkedList = list;
 }
        public virtual void RemoveFirstMatch(Predicate <T> match)
        {
            if (IsEmpty())
            {
                throw new IndexOutOfRangeException();
            }

            if (match(_firstNode.Data))
            {
                _firstNode = _firstNode.Next;

                if (_firstNode != null)
                {
                    _firstNode.Previous = null;
                }
            }
            else if (match(_lastNode.Data))
            {
                _lastNode = _lastNode.Previous;

                if (_lastNode != null)
                {
                    _lastNode.Next = null;
                }
            }
            else
            {
                // Remove
                var currentNode = _firstNode;

                // Get currentNode to reference the element at the index.
                while (currentNode.Next != null)
                {
                    if (match(currentNode.Data))
                    {
                        break;
                    }

                    currentNode = currentNode.Next;
                }
                if (!match(currentNode.Data))
                {
                    throw new Exception("Item was not found!");
                }

                DLinkedListNode <T> newPrevious = currentNode.Previous;
                DLinkedListNode <T> newNext     = currentNode.Next;

                if (newPrevious != null)
                {
                    newPrevious.Next = newNext;
                }

                if (newNext != null)
                {
                    newNext.Previous = newPrevious;
                }

                currentNode = newPrevious;
            }

            _count--;
        }
        public virtual void Remove(T dataItem)
        {
            if (IsEmpty())
            {
                throw new IndexOutOfRangeException();
            }

            if (_firstNode.Data.IsEqualTo(dataItem))
            {
                _firstNode = _firstNode.Next;

                if (_firstNode != null)
                {
                    _firstNode.Previous = null;
                }
            }
            else if (_lastNode.Data.IsEqualTo(dataItem))
            {
                _lastNode = _lastNode.Previous;

                if (_lastNode != null)
                {
                    _lastNode.Next = null;
                }
            }
            else
            {
                // Remove
                var currentNode = _firstNode;
                while (currentNode.Next != null)
                {
                    if (currentNode.Data.IsEqualTo(dataItem))
                    {
                        break;
                    }

                    currentNode = currentNode.Next;
                }
                if (!currentNode.Data.IsEqualTo(dataItem))
                {
                    throw new Exception("Item was not found!");
                }

                // Remove element
                DLinkedListNode <T> newPrevious = currentNode.Previous;
                DLinkedListNode <T> newNext     = currentNode.Next;

                if (newPrevious != null)
                {
                    newPrevious.Next = newNext;
                }

                if (newNext != null)
                {
                    newNext.Previous = newPrevious;
                }

                currentNode = newPrevious;
            }

            // Decrement count.
            _count--;
        }
 public DLinkedListNode(T dataItem, DLinkedListNode <T> next, DLinkedListNode <T> previous)
 {
     Data     = dataItem;
     Next     = next;
     Previous = previous;
 }