context: /* $Id$
   *
   * OpenMAMA: The open middleware agnostic messaging API
   * Copyright (C) 2011 NYSE Technologies, Inc.
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   * 02110-1301 USA
   */
  
  using System;
  using System.Collections;
  
  namespace Wombat.Containers
  {
  	public class HashMap : Map, ICloneable
  	{
  		public HashMap(int initialCapacity, float loadFactor)
  		{
  			mHashTable = new Hashtable(initialCapacity, loadFactor);
  		}
  
  		public HashMap(int initialCapacity)
  		{
  			mHashTable = new Hashtable(initialCapacity);
  		}
  
  		public HashMap()
  		{
  			mHashTable = new Hashtable();
  		}
  
  		public HashMap(HashMap m)
  		{
  			mHashTable = new Hashtable(m.mHashTable);
  		}
  
  		internal HashMap(Hashtable ht)
  		{
  			mHashTable = ht;
  		}
  
  		#region Map Members
  
  		public int size()
  		{
  			return mHashTable.Count;
  		}
  
  		public bool isEmpty()
  		{
  			return size() == 0;
  		}
  
  		public bool containsKey(object key)
  		{
  			return mHashTable.ContainsKey(key);
  		}
  
  		public bool containsValue(object value)
  		{
  			return mHashTable.ContainsValue(value);
  		}
  
  		public object valueOf(object key)
  		{
  			return mHashTable[key];
  		}
  
  		public object put(object key, object value)
  		{
  			object previous = mHashTable[key];
  			mHashTable[key] = value;
  			return previous;
  		}
  
  		public object remove(object key)
  		{
  			object previous = mHashTable[key];
  			mHashTable.Remove(key);
  			return previous;
  		}
  
  		public void putAll(Map m)
  		{
  			Set s = m.entrySet();
  			Iterator i = s.iterator();
  			while (i.hasNext())
  			{
  				MapEntry e = (MapEntry)i.next();
  				putFast(e.getKey(), e.getValue());
  			}
  		}
  
  		public void clear()
  		{
  			mHashTable.Clear();
  		}
  
  		public Set keySet()
  		{
  			return new HashMapSetOverHashtableKeys(mHashTable);
  		}
  
  		public Collection values()
  		{
  			return new HashMapCollectionOverHashtableValues(mHashTable);
  		}
  
  		public Set entrySet()
  		{
  			return new HashMapSetOverHashtableEntries(this);
  		}
  
  		#endregion
  
  		private void putFast(object key, object value)
  		{
  			mHashTable[key] = value;
  		}
  
  		private sealed class HashMapSetOverHashtableKeys : Set
  		{
  			public HashMapSetOverHashtableKeys(Hashtable ht)
  			{
  				mHashTable = ht;
  			}
  
  			#region Collection Members
  
  			public int size()
  			{
  				return mHashTable.Count;
  			}
  
  			public bool isEmpty()
  			{
  				return size() == 0;
  			}
  
  			public bool contains(object o)
  			{
  				return mHashTable.ContainsKey(o);
  			}
  
  			public object[] toArray()
  			{
  				ICollection k = mHashTable.Keys;
  				object[] keys = new object[k.Count];
  				k.CopyTo(keys, 0);
  				return keys;
  			}
  
  			public bool add(object o)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool remove(object o)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool containsAll(Collection c)
  			{
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					object key = i.next();
  					if (!mHashTable.ContainsKey(key))
  						return false;
  				}
  				return true;
  			}
  
  			public bool addAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool removeAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool retainAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public void clear()
  			{
  				throw new NotSupportedException();
  			}
  
  			#endregion
  
  			#region Iterable Members
  
  			public Iterator iterator()
  			{
  				return new ReadonlyIteratorOverEnumerator(mHashTable.Keys.GetEnumerator());
  			}
  
  			#endregion
  
  			private Hashtable mHashTable;
  		}
  
  		private sealed class HashMapCollectionOverHashtableValues : Collection
  		{
  			public HashMapCollectionOverHashtableValues(Hashtable ht)
  			{
  				mHashTable = ht;
  			}
  
  			#region Collection Members
  
  			public int size()
  			{
  				return mHashTable.Count;
  			}
  
  			public bool isEmpty()
  			{
  				return size() == 0;
  			}
  
  			public bool contains(object o)
  			{
  				return mHashTable.ContainsValue(o);
  			}
  
  			public object[] toArray()
  			{
  				ICollection values = mHashTable.Values;
  				object[] vals = new object[values.Count];
  				values.CopyTo(vals, 0);
  				return vals;
  			}
  
  			public bool add(object o)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool remove(object o)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool containsAll(Collection c)
  			{
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					object value = i.next();
  					if (!mHashTable.ContainsValue(value))
  						return false;
  				}
  				return true;
  			}
  
  			public bool addAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool removeAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public bool retainAll(Collection c)
  			{
  				throw new NotSupportedException();
  			}
  
  			public void clear()
  			{
  				throw new NotSupportedException();
  			}
  
  			#endregion
  
  			#region Iterable Members
  
  			public Iterator iterator()
  			{
  				return new ReadonlyIteratorOverEnumerator(mHashTable.Values.GetEnumerator());
  			}
  
  			#endregion
  
  			private Hashtable mHashTable;
  		}
  
  		private sealed class HashMapSetOverHashtableEntries : Set
  		{
  			public HashMapSetOverHashtableEntries(HashMap hm)
  			{
  				mHashMap = hm;
  			}
  
  			#region Collection Members
  
  			public int size()
  			{
  				return mHashMap.mHashTable.Count;
  			}
  
  			public bool isEmpty()
  			{
  				return size() == 0;
  			}
  
  			public bool contains(object o)
  			{
  				MapEntry me = (MapEntry)o;
  				object val = mHashMap.mHashTable[me.getKey()];
  				return val == me.getValue();
  			}
  
  			public object[] toArray()
  			{
  				object[] vals = new object[mHashMap.mHashTable.Count];
  				int i = 0;
  				foreach (DictionaryEntry e in mHashMap.mHashTable)
  				{
  					vals[i++] = new MapEntryOverDictionaryEntry(e);
  				}
  				return vals;
  			}
  
  			public bool add(object o)
  			{
  				MapEntry me = (MapEntry)o;
  				int count = mHashMap.size();
  				mHashMap.put(me.getKey(), me.getValue());
  				return count != mHashMap.size();
  			}
  
  			public bool remove(object o)
  			{
  				MapEntry me = (MapEntry)o;
  				int count = mHashMap.size();
  				mHashMap.mHashTable.Remove(me.getKey());
  				return count != mHashMap.size();
  			}
  
  			public bool containsAll(Collection c)
  			{
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					MapEntry me = (MapEntry)i.next();
  					if (!mHashMap.mHashTable.ContainsKey(me.getKey()))
  						return false;
  				}
  				return true;
  			}
  
  			public bool addAll(Collection c)
  			{
  				int count = mHashMap.mHashTable.Count;
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					MapEntry me = (MapEntry)i.next();
  					mHashMap.mHashTable[me.getKey()] = me.getValue();
  				}
  				return mHashMap.mHashTable.Count != count;
  			}
  
  			public bool removeAll(Collection c)
  			{
  				int count = mHashMap.mHashTable.Count;
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					MapEntry me = (MapEntry)i.next();
  					mHashMap.mHashTable.Remove(me.getKey());
  				}
  				return mHashMap.mHashTable.Count != count;
  			}
  
  			public bool retainAll(Collection c)
  			{
  				int count = mHashMap.mHashTable.Count;
  				Iterator i = c.iterator();
  				while (i.hasNext())
  				{
  					MapEntry me = (MapEntry)i.next();
  					object val = mHashMap.mHashTable[me.getKey()];
  					if (val != me.getValue())
  					{
  						if (!mHashMap.mHashTable.ContainsKey(me.getKey()))
  							mHashMap.mHashTable.Add(me.getKey(), me.getValue());
  						else
  							mHashMap.mHashTable.Remove(me.getKey());
  					}
  				}
  
gt: 				return mHashMap.mHashTable.Count != count;