diff --git a/src/xercesc/util/RefHash2KeysTableOf.c b/src/xercesc/util/RefHash2KeysTableOf.c
index c3c36ae4b744345bc1f00c51f40c5a2c2abb5a6c..cbe53f8de131e0a6c16c04bc831545ad3ed334f2 100644
--- a/src/xercesc/util/RefHash2KeysTableOf.c
+++ b/src/xercesc/util/RefHash2KeysTableOf.c
@@ -16,6 +16,9 @@
 
 /**
  * $Log$
+ * Revision 1.15  2005/02/02 09:27:53  amassari
+ * Added rehashing capabilities
+ *
  * Revision 1.14  2004/12/30 14:52:34  amassari
  * Added API to remove all entries having the same primary key
  *
@@ -98,6 +101,7 @@ RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf( const unsigned int   modulus
 	, fAdoptedElems(adoptElems)
     , fBucketList(0)
     , fHashModulus(modulus)
+    , fCount(0)
     , fHash(0)
 {
     initialize(modulus);
@@ -115,6 +119,7 @@ RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf( const unsigned int   modulus
     , fAdoptedElems(adoptElems)
     , fBucketList(0)
     , fHashModulus(modulus)
+    , fCount(0)
     , fHash(0)
 {
 	initialize(modulus);
@@ -129,6 +134,7 @@ RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf(const unsigned int modulus,
     , fAdoptedElems(true)
     , fBucketList(0)
     , fHashModulus(modulus)
+    , fCount(0)
     , fHash(0)
 {
 	initialize(modulus);
@@ -167,13 +173,7 @@ template <class TVal> RefHash2KeysTableOf<TVal>::~RefHash2KeysTableOf()
 // ---------------------------------------------------------------------------
 template <class TVal> bool RefHash2KeysTableOf<TVal>::isEmpty() const
 {
-    // Just check the bucket list for non-empty elements
-    for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
-    {
-        if (fBucketList[buckInd] != 0)
-            return false;
-    }
-    return true;
+    return (fCount==0);
 }
 
 template <class TVal> bool RefHash2KeysTableOf<TVal>::
@@ -187,8 +187,52 @@ containsKey(const void* const key1, const int key2) const
 template <class TVal> void RefHash2KeysTableOf<TVal>::
 removeKey(const void* const key1, const int key2)
 {
-    unsigned int hashVal;
-    removeBucketElem(key1, key2, hashVal);
+    // Hash the key
+    unsigned int hashVal = fHash->getHashVal(key1, fHashModulus);
+    assert(hashVal < fHashModulus);
+
+    //
+    //  Search the given bucket for this key. Keep up with the previous
+    //  element so we can patch around it.
+    //
+    RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
+    RefHash2KeysTableBucketElem<TVal>* lastElem = 0;
+
+    while (curElem)
+    {
+        if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2))
+        {
+            if (!lastElem)
+            {
+                // It was the first in the bucket
+                fBucketList[hashVal] = curElem->fNext;
+            }
+            else
+            {
+                // Patch around the current element
+                lastElem->fNext = curElem->fNext;
+            }
+
+            // If we adopted the elements, then delete the data
+            if (fAdoptedElems)
+                delete curElem->fData;
+
+            // Delete the current element
+            // delete curElem;
+            // destructor is empty...
+            // curElem->~RefHash2KeysTableBucketElem();
+            fMemoryManager->deallocate(curElem);            
+            fCount--;
+            return;
+        }
+
+        // Move both pointers upwards
+        lastElem = curElem;
+        curElem = curElem->fNext;
+    }
+
+    // We never found that key
+    ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists, fMemoryManager);
 }
 
 template <class TVal> void RefHash2KeysTableOf<TVal>::
@@ -232,6 +276,7 @@ removeKey(const void* const key1)
             // destructor is empty...
             // curElem->~RefHash2KeysTableBucketElem();
             fMemoryManager->deallocate(toBeDeleted);
+            fCount--;
         }
         else
         {
@@ -244,6 +289,9 @@ removeKey(const void* const key1)
 
 template <class TVal> void RefHash2KeysTableOf<TVal>::removeAll()
 {
+    if(isEmpty())
+        return;
+
     // Clean up the buckets first
     for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
     {
@@ -272,6 +320,7 @@ template <class TVal> void RefHash2KeysTableOf<TVal>::removeAll()
         // Clean out this entry
         fBucketList[buckInd] = 0;
     }
+    fCount=0;
 }
 
 // this function transfer the data from key1 to key2
@@ -304,7 +353,24 @@ template <class TVal> void RefHash2KeysTableOf<TVal>::transferElement(const void
                 lastElem->fNext = curElem->fNext;
             }
 
-            put(key2, curElem->fKey2, curElem->fData);
+            // this code comes from put(), but it doesn't update fCount
+            unsigned int hashVal2;
+            RefHash2KeysTableBucketElem<TVal>* newBucket = findBucketElem(key2, curElem->fKey2, hashVal2);
+            if (newBucket)
+            {
+                if (fAdoptedElems)
+                    delete newBucket->fData;
+                newBucket->fData = curElem->fData;
+		        newBucket->fKey1 = key2;
+		        newBucket->fKey2 = curElem->fKey2;
+            }
+             else
+            {
+                newBucket =
+                    new (fMemoryManager->allocate(sizeof(RefHash2KeysTableBucketElem<TVal>)))
+                    RefHash2KeysTableBucketElem<TVal>(key2, curElem->fKey2, curElem->fData, fBucketList[hashVal2]);
+                fBucketList[hashVal2] = newBucket;
+            }
 
             RefHash2KeysTableBucketElem<TVal>* elemToDelete = curElem;
             
@@ -315,7 +381,7 @@ template <class TVal> void RefHash2KeysTableOf<TVal>::transferElement(const void
             // delete elemToDelete;
             // destructor is empty...
             // curElem->~RefHash2KeysTableBucketElem();
-            fMemoryManager->deallocate(elemToDelete);           
+            fMemoryManager->deallocate(elemToDelete);
         }
         else
         {
@@ -367,6 +433,13 @@ unsigned int RefHash2KeysTableOf<TVal>::getHashModulus() const
 // ---------------------------------------------------------------------------
 template <class TVal> void RefHash2KeysTableOf<TVal>::put(void* key1, int key2, TVal* const valueToAdopt)
 {
+    // Apply 4 load factor to find threshold.
+    unsigned int threshold = fHashModulus * 4;
+    
+    // If we've grown too big, expand the table and rehash.
+    if (fCount >= threshold)
+        rehash();
+
     // First see if the key exists already
     unsigned int hashVal;
     RefHash2KeysTableBucketElem<TVal>* newBucket = findBucketElem(key1, key2, hashVal);
@@ -389,6 +462,7 @@ template <class TVal> void RefHash2KeysTableOf<TVal>::put(void* key1, int key2,
             new (fMemoryManager->allocate(sizeof(RefHash2KeysTableBucketElem<TVal>)))
             RefHash2KeysTableBucketElem<TVal>(key1, key2, valueToAdopt, fBucketList[hashVal]);
         fBucketList[hashVal] = newBucket;
+        fCount++;
     }
 }
 
@@ -437,59 +511,52 @@ findBucketElem(const void* const key1, const int key2, unsigned int& hashVal) co
 
 
 template <class TVal> void RefHash2KeysTableOf<TVal>::
-removeBucketElem(const void* const key1, const int key2, unsigned int& hashVal)
+rehash()
 {
-    // Hash the key
-    hashVal = fHash->getHashVal(key1, fHashModulus);
-    assert(hashVal < fHashModulus);
-
-    //
-    //  Search the given bucket for this key. Keep up with the previous
-    //  element so we can patch around it.
-    //
-    RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
-    RefHash2KeysTableBucketElem<TVal>* lastElem = 0;
-
-    while (curElem)
+    unsigned int index;
+    unsigned int oldMod = fHashModulus;
+    fHashModulus = (fHashModulus * 8) + 1;
+    
+    RefHash2KeysTableBucketElem<TVal>** oldBucketList = fBucketList;
+    
+    fBucketList = (RefHash2KeysTableBucketElem<TVal>**) fMemoryManager->allocate
+    (
+        fHashModulus * sizeof(RefHash2KeysTableBucketElem<TVal>*)
+    );//new RefHash2KeysTableBucketElem<TVal>*[fHashModulus];
+    for (index = 0; index < fHashModulus; index++)
+        fBucketList[index] = 0;
+    
+    
+    // Rehash all existing entries.
+    for (index = 0; index < oldMod; index++)
     {
-        if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2))
+        // Get the bucket list head for this entry
+        RefHash2KeysTableBucketElem<TVal>* curElem = oldBucketList[index];
+        RefHash2KeysTableBucketElem<TVal>* nextElem;
+        while (curElem)
         {
-            if (!lastElem)
-            {
-                // It was the first in the bucket
-                fBucketList[hashVal] = curElem->fNext;
-            }
-            else
-            {
-                // Patch around the current element
-                lastElem->fNext = curElem->fNext;
-            }
-
-            // If we adopted the elements, then delete the data
-            if (fAdoptedElems)
-                delete curElem->fData;
+            // Save the next element before we detach this one
+            nextElem = curElem->fNext;
 
-            // Delete the current element
-            // delete curElem;
-            // destructor is empty...
-            // curElem->~RefHash2KeysTableBucketElem();
-            fMemoryManager->deallocate(curElem);
+            unsigned int hashVal = fHash->getHashVal(curElem->fKey1, fHashModulus, fMemoryManager);
+            assert(hashVal < fHashModulus);
             
-            return;
+            RefHash2KeysTableBucketElem<TVal>* newHeadElem = fBucketList[hashVal];
+            
+            // Insert at the start of this bucket's list.
+            curElem->fNext = newHeadElem;
+            fBucketList[hashVal] = curElem;
+            
+            curElem = nextElem;
         }
-
-        // Move both pointers upwards
-        lastElem = curElem;
-        curElem = curElem->fNext;
     }
-
-    // We never found that key
-    ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists, fMemoryManager);
+            
+    fMemoryManager->deallocate(oldBucketList);//delete[] oldBucketList;
+    
 }
 
 
 
-
 // ---------------------------------------------------------------------------
 //  RefHash2KeysTableOfEnumerator: Constructors and Destructor
 // ---------------------------------------------------------------------------
@@ -625,11 +692,8 @@ template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::findNext()
             return;
 
         // Else find the next non-empty bucket
-        while (true)
+        while (fToEnum->fBucketList[fCurHash]==0)
         {
-            if (fToEnum->fBucketList[fCurHash])
-                break;
-
             // Bump to the next hash value. If we max out return
             fCurHash++;
             if (fCurHash == fToEnum->fHashModulus)
diff --git a/src/xercesc/util/RefHash2KeysTableOf.hpp b/src/xercesc/util/RefHash2KeysTableOf.hpp
index d23f4abf72bd4f87d2eb2b1a145aefef5d6462cc..34812dcc111ee11d125e0e9e1c7cf97a493b3057 100644
--- a/src/xercesc/util/RefHash2KeysTableOf.hpp
+++ b/src/xercesc/util/RefHash2KeysTableOf.hpp
@@ -16,6 +16,9 @@
 
 /*
  * $Log$
+ * Revision 1.15  2005/02/02 09:27:54  amassari
+ * Added rehashing capabilities
+ *
  * Revision 1.14  2004/12/30 14:52:34  amassari
  * Added API to remove all entries having the same primary key
  *
@@ -204,8 +207,8 @@ private:
     // -----------------------------------------------------------------------
     RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, unsigned int& hashVal);
     const RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, unsigned int& hashVal) const;
-    void removeBucketElem(const void* const key1, const int key2, unsigned int& hashVal);
-	void initialize(const unsigned int modulus);
+    void initialize(const unsigned int modulus);
+    void rehash();
 
 
     // -----------------------------------------------------------------------
@@ -223,15 +226,19 @@ private:
     //  fHashModulus
     //      The modulus used for this hash table, to hash the keys. This is
     //      also the number of elements in the bucket list.
-	//
-	//  fHash
-	//      The hasher for the key1 data type.
+    //
+    //  fCount
+    //      The number of elements currently in the map
+    //
+    //  fHash
+    //      The hasher for the key1 data type.
     // -----------------------------------------------------------------------
     MemoryManager*                      fMemoryManager;
     bool                                fAdoptedElems;
     RefHash2KeysTableBucketElem<TVal>** fBucketList;
     unsigned int                        fHashModulus;
-	HashBase*							fHash;
+    unsigned int                        fCount;
+    HashBase*							fHash;
 };