I've implemented Dispose...everywhere that supports it.  I am removing all event handlers.  I'm not calling native code.  
I even iterate through every dictionary and set the values to null and call .Clear() on all the items.
Question:
How can I figure out where my code is leaking?
I first discovered the leak by running it in test overnight. It uses a fixed amount of memory so it should grow and then become somewhat static. I then made the foreground thread display memory like this:
            if (key.KeyChar == 'g')
             {
                long pre = GC.GetTotalMemory(false);
                long post = GC.GetTotalMemory(true);
                Console.WriteLine("{2} Pre:{0}  \tPost:{1}", pre, post, System.DateTime.Now);
                 GC.Collect();
              }
I ran this several times (over several hours, pressing "g" once in a while) and saw an ever-increasing number.
 
     
     
     
     
    