/// <summary>
        /// Creates a new cache of the specified size.
        /// </summary>
        /// <param name="size">
        /// The size of the cache.
        /// </param>
        public Cache(int size)
        {
            mMap       = new Hashtable(size);
            mWrappers  = new ObjectWrapper[size];
            mCacheSize = size;
            object item = new object();

            mFirstElement = new DoubleLinkedListElement(null, null, item);
            object tempObject;

            tempObject   = new ObjectWrapper(null, mFirstElement);
            mMap[item]   = tempObject;
            mWrappers[0] = new ObjectWrapper(null, mFirstElement);

            DoubleLinkedListElement element = mFirstElement;

            for (int currentItem = 1; currentItem < mCacheSize; currentItem++)
            {
                item    = new object();
                element = new DoubleLinkedListElement(element, null, item);
                mWrappers[currentItem] = new ObjectWrapper(null, element);
                object tempObject2;
                tempObject2           = mWrappers[currentItem];
                mMap[item]            = tempObject2;
                element.Previous.Next = element;
            }
            mLastElement = element;
        }
 public virtual DoubleLinkedListElement Previous()
 {
     if (Current.Previous != null)
     {
         Current = Current.Previous;
     }
     return(Current);
 }
 public virtual DoubleLinkedListElement Next()
 {
     if (Current.Next != null)
     {
         Current = Current.Next;
     }
     return(Current);
 }
        public virtual void AddFirst(object item)
        {
            First = new DoubleLinkedListElement(null, First, item);

            if (Current.Next == null)
            {
                Last = Current;
            }
        }
        public virtual void AddLast(object item)
        {
            Last = new DoubleLinkedListElement(Last, null, item);

            if (Current.Previous == null)
            {
                First = Current;
            }
        }
        public virtual void Clear()
        {
            mMap.Clear();
            DoubleLinkedListElement element = mFirstElement;

            for (int currentItem = 0; currentItem < mCacheSize; currentItem++)
            {
                mWrappers[currentItem].Item = null;
                object o = new object();
                mMap.Add(o, mWrappers[currentItem]);
                element.Item = o;
                element      = element.Next;
            }
        }
        public DoubleLinkedListElement(DoubleLinkedListElement previousElement, DoubleLinkedListElement nextElement, object item)
        {
            mPrevious = previousElement;
            mNext     = nextElement;
            mItem     = item;

            if (previousElement != null)
            {
                previousElement.Next = this;
            }

            if (nextElement != null)
            {
                nextElement.Previous = this;
            }
        }
        public override string ToString()
        {
            DoubleLinkedListElement element = First;
            StringBuilder           buffer  = new StringBuilder();

            buffer.Append("[").Append(element.Item.ToString());

            element = element.Next;

            while (element != null)
            {
                buffer.Append(", ").Append(element.Item.ToString());
                element = element.Next;
            }

            buffer.Append("]");

            return(buffer.ToString());
        }
        public virtual void Insert(object item)
        {
            if (Current == null)
            {
                Current = new DoubleLinkedListElement(null, null, item);
            }
            else
            {
                Current = new DoubleLinkedListElement(Current.Previous, Current, item);
            }

            if (Current.Previous == null)
            {
                First = Current;
            }

            if (Current.Next == null)
            {
                Last = Current;
            }
        }
 public DoubleLinkedList()
 {
     First   = null;
     Last    = null;
     Current = null;
 }
 public ObjectWrapper(object item, DoubleLinkedListElement listItem)
 {
     mItem     = item;
     mListItem = listItem;
 }
        public object this[object key]
        {
            get
            {
                ObjectWrapper wrapper = (ObjectWrapper)mMap[key];

                if (wrapper != null)
                {
                    // Move it to the front
                    DoubleLinkedListElement element = (DoubleLinkedListElement)wrapper.ListItem;

                    //move to front
                    if (element != mFirstElement)
                    {
                        //remove list item
                        element.Previous.Next = element.Next;
                        if (element.Next != null)
                        {
                            element.Next.Previous = element.Previous;
                        }
                        else
                        {
                            //were moving last
                            mLastElement = element.Previous;
                        }
                        //put list item in front
                        element.Next           = mFirstElement;
                        mFirstElement.Previous = element;
                        element.Previous       = null;

                        //update first
                        mFirstElement = element;
                    }
                    return(wrapper.Item);
                }
                else
                {
                    return(null);
                }
            }

            set
            {
                ObjectWrapper wrapper = (ObjectWrapper)mMap[key];
                if (wrapper != null)
                {
                    /* this should never be the case, we only do a put on a cache miss which
                     *                  means the current value wasn't in the cache.  However if the user
                     *                  screws up or wants to use this as a fixed size hash and puts the same
                     *                  thing in the list twice things break
                     */

                    //System.err.println("Cache.put: inserting same object into cache!!!!");
                    // Move wrapper's partner in the list to front
                    DoubleLinkedListElement element = wrapper.ListItem;

                    //move to front
                    if (element != mFirstElement)
                    {
                        //remove list item
                        element.Previous.Next = element.Next;
                        if (element.Next != null)
                        {
                            element.Next.Previous = element.Previous;
                        }
                        else
                        {
                            //were moving last
                            mLastElement = element.Previous;
                        }

                        //put list item in front
                        element.Next           = mFirstElement;
                        mFirstElement.Previous = element;
                        element.Previous       = null;

                        //update first
                        mFirstElement = element;
                    }
                    return;
                }
                // Put wrapper in the front and remove the last one
                mLastKey          = mLastElement.Item; // store key to remove from hash later
                mLastElement.Item = key;               //update list element with new key

                // connect list item to front of list
                mLastElement.Next      = mFirstElement;
                mFirstElement.Previous = mLastElement;

                // update first and last value
                mFirstElement          = mLastElement;
                mLastElement           = mLastElement.Previous;
                mFirstElement.Previous = null;
                mLastElement.Next      = null;

                // remove old value from cache
                mTempSwapWrapper = (ObjectWrapper)mMap[mLastKey];
                mMap.Remove(mLastKey);

                //update wrapper
                mTempSwapWrapper.Item     = value;
                mTempSwapWrapper.ListItem = mFirstElement;

                object tempObject;
                tempObject = mTempSwapWrapper;
                mMap[key]  = tempObject;
            }
        }