import java.util.Map;
import java.util.Set;
import java.util.AbstractSet;

/**
 * A skeleton layout showing how you might build a keySet for a Map.
 *
 * @author <a href="mailto:terran@dhcp-41.cs.unm.edu">Terran Lane</a>
 * @version 1.0
 */
abstract public class HashTableKeySetSkel implements Map {

  public Set keySet() { return new _keySetBacking(); }

  public int size() { return _keyCount; }

  /* ******************** end of public interface ******************** */

  // data store for the actual key/value pairs
  private Entry[] _table;
  // count of number of keys in the table -- should be incremented by put()
  // and decremented by get()
  private int _keyCount;

  /**
   * This inner class provides the implementation of the Set to support the
   * keySet() operation.  By virtue of being an inner class, it has direct
   * access to all of the methods and data of HashTableKeySetSkel, should it
   * need them.
   */
  private class _keySetBacking extends AbstractSet {
    public _keySetBacking() {
      // set up any necessary accounting stuff here
    }

    public int size() { return HashTableKeySetSkel.this.size(); }

    public Iterator iterator() {
      return new _keyIterBacking();
    }

    // other methods to fully instantiate AbstractSet...

    private class _keyIterBacking implements Iterator {
      public _keyIterBacking() {
	// set up iterator accounting information here
      }
      public boolean hasNext() {}
      public Object next() {
	// Note!  This reference to _table is to the _keySetBacking _table
	// which is, itself, just a reference to HashTableKeySetSkel._table.
	// The magic of inner classes!
	Object k=_table[_curLoc].getKey();
	// increment _curLoc
	return k;
      }
      public Object remove() {
	// remove the key/value pair from the hash table
      }
      // assumes linear probing or somesuch; not chaining
      private int _curLoc;
    }
  }
}
