@Override
 public boolean evaluate(ThreadSnapshot snapshot) {
   for (ThreadSnapshotFilter f : filters) {
     if (f.evaluate(snapshot)) {
       return true;
     }
   }
   return false;
 }
 @Override
 public boolean evaluate(ThreadSnapshot snapshot) {
   int n = -1;
   while (true) {
     int m = matcher.matchNext(snapshot.stackTrace(), n + 1);
     if (m < 0) {
       break;
     }
     n = m;
   }
   if (n >= 0) {
     StackFrameList remained = snapshot.stackTrace();
     remained = remained.fragment(0, n);
     return tailFilter.evaluate(new ThreadSnapProxy(snapshot, remained));
   } else {
     return false;
   }
 }