diff --git a/newbrt/Makefile b/newbrt/Makefile
index 510cb0f6f1d..3ec990f82de 100644
--- a/newbrt/Makefile
+++ b/newbrt/Makefile
@@ -26,23 +26,28 @@ endif
 default: bins
 # Put these one-per-line so that if we insert a new one the svn diff can understand it better.
 # Also keep them sorted.
-BINS =  \
-        benchmark-test \
+REGRESSION_TESTS = \
+        ybt-test \
+        pma-test \
         brt-serialize-test \
         brt-test \
         cachetable-test \
+        cachetable-test2 \
         hashtest \
-        pma-test \
+# This line intentially kept commented so I can have a \ on the end of the previous line
+
+BINS =  $(REGRESSION_TESTS) \
+        benchmark-test \
         randbrt \
         randdb4 \
-        ybt-test \
-# This line intentially kept blank so I can have a \ on the end of the previous line
+# This line intentially kept commented so I can have a \ on the end of the previous line
 
 bins: $(BINS)
 check: bins
 	$(DTOOL) ./ybt-test
 	$(DTOOL) ./pma-test
 	$(DTOOL) ./cachetable-test
+	$(DTOOL) ./cachetable-test2
 	$(DTOOL) ./brt-serialize-test
 	$(DTOOL) ./brt-test
 	$(DTOOL) ./hashtest
@@ -85,6 +90,9 @@ brt-serialize-test: brt-serialize-test.o brt-serialize.o memory.o hashtable.o pm
 cachetable-test.o: cachetable.h memory.h
 cachetable-test: cachetable.o memory.o cachetable-test.o
 
+cachetable-test2.o: cachetable.h memory.h
+cachetable-test2: cachetable.o memory.o cachetable-test2.o
+
 benchmark-test: benchmark-test.o ybt.o memory.o brt.o pma.o cachetable.o key.o hashtable.o brt-serialize.o primes.o
 benchmark-test.o: brt.h ../include/db.h
 
diff --git a/newbrt/brt.c b/newbrt/brt.c
index 4a34436de19..96ba7097450 100644
--- a/newbrt/brt.c
+++ b/newbrt/brt.c
@@ -1314,7 +1314,6 @@ int brt_insert (BRT brt, DBT *key, DBT *val, DB* db) {
 }
 
 int brt_lookup_node (BRT brt, diskoff off, DBT *k, DBT *v, DB *db) {
-    int result;
     void *node_v;
     int r = cachetable_get_and_pin(brt->cf, off, &node_v,
 				   brtnode_flush_callback, brtnode_fetch_callback, (void*)(long)brt->h->nodesize);
@@ -1325,7 +1324,7 @@ int brt_lookup_node (BRT brt, diskoff off, DBT *k, DBT *v, DB *db) {
     int childnum;
 
     if (node->height==0) {
-	result = pma_lookup(node->u.l.buffer, k, v, db);
+	int result = pma_lookup(node->u.l.buffer, k, v, db);
 	//printf("%s:%d looked up something, got answerlen=%d\n", __FILE__, __LINE__, answerlen);
 	r = cachetable_unpin(brt->cf, off, 0);
 	assert(r == 0);
@@ -1338,6 +1337,7 @@ int brt_lookup_node (BRT brt, diskoff off, DBT *k, DBT *v, DB *db) {
 	ITEMLEN hanswerlen;
         int type;
 	if (toku_hash_find (node->u.n.htables[childnum], k->data, k->size, &hanswer, &hanswerlen, &type)==0) {
+	    int result;
 	    if (type == BRT_INSERT) {
                 //printf("Found %d bytes\n", *vallen);
                 ybt_set_value(v, hanswer, hanswerlen, &brt->sval);
@@ -1345,18 +1345,22 @@ int brt_lookup_node (BRT brt, diskoff off, DBT *k, DBT *v, DB *db) {
                  result = 0;
             } else if (type == BRT_DELETE) {
                 result = DB_NOTFOUND;
-            } else
+            } else {
                 assert(0);
+		result = -1; // Some versions of gcc complain
+	    }
             r = cachetable_unpin(brt->cf, off, 0);
             assert(r == 0);
             return result;
 	}
     }
     
-    result = brt_lookup_node(brt, node->u.n.children[childnum], k, v, db);
-    r = cachetable_unpin(brt->cf, off, 0);
-    assert(r == 0);
-    return result;
+    {
+	int result = brt_lookup_node(brt, node->u.n.children[childnum], k, v, db);
+	r = cachetable_unpin(brt->cf, off, 0);
+	assert(r == 0);
+	return result;
+    }
 }
 
 
diff --git a/newbrt/cachetable-test.c b/newbrt/cachetable-test.c
index 812a489c35c..5972aa39c84 100644
--- a/newbrt/cachetable-test.c
+++ b/newbrt/cachetable-test.c
@@ -2,9 +2,9 @@
 #include "cachetable.h"
 
 #include <assert.h>
-#include <string.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 struct item {
diff --git a/newbrt/cachetable-test2.c b/newbrt/cachetable-test2.c
new file mode 100644
index 00000000000..4fb63f1c9e7
--- /dev/null
+++ b/newbrt/cachetable-test2.c
@@ -0,0 +1,161 @@
+#include "memory.h"
+#include "cachetable.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+CACHETABLE ct;
+
+enum { N_PRESENT_LIMIT = 4, TRIALS=200, N_FILES=2 };
+int n_present=0;
+struct present_items {
+    CACHEKEY key;
+    CACHEFILE cf;
+} present_items[N_PRESENT_LIMIT];
+
+static void print_ints(void) __attribute__((__unused__));
+static void print_ints(void) {
+    int i;
+    for (i=0; i<n_present; i++) {
+	if (i==0) printf("{"); else printf(",");
+	printf("{%lld,%p}", present_items[i].key, present_items[i].cf);
+    }
+    printf("}\n");
+}
+
+static void item_becomes_present(CACHEFILE cf, CACHEKEY key) {
+    assert(n_present<N_PRESENT_LIMIT);
+    present_items[n_present].cf     = cf;
+    present_items[n_present].key    = key;
+    n_present++;
+}
+
+static void item_becomes_not_present(CACHEFILE cf, CACHEKEY key) {
+    int i;
+    //printf("Removing {%4lld %16p}: Initially: ", key, cf); print_ints();
+    assert(n_present<=N_PRESENT_LIMIT);
+    for (i=0; i<n_present; i++) {
+	if (present_items[i].cf==cf && present_items[i].key==key) {
+	    present_items[i]=present_items[n_present-1];
+	    n_present--;
+	    //printf("                                    Finally: "); print_ints();
+	    return;
+	}
+    }
+    printf("Whoops, %p,%lld was already not present\n", cf ,key);
+    abort();
+}
+
+static void file_is_not_present(CACHEFILE cf) {
+    int i;
+    for (i=0; i<n_present; i++) {
+	assert(present_items[i].cf!=cf);
+    }
+}
+
+
+static void flush_forchain (CACHEFILE f __attribute__((__unused__)), CACHEKEY key, void *value, int write_me __attribute__((__unused__)), int keep_me __attribute__((__unused__))) {
+    int *v = value;
+    //cachetable_print_state(ct);
+    //printf("Flush %lld %d\n", key, (int)value);
+    assert((int)v==(int)key);
+    item_becomes_not_present(f, key);
+    //print_ints();
+}
+
+static int fetch_forchain (CACHEFILE f __attribute__((__unused__)), CACHEKEY key, void**value, void*extraargs) {
+    assert((int)extraargs==(int)key);
+    *value = (void*)(int)key;
+    return 0;
+}
+
+void verify_cachetable_against_present (void) {
+    int i;
+    for (i=0; i<n_present; i++) {
+	void *v;
+	int r;
+	assert(cachetable_maybe_get_and_pin(present_items[i].cf,
+					    present_items[i].key,
+					    &v)==0);
+	r = cachetable_unpin(present_items[i].cf, present_items[i].key, 0);
+    }
+}
+
+
+void test_chaining (void) {
+    /* Make sure that the hash chain and the LRU list don't get confused. */
+    CACHEFILE f[N_FILES];
+    enum { FILENAME_LEN=100 };
+    char fname[N_FILES][FILENAME_LEN];
+    int r;
+    int i, trial;
+    r = create_cachetable(&ct, N_PRESENT_LIMIT);                               assert(r==0);
+    for (i=0; i<N_FILES; i++) {
+	int r = snprintf(fname[i], FILENAME_LEN, "cachetabletest2.%d.dat", i);
+	assert(r>0 && r<FILENAME_LEN);
+	unlink(fname[i]);
+	r = cachetable_openf(&f[i], ct, fname[i], O_RDWR|O_CREAT, 0777);   assert(r==0);
+	}
+    for (i=0; i<N_PRESENT_LIMIT; i++) {
+	int fnum = i%N_FILES;
+	//printf("%s:%d Add %d\n", __FILE__, __LINE__, i);
+	r = cachetable_put(f[fnum], i, (void*)i, flush_forchain, fetch_forchain, (void*)i); assert(r==0);
+	item_becomes_present(f[fnum], i);
+	r = cachetable_unpin(f[fnum], i, 0);                                                assert(r==0);
+	//print_ints();
+    }
+    for (trial=0; trial<TRIALS; trial++) {
+	if (n_present>0) {
+	    // First touch some random ones
+	    int whichone = random()%n_present;
+	    void *value;
+	    //printf("Touching %d (%lld, %p)\n", whichone, present_items[whichone].key, present_items[whichone].cf);
+	    r = cachetable_get_and_pin(present_items[whichone].cf,
+				       present_items[whichone].key,
+				       &value,
+				       flush_forchain,
+				       fetch_forchain,
+				       (void*)(int)present_items[whichone].key
+				       );
+	    assert(r==0);
+	    r = cachetable_unpin(present_items[whichone].cf,
+				 present_items[whichone].key,
+				 0);
+	    assert(r==0);
+	}
+
+	i += 1+ random()%100;
+	int fnum = i%N_FILES;
+	// i is always incrementing, so we need not worry about inserting a duplicate
+	//printf("%s:%d Add {%d,%p}\n", __FILE__, __LINE__, i, f[fnum]);
+	r = cachetable_put(f[fnum], i, (void*)i, flush_forchain, fetch_forchain, (void*)i); assert(r==0);
+	item_becomes_present(f[fnum], i);
+	//print_ints();
+	//cachetable_print_state(ct);
+	r = cachetable_unpin(f[fnum], i, 0);                                                assert(r==0);
+	verify_cachetable_against_present();
+
+	if (random()%10==0) {
+	    i = random()%N_FILES;
+	    //printf("Close %d (%p), now n_present=%d\n", i, f[i], n_present);
+	    //print_ints();
+	    CACHEFILE oldcf=f[i];
+	    r = cachefile_close(&f[i]);                            assert(r==0);
+	    file_is_not_present(oldcf);
+	    r = cachetable_openf(&f[i], ct, fname[i], O_RDWR, 0777); assert(r==0);
+	}
+    }
+    for (i=0; i<N_FILES; i++) {
+	r = cachefile_close(&f[i]); assert(r==0);
+    }
+    r = cachetable_close(&ct); assert(r==0);
+}
+
+int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
+    test_chaining();
+    malloc_cleanup();
+    printf("ok\n");
+    return 0;
+}
diff --git a/newbrt/cachetable.c b/newbrt/cachetable.c
index 61ebcc427ad..b6542c59dea 100644
--- a/newbrt/cachetable.c
+++ b/newbrt/cachetable.c
@@ -53,6 +53,18 @@ struct cachefile {
     struct fileid fileid;
 };
 
+void cachetable_print_state (CACHETABLE ct) {
+    int i;
+    for (i=0; i<ct->table_size; i++) {
+	PAIR p;
+	printf("t[%d]=", i);
+	for (p=ct->table[i]; p; p=p->hash_chain) {
+	    printf(" {%lld, %p}", p->key, p->cachefile);
+	}
+	printf("\n");
+    }
+}
+
 int create_cachetable (CACHETABLE *result, int n_entries) {
     TAGMALLOC(CACHETABLE, t);
     int i;
@@ -112,7 +124,7 @@ CACHEFILE remove_cf_from_list (CACHEFILE cf, CACHEFILE list) {
     }
 }
 
-int cachefile_flush (CACHEFILE cf);
+static int cachefile_flush_and_remove (CACHEFILE cf);
 
 int cachefile_close (CACHEFILE *cfp) {
     CACHEFILE cf = *cfp;
@@ -120,7 +132,7 @@ int cachefile_close (CACHEFILE *cfp) {
     cf->refcount--;
     if (cf->refcount==0) {
 	int r;
-	if ((r = cachefile_flush(cf))) return r;
+	if ((r = cachefile_flush_and_remove(cf))) return r;
 	r = close(cf->fd);
 	cf->cachetable->cachefiles = remove_cf_from_list(cf, cf->cachetable->cachefiles);
 	toku_free(cf);
@@ -337,7 +349,7 @@ int cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, void**value
 	    *value = p->value;
 	    p->pinned++;
 	    lru_touch(t,p);
-	    printf("%s:%d cachetable_maybe_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value);
+	    //printf("%s:%d cachetable_maybe_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value);
 	    return 0;
 	}
     }
@@ -374,7 +386,28 @@ int cachetable_flush (CACHETABLE t) {
     return 0;
 }
 
-int cachefile_flush (CACHEFILE cf) {
+static void assert_cachefile_is_flushed_and_removed (CACHEFILE cf) {
+    CACHETABLE t = cf->cachetable;
+    int i;
+    // Check it two ways
+    // First way: Look through all the hash chains
+    for (i=0; i<t->table_size; i++) {
+	PAIR p;
+	for (p=t->table[i]; p; p=p->hash_chain) {
+	    assert(p->cachefile!=cf);
+	}
+    }
+    // Second way: Look through the LRU list.
+    {
+	PAIR p;
+	for (p=t->head; p; p=p->next) {
+	    assert(p->cachefile!=cf);
+	}
+    }
+}
+
+
+static int cachefile_flush_and_remove (CACHEFILE cf) {
     int i;
     CACHETABLE t = cf->cachetable;
     for (i=0; i<t->table_size; i++) {
@@ -390,10 +423,10 @@ int cachefile_flush (CACHEFILE cf) {
 	    }
 	}
     }
+    assert_cachefile_is_flushed_and_removed(cf);
     return 0;
 }
 
-
 /* Require that it all be flushed. */
 int cachetable_close (CACHETABLE *tp) {
     CACHETABLE t=*tp;
diff --git a/newbrt/cachetable.h b/newbrt/cachetable.h
index c6484e277f1..47a53d49986 100644
--- a/newbrt/cachetable.h
+++ b/newbrt/cachetable.h
@@ -18,6 +18,7 @@ typedef struct cachefile *CACHEFILE;
  * Note: The cachetable should use a common pool of memory, flushing things across cachetables.
  *  (The first implementation doesn't)
  * If you pin something twice, you must unpin it twice.
+ * n_entries says how many items can fit into the cache table at a time.
  */
 int create_cachetable (CACHETABLE */*result*/, int /*n_entries*/);
 
@@ -56,4 +57,7 @@ int cachefile_close (CACHEFILE*);
 
 int cachefile_fd (CACHEFILE);
 
+// Useful for debugging 
+void cachetable_print_state (CACHETABLE ct);
+
 #endif