/**
   * Increases the capacity of and internally reorganizes this SymbolTable, in order to accommodate
   * and access its entries more efficiently. This method is called automatically when the number of
   * keys in the SymbolTable exceeds this hashtable's capacity and load factor.
   */
  protected void rehash() {

    int oldCapacity = fBuckets.length;
    SREntry[] oldTable = fBuckets;

    int newCapacity = oldCapacity * 2 + 1;
    SREntry[] newTable = new SREntry[newCapacity];

    fThreshold = (int) (newCapacity * fLoadFactor);
    fBuckets = newTable;
    fTableSize = fBuckets.length;

    for (int i = oldCapacity; i-- > 0; ) {
      for (SREntry old = oldTable[i]; old != null; ) {
        SREntry e = old;
        old = old.next;

        SREntryData data = (SREntryData) e.get();
        if (data != null) {
          int index = hash(data.characters, 0, data.characters.length) % newCapacity;
          if (newTable[index] != null) {
            newTable[index].prev = e;
          }
          e.next = newTable[index];
          e.prev = null;
          newTable[index] = e;
        } else {
          fCount--;
        }
      }
    }
  }