You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2003/12/01 23:34:55 UTC

cvs commit: jakarta-commons/collections/src/test/org/apache/commons/collections/iterators TestUnmodifiableOrderedMapIterator.java TestUnmodifiableMapIterator.java

scolebourne    2003/12/01 14:34:55

  Modified:    collections/src/java/org/apache/commons/collections/map
                        AbstractOrderedMapDecorator.java
                        ListOrderedMap.java Flat3Map.java
                        UnmodifiableMap.java UnmodifiableOrderedMap.java
               collections/src/test/org/apache/commons/collections/bidimap
                        AbstractTestSortedBidiMap.java
                        TestDualTreeBidiMap.java TestDualHashBidiMap.java
                        AbstractTestOrderedBidiMap.java
                        TestTreeBidiMap.java AbstractTestBidiMap.java
               collections/src/test/org/apache/commons/collections/map
                        TestFlat3Map.java TestAll.java
                        AbstractTestOrderedMap.java
                        TestUnmodifiableMap.java
                        TestUnmodifiableOrderedMap.java
               collections/src/java/org/apache/commons/collections/bidimap
                        AbstractDualBidiMap.java DualHashBidiMap.java
                        DualTreeBidiMap.java TreeBidiMap.java
               collections/src/test/org/apache/commons/collections/iterators
                        TestUnmodifiableOrderedMapIterator.java
                        TestUnmodifiableMapIterator.java
  Added:       collections/src/java/org/apache/commons/collections/map
                        HashedMap.java
               collections/src/test/org/apache/commons/collections/map
                        AbstractTestAMap.java TestHashedMap.java
               collections/src/java/org/apache/commons/collections
                        OrderedMap.java OrderedBidiMap.java
                        SortedBidiMap.java BidiMap.java AMap.java
  Removed:     collections/src/java/org/apache/commons/collections/map
                        OrderedMap.java
               collections/src/java/org/apache/commons/collections/bidimap
                        OrderedBidiMap.java SortedBidiMap.java BidiMap.java
  Log:
  Move map interfaces to main package
  Add AMap interface
  Add HashedMap implementation
  
  Revision  Changes    Path
  1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/AbstractOrderedMapDecorator.java
  
  Index: AbstractOrderedMapDecorator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/AbstractOrderedMapDecorator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractOrderedMapDecorator.java	20 Nov 2003 22:33:54 -0000	1.1
  +++ AbstractOrderedMapDecorator.java	1 Dec 2003 22:34:53 -0000	1.2
  @@ -57,6 +57,7 @@
    */
   package org.apache.commons.collections.map;
   
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.iterators.MapIterator;
   import org.apache.commons.collections.iterators.OrderedMapIterator;
   
  
  
  
  1.4       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java
  
  Index: ListOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ListOrderedMap.java	20 Nov 2003 21:46:41 -0000	1.3
  +++ ListOrderedMap.java	1 Dec 2003 22:34:53 -0000	1.4
  @@ -68,6 +68,7 @@
   import java.util.NoSuchElementException;
   import java.util.Set;
   
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
   import org.apache.commons.collections.iterators.MapIterator;
   import org.apache.commons.collections.iterators.OrderedMapIterator;
  
  
  
  1.3       +4 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java
  
  Index: Flat3Map.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Flat3Map.java	18 Nov 2003 23:34:47 -0000	1.2
  +++ Flat3Map.java	1 Dec 2003 22:34:53 -0000	1.3
  @@ -66,6 +66,7 @@
   import java.util.NoSuchElementException;
   import java.util.Set;
   
  +import org.apache.commons.collections.AMap;
   import org.apache.commons.collections.IteratorUtils;
   import org.apache.commons.collections.iterators.EntrySetMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
  @@ -103,7 +104,7 @@
    *
    * @author Stephen Colebourne
    */
  -public class Flat3Map implements Map {
  +public class Flat3Map implements AMap {
       
       /** The size of the map, used while in flat mode */
       private int iSize;
  
  
  
  1.3       +17 -3     jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableMap.java
  
  Index: UnmodifiableMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- UnmodifiableMap.java	20 Nov 2003 22:35:50 -0000	1.2
  +++ UnmodifiableMap.java	1 Dec 2003 22:34:53 -0000	1.3
  @@ -63,9 +63,13 @@
   import java.util.Map;
   import java.util.Set;
   
  +import org.apache.commons.collections.AMap;
   import org.apache.commons.collections.Unmodifiable;
   import org.apache.commons.collections.collection.UnmodifiableCollection;
   import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
  +import org.apache.commons.collections.iterators.EntrySetMapIterator;
  +import org.apache.commons.collections.iterators.MapIterator;
  +import org.apache.commons.collections.iterators.UnmodifiableMapIterator;
   import org.apache.commons.collections.pairs.AbstractMapEntryDecorator;
   import org.apache.commons.collections.set.UnmodifiableSet;
   
  @@ -77,7 +81,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public final class UnmodifiableMap extends AbstractMapDecorator implements Unmodifiable {
  +public final class UnmodifiableMap extends AbstractMapDecorator implements AMap, Unmodifiable {
   
       /**
        * Factory method to create an unmodifiable map.
  @@ -118,6 +122,16 @@
   
       public Object remove(Object key) {
           throw new UnsupportedOperationException();
  +    }
  +
  +    public MapIterator mapIterator() {
  +        if (map instanceof AMap) {
  +            MapIterator it = ((AMap) map).mapIterator();
  +            return UnmodifiableMapIterator.decorate(it);
  +        } else {
  +            MapIterator it = new EntrySetMapIterator(map);
  +            return UnmodifiableMapIterator.decorate(it);
  +        }
       }
   
       public Set entrySet() {
  
  
  
  1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableOrderedMap.java
  
  Index: UnmodifiableOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableOrderedMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- UnmodifiableOrderedMap.java	20 Nov 2003 22:35:50 -0000	1.1
  +++ UnmodifiableOrderedMap.java	1 Dec 2003 22:34:53 -0000	1.2
  @@ -61,6 +61,7 @@
   import java.util.Map;
   import java.util.Set;
   
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.Unmodifiable;
   import org.apache.commons.collections.collection.UnmodifiableCollection;
   import org.apache.commons.collections.iterators.MapIterator;
  
  
  
  1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/map/HashedMap.java
  
  Index: HashedMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/HashedMap.java,v 1.1 2003/12/01 22:34:53 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections.map;
  
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.Serializable;
  import java.util.AbstractCollection;
  import java.util.AbstractSet;
  import java.util.Collection;
  import java.util.ConcurrentModificationException;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.NoSuchElementException;
  import java.util.Set;
  
  import org.apache.commons.collections.AMap;
  import org.apache.commons.collections.IteratorUtils;
  import org.apache.commons.collections.iterators.MapIterator;
  
  /**
   * A <code>Map</code> implementation that is a general purpose replacement
   * for <code>HashMap</code>.
   * <p>
   * This implementation improves on the JDK1.4 HahMap by adding the 
   * {@link org.apache.commons.collections.iterators.MapIterator MapIterator}
   * functionality and improving performance of <code>putAll</code>.
   * <p>
   * The implementation is also designed to be subclassed, with lots of useful
   * methods exposed.
   * 
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:53 $
   *
   * @author java util HashMap
   * @author Stephen Colebourne
   */
  public class HashedMap implements AMap, Serializable, Cloneable {
      
      /** Serialisation version */
      static final long serialVersionUID = -1593250834999590599L;
      /** The default capacity to use */
      protected static final int DEFAULT_CAPACITY = 16;
      /** The default load factor to use */
      protected static final float DEFAULT_LOAD_FACTOR = 0.75f;
      /** The maximum capacity allowed */
      protected static final int MAXIMUM_CAPACITY = 1 << 30;
      /** An object for masking null */
      protected static final Object NULL = new Object();
      
      /** Load factor, normally 0.75 */
      private final float loadFactor;
      /** The size of the map */
      private transient int size;
      /** Map entries */
      private transient HashEntry[] data;
      /** Size at which to rehash */
      private transient int threshold;
      /** Modification count for iterators */
      private transient int modCount;
      /** Entry set */
      private transient EntrySet entrySet;
      /** Key set */
      private transient KeySet keySet;
      /** Values */
      private transient Values values;
  
      /**
       * Constructs a new empty map with default size and load factor.
       */
      public HashedMap() {
          super();
          this.loadFactor = DEFAULT_LOAD_FACTOR;
          this.threshold = calculateThreshold(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
          this.data = new HashEntry[DEFAULT_CAPACITY];
      }
  
      /**
       * Constructs a new, empty map with the specified initial capacity. 
       *
       * @param initialCapacity  the initial capacity
       * @throws IllegalArgumentException if the initial capacity is less than one
       */
      public HashedMap(int initialCapacity) {
          this(initialCapacity, DEFAULT_LOAD_FACTOR);
      }
  
      /**
       * Constructs a new, empty map with the specified initial capacity and
       * load factor. 
       *
       * @param initialCapacity  the initial capacity
       * @param loadFactor  the load factor
       * @throws IllegalArgumentException if the initial capacity is less than one
       * @throws IllegalArgumentException if the load factor is less than one
       */
      public HashedMap(int initialCapacity, float loadFactor) {
          super();
          if (initialCapacity < 1) {
              throw new IllegalArgumentException("Initial capacity must be greater than 0");
          }
          if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
              throw new IllegalArgumentException("Load factor must be greater than 0");
          }
          this.loadFactor = loadFactor;
          this.threshold = calculateThreshold(initialCapacity, loadFactor);
          initialCapacity = calculateNewCapacity(initialCapacity);
          this.data = new HashEntry[initialCapacity];
      }
  
      /**
       * Constructor copying elements from another map.
       *
       * @param map  the map to copy
       * @throws NullPointerException if the map is null
       */
      public HashedMap(Map map) {
          this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
          putAll(map);
      }
  
      //-----------------------------------------------------------------------
      /**
       * Gets the value mapped to the key specified.
       * 
       * @param key  the key
       * @return the mapped value, null if no match
       */
      public Object get(Object key) {
          key = convertKey(key);
          int hashCode = hash(key);
          HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
          while (entry != null) {
              if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                  return entry.getValue();
              }
              entry = entry.next;
          }
          return null;
      }
  
      /**
       * Gets the size of the map.
       * 
       * @return the size
       */
      public int size() {
          return size;
      }
  
      /**
       * Checks whether the map is currently empty.
       * 
       * @return true if the map is currently size zero
       */
      public boolean isEmpty() {
          return (size == 0);
      }
  
      //-----------------------------------------------------------------------
      /**
       * Checks whether the map contains the specified key.
       * 
       * @param key  the key to search for
       * @return true if the map contains the key
       */
      public boolean containsKey(Object key) {
          key = convertKey(key);
          int hashCode = hash(key);
          HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
          while (entry != null) {
              if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                  return true;
              }
              entry = entry.next;
          }
          return false;
      }
  
      /**
       * Checks whether the map contains the specified value.
       * 
       * @param value  the value to search for
       * @return true if the map contains the value
       */
      public boolean containsValue(Object value) {
          if (value == null) {
              for (int i = 0, isize = data.length; i < isize; i++) {
                  HashEntry entry = data[i];
                  while (entry != null) {
                      if (entry.getValue() == null) {
                          return true;
                      }
                      entry = entry.next;
                  }
              }
          } else {
              for (int i = 0, isize = data.length; i < isize; i++) {
                  HashEntry entry = data[i];
                  while (entry != null) {
                      if (isEqualValue(value, entry.getValue())) {
                          return true;
                      }
                      entry = entry.next;
                  }
              }
          }
          return false;
      }
  
      //-----------------------------------------------------------------------
      /**
       * Puts a key-value mapping into this map.
       * 
       * @param key  the key to add
       * @param value  the value to add
       * @return the value previously mapped to this key, null if none
       */
      public Object put(Object key, Object value) {
          key = convertKey(key);
          int hashCode = hash(key);
          int index = hashIndex(hashCode, data.length);
          HashEntry entry = data[index];
          while (entry != null) {
              if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                  Object oldValue = entry.getValue();
                  entry.setValue(value);
                  return oldValue;
              }
              entry = entry.next;
          }
          
          modCount++;
          add(hashCode, index, key, value);
          return null;
      }
  
      /**
       * Puts all the values from the specified map into this map.
       * 
       * @param map  the map to add
       * @throws NullPointerException if the map is null
       */
      public void putAll(Map map) {
          int mapSize = map.size();
          if (mapSize == 0) {
              return;
          }
          ensureCapacity(calculateNewCapacity(size + mapSize));
          for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
              Map.Entry entry = (Map.Entry) it.next();
              put(entry.getKey(), entry.getValue());
          }
      }
  
      /**
       * Removes the specified mapping from this map.
       * 
       * @param key  the mapping to remove
       * @return the value mapped to the removed key, null if key not in map
       */
      public Object remove(Object key) {
          key = convertKey(key);
          int hashCode = hash(key);
          int index = hashIndex(hashCode, data.length);
          HashEntry entry = data[index]; 
          HashEntry previous = null;
          while (entry != null) {
              if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                  modCount++;
                  if (previous == null) {
                      data[index] = entry.next;
                  } else {
                      previous.next = entry.next;
                  }
                  size--;
                  return destroyEntry(entry);
              }
              previous = entry;
              entry = entry.next;
          }
          return null;
      }
  
      /**
       * Clears the map, resetting the size to zero and nullifying references
       * to avoid garbage collection issues.
       */
      public void clear() {
          modCount++;
          HashEntry[] data = this.data;
          for (int i = data.length - 1; i >= 0; i--) {
              data[i] = null;
          }
          size = 0;
      }
  
      //-----------------------------------------------------------------------
      /**
       * Converts input keys to another object for storage in the map.
       * This implementation masks nulls.
       * Subclasses can override this to perform alternate key conversions.
       * <p>
       * The reverse conversion can be changed, if required, by overriding the
       * getKey() method in the hash entry.
       * 
       * @param key  the key to get a hash code for
       * @return the hash code
       */
      protected Object convertKey(Object key) {
          return (key == null ? NULL : key);
      }
      
      /**
       * Gets the hash code for the key specified.
       * This implementation uses the additional hashing routine from JDK1.4.
       * Subclasses can override this to return alternate hash codes.
       * 
       * @param key  the key to get a hash code for
       * @return the hash code
       */
      protected int hash(Object key) {
          // same as JDK 1.4
          int h = key.hashCode();
          h += ~(h << 9);
          h ^=  (h >>> 14);
          h +=  (h << 4);
          h ^=  (h >>> 10);
          return h;
      }
      
      /**
       * Compares two keys for equals.
       * This implementation uses the equals method.
       * Subclasses can override this to match differently.
       * 
       * @param key1  the first key to compare
       * @param key2  the second key to compare
       * @return true if equal
       */
      protected boolean isEqualKey(Object key1, Object key2) {
          return (key1 == key2 || key1.equals(key2));
      }
      
      /**
       * Compares two values for equals.
       * This implementation uses the equals method.
       * Subclasses can override this to match differently.
       * 
       * @param value1  the first value to compare
       * @param value2  the second value to compare
       * @return true if equal
       */
      protected boolean isEqualValue(Object value1, Object value2) {
          return (value1 == value2 || value1.equals(value2));
      }
      
      /**
       * Gets the index into the data storage for the hashCode specified.
       * This implementation uses the least significant bits of the hashCode.
       * Subclasses can override this to return alternate bucketing.
       * 
       * @param hashCode  the hash code to use
       * @param dataSize  the size of the data to pick a bucket from
       * @return the bucket index
       */
      protected int hashIndex(int hashCode, int dataSize) {
          return hashCode & (dataSize - 1);
      }
      
      /**
       * Creates an entry to store the data.
       * This implementation creates a HashEntry instance.
       * Subclasses can override this to return a different storage class,
       * or implement caching.
       * 
       * @param next  the next entry in sequence
       * @param hashCode  the hash code to use
       * @param key  the key to store
       * @param value  the value to store
       * @return the newly created entry
       */
      protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
          return new HashEntry(next, hashCode, key, value);
      }
      
      /**
       * Kills an entry ready for the garbage collector.
       * This implementation prepares the HashEntry for garbage collection.
       * Subclasses can override this to implement caching (override clear as well).
       * 
       * @param entry  the entry to destroy
       * @return the value from the entry
       */
      protected Object destroyEntry(HashEntry entry) {
          entry.next = null;
          return entry.value;
      }
      
      /**
       * Adds a new key-value mapping into this map.
       * Subclasses could override to fix the size of the map.
       * 
       * @param key  the key to add
       * @param value  the value to add
       * @return the value previously mapped to this key, null if none
       */
      protected void add(int hashCode, int hashIndex, Object key, Object value) {
          data[hashIndex] = createEntry(data[hashIndex], hashCode, key, value);
          if (size++ >= threshold) {
              ensureCapacity(data.length * 2);
          }
      }
      
      /**
       * Changes the size of the data structure to the capacity proposed.
       * 
       * @param newCapacity  the new capacity of the array
       */
      protected void ensureCapacity(int newCapacity) {
          int oldCapacity = data.length;
          if (newCapacity <= oldCapacity) {
              return;
          }
          HashEntry oldEntries[] = data;
          HashEntry newEntries[] = new HashEntry[newCapacity];
  
          modCount++;
          for (int i = oldCapacity - 1; i >= 0; i--) {
              HashEntry entry = oldEntries[i];
              if (entry != null) {
                  oldEntries[i] = null;  // gc
                  do {
                      HashEntry next = entry.next;
                      int index = hashIndex(entry.hashCode, newCapacity);  
                      entry.next = newEntries[index];
                      newEntries[index] = entry;
                      entry = next;
                  } while (entry != null);
              }
          }
          threshold = calculateThreshold(newCapacity, loadFactor);
          data = newEntries;
      }
  
      /**
       * Calculates the new capacity of the map.
       * This implementation normalizes the capacity to a power of two.
       * 
       * @param proposedCapacity  the proposed capacity
       * @return the normalized new capacity
       */
      protected int calculateNewCapacity(int proposedCapacity) {
          int newCapacity = 1;
          if (proposedCapacity > MAXIMUM_CAPACITY) {
              newCapacity = MAXIMUM_CAPACITY;
          } else {
              while (newCapacity < proposedCapacity) {
                  newCapacity <<= 1;  // multiply by two
              }
              if (proposedCapacity > MAXIMUM_CAPACITY) {
                  newCapacity = MAXIMUM_CAPACITY;
              }
          }
          return newCapacity;
      }
      
      /**
       * Calculates the new threshold of the map, where it will be resized.
       * This implementation uses the load factor.
       * 
       * @param newCapacity  the new capacity
       * @param factor  the load factor
       * @return the new resize threshold
       */
      protected int calculateThreshold(int newCapacity, float factor) {
          return (int) (newCapacity * factor);
      }
      
      //-----------------------------------------------------------------------
      /**
       * Gets an iterator over the map.
       * Changes made to the iterator affect this map.
       * <p>
       * A MapIterator returns the keys in the map. It also provides convenient
       * methods to get the key and value, and set the value.
       * It avoids the need to create an entrySet/keySet/values object.
       * It also avoids creating the Mep Entry object.
       * 
       * @return the map iterator
       */
      public MapIterator mapIterator() {
          if (size == 0) {
              return IteratorUtils.EMPTY_MAP_ITERATOR;
          }
          return new HashMapIterator(this);
      }
  
      /**
       * MapIterator
       */
      static class HashMapIterator extends HashIterator implements MapIterator {
          
          HashMapIterator(HashedMap map) {
              super(map);
          }
  
          public Object next() {
              return super.nextEntry().getKey();
          }
  
          public Object getKey() {
              HashEntry current = currentEntry();
              if (current == null) {
                  throw new IllegalStateException("Iterator remove() can only be called once after next()");
              }
              return current.getKey();
          }
  
          public Object getValue() {
              HashEntry current = currentEntry();
              if (current == null) {
                  throw new IllegalStateException("Iterator remove() can only be called once after next()");
              }
              return current.getValue();
          }
  
          public Object setValue(Object value) {
              HashEntry current = currentEntry();
              if (current == null) {
                  throw new IllegalStateException("Iterator remove() can only be called once after next()");
              }
              Object old = current.getValue();
              current.setValue(value);
              return old;
          }
      }
      
      //-----------------------------------------------------------------------    
      /**
       * Gets the entrySet view of the map.
       * Changes made to the view affect this map.
       * The Map Entry is not an independent object and changes as the 
       * iterator progresses.
       * To simply iterate through the entries, use {@link #mapIterator()}.
       * 
       * @return the entrySet view
       */
      public Set entrySet() {
          if (entrySet == null) {
              entrySet = new EntrySet(this);
          }
          return entrySet;
      }
      
      /**
       * Creates an entry set iterator.
       * Subclasses can override this to return iterators with different properties.
       * 
       * @return the entrySet iterator
       */
      protected Iterator createEntrySetIterator() {
          if (size() == 0) {
              return IteratorUtils.EMPTY_ITERATOR;
          }
          return new EntrySetIterator(this);
      }
  
      /**
       * EntrySet
       */
      static class EntrySet extends AbstractSet {
          private final HashedMap map;
          
          EntrySet(HashedMap map) {
              super();
              this.map = map;
          }
  
          public int size() {
              return map.size();
          }
          
          public void clear() {
              map.clear();
          }
          
          public boolean contains(Object entry) {
              if (entry instanceof Map.Entry) {
                  return map.containsKey(((Map.Entry) entry).getKey());
              }
              return false;
          }
          
          public boolean remove(Object obj) {
              if (obj instanceof Map.Entry == false) {
                  return false;
              }
              Map.Entry entry = (Map.Entry) obj;
              Object key = entry.getKey();
              boolean result = map.containsKey(key);
              map.remove(key);
              return result;
          }
  
          public Iterator iterator() {
              return map.createEntrySetIterator();
          }
      }
  
      /**
       * EntrySetIterator and MapEntry
       */
      static class EntrySetIterator extends HashIterator {
          
          EntrySetIterator(HashedMap map) {
              super(map);
          }
  
          public Object next() {
              return super.nextEntry();
          }
      }
  
      //-----------------------------------------------------------------------    
      /**
       * Gets the keySet view of the map.
       * Changes made to the view affect this map.
       * To simply iterate through the keys, use {@link #mapIterator()}.
       * 
       * @return the keySet view
       */
      public Set keySet() {
          if (keySet == null) {
              keySet = new KeySet(this);
          }
          return keySet;
      }
  
      /**
       * Creates a key set iterator.
       * Subclasses can override this to return iterators with different properties.
       * 
       * @return the keySet iterator
       */
      protected Iterator createKeySetIterator() {
          if (size() == 0) {
              return IteratorUtils.EMPTY_ITERATOR;
          }
          return new KeySetIterator(this);
      }
  
      /**
       * KeySet
       */
      static class KeySet extends AbstractSet {
          private final HashedMap map;
          
          KeySet(HashedMap map) {
              super();
              this.map = map;
          }
  
          public int size() {
              return map.size();
          }
          
          public void clear() {
              map.clear();
          }
          
          public boolean contains(Object key) {
              return map.containsKey(key);
          }
          
          public boolean remove(Object key) {
              boolean result = map.containsKey(key);
              map.remove(key);
              return result;
          }
  
          public Iterator iterator() {
              return map.createKeySetIterator();
          }
      }
  
      /**
       * KeySetIterator
       */
      static class KeySetIterator extends EntrySetIterator {
          
          KeySetIterator(HashedMap map) {
              super(map);
          }
  
          public Object next() {
              return super.nextEntry().getKey();
          }
      }
      
      //-----------------------------------------------------------------------    
      /**
       * Gets the values view of the map.
       * Changes made to the view affect this map.
       * To simply iterate through the values, use {@link #mapIterator()}.
       * 
       * @return the values view
       */
      public Collection values() {
          if (values == null) {
              values = new Values(this);
          }
          return values;
      }
  
      /**
       * Creates a values iterator.
       * Subclasses can override this to return iterators with different properties.
       * 
       * @return the values iterator
       */
      protected Iterator createValuesIterator() {
          if (size() == 0) {
              return IteratorUtils.EMPTY_ITERATOR;
          }
          return new ValuesIterator(this);
      }
  
      /**
       * Values
       */
      static class Values extends AbstractCollection {
          private final HashedMap map;
          
          Values(HashedMap map) {
              super();
              this.map = map;
          }
  
          public int size() {
              return map.size();
          }
          
          public void clear() {
              map.clear();
          }
          
          public boolean contains(Object value) {
              return map.containsValue(value);
          }
          
          public Iterator iterator() {
              return map.createValuesIterator();
          }
      }
  
      /**
       * ValuesIterator
       */
      static class ValuesIterator extends HashIterator {
          
          ValuesIterator(HashedMap map) {
              super(map);
          }
  
          public Object next() {
              return super.nextEntry().getValue();
          }
      }
      
      //-----------------------------------------------------------------------
      /**
       * HashEntry
       */
      protected static class HashEntry implements Map.Entry {
          protected HashEntry next;
          protected int hashCode;
          protected Object key;
          protected Object value;
          
          HashEntry(HashEntry next, int hashCode, Object key, Object value) {
              super();
              this.next = next;
              this.hashCode = hashCode;
              this.key = key;
              this.value = value;
          }
          public Object getKey() {
              return (key == NULL ? null : key);
          }
          public Object getValue() {
              return value;
          }
          public Object setValue(Object value) {
              Object old = value;
              this.value = value;
              return old;
          }
          public boolean equals(Object obj) {
              if (obj == this) {
                  return true;
              }
              if (obj instanceof Map.Entry == false) {
                  return false;
              }
              Map.Entry other = (Map.Entry) obj;
              return
                  (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) &&
                  (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
          }
          public int hashCode() {
              return (getKey() == null ? 0 : getKey().hashCode()) ^
                     (getValue() == null ? 0 : getValue().hashCode()); 
          }
          public String toString() {
              return new StringBuffer().append(getKey()).append('=').append(getValue()).toString();
          }
      }
      
      /**
       * Base Iterator
       */
      protected static abstract class HashIterator implements Iterator {
          private final HashedMap map;
          private int hashIndex;
          private HashEntry current;
          private HashEntry next;
          private int expectedModCount;
          
          HashIterator(HashedMap map) {
              super();
              this.map = map;
              HashEntry[] data = map.data;
              int i = data.length;
              HashEntry next = null;
              while (i > 0 && next == null) {
                  next = data[--i];
              }
              this.next = next;
              this.hashIndex = i;
              this.expectedModCount = map.modCount;
          }
  
          public boolean hasNext() {
              return (next != null);
          }
  
          HashEntry nextEntry() { 
              if (map.modCount != expectedModCount) {
                  throw new ConcurrentModificationException();
              }
              HashEntry newCurrent = next;
              if (newCurrent == null)  {
                  throw new NoSuchElementException("No more elements in the iteration");
              }
              HashEntry[] data = map.data;
              int i = hashIndex;
              HashEntry n = newCurrent.next;
              while (n == null && i > 0) {
                  n = data[--i];
              }
              next = n;
              hashIndex = i;
              current = newCurrent;
              return newCurrent;
          }
  
          public HashEntry currentEntry() {
              return current;
          }
          
          public void remove() {
              if (current == null) {
                  throw new IllegalStateException("Iterator remove() can only be called once after next()");
              }
              if (map.modCount != expectedModCount) {
                  throw new ConcurrentModificationException();
              }
              map.remove(current.getKey());
              current = null;
              expectedModCount = map.modCount;
          }
  
          public String toString() {
              if (current != null) {
                  return "Iterator[" + current.getKey() + "=" + current.getValue() + "]";
              } else {
                  return "Iterator[]";
              }
          }
      }
      
      //-----------------------------------------------------------------------
      /**
       * Write the map out using a custom routine.
       */
      private void writeObject(ObjectOutputStream out) throws IOException {
          out.defaultWriteObject();
          out.writeInt(data.length);
          out.writeInt(size);
          for (MapIterator it = mapIterator(); it.hasNext();) {
              out.writeObject(it.next());
              out.writeObject(it.getValue());
          }
      }
  
      /**
       * Read the map in using a custom routine.
       */
      private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
          in.defaultReadObject();
          int capacity = in.readInt();
          int size = in.readInt();
          data = new HashEntry[capacity];
          for (int i = 0; i < size; i++) {
              Object key = in.readObject();
              Object value = in.readObject();
              put(key, value);
          }
      }
      //-----------------------------------------------------------------------
      /**
       * Clones the map without cloning the keys or values.
       *
       * @return a shallow clone
       */
      public Object clone() {
          try {
              HashedMap cloned = (HashedMap) super.clone();
              cloned.data = new HashEntry[data.length];
              cloned.entrySet = null;
              cloned.keySet = null;
              cloned.values = null;
              cloned.modCount = 0;
              cloned.size = 0;
              cloned.putAll(this);
              return cloned;
              
          } catch (CloneNotSupportedException ex) {
              return null;  // should never happen
          }
      }
      
      /**
       * Compares this map with another.
       * 
       * @param obj  the object to compare to
       * @return true if equal
       */
      public boolean equals(Object obj) {
          if (obj == this) {
              return true;
          }
          if (obj instanceof Map == false) {
              return false;
          }
          Map map = (Map) obj;
          if (map.size() != size()) {
              return false;
          }
          MapIterator it = mapIterator();
          try {
              while (it.hasNext()) {
                  Object key = it.next();
                  Object value = it.getValue();
                  if (value == null) {
                      if (map.get(key) != null || map.containsKey(key) == false) {
                          return false;
                      }
                  } else {
                      if (value.equals(map.get(key)) == false) {
                          return false;
                      }
                  }
              }
          } catch (ClassCastException ignored)   {
              return false;
          } catch (NullPointerException ignored) {
              return false;
          }
          return true;
      }
  
      /**
       * Gets the standard Map hashCode.
       * 
       * @return the hashcode defined in the Map interface
       */
      public int hashCode() {
          int total = 0;
          Iterator it = createEntrySetIterator();
          while (it.hasNext()) {
              total += it.next().hashCode();
          }
          return total;
      }
  
      /**
       * Gets the map as a String.
       * 
       * @return a string version of the map
       */
      public String toString() {
          if (size() == 0) {
              return "{}";
          }
          StringBuffer buf = new StringBuffer(32 * size());
          buf.append('{');
  
          MapIterator it = mapIterator();
          boolean hasNext = it.hasNext();
          while (hasNext) {
              Object key = it.next();
              Object value = it.getValue();
              buf.append(key == this ? "(this Map)" : key)
                 .append('=')
                 .append(value == this ? "(this Map)" : value);
  
              hasNext = it.hasNext();
              if (hasNext) {
                  buf.append(',').append(' ');
              }
          }
  
          buf.append('}');
          return buf.toString();
      }
  }
  
  
  
  1.5       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java
  
  Index: AbstractTestSortedBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractTestSortedBidiMap.java	18 Nov 2003 22:37:16 -0000	1.4
  +++ AbstractTestSortedBidiMap.java	1 Dec 2003 22:34:54 -0000	1.5
  @@ -70,6 +70,7 @@
   import java.util.TreeSet;
   
   import org.apache.commons.collections.BulkTest;
  +import org.apache.commons.collections.SortedBidiMap;
   import org.apache.commons.collections.map.AbstractTestSortedMap;
   
   /**
  
  
  
  1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java
  
  Index: TestDualTreeBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestDualTreeBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
  +++ TestDualTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
  @@ -60,6 +60,7 @@
   import junit.framework.Test;
   import junit.textui.TestRunner;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.BulkTest;
   
   /**
  
  
  
  1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java
  
  Index: TestDualHashBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestDualHashBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
  +++ TestDualHashBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
  @@ -60,6 +60,7 @@
   import junit.framework.Test;
   import junit.textui.TestRunner;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.BulkTest;
   
   /**
  
  
  
  1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java
  
  Index: AbstractTestOrderedBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractTestOrderedBidiMap.java	20 Nov 2003 00:31:42 -0000	1.2
  +++ AbstractTestOrderedBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
  @@ -65,6 +65,7 @@
   import java.util.NoSuchElementException;
   
   import org.apache.commons.collections.BulkTest;
  +import org.apache.commons.collections.OrderedBidiMap;
   import org.apache.commons.collections.iterators.AbstractTestMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
   
  
  
  
  1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java
  
  Index: TestTreeBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestTreeBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
  +++ TestTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
  @@ -63,6 +63,7 @@
   import junit.framework.Test;
   import junit.textui.TestRunner;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.BulkTest;
   
   /**
  
  
  
  1.4       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java
  
  Index: AbstractTestBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractTestBidiMap.java	18 Nov 2003 22:37:16 -0000	1.3
  +++ AbstractTestBidiMap.java	1 Dec 2003 22:34:54 -0000	1.4
  @@ -63,6 +63,7 @@
   import java.util.Map;
   import java.util.Set;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.BulkTest;
   import org.apache.commons.collections.iterators.AbstractTestMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
  
  
  
  1.2       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java
  
  Index: TestFlat3Map.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestFlat3Map.java	18 Nov 2003 23:23:05 -0000	1.1
  +++ TestFlat3Map.java	1 Dec 2003 22:34:54 -0000	1.2
  @@ -73,7 +73,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public class TestFlat3Map extends AbstractTestMap {
  +public class TestFlat3Map extends AbstractTestAMap {
   
       public TestFlat3Map(String testName) {
           super(testName);
  
  
  
  1.4       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestAll.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestAll.java	20 Nov 2003 22:35:50 -0000	1.3
  +++ TestAll.java	1 Dec 2003 22:34:54 -0000	1.4
  @@ -86,6 +86,7 @@
           suite.addTest(TestFixedSizeMap.suite());
           suite.addTest(TestFixedSizeSortedMap.suite());
           suite.addTest(TestFlat3Map.suite());
  +        suite.addTest(TestHashedMap.suite());
           suite.addTest(TestLazyMap.suite());
           suite.addTest(TestLazySortedMap.suite());
           suite.addTest(TestListOrderedMap.suite());
  
  
  
  1.2       +4 -50     jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestOrderedMap.java
  
  Index: AbstractTestOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestOrderedMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractTestOrderedMap.java	20 Nov 2003 22:34:49 -0000	1.1
  +++ AbstractTestOrderedMap.java	1 Dec 2003 22:34:54 -0000	1.2
  @@ -67,8 +67,8 @@
   import java.util.TreeMap;
   
   import org.apache.commons.collections.BulkTest;
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.comparators.NullComparator;
  -import org.apache.commons.collections.iterators.AbstractTestMapIterator;
   import org.apache.commons.collections.iterators.AbstractTestOrderedMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
   
  @@ -79,7 +79,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public abstract class AbstractTestOrderedMap extends AbstractTestMap {
  +public abstract class AbstractTestOrderedMap extends AbstractTestAMap {
   
       /**
        * JUnit constructor.
  @@ -214,56 +214,10 @@
       }
       
       //-----------------------------------------------------------------------
  -    public BulkTest bulkTestMapIterator() {
  -        return new InnerTestOrderedMapIterator();
  -    }
  -    
  -    // TODO: Test mapIterator() and orderedMapIterator() separately
  -    public class InnerTestMapIterator extends AbstractTestMapIterator {
  -        public InnerTestMapIterator() {
  -            super("InnerTestMapIterator");
  -        }
  -        
  -        public boolean supportsRemove() {
  -            return AbstractTestOrderedMap.this.isRemoveSupported();
  -        }
  -
  -        public boolean supportsSetValue() {
  -            return AbstractTestOrderedMap.this.isSetValueSupported();
  -        }
  -
  -        public MapIterator makeEmptyMapIterator() {
  -            resetEmpty();
  -            return ((OrderedMap) AbstractTestOrderedMap.this.map).mapIterator();
  -        }
  -
  -        public MapIterator makeFullMapIterator() {
  -            resetFull();
  -            return ((OrderedMap) AbstractTestOrderedMap.this.map).mapIterator();
  -        }
  -        
  -        public Map getMap() {
  -            // assumes makeFullMapIterator() called first
  -            return AbstractTestOrderedMap.this.map;
  -        }
  -        
  -        public Map getConfirmedMap() {
  -            // assumes makeFullMapIterator() called first
  -            return AbstractTestOrderedMap.this.confirmed;
  -        }
  -        
  -        public void verify() {
  -            super.verify();
  -            AbstractTestOrderedMap.this.verify();
  -        }
  -    }
  -    
  -    //-----------------------------------------------------------------------
       public BulkTest bulkTestOrderedMapIterator() {
           return new InnerTestOrderedMapIterator();
       }
       
  -    // TODO: Test mapIterator() and orderedMapIterator() separately
       public class InnerTestOrderedMapIterator extends AbstractTestOrderedMapIterator {
           public InnerTestOrderedMapIterator() {
               super("InnerTestOrderedMapIterator");
  
  
  
  1.5       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableMap.java
  
  Index: TestUnmodifiableMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableMap.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestUnmodifiableMap.java	20 Nov 2003 22:35:50 -0000	1.4
  +++ TestUnmodifiableMap.java	1 Dec 2003 22:34:54 -0000	1.5
  @@ -74,7 +74,7 @@
    * 
    * @author Phil Steitz
    */
  -public class TestUnmodifiableMap extends AbstractTestMap{
  +public class TestUnmodifiableMap extends AbstractTestAMap{
       
       public TestUnmodifiableMap(String testName) {
           super(testName);
  
  
  
  1.2       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableOrderedMap.java
  
  Index: TestUnmodifiableOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableOrderedMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestUnmodifiableOrderedMap.java	20 Nov 2003 22:35:50 -0000	1.1
  +++ TestUnmodifiableOrderedMap.java	1 Dec 2003 22:34:54 -0000	1.2
  @@ -63,6 +63,7 @@
   import junit.framework.Test;
   import junit.framework.TestSuite;
   
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.Unmodifiable;
   
   /**
  
  
  
  1.1                  jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestAMap.java
  
  Index: AbstractTestAMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestAMap.java,v 1.1 2003/12/01 22:34:54 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections.map;
  
  import java.util.ConcurrentModificationException;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.collections.AMap;
  import org.apache.commons.collections.BulkTest;
  import org.apache.commons.collections.iterators.AbstractTestMapIterator;
  import org.apache.commons.collections.iterators.MapIterator;
  
  /**
   * Abstract test class for {@link AMap} methods and contracts.
   *
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:54 $
   * 
   * @author Stephen Colebourne
   */
  public abstract class AbstractTestAMap extends AbstractTestMap {
  
      /**
       * JUnit constructor.
       * 
       * @param testName  the test name
       */
      public AbstractTestAMap(String testName) {
          super(testName);
      }
      
      //-----------------------------------------------------------------------
      public void testFailFastEntrySet() {
          if (isRemoveSupported() == false) return;
          resetFull();
          Iterator it = map.entrySet().iterator();
          Map.Entry val = (Map.Entry) it.next();
          map.remove(val.getKey());
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
          
          resetFull();
          it = map.entrySet().iterator();
          it.next();
          map.clear();
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
      }
      
      public void testFailFastKeySet() {
          if (isRemoveSupported() == false) return;
          resetFull();
          Iterator it = map.keySet().iterator();
          Object val = it.next();
          map.remove(val);
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
          
          resetFull();
          it = map.keySet().iterator();
          it.next();
          map.clear();
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
      }
      
      public void testFailFastValues() {
          if (isRemoveSupported() == false) return;
          resetFull();
          Iterator it = map.values().iterator();
          it.next();
          map.remove(map.keySet().iterator().next());
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
          
          resetFull();
          it = map.values().iterator();
          it.next();
          map.clear();
          try {
              it.next();
              fail();
          } catch (ConcurrentModificationException ex) {}
      }
      
      //-----------------------------------------------------------------------
      public BulkTest bulkTestMapIterator() {
          return new InnerTestMapIterator();
      }
      
      public class InnerTestMapIterator extends AbstractTestMapIterator {
          public InnerTestMapIterator() {
              super("InnerTestMapIterator");
          }
          
          public Object[] addSetValues() {
              return AbstractTestAMap.this.getNewSampleValues();
          }
          
          public boolean supportsRemove() {
              return AbstractTestAMap.this.isRemoveSupported();
          }
  
          public boolean supportsSetValue() {
              return AbstractTestAMap.this.isSetValueSupported();
          }
  
          public MapIterator makeEmptyMapIterator() {
              resetEmpty();
              return ((AMap) AbstractTestAMap.this.map).mapIterator();
          }
  
          public MapIterator makeFullMapIterator() {
              resetFull();
              return ((AMap) AbstractTestAMap.this.map).mapIterator();
          }
          
          public Map getMap() {
              // assumes makeFullMapIterator() called first
              return AbstractTestAMap.this.map;
          }
          
          public Map getConfirmedMap() {
              // assumes makeFullMapIterator() called first
              return AbstractTestAMap.this.confirmed;
          }
          
          public void verify() {
              super.verify();
              AbstractTestAMap.this.verify();
          }
      }
      
  //  public void testCreate() throws Exception {
  //      resetEmpty();
  //      writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/HashedMap.emptyCollection.version3.obj");
  //      resetFull();
  //      writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/HashedMap.fullCollection.version3.obj");
  //  }
  }
  
  
  
  1.1                  jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestHashedMap.java
  
  Index: TestHashedMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestHashedMap.java,v 1.1 2003/12/01 22:34:54 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections.map;
  
  import java.util.Map;
  
  import junit.framework.Test;
  import junit.textui.TestRunner;
  
  import org.apache.commons.collections.BulkTest;
  
  /**
   * JUnit tests.
   * 
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:54 $
   * 
   * @author Stephen Colebourne
   */
  public class TestHashedMap extends AbstractTestAMap {
  
      public TestHashedMap(String testName) {
          super(testName);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
      
      public static Test suite() {
          return BulkTest.makeSuite(TestHashedMap.class);
      }
  
      public Map makeEmptyMap() {
          return new HashedMap();
      }
      
      public String getCompatibilityVersion() {
          return "3";
      }
  
  }
  
  
  
  1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java
  
  Index: AbstractDualBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractDualBidiMap.java	16 Nov 2003 20:35:46 -0000	1.1
  +++ AbstractDualBidiMap.java	1 Dec 2003 22:34:54 -0000	1.2
  @@ -62,6 +62,7 @@
   import java.util.Map;
   import java.util.Set;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.collection.AbstractCollectionDecorator;
   import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
   import org.apache.commons.collections.iterators.MapIterator;
  
  
  
  1.2       +4 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java
  
  Index: DualHashBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DualHashBidiMap.java	16 Nov 2003 20:35:46 -0000	1.1
  +++ DualHashBidiMap.java	1 Dec 2003 22:34:54 -0000	1.2
  @@ -64,6 +64,8 @@
   import java.util.HashMap;
   import java.util.Map;
   
  +import org.apache.commons.collections.BidiMap;
  +
   /**
    * Implementation of <code>BidiMap</code> that uses two <code>HashMap</code> instances.
    * 
  
  
  
  1.4       +6 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
  
  Index: DualTreeBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DualTreeBidiMap.java	20 Nov 2003 00:31:42 -0000	1.3
  +++ DualTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.4
  @@ -69,10 +69,13 @@
   import java.util.SortedMap;
   import java.util.TreeMap;
   
  +import org.apache.commons.collections.BidiMap;
  +import org.apache.commons.collections.OrderedBidiMap;
  +import org.apache.commons.collections.OrderedMap;
  +import org.apache.commons.collections.SortedBidiMap;
   import org.apache.commons.collections.iterators.OrderedMapIterator;
   import org.apache.commons.collections.iterators.ResettableIterator;
   import org.apache.commons.collections.map.AbstractSortedMapDecorator;
  -import org.apache.commons.collections.map.OrderedMap;
   
   /**
    * Implementation of <code>BidiMap</code> that uses two <code>TreeMap</code> instances.
  
  
  
  1.3       +4 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java
  
  Index: TreeBidiMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TreeBidiMap.java	20 Nov 2003 00:31:42 -0000	1.2
  +++ TreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
  @@ -65,7 +65,9 @@
   import java.util.NoSuchElementException;
   import java.util.Set;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.IteratorUtils;
  +import org.apache.commons.collections.OrderedBidiMap;
   import org.apache.commons.collections.iterators.MapIterator;
   import org.apache.commons.collections.iterators.OrderedIterator;
   import org.apache.commons.collections.iterators.OrderedMapIterator;
  
  
  
  1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedMap.java
  
  Index: OrderedMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections;
  
  import org.apache.commons.collections.iterators.OrderedMapIterator;
  
  /**
   * Defines a map that maintains order and allows both forward and backward
   * iteration through that order.
   * 
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
   *
   * @author Stephen Colebourne
   */
  public interface OrderedMap extends AMap {
      
      /**
       * Obtains an <code>OrderedMapIterator</code> over the map.
       * <p>
       * A ordered map iterator is an efficient way of iterating over maps
       * in both directions.
       * <pre>
       * BidiMap map = new TreeBidiMap();
       * MapIterator it = map.mapIterator();
       * while (it.hasNext()) {
       *   Object key = it.next();
       *   Object value = it.getValue();
       *   it.setValue("newValue");
       *   Object previousKey = it.previous();
       * }
       * </pre>
       * 
       * @return a map iterator
       */
      OrderedMapIterator orderedMapIterator();
      
      /**
       * Gets the first key currently in this map.
       *
       * @return the first key currently in this map
       * @throws NoSuchElementException if this map is empty
       */
      public Object firstKey();
  
      /**
       * Gets the last key currently in this map.
       *
       * @return the last key currently in this map
       * @throws NoSuchElementException if this map is empty
       */
      public Object lastKey();
      
      /**
       * Gets the next key after the one specified.
       *
       * @param key  the key to search for next from
       * @return the next key, null if no match or at end
       */
      public Object nextKey(Object key);
  
      /**
       * Gets the previous key before the one specified.
       *
       * @param key  the key to search for previous from
       * @return the previous key, null if no match or at start
       */
      public Object previousKey(Object key);
      
  }
  
  
  
  1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedBidiMap.java
  
  Index: OrderedBidiMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedBidiMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections;
  
  /**
   * Defines a map that allows bidirectional lookup between key and values
   * and retains and provides access to an ordering.
   * <p>
   * Implementations should allow a value to be looked up from a key and
   * a key to be looked up from a value with equal performance.
   * 
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
   *
   * @author Stephen Colebourne
   */
  public interface OrderedBidiMap extends BidiMap, OrderedMap {
      
      /**
       * Gets a view of this map where the keys and values are reversed.
       * <p>
       * Changes to one map will be visible in the other and vice versa.
       * This enables both directions of the map to be accessed equally.
       * <p>
       * Implementations should seek to avoid creating a new object every time this
       * method is called. See <code>AbstractMap.values()</code> etc. Calling this
       * method on the inverse map should return the original.
       * <p>
       * Implementations must return an <code>OrderedBidiMap</code> instance,
       * usually by forwarding to <code>inverseOrderedBidiMap()</code>.
       *
       * @return an inverted bidirectional map
       */
      public BidiMap inverseBidiMap();
      
      /**
       * Gets a view of this map where the keys and values are reversed.
       * <p>
       * Changes to one map will be visible in the other and vice versa.
       * This enables both directions of the map to be accessed equally.
       * <p>
       * Implementations should seek to avoid creating a new object every time this
       * method is called. See <code>AbstractMap.values()</code> etc. Calling this
       * method on the inverse map should return the original.
       *
       * @return an inverted bidirectional map
       */
      public OrderedBidiMap inverseOrderedBidiMap();
      
  }
  
  
  
  1.3       +23 -3     jakarta-commons/collections/src/java/org/apache/commons/collections/SortedBidiMap.java
  
  
  
  
  1.8       +2 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/BidiMap.java
  
  
  
  
  1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/AMap.java
  
  Index: AMap.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/AMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections;
  
  import java.util.Map;
  
  import org.apache.commons.collections.iterators.MapIterator;
  
  /**
   * Defines a map that can be iterated directly without needing to create an entry set.
   * <p>
   * A map iterator is an efficient way of iterating over maps.
   * There is no need to access the entry set or cast to Map Entry objects.
   * <pre>
   * AMap map = new HashedMap();
   * MapIterator it = map.mapIterator();
   * while (it.hasNext()) {
   *   Object key = it.next();
   *   Object value = it.getValue();
   *   it.setValue("newValue");
   * }
   * </pre>
   * 
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
   *
   * @author Stephen Colebourne
   */
  public interface AMap extends Map {
      
      /**
       * Obtains a <code>MapIterator</code> over the map.
       * <p>
       * A map iterator is an efficient way of iterating over maps.
       * There is no need to access the entry set or cast to Map Entry objects.
       * <pre>
       * AMap map = new HashedMap();
       * MapIterator it = map.mapIterator();
       * while (it.hasNext()) {
       *   Object key = it.next();
       *   Object value = it.getValue();
       *   it.setValue("newValue");
       * }
       * </pre>
       * 
       * @return a map iterator
       */
      MapIterator mapIterator();
      
  }
  
  
  
  1.2       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableOrderedMapIterator.java
  
  Index: TestUnmodifiableOrderedMapIterator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableOrderedMapIterator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestUnmodifiableOrderedMapIterator.java	20 Nov 2003 21:45:35 -0000	1.1
  +++ TestUnmodifiableOrderedMapIterator.java	1 Dec 2003 22:34:55 -0000	1.2
  @@ -64,9 +64,9 @@
   import junit.framework.Test;
   import junit.framework.TestSuite;
   
  +import org.apache.commons.collections.OrderedMap;
   import org.apache.commons.collections.Unmodifiable;
   import org.apache.commons.collections.map.ListOrderedMap;
  -import org.apache.commons.collections.map.OrderedMap;
   
   /**
    * Tests the UnmodifiableOrderedMapIterator.
  
  
  
  1.5       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java
  
  Index: TestUnmodifiableMapIterator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestUnmodifiableMapIterator.java	18 Nov 2003 22:37:13 -0000	1.4
  +++ TestUnmodifiableMapIterator.java	1 Dec 2003 22:34:55 -0000	1.5
  @@ -63,8 +63,8 @@
   import junit.framework.Test;
   import junit.framework.TestSuite;
   
  +import org.apache.commons.collections.BidiMap;
   import org.apache.commons.collections.Unmodifiable;
  -import org.apache.commons.collections.bidimap.BidiMap;
   import org.apache.commons.collections.bidimap.DualHashBidiMap;
   
   /**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: cvs commit: jakarta-commons/collections/src/test/org/apache/commons/collections/iterators TestUnmodifiableOrderedMapIterator.java TestUnmodifiableMapIterator.java

Posted by Michael Heuer <he...@acm.org>.
Might the name IterateableMap or IteratableMap (the proper spelling
alludes me) be more descriptive than AMap?

   michael


On 1 Dec 2003 scolebourne@apache.org wrote:

> scolebourne    2003/12/01 14:34:55
>
>   Modified:    collections/src/java/org/apache/commons/collections/map
>                         AbstractOrderedMapDecorator.java
>                         ListOrderedMap.java Flat3Map.java
>                         UnmodifiableMap.java UnmodifiableOrderedMap.java
>                collections/src/test/org/apache/commons/collections/bidimap
>                         AbstractTestSortedBidiMap.java
>                         TestDualTreeBidiMap.java TestDualHashBidiMap.java
>                         AbstractTestOrderedBidiMap.java
>                         TestTreeBidiMap.java AbstractTestBidiMap.java
>                collections/src/test/org/apache/commons/collections/map
>                         TestFlat3Map.java TestAll.java
>                         AbstractTestOrderedMap.java
>                         TestUnmodifiableMap.java
>                         TestUnmodifiableOrderedMap.java
>                collections/src/java/org/apache/commons/collections/bidimap
>                         AbstractDualBidiMap.java DualHashBidiMap.java
>                         DualTreeBidiMap.java TreeBidiMap.java
>                collections/src/test/org/apache/commons/collections/iterators
>                         TestUnmodifiableOrderedMapIterator.java
>                         TestUnmodifiableMapIterator.java
>   Added:       collections/src/java/org/apache/commons/collections/map
>                         HashedMap.java
>                collections/src/test/org/apache/commons/collections/map
>                         AbstractTestAMap.java TestHashedMap.java
>                collections/src/java/org/apache/commons/collections
>                         OrderedMap.java OrderedBidiMap.java
>                         SortedBidiMap.java BidiMap.java AMap.java
>   Removed:     collections/src/java/org/apache/commons/collections/map
>                         OrderedMap.java
>                collections/src/java/org/apache/commons/collections/bidimap
>                         OrderedBidiMap.java SortedBidiMap.java BidiMap.java
>   Log:
>   Move map interfaces to main package
>   Add AMap interface
>   Add HashedMap implementation
>
>   Revision  Changes    Path
>   1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/AbstractOrderedMapDecorator.java
>
>   Index: AbstractOrderedMapDecorator.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/AbstractOrderedMapDecorator.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- AbstractOrderedMapDecorator.java	20 Nov 2003 22:33:54 -0000	1.1
>   +++ AbstractOrderedMapDecorator.java	1 Dec 2003 22:34:53 -0000	1.2
>   @@ -57,6 +57,7 @@
>     */
>    package org.apache.commons.collections.map;
>
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.iterators.MapIterator;
>    import org.apache.commons.collections.iterators.OrderedMapIterator;
>
>
>
>
>   1.4       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java
>
>   Index: ListOrderedMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java,v
>   retrieving revision 1.3
>   retrieving revision 1.4
>   diff -u -r1.3 -r1.4
>   --- ListOrderedMap.java	20 Nov 2003 21:46:41 -0000	1.3
>   +++ ListOrderedMap.java	1 Dec 2003 22:34:53 -0000	1.4
>   @@ -68,6 +68,7 @@
>    import java.util.NoSuchElementException;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
>    import org.apache.commons.collections.iterators.MapIterator;
>    import org.apache.commons.collections.iterators.OrderedMapIterator;
>
>
>
>   1.3       +4 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java
>
>   Index: Flat3Map.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- Flat3Map.java	18 Nov 2003 23:34:47 -0000	1.2
>   +++ Flat3Map.java	1 Dec 2003 22:34:53 -0000	1.3
>   @@ -66,6 +66,7 @@
>    import java.util.NoSuchElementException;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.AMap;
>    import org.apache.commons.collections.IteratorUtils;
>    import org.apache.commons.collections.iterators.EntrySetMapIterator;
>    import org.apache.commons.collections.iterators.MapIterator;
>   @@ -103,7 +104,7 @@
>     *
>     * @author Stephen Colebourne
>     */
>   -public class Flat3Map implements Map {
>   +public class Flat3Map implements AMap {
>
>        /** The size of the map, used while in flat mode */
>        private int iSize;
>
>
>
>   1.3       +17 -3     jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableMap.java
>
>   Index: UnmodifiableMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- UnmodifiableMap.java	20 Nov 2003 22:35:50 -0000	1.2
>   +++ UnmodifiableMap.java	1 Dec 2003 22:34:53 -0000	1.3
>   @@ -63,9 +63,13 @@
>    import java.util.Map;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.AMap;
>    import org.apache.commons.collections.Unmodifiable;
>    import org.apache.commons.collections.collection.UnmodifiableCollection;
>    import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
>   +import org.apache.commons.collections.iterators.EntrySetMapIterator;
>   +import org.apache.commons.collections.iterators.MapIterator;
>   +import org.apache.commons.collections.iterators.UnmodifiableMapIterator;
>    import org.apache.commons.collections.pairs.AbstractMapEntryDecorator;
>    import org.apache.commons.collections.set.UnmodifiableSet;
>
>   @@ -77,7 +81,7 @@
>     *
>     * @author Stephen Colebourne
>     */
>   -public final class UnmodifiableMap extends AbstractMapDecorator implements Unmodifiable {
>   +public final class UnmodifiableMap extends AbstractMapDecorator implements AMap, Unmodifiable {
>
>        /**
>         * Factory method to create an unmodifiable map.
>   @@ -118,6 +122,16 @@
>
>        public Object remove(Object key) {
>            throw new UnsupportedOperationException();
>   +    }
>   +
>   +    public MapIterator mapIterator() {
>   +        if (map instanceof AMap) {
>   +            MapIterator it = ((AMap) map).mapIterator();
>   +            return UnmodifiableMapIterator.decorate(it);
>   +        } else {
>   +            MapIterator it = new EntrySetMapIterator(map);
>   +            return UnmodifiableMapIterator.decorate(it);
>   +        }
>        }
>
>        public Set entrySet() {
>
>
>
>   1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableOrderedMap.java
>
>   Index: UnmodifiableOrderedMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/UnmodifiableOrderedMap.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- UnmodifiableOrderedMap.java	20 Nov 2003 22:35:50 -0000	1.1
>   +++ UnmodifiableOrderedMap.java	1 Dec 2003 22:34:53 -0000	1.2
>   @@ -61,6 +61,7 @@
>    import java.util.Map;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.Unmodifiable;
>    import org.apache.commons.collections.collection.UnmodifiableCollection;
>    import org.apache.commons.collections.iterators.MapIterator;
>
>
>
>   1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/map/HashedMap.java
>
>   Index: HashedMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/HashedMap.java,v 1.1 2003/12/01 22:34:53 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections.map;
>
>   import java.io.IOException;
>   import java.io.ObjectInputStream;
>   import java.io.ObjectOutputStream;
>   import java.io.Serializable;
>   import java.util.AbstractCollection;
>   import java.util.AbstractSet;
>   import java.util.Collection;
>   import java.util.ConcurrentModificationException;
>   import java.util.Iterator;
>   import java.util.Map;
>   import java.util.NoSuchElementException;
>   import java.util.Set;
>
>   import org.apache.commons.collections.AMap;
>   import org.apache.commons.collections.IteratorUtils;
>   import org.apache.commons.collections.iterators.MapIterator;
>
>   /**
>    * A <code>Map</code> implementation that is a general purpose replacement
>    * for <code>HashMap</code>.
>    * <p>
>    * This implementation improves on the JDK1.4 HahMap by adding the
>    * {@link org.apache.commons.collections.iterators.MapIterator MapIterator}
>    * functionality and improving performance of <code>putAll</code>.
>    * <p>
>    * The implementation is also designed to be subclassed, with lots of useful
>    * methods exposed.
>    *
>    * @since Commons Collections 3.0
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:53 $
>    *
>    * @author java util HashMap
>    * @author Stephen Colebourne
>    */
>   public class HashedMap implements AMap, Serializable, Cloneable {
>
>       /** Serialisation version */
>       static final long serialVersionUID = -1593250834999590599L;
>       /** The default capacity to use */
>       protected static final int DEFAULT_CAPACITY = 16;
>       /** The default load factor to use */
>       protected static final float DEFAULT_LOAD_FACTOR = 0.75f;
>       /** The maximum capacity allowed */
>       protected static final int MAXIMUM_CAPACITY = 1 << 30;
>       /** An object for masking null */
>       protected static final Object NULL = new Object();
>
>       /** Load factor, normally 0.75 */
>       private final float loadFactor;
>       /** The size of the map */
>       private transient int size;
>       /** Map entries */
>       private transient HashEntry[] data;
>       /** Size at which to rehash */
>       private transient int threshold;
>       /** Modification count for iterators */
>       private transient int modCount;
>       /** Entry set */
>       private transient EntrySet entrySet;
>       /** Key set */
>       private transient KeySet keySet;
>       /** Values */
>       private transient Values values;
>
>       /**
>        * Constructs a new empty map with default size and load factor.
>        */
>       public HashedMap() {
>           super();
>           this.loadFactor = DEFAULT_LOAD_FACTOR;
>           this.threshold = calculateThreshold(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
>           this.data = new HashEntry[DEFAULT_CAPACITY];
>       }
>
>       /**
>        * Constructs a new, empty map with the specified initial capacity.
>        *
>        * @param initialCapacity  the initial capacity
>        * @throws IllegalArgumentException if the initial capacity is less than one
>        */
>       public HashedMap(int initialCapacity) {
>           this(initialCapacity, DEFAULT_LOAD_FACTOR);
>       }
>
>       /**
>        * Constructs a new, empty map with the specified initial capacity and
>        * load factor.
>        *
>        * @param initialCapacity  the initial capacity
>        * @param loadFactor  the load factor
>        * @throws IllegalArgumentException if the initial capacity is less than one
>        * @throws IllegalArgumentException if the load factor is less than one
>        */
>       public HashedMap(int initialCapacity, float loadFactor) {
>           super();
>           if (initialCapacity < 1) {
>               throw new IllegalArgumentException("Initial capacity must be greater than 0");
>           }
>           if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
>               throw new IllegalArgumentException("Load factor must be greater than 0");
>           }
>           this.loadFactor = loadFactor;
>           this.threshold = calculateThreshold(initialCapacity, loadFactor);
>           initialCapacity = calculateNewCapacity(initialCapacity);
>           this.data = new HashEntry[initialCapacity];
>       }
>
>       /**
>        * Constructor copying elements from another map.
>        *
>        * @param map  the map to copy
>        * @throws NullPointerException if the map is null
>        */
>       public HashedMap(Map map) {
>           this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
>           putAll(map);
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Gets the value mapped to the key specified.
>        *
>        * @param key  the key
>        * @return the mapped value, null if no match
>        */
>       public Object get(Object key) {
>           key = convertKey(key);
>           int hashCode = hash(key);
>           HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
>           while (entry != null) {
>               if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
>                   return entry.getValue();
>               }
>               entry = entry.next;
>           }
>           return null;
>       }
>
>       /**
>        * Gets the size of the map.
>        *
>        * @return the size
>        */
>       public int size() {
>           return size;
>       }
>
>       /**
>        * Checks whether the map is currently empty.
>        *
>        * @return true if the map is currently size zero
>        */
>       public boolean isEmpty() {
>           return (size == 0);
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Checks whether the map contains the specified key.
>        *
>        * @param key  the key to search for
>        * @return true if the map contains the key
>        */
>       public boolean containsKey(Object key) {
>           key = convertKey(key);
>           int hashCode = hash(key);
>           HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
>           while (entry != null) {
>               if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
>                   return true;
>               }
>               entry = entry.next;
>           }
>           return false;
>       }
>
>       /**
>        * Checks whether the map contains the specified value.
>        *
>        * @param value  the value to search for
>        * @return true if the map contains the value
>        */
>       public boolean containsValue(Object value) {
>           if (value == null) {
>               for (int i = 0, isize = data.length; i < isize; i++) {
>                   HashEntry entry = data[i];
>                   while (entry != null) {
>                       if (entry.getValue() == null) {
>                           return true;
>                       }
>                       entry = entry.next;
>                   }
>               }
>           } else {
>               for (int i = 0, isize = data.length; i < isize; i++) {
>                   HashEntry entry = data[i];
>                   while (entry != null) {
>                       if (isEqualValue(value, entry.getValue())) {
>                           return true;
>                       }
>                       entry = entry.next;
>                   }
>               }
>           }
>           return false;
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Puts a key-value mapping into this map.
>        *
>        * @param key  the key to add
>        * @param value  the value to add
>        * @return the value previously mapped to this key, null if none
>        */
>       public Object put(Object key, Object value) {
>           key = convertKey(key);
>           int hashCode = hash(key);
>           int index = hashIndex(hashCode, data.length);
>           HashEntry entry = data[index];
>           while (entry != null) {
>               if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
>                   Object oldValue = entry.getValue();
>                   entry.setValue(value);
>                   return oldValue;
>               }
>               entry = entry.next;
>           }
>
>           modCount++;
>           add(hashCode, index, key, value);
>           return null;
>       }
>
>       /**
>        * Puts all the values from the specified map into this map.
>        *
>        * @param map  the map to add
>        * @throws NullPointerException if the map is null
>        */
>       public void putAll(Map map) {
>           int mapSize = map.size();
>           if (mapSize == 0) {
>               return;
>           }
>           ensureCapacity(calculateNewCapacity(size + mapSize));
>           for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
>               Map.Entry entry = (Map.Entry) it.next();
>               put(entry.getKey(), entry.getValue());
>           }
>       }
>
>       /**
>        * Removes the specified mapping from this map.
>        *
>        * @param key  the mapping to remove
>        * @return the value mapped to the removed key, null if key not in map
>        */
>       public Object remove(Object key) {
>           key = convertKey(key);
>           int hashCode = hash(key);
>           int index = hashIndex(hashCode, data.length);
>           HashEntry entry = data[index];
>           HashEntry previous = null;
>           while (entry != null) {
>               if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
>                   modCount++;
>                   if (previous == null) {
>                       data[index] = entry.next;
>                   } else {
>                       previous.next = entry.next;
>                   }
>                   size--;
>                   return destroyEntry(entry);
>               }
>               previous = entry;
>               entry = entry.next;
>           }
>           return null;
>       }
>
>       /**
>        * Clears the map, resetting the size to zero and nullifying references
>        * to avoid garbage collection issues.
>        */
>       public void clear() {
>           modCount++;
>           HashEntry[] data = this.data;
>           for (int i = data.length - 1; i >= 0; i--) {
>               data[i] = null;
>           }
>           size = 0;
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Converts input keys to another object for storage in the map.
>        * This implementation masks nulls.
>        * Subclasses can override this to perform alternate key conversions.
>        * <p>
>        * The reverse conversion can be changed, if required, by overriding the
>        * getKey() method in the hash entry.
>        *
>        * @param key  the key to get a hash code for
>        * @return the hash code
>        */
>       protected Object convertKey(Object key) {
>           return (key == null ? NULL : key);
>       }
>
>       /**
>        * Gets the hash code for the key specified.
>        * This implementation uses the additional hashing routine from JDK1.4.
>        * Subclasses can override this to return alternate hash codes.
>        *
>        * @param key  the key to get a hash code for
>        * @return the hash code
>        */
>       protected int hash(Object key) {
>           // same as JDK 1.4
>           int h = key.hashCode();
>           h += ~(h << 9);
>           h ^=  (h >>> 14);
>           h +=  (h << 4);
>           h ^=  (h >>> 10);
>           return h;
>       }
>
>       /**
>        * Compares two keys for equals.
>        * This implementation uses the equals method.
>        * Subclasses can override this to match differently.
>        *
>        * @param key1  the first key to compare
>        * @param key2  the second key to compare
>        * @return true if equal
>        */
>       protected boolean isEqualKey(Object key1, Object key2) {
>           return (key1 == key2 || key1.equals(key2));
>       }
>
>       /**
>        * Compares two values for equals.
>        * This implementation uses the equals method.
>        * Subclasses can override this to match differently.
>        *
>        * @param value1  the first value to compare
>        * @param value2  the second value to compare
>        * @return true if equal
>        */
>       protected boolean isEqualValue(Object value1, Object value2) {
>           return (value1 == value2 || value1.equals(value2));
>       }
>
>       /**
>        * Gets the index into the data storage for the hashCode specified.
>        * This implementation uses the least significant bits of the hashCode.
>        * Subclasses can override this to return alternate bucketing.
>        *
>        * @param hashCode  the hash code to use
>        * @param dataSize  the size of the data to pick a bucket from
>        * @return the bucket index
>        */
>       protected int hashIndex(int hashCode, int dataSize) {
>           return hashCode & (dataSize - 1);
>       }
>
>       /**
>        * Creates an entry to store the data.
>        * This implementation creates a HashEntry instance.
>        * Subclasses can override this to return a different storage class,
>        * or implement caching.
>        *
>        * @param next  the next entry in sequence
>        * @param hashCode  the hash code to use
>        * @param key  the key to store
>        * @param value  the value to store
>        * @return the newly created entry
>        */
>       protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
>           return new HashEntry(next, hashCode, key, value);
>       }
>
>       /**
>        * Kills an entry ready for the garbage collector.
>        * This implementation prepares the HashEntry for garbage collection.
>        * Subclasses can override this to implement caching (override clear as well).
>        *
>        * @param entry  the entry to destroy
>        * @return the value from the entry
>        */
>       protected Object destroyEntry(HashEntry entry) {
>           entry.next = null;
>           return entry.value;
>       }
>
>       /**
>        * Adds a new key-value mapping into this map.
>        * Subclasses could override to fix the size of the map.
>        *
>        * @param key  the key to add
>        * @param value  the value to add
>        * @return the value previously mapped to this key, null if none
>        */
>       protected void add(int hashCode, int hashIndex, Object key, Object value) {
>           data[hashIndex] = createEntry(data[hashIndex], hashCode, key, value);
>           if (size++ >= threshold) {
>               ensureCapacity(data.length * 2);
>           }
>       }
>
>       /**
>        * Changes the size of the data structure to the capacity proposed.
>        *
>        * @param newCapacity  the new capacity of the array
>        */
>       protected void ensureCapacity(int newCapacity) {
>           int oldCapacity = data.length;
>           if (newCapacity <= oldCapacity) {
>               return;
>           }
>           HashEntry oldEntries[] = data;
>           HashEntry newEntries[] = new HashEntry[newCapacity];
>
>           modCount++;
>           for (int i = oldCapacity - 1; i >= 0; i--) {
>               HashEntry entry = oldEntries[i];
>               if (entry != null) {
>                   oldEntries[i] = null;  // gc
>                   do {
>                       HashEntry next = entry.next;
>                       int index = hashIndex(entry.hashCode, newCapacity);
>                       entry.next = newEntries[index];
>                       newEntries[index] = entry;
>                       entry = next;
>                   } while (entry != null);
>               }
>           }
>           threshold = calculateThreshold(newCapacity, loadFactor);
>           data = newEntries;
>       }
>
>       /**
>        * Calculates the new capacity of the map.
>        * This implementation normalizes the capacity to a power of two.
>        *
>        * @param proposedCapacity  the proposed capacity
>        * @return the normalized new capacity
>        */
>       protected int calculateNewCapacity(int proposedCapacity) {
>           int newCapacity = 1;
>           if (proposedCapacity > MAXIMUM_CAPACITY) {
>               newCapacity = MAXIMUM_CAPACITY;
>           } else {
>               while (newCapacity < proposedCapacity) {
>                   newCapacity <<= 1;  // multiply by two
>               }
>               if (proposedCapacity > MAXIMUM_CAPACITY) {
>                   newCapacity = MAXIMUM_CAPACITY;
>               }
>           }
>           return newCapacity;
>       }
>
>       /**
>        * Calculates the new threshold of the map, where it will be resized.
>        * This implementation uses the load factor.
>        *
>        * @param newCapacity  the new capacity
>        * @param factor  the load factor
>        * @return the new resize threshold
>        */
>       protected int calculateThreshold(int newCapacity, float factor) {
>           return (int) (newCapacity * factor);
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Gets an iterator over the map.
>        * Changes made to the iterator affect this map.
>        * <p>
>        * A MapIterator returns the keys in the map. It also provides convenient
>        * methods to get the key and value, and set the value.
>        * It avoids the need to create an entrySet/keySet/values object.
>        * It also avoids creating the Mep Entry object.
>        *
>        * @return the map iterator
>        */
>       public MapIterator mapIterator() {
>           if (size == 0) {
>               return IteratorUtils.EMPTY_MAP_ITERATOR;
>           }
>           return new HashMapIterator(this);
>       }
>
>       /**
>        * MapIterator
>        */
>       static class HashMapIterator extends HashIterator implements MapIterator {
>
>           HashMapIterator(HashedMap map) {
>               super(map);
>           }
>
>           public Object next() {
>               return super.nextEntry().getKey();
>           }
>
>           public Object getKey() {
>               HashEntry current = currentEntry();
>               if (current == null) {
>                   throw new IllegalStateException("Iterator remove() can only be called once after next()");
>               }
>               return current.getKey();
>           }
>
>           public Object getValue() {
>               HashEntry current = currentEntry();
>               if (current == null) {
>                   throw new IllegalStateException("Iterator remove() can only be called once after next()");
>               }
>               return current.getValue();
>           }
>
>           public Object setValue(Object value) {
>               HashEntry current = currentEntry();
>               if (current == null) {
>                   throw new IllegalStateException("Iterator remove() can only be called once after next()");
>               }
>               Object old = current.getValue();
>               current.setValue(value);
>               return old;
>           }
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Gets the entrySet view of the map.
>        * Changes made to the view affect this map.
>        * The Map Entry is not an independent object and changes as the
>        * iterator progresses.
>        * To simply iterate through the entries, use {@link #mapIterator()}.
>        *
>        * @return the entrySet view
>        */
>       public Set entrySet() {
>           if (entrySet == null) {
>               entrySet = new EntrySet(this);
>           }
>           return entrySet;
>       }
>
>       /**
>        * Creates an entry set iterator.
>        * Subclasses can override this to return iterators with different properties.
>        *
>        * @return the entrySet iterator
>        */
>       protected Iterator createEntrySetIterator() {
>           if (size() == 0) {
>               return IteratorUtils.EMPTY_ITERATOR;
>           }
>           return new EntrySetIterator(this);
>       }
>
>       /**
>        * EntrySet
>        */
>       static class EntrySet extends AbstractSet {
>           private final HashedMap map;
>
>           EntrySet(HashedMap map) {
>               super();
>               this.map = map;
>           }
>
>           public int size() {
>               return map.size();
>           }
>
>           public void clear() {
>               map.clear();
>           }
>
>           public boolean contains(Object entry) {
>               if (entry instanceof Map.Entry) {
>                   return map.containsKey(((Map.Entry) entry).getKey());
>               }
>               return false;
>           }
>
>           public boolean remove(Object obj) {
>               if (obj instanceof Map.Entry == false) {
>                   return false;
>               }
>               Map.Entry entry = (Map.Entry) obj;
>               Object key = entry.getKey();
>               boolean result = map.containsKey(key);
>               map.remove(key);
>               return result;
>           }
>
>           public Iterator iterator() {
>               return map.createEntrySetIterator();
>           }
>       }
>
>       /**
>        * EntrySetIterator and MapEntry
>        */
>       static class EntrySetIterator extends HashIterator {
>
>           EntrySetIterator(HashedMap map) {
>               super(map);
>           }
>
>           public Object next() {
>               return super.nextEntry();
>           }
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Gets the keySet view of the map.
>        * Changes made to the view affect this map.
>        * To simply iterate through the keys, use {@link #mapIterator()}.
>        *
>        * @return the keySet view
>        */
>       public Set keySet() {
>           if (keySet == null) {
>               keySet = new KeySet(this);
>           }
>           return keySet;
>       }
>
>       /**
>        * Creates a key set iterator.
>        * Subclasses can override this to return iterators with different properties.
>        *
>        * @return the keySet iterator
>        */
>       protected Iterator createKeySetIterator() {
>           if (size() == 0) {
>               return IteratorUtils.EMPTY_ITERATOR;
>           }
>           return new KeySetIterator(this);
>       }
>
>       /**
>        * KeySet
>        */
>       static class KeySet extends AbstractSet {
>           private final HashedMap map;
>
>           KeySet(HashedMap map) {
>               super();
>               this.map = map;
>           }
>
>           public int size() {
>               return map.size();
>           }
>
>           public void clear() {
>               map.clear();
>           }
>
>           public boolean contains(Object key) {
>               return map.containsKey(key);
>           }
>
>           public boolean remove(Object key) {
>               boolean result = map.containsKey(key);
>               map.remove(key);
>               return result;
>           }
>
>           public Iterator iterator() {
>               return map.createKeySetIterator();
>           }
>       }
>
>       /**
>        * KeySetIterator
>        */
>       static class KeySetIterator extends EntrySetIterator {
>
>           KeySetIterator(HashedMap map) {
>               super(map);
>           }
>
>           public Object next() {
>               return super.nextEntry().getKey();
>           }
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Gets the values view of the map.
>        * Changes made to the view affect this map.
>        * To simply iterate through the values, use {@link #mapIterator()}.
>        *
>        * @return the values view
>        */
>       public Collection values() {
>           if (values == null) {
>               values = new Values(this);
>           }
>           return values;
>       }
>
>       /**
>        * Creates a values iterator.
>        * Subclasses can override this to return iterators with different properties.
>        *
>        * @return the values iterator
>        */
>       protected Iterator createValuesIterator() {
>           if (size() == 0) {
>               return IteratorUtils.EMPTY_ITERATOR;
>           }
>           return new ValuesIterator(this);
>       }
>
>       /**
>        * Values
>        */
>       static class Values extends AbstractCollection {
>           private final HashedMap map;
>
>           Values(HashedMap map) {
>               super();
>               this.map = map;
>           }
>
>           public int size() {
>               return map.size();
>           }
>
>           public void clear() {
>               map.clear();
>           }
>
>           public boolean contains(Object value) {
>               return map.containsValue(value);
>           }
>
>           public Iterator iterator() {
>               return map.createValuesIterator();
>           }
>       }
>
>       /**
>        * ValuesIterator
>        */
>       static class ValuesIterator extends HashIterator {
>
>           ValuesIterator(HashedMap map) {
>               super(map);
>           }
>
>           public Object next() {
>               return super.nextEntry().getValue();
>           }
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * HashEntry
>        */
>       protected static class HashEntry implements Map.Entry {
>           protected HashEntry next;
>           protected int hashCode;
>           protected Object key;
>           protected Object value;
>
>           HashEntry(HashEntry next, int hashCode, Object key, Object value) {
>               super();
>               this.next = next;
>               this.hashCode = hashCode;
>               this.key = key;
>               this.value = value;
>           }
>           public Object getKey() {
>               return (key == NULL ? null : key);
>           }
>           public Object getValue() {
>               return value;
>           }
>           public Object setValue(Object value) {
>               Object old = value;
>               this.value = value;
>               return old;
>           }
>           public boolean equals(Object obj) {
>               if (obj == this) {
>                   return true;
>               }
>               if (obj instanceof Map.Entry == false) {
>                   return false;
>               }
>               Map.Entry other = (Map.Entry) obj;
>               return
>                   (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) &&
>                   (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
>           }
>           public int hashCode() {
>               return (getKey() == null ? 0 : getKey().hashCode()) ^
>                      (getValue() == null ? 0 : getValue().hashCode());
>           }
>           public String toString() {
>               return new StringBuffer().append(getKey()).append('=').append(getValue()).toString();
>           }
>       }
>
>       /**
>        * Base Iterator
>        */
>       protected static abstract class HashIterator implements Iterator {
>           private final HashedMap map;
>           private int hashIndex;
>           private HashEntry current;
>           private HashEntry next;
>           private int expectedModCount;
>
>           HashIterator(HashedMap map) {
>               super();
>               this.map = map;
>               HashEntry[] data = map.data;
>               int i = data.length;
>               HashEntry next = null;
>               while (i > 0 && next == null) {
>                   next = data[--i];
>               }
>               this.next = next;
>               this.hashIndex = i;
>               this.expectedModCount = map.modCount;
>           }
>
>           public boolean hasNext() {
>               return (next != null);
>           }
>
>           HashEntry nextEntry() {
>               if (map.modCount != expectedModCount) {
>                   throw new ConcurrentModificationException();
>               }
>               HashEntry newCurrent = next;
>               if (newCurrent == null)  {
>                   throw new NoSuchElementException("No more elements in the iteration");
>               }
>               HashEntry[] data = map.data;
>               int i = hashIndex;
>               HashEntry n = newCurrent.next;
>               while (n == null && i > 0) {
>                   n = data[--i];
>               }
>               next = n;
>               hashIndex = i;
>               current = newCurrent;
>               return newCurrent;
>           }
>
>           public HashEntry currentEntry() {
>               return current;
>           }
>
>           public void remove() {
>               if (current == null) {
>                   throw new IllegalStateException("Iterator remove() can only be called once after next()");
>               }
>               if (map.modCount != expectedModCount) {
>                   throw new ConcurrentModificationException();
>               }
>               map.remove(current.getKey());
>               current = null;
>               expectedModCount = map.modCount;
>           }
>
>           public String toString() {
>               if (current != null) {
>                   return "Iterator[" + current.getKey() + "=" + current.getValue() + "]";
>               } else {
>                   return "Iterator[]";
>               }
>           }
>       }
>
>       //-----------------------------------------------------------------------
>       /**
>        * Write the map out using a custom routine.
>        */
>       private void writeObject(ObjectOutputStream out) throws IOException {
>           out.defaultWriteObject();
>           out.writeInt(data.length);
>           out.writeInt(size);
>           for (MapIterator it = mapIterator(); it.hasNext();) {
>               out.writeObject(it.next());
>               out.writeObject(it.getValue());
>           }
>       }
>
>       /**
>        * Read the map in using a custom routine.
>        */
>       private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
>           in.defaultReadObject();
>           int capacity = in.readInt();
>           int size = in.readInt();
>           data = new HashEntry[capacity];
>           for (int i = 0; i < size; i++) {
>               Object key = in.readObject();
>               Object value = in.readObject();
>               put(key, value);
>           }
>       }
>       //-----------------------------------------------------------------------
>       /**
>        * Clones the map without cloning the keys or values.
>        *
>        * @return a shallow clone
>        */
>       public Object clone() {
>           try {
>               HashedMap cloned = (HashedMap) super.clone();
>               cloned.data = new HashEntry[data.length];
>               cloned.entrySet = null;
>               cloned.keySet = null;
>               cloned.values = null;
>               cloned.modCount = 0;
>               cloned.size = 0;
>               cloned.putAll(this);
>               return cloned;
>
>           } catch (CloneNotSupportedException ex) {
>               return null;  // should never happen
>           }
>       }
>
>       /**
>        * Compares this map with another.
>        *
>        * @param obj  the object to compare to
>        * @return true if equal
>        */
>       public boolean equals(Object obj) {
>           if (obj == this) {
>               return true;
>           }
>           if (obj instanceof Map == false) {
>               return false;
>           }
>           Map map = (Map) obj;
>           if (map.size() != size()) {
>               return false;
>           }
>           MapIterator it = mapIterator();
>           try {
>               while (it.hasNext()) {
>                   Object key = it.next();
>                   Object value = it.getValue();
>                   if (value == null) {
>                       if (map.get(key) != null || map.containsKey(key) == false) {
>                           return false;
>                       }
>                   } else {
>                       if (value.equals(map.get(key)) == false) {
>                           return false;
>                       }
>                   }
>               }
>           } catch (ClassCastException ignored)   {
>               return false;
>           } catch (NullPointerException ignored) {
>               return false;
>           }
>           return true;
>       }
>
>       /**
>        * Gets the standard Map hashCode.
>        *
>        * @return the hashcode defined in the Map interface
>        */
>       public int hashCode() {
>           int total = 0;
>           Iterator it = createEntrySetIterator();
>           while (it.hasNext()) {
>               total += it.next().hashCode();
>           }
>           return total;
>       }
>
>       /**
>        * Gets the map as a String.
>        *
>        * @return a string version of the map
>        */
>       public String toString() {
>           if (size() == 0) {
>               return "{}";
>           }
>           StringBuffer buf = new StringBuffer(32 * size());
>           buf.append('{');
>
>           MapIterator it = mapIterator();
>           boolean hasNext = it.hasNext();
>           while (hasNext) {
>               Object key = it.next();
>               Object value = it.getValue();
>               buf.append(key == this ? "(this Map)" : key)
>                  .append('=')
>                  .append(value == this ? "(this Map)" : value);
>
>               hasNext = it.hasNext();
>               if (hasNext) {
>                   buf.append(',').append(' ');
>               }
>           }
>
>           buf.append('}');
>           return buf.toString();
>       }
>   }
>
>
>
>   1.5       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java
>
>   Index: AbstractTestSortedBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java,v
>   retrieving revision 1.4
>   retrieving revision 1.5
>   diff -u -r1.4 -r1.5
>   --- AbstractTestSortedBidiMap.java	18 Nov 2003 22:37:16 -0000	1.4
>   +++ AbstractTestSortedBidiMap.java	1 Dec 2003 22:34:54 -0000	1.5
>   @@ -70,6 +70,7 @@
>    import java.util.TreeSet;
>
>    import org.apache.commons.collections.BulkTest;
>   +import org.apache.commons.collections.SortedBidiMap;
>    import org.apache.commons.collections.map.AbstractTestSortedMap;
>
>    /**
>
>
>
>   1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java
>
>   Index: TestDualTreeBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- TestDualTreeBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
>   +++ TestDualTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
>   @@ -60,6 +60,7 @@
>    import junit.framework.Test;
>    import junit.textui.TestRunner;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.BulkTest;
>
>    /**
>
>
>
>   1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java
>
>   Index: TestDualHashBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- TestDualHashBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
>   +++ TestDualHashBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
>   @@ -60,6 +60,7 @@
>    import junit.framework.Test;
>    import junit.textui.TestRunner;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.BulkTest;
>
>    /**
>
>
>
>   1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java
>
>   Index: AbstractTestOrderedBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- AbstractTestOrderedBidiMap.java	20 Nov 2003 00:31:42 -0000	1.2
>   +++ AbstractTestOrderedBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
>   @@ -65,6 +65,7 @@
>    import java.util.NoSuchElementException;
>
>    import org.apache.commons.collections.BulkTest;
>   +import org.apache.commons.collections.OrderedBidiMap;
>    import org.apache.commons.collections.iterators.AbstractTestMapIterator;
>    import org.apache.commons.collections.iterators.MapIterator;
>
>
>
>
>   1.3       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java
>
>   Index: TestTreeBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- TestTreeBidiMap.java	18 Nov 2003 22:37:16 -0000	1.2
>   +++ TestTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
>   @@ -63,6 +63,7 @@
>    import junit.framework.Test;
>    import junit.textui.TestRunner;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.BulkTest;
>
>    /**
>
>
>
>   1.4       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java
>
>   Index: AbstractTestBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java,v
>   retrieving revision 1.3
>   retrieving revision 1.4
>   diff -u -r1.3 -r1.4
>   --- AbstractTestBidiMap.java	18 Nov 2003 22:37:16 -0000	1.3
>   +++ AbstractTestBidiMap.java	1 Dec 2003 22:34:54 -0000	1.4
>   @@ -63,6 +63,7 @@
>    import java.util.Map;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.BulkTest;
>    import org.apache.commons.collections.iterators.AbstractTestMapIterator;
>    import org.apache.commons.collections.iterators.MapIterator;
>
>
>
>   1.2       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java
>
>   Index: TestFlat3Map.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- TestFlat3Map.java	18 Nov 2003 23:23:05 -0000	1.1
>   +++ TestFlat3Map.java	1 Dec 2003 22:34:54 -0000	1.2
>   @@ -73,7 +73,7 @@
>     *
>     * @author Stephen Colebourne
>     */
>   -public class TestFlat3Map extends AbstractTestMap {
>   +public class TestFlat3Map extends AbstractTestAMap {
>
>        public TestFlat3Map(String testName) {
>            super(testName);
>
>
>
>   1.4       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestAll.java
>
>   Index: TestAll.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestAll.java,v
>   retrieving revision 1.3
>   retrieving revision 1.4
>   diff -u -r1.3 -r1.4
>   --- TestAll.java	20 Nov 2003 22:35:50 -0000	1.3
>   +++ TestAll.java	1 Dec 2003 22:34:54 -0000	1.4
>   @@ -86,6 +86,7 @@
>            suite.addTest(TestFixedSizeMap.suite());
>            suite.addTest(TestFixedSizeSortedMap.suite());
>            suite.addTest(TestFlat3Map.suite());
>   +        suite.addTest(TestHashedMap.suite());
>            suite.addTest(TestLazyMap.suite());
>            suite.addTest(TestLazySortedMap.suite());
>            suite.addTest(TestListOrderedMap.suite());
>
>
>
>   1.2       +4 -50     jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestOrderedMap.java
>
>   Index: AbstractTestOrderedMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestOrderedMap.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- AbstractTestOrderedMap.java	20 Nov 2003 22:34:49 -0000	1.1
>   +++ AbstractTestOrderedMap.java	1 Dec 2003 22:34:54 -0000	1.2
>   @@ -67,8 +67,8 @@
>    import java.util.TreeMap;
>
>    import org.apache.commons.collections.BulkTest;
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.comparators.NullComparator;
>   -import org.apache.commons.collections.iterators.AbstractTestMapIterator;
>    import org.apache.commons.collections.iterators.AbstractTestOrderedMapIterator;
>    import org.apache.commons.collections.iterators.MapIterator;
>
>   @@ -79,7 +79,7 @@
>     *
>     * @author Stephen Colebourne
>     */
>   -public abstract class AbstractTestOrderedMap extends AbstractTestMap {
>   +public abstract class AbstractTestOrderedMap extends AbstractTestAMap {
>
>        /**
>         * JUnit constructor.
>   @@ -214,56 +214,10 @@
>        }
>
>        //-----------------------------------------------------------------------
>   -    public BulkTest bulkTestMapIterator() {
>   -        return new InnerTestOrderedMapIterator();
>   -    }
>   -
>   -    // TODO: Test mapIterator() and orderedMapIterator() separately
>   -    public class InnerTestMapIterator extends AbstractTestMapIterator {
>   -        public InnerTestMapIterator() {
>   -            super("InnerTestMapIterator");
>   -        }
>   -
>   -        public boolean supportsRemove() {
>   -            return AbstractTestOrderedMap.this.isRemoveSupported();
>   -        }
>   -
>   -        public boolean supportsSetValue() {
>   -            return AbstractTestOrderedMap.this.isSetValueSupported();
>   -        }
>   -
>   -        public MapIterator makeEmptyMapIterator() {
>   -            resetEmpty();
>   -            return ((OrderedMap) AbstractTestOrderedMap.this.map).mapIterator();
>   -        }
>   -
>   -        public MapIterator makeFullMapIterator() {
>   -            resetFull();
>   -            return ((OrderedMap) AbstractTestOrderedMap.this.map).mapIterator();
>   -        }
>   -
>   -        public Map getMap() {
>   -            // assumes makeFullMapIterator() called first
>   -            return AbstractTestOrderedMap.this.map;
>   -        }
>   -
>   -        public Map getConfirmedMap() {
>   -            // assumes makeFullMapIterator() called first
>   -            return AbstractTestOrderedMap.this.confirmed;
>   -        }
>   -
>   -        public void verify() {
>   -            super.verify();
>   -            AbstractTestOrderedMap.this.verify();
>   -        }
>   -    }
>   -
>   -    //-----------------------------------------------------------------------
>        public BulkTest bulkTestOrderedMapIterator() {
>            return new InnerTestOrderedMapIterator();
>        }
>
>   -    // TODO: Test mapIterator() and orderedMapIterator() separately
>        public class InnerTestOrderedMapIterator extends AbstractTestOrderedMapIterator {
>            public InnerTestOrderedMapIterator() {
>                super("InnerTestOrderedMapIterator");
>
>
>
>   1.5       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableMap.java
>
>   Index: TestUnmodifiableMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableMap.java,v
>   retrieving revision 1.4
>   retrieving revision 1.5
>   diff -u -r1.4 -r1.5
>   --- TestUnmodifiableMap.java	20 Nov 2003 22:35:50 -0000	1.4
>   +++ TestUnmodifiableMap.java	1 Dec 2003 22:34:54 -0000	1.5
>   @@ -74,7 +74,7 @@
>     *
>     * @author Phil Steitz
>     */
>   -public class TestUnmodifiableMap extends AbstractTestMap{
>   +public class TestUnmodifiableMap extends AbstractTestAMap{
>
>        public TestUnmodifiableMap(String testName) {
>            super(testName);
>
>
>
>   1.2       +3 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableOrderedMap.java
>
>   Index: TestUnmodifiableOrderedMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestUnmodifiableOrderedMap.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- TestUnmodifiableOrderedMap.java	20 Nov 2003 22:35:50 -0000	1.1
>   +++ TestUnmodifiableOrderedMap.java	1 Dec 2003 22:34:54 -0000	1.2
>   @@ -63,6 +63,7 @@
>    import junit.framework.Test;
>    import junit.framework.TestSuite;
>
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.Unmodifiable;
>
>    /**
>
>
>
>   1.1                  jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestAMap.java
>
>   Index: AbstractTestAMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/AbstractTestAMap.java,v 1.1 2003/12/01 22:34:54 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections.map;
>
>   import java.util.ConcurrentModificationException;
>   import java.util.Iterator;
>   import java.util.Map;
>
>   import org.apache.commons.collections.AMap;
>   import org.apache.commons.collections.BulkTest;
>   import org.apache.commons.collections.iterators.AbstractTestMapIterator;
>   import org.apache.commons.collections.iterators.MapIterator;
>
>   /**
>    * Abstract test class for {@link AMap} methods and contracts.
>    *
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:54 $
>    *
>    * @author Stephen Colebourne
>    */
>   public abstract class AbstractTestAMap extends AbstractTestMap {
>
>       /**
>        * JUnit constructor.
>        *
>        * @param testName  the test name
>        */
>       public AbstractTestAMap(String testName) {
>           super(testName);
>       }
>
>       //-----------------------------------------------------------------------
>       public void testFailFastEntrySet() {
>           if (isRemoveSupported() == false) return;
>           resetFull();
>           Iterator it = map.entrySet().iterator();
>           Map.Entry val = (Map.Entry) it.next();
>           map.remove(val.getKey());
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>
>           resetFull();
>           it = map.entrySet().iterator();
>           it.next();
>           map.clear();
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>       }
>
>       public void testFailFastKeySet() {
>           if (isRemoveSupported() == false) return;
>           resetFull();
>           Iterator it = map.keySet().iterator();
>           Object val = it.next();
>           map.remove(val);
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>
>           resetFull();
>           it = map.keySet().iterator();
>           it.next();
>           map.clear();
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>       }
>
>       public void testFailFastValues() {
>           if (isRemoveSupported() == false) return;
>           resetFull();
>           Iterator it = map.values().iterator();
>           it.next();
>           map.remove(map.keySet().iterator().next());
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>
>           resetFull();
>           it = map.values().iterator();
>           it.next();
>           map.clear();
>           try {
>               it.next();
>               fail();
>           } catch (ConcurrentModificationException ex) {}
>       }
>
>       //-----------------------------------------------------------------------
>       public BulkTest bulkTestMapIterator() {
>           return new InnerTestMapIterator();
>       }
>
>       public class InnerTestMapIterator extends AbstractTestMapIterator {
>           public InnerTestMapIterator() {
>               super("InnerTestMapIterator");
>           }
>
>           public Object[] addSetValues() {
>               return AbstractTestAMap.this.getNewSampleValues();
>           }
>
>           public boolean supportsRemove() {
>               return AbstractTestAMap.this.isRemoveSupported();
>           }
>
>           public boolean supportsSetValue() {
>               return AbstractTestAMap.this.isSetValueSupported();
>           }
>
>           public MapIterator makeEmptyMapIterator() {
>               resetEmpty();
>               return ((AMap) AbstractTestAMap.this.map).mapIterator();
>           }
>
>           public MapIterator makeFullMapIterator() {
>               resetFull();
>               return ((AMap) AbstractTestAMap.this.map).mapIterator();
>           }
>
>           public Map getMap() {
>               // assumes makeFullMapIterator() called first
>               return AbstractTestAMap.this.map;
>           }
>
>           public Map getConfirmedMap() {
>               // assumes makeFullMapIterator() called first
>               return AbstractTestAMap.this.confirmed;
>           }
>
>           public void verify() {
>               super.verify();
>               AbstractTestAMap.this.verify();
>           }
>       }
>
>   //  public void testCreate() throws Exception {
>   //      resetEmpty();
>   //      writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/HashedMap.emptyCollection.version3.obj");
>   //      resetFull();
>   //      writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/HashedMap.fullCollection.version3.obj");
>   //  }
>   }
>
>
>
>   1.1                  jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestHashedMap.java
>
>   Index: TestHashedMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestHashedMap.java,v 1.1 2003/12/01 22:34:54 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections.map;
>
>   import java.util.Map;
>
>   import junit.framework.Test;
>   import junit.textui.TestRunner;
>
>   import org.apache.commons.collections.BulkTest;
>
>   /**
>    * JUnit tests.
>    *
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:54 $
>    *
>    * @author Stephen Colebourne
>    */
>   public class TestHashedMap extends AbstractTestAMap {
>
>       public TestHashedMap(String testName) {
>           super(testName);
>       }
>
>       public static void main(String[] args) {
>           TestRunner.run(suite());
>       }
>
>       public static Test suite() {
>           return BulkTest.makeSuite(TestHashedMap.class);
>       }
>
>       public Map makeEmptyMap() {
>           return new HashedMap();
>       }
>
>       public String getCompatibilityVersion() {
>           return "3";
>       }
>
>   }
>
>
>
>   1.2       +3 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java
>
>   Index: AbstractDualBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- AbstractDualBidiMap.java	16 Nov 2003 20:35:46 -0000	1.1
>   +++ AbstractDualBidiMap.java	1 Dec 2003 22:34:54 -0000	1.2
>   @@ -62,6 +62,7 @@
>    import java.util.Map;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.collection.AbstractCollectionDecorator;
>    import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
>    import org.apache.commons.collections.iterators.MapIterator;
>
>
>
>   1.2       +4 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java
>
>   Index: DualHashBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- DualHashBidiMap.java	16 Nov 2003 20:35:46 -0000	1.1
>   +++ DualHashBidiMap.java	1 Dec 2003 22:34:54 -0000	1.2
>   @@ -64,6 +64,8 @@
>    import java.util.HashMap;
>    import java.util.Map;
>
>   +import org.apache.commons.collections.BidiMap;
>   +
>    /**
>     * Implementation of <code>BidiMap</code> that uses two <code>HashMap</code> instances.
>     *
>
>
>
>   1.4       +6 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
>
>   Index: DualTreeBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java,v
>   retrieving revision 1.3
>   retrieving revision 1.4
>   diff -u -r1.3 -r1.4
>   --- DualTreeBidiMap.java	20 Nov 2003 00:31:42 -0000	1.3
>   +++ DualTreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.4
>   @@ -69,10 +69,13 @@
>    import java.util.SortedMap;
>    import java.util.TreeMap;
>
>   +import org.apache.commons.collections.BidiMap;
>   +import org.apache.commons.collections.OrderedBidiMap;
>   +import org.apache.commons.collections.OrderedMap;
>   +import org.apache.commons.collections.SortedBidiMap;
>    import org.apache.commons.collections.iterators.OrderedMapIterator;
>    import org.apache.commons.collections.iterators.ResettableIterator;
>    import org.apache.commons.collections.map.AbstractSortedMapDecorator;
>   -import org.apache.commons.collections.map.OrderedMap;
>
>    /**
>     * Implementation of <code>BidiMap</code> that uses two <code>TreeMap</code> instances.
>
>
>
>   1.3       +4 -2      jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java
>
>   Index: TreeBidiMap.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java,v
>   retrieving revision 1.2
>   retrieving revision 1.3
>   diff -u -r1.2 -r1.3
>   --- TreeBidiMap.java	20 Nov 2003 00:31:42 -0000	1.2
>   +++ TreeBidiMap.java	1 Dec 2003 22:34:54 -0000	1.3
>   @@ -65,7 +65,9 @@
>    import java.util.NoSuchElementException;
>    import java.util.Set;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.IteratorUtils;
>   +import org.apache.commons.collections.OrderedBidiMap;
>    import org.apache.commons.collections.iterators.MapIterator;
>    import org.apache.commons.collections.iterators.OrderedIterator;
>    import org.apache.commons.collections.iterators.OrderedMapIterator;
>
>
>
>   1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedMap.java
>
>   Index: OrderedMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections;
>
>   import org.apache.commons.collections.iterators.OrderedMapIterator;
>
>   /**
>    * Defines a map that maintains order and allows both forward and backward
>    * iteration through that order.
>    *
>    * @since Commons Collections 3.0
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
>    *
>    * @author Stephen Colebourne
>    */
>   public interface OrderedMap extends AMap {
>
>       /**
>        * Obtains an <code>OrderedMapIterator</code> over the map.
>        * <p>
>        * A ordered map iterator is an efficient way of iterating over maps
>        * in both directions.
>        * <pre>
>        * BidiMap map = new TreeBidiMap();
>        * MapIterator it = map.mapIterator();
>        * while (it.hasNext()) {
>        *   Object key = it.next();
>        *   Object value = it.getValue();
>        *   it.setValue("newValue");
>        *   Object previousKey = it.previous();
>        * }
>        * </pre>
>        *
>        * @return a map iterator
>        */
>       OrderedMapIterator orderedMapIterator();
>
>       /**
>        * Gets the first key currently in this map.
>        *
>        * @return the first key currently in this map
>        * @throws NoSuchElementException if this map is empty
>        */
>       public Object firstKey();
>
>       /**
>        * Gets the last key currently in this map.
>        *
>        * @return the last key currently in this map
>        * @throws NoSuchElementException if this map is empty
>        */
>       public Object lastKey();
>
>       /**
>        * Gets the next key after the one specified.
>        *
>        * @param key  the key to search for next from
>        * @return the next key, null if no match or at end
>        */
>       public Object nextKey(Object key);
>
>       /**
>        * Gets the previous key before the one specified.
>        *
>        * @param key  the key to search for previous from
>        * @return the previous key, null if no match or at start
>        */
>       public Object previousKey(Object key);
>
>   }
>
>
>
>   1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedBidiMap.java
>
>   Index: OrderedBidiMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/OrderedBidiMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections;
>
>   /**
>    * Defines a map that allows bidirectional lookup between key and values
>    * and retains and provides access to an ordering.
>    * <p>
>    * Implementations should allow a value to be looked up from a key and
>    * a key to be looked up from a value with equal performance.
>    *
>    * @since Commons Collections 3.0
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
>    *
>    * @author Stephen Colebourne
>    */
>   public interface OrderedBidiMap extends BidiMap, OrderedMap {
>
>       /**
>        * Gets a view of this map where the keys and values are reversed.
>        * <p>
>        * Changes to one map will be visible in the other and vice versa.
>        * This enables both directions of the map to be accessed equally.
>        * <p>
>        * Implementations should seek to avoid creating a new object every time this
>        * method is called. See <code>AbstractMap.values()</code> etc. Calling this
>        * method on the inverse map should return the original.
>        * <p>
>        * Implementations must return an <code>OrderedBidiMap</code> instance,
>        * usually by forwarding to <code>inverseOrderedBidiMap()</code>.
>        *
>        * @return an inverted bidirectional map
>        */
>       public BidiMap inverseBidiMap();
>
>       /**
>        * Gets a view of this map where the keys and values are reversed.
>        * <p>
>        * Changes to one map will be visible in the other and vice versa.
>        * This enables both directions of the map to be accessed equally.
>        * <p>
>        * Implementations should seek to avoid creating a new object every time this
>        * method is called. See <code>AbstractMap.values()</code> etc. Calling this
>        * method on the inverse map should return the original.
>        *
>        * @return an inverted bidirectional map
>        */
>       public OrderedBidiMap inverseOrderedBidiMap();
>
>   }
>
>
>
>   1.3       +23 -3     jakarta-commons/collections/src/java/org/apache/commons/collections/SortedBidiMap.java
>
>
>
>
>   1.8       +2 -3      jakarta-commons/collections/src/java/org/apache/commons/collections/BidiMap.java
>
>
>
>
>   1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/AMap.java
>
>   Index: AMap.java
>   ===================================================================
>   /*
>    * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/AMap.java,v 1.1 2003/12/01 22:34:55 scolebourne Exp $
>    * ====================================================================
>    *
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution, if
>    *    any, must include the following acknowledgement:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgement may appear in the software itself,
>    *    if and wherever such third-party acknowledgements normally appear.
>    *
>    * 4. The names "The Jakarta Project", "Commons", and "Apache Software
>    *    Foundation" must not be used to endorse or promote products derived
>    *    from this software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache"
>    *    nor may "Apache" appear in their names without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    */
>   package org.apache.commons.collections;
>
>   import java.util.Map;
>
>   import org.apache.commons.collections.iterators.MapIterator;
>
>   /**
>    * Defines a map that can be iterated directly without needing to create an entry set.
>    * <p>
>    * A map iterator is an efficient way of iterating over maps.
>    * There is no need to access the entry set or cast to Map Entry objects.
>    * <pre>
>    * AMap map = new HashedMap();
>    * MapIterator it = map.mapIterator();
>    * while (it.hasNext()) {
>    *   Object key = it.next();
>    *   Object value = it.getValue();
>    *   it.setValue("newValue");
>    * }
>    * </pre>
>    *
>    * @since Commons Collections 3.0
>    * @version $Revision: 1.1 $ $Date: 2003/12/01 22:34:55 $
>    *
>    * @author Stephen Colebourne
>    */
>   public interface AMap extends Map {
>
>       /**
>        * Obtains a <code>MapIterator</code> over the map.
>        * <p>
>        * A map iterator is an efficient way of iterating over maps.
>        * There is no need to access the entry set or cast to Map Entry objects.
>        * <pre>
>        * AMap map = new HashedMap();
>        * MapIterator it = map.mapIterator();
>        * while (it.hasNext()) {
>        *   Object key = it.next();
>        *   Object value = it.getValue();
>        *   it.setValue("newValue");
>        * }
>        * </pre>
>        *
>        * @return a map iterator
>        */
>       MapIterator mapIterator();
>
>   }
>
>
>
>   1.2       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableOrderedMapIterator.java
>
>   Index: TestUnmodifiableOrderedMapIterator.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableOrderedMapIterator.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- TestUnmodifiableOrderedMapIterator.java	20 Nov 2003 21:45:35 -0000	1.1
>   +++ TestUnmodifiableOrderedMapIterator.java	1 Dec 2003 22:34:55 -0000	1.2
>   @@ -64,9 +64,9 @@
>    import junit.framework.Test;
>    import junit.framework.TestSuite;
>
>   +import org.apache.commons.collections.OrderedMap;
>    import org.apache.commons.collections.Unmodifiable;
>    import org.apache.commons.collections.map.ListOrderedMap;
>   -import org.apache.commons.collections.map.OrderedMap;
>
>    /**
>     * Tests the UnmodifiableOrderedMapIterator.
>
>
>
>   1.5       +3 -3      jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java
>
>   Index: TestUnmodifiableMapIterator.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java,v
>   retrieving revision 1.4
>   retrieving revision 1.5
>   diff -u -r1.4 -r1.5
>   --- TestUnmodifiableMapIterator.java	18 Nov 2003 22:37:13 -0000	1.4
>   +++ TestUnmodifiableMapIterator.java	1 Dec 2003 22:34:55 -0000	1.5
>   @@ -63,8 +63,8 @@
>    import junit.framework.Test;
>    import junit.framework.TestSuite;
>
>   +import org.apache.commons.collections.BidiMap;
>    import org.apache.commons.collections.Unmodifiable;
>   -import org.apache.commons.collections.bidimap.BidiMap;
>    import org.apache.commons.collections.bidimap.DualHashBidiMap;
>
>    /**
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org