Program: 144820
Project: 144820
Buggy source:
public void run(){
  Vector<Integer> toRemove=new Vector<Integer>();
  while (true) {
    try {
      toRemove.removeAllElements();
      for (int i=0; i < caches.size(); ++i) {
        CacheTable cache=(CacheTable)caches.elementAt(i).get();
        if (cache == null) {
          toRemove.addElement(DataUtil.integer(i));
        }
 else {
          Hashtable<Integer,WeakReference> table=cache.currentTable;
          int start=table.size();
          if (start > cache.largestSize) {
            cache.largestSize=start;
          }
          for (Enumeration en=table.keys(); en.hasMoreElements(); ) {
            Object key=en.nextElement();
            if (((WeakReference)table.get(key)).get() == null) {
              table.remove(key);
            }
          }
synchronized (cache) {
            if (cache.largestSize > 50 && cache.largestSize > (cache.currentTable.size() >> 2)) {
              Hashtable newTable=new Hashtable(cache.currentTable.size());
              for (Enumeration en=table.keys(); en.hasMoreElements(); ) {
                Object key=en.nextElement();
                newTable.put(key,cache.currentTable.get(key));
              }
              cache.currentTable=newTable;
              cache.largestSize=cache.currentTable.size();
            }
          }
        }
      }
      for (int id=toRemove.size() - 1; id >= 0; --id) {
        caches.removeElementAt(toRemove.elementAt(id));
      }
      try {
        Thread.sleep(3000);
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
 catch (    Exception e) {
      e.printStackTrace();
    }
  }
}

Fixed version (ground truth):
public void run(){
  Vector<Integer> toRemove=new Vector<Integer>();
  while (true) {
    try {
      toRemove.removeAllElements();
      for (int i=0; i < caches.size(); ++i) {
        CacheTable cache=(CacheTable)caches.elementAt(i).get();
        if (cache == null) {
          toRemove.addElement(DataUtil.integer(i));
        }
 else {
          Hashtable<Integer,WeakReference> table=cache.currentTable;
          int start=table.size();
          if (start > cache.totalAdditions) {
            cache.totalAdditions=start;
          }
          for (Enumeration en=table.keys(); en.hasMoreElements(); ) {
            Object key=en.nextElement();
            if (((WeakReference)table.get(key)).get() == null) {
synchronized (cache) {
                table.remove(key);
              }
            }
          }
synchronized (cache) {
            if (cache.totalAdditions > 50 && cache.totalAdditions - cache.currentTable.size() > (cache.currentTable.size() >> 2)) {
              Hashtable newTable=new Hashtable(cache.currentTable.size());
              int oldMax=cache.totalAdditions;
              for (Enumeration en=table.keys(); en.hasMoreElements(); ) {
                Object key=en.nextElement();
                newTable.put(key,cache.currentTable.get(key));
              }
              cache.currentTable=newTable;
              cache.totalAdditions=cache.currentTable.size();
            }
          }
        }
      }
      for (int id=toRemove.size() - 1; id >= 0; --id) {
        caches.removeElementAt(toRemove.elementAt(id));
      }
      try {
        Thread.sleep(3000);
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
 catch (    Exception e) {
      e.printStackTrace();
    }
  }
}