public void executeQueue(int timeoutMillis) {
   if (memoryHog == null) memoryHog = new byte[64 * 1024]; // 64K should be enough for everyone
   memoryHog[0] = 42;
   long start = System.currentTimeMillis();
   long fin = (timeoutMillis <= 0 ? -1 : System.currentTimeMillis() + timeoutMillis);
   GoalState current;
   int loopNo = 0;
   while ((current = queue.poll()) != null) {
     //           System.out.println("RUNNING " + current);
     if (loopNo++ == 50) {
       loopNo = 0;
       long freeMemory = computeFreeMemory();
       if (freeMemory < 20 * 1024 * 1024) {
         Runtime.getRuntime().gc();
         freeMemory = computeFreeMemory();
         if (freeMemory < 40 * 1024 * 1024) {
           timeLimitReached();
           break;
         }
       }
     }
     try {
       current.run();
     } catch (RuntimeException e) {
       Bugs.bug(new GoalEvaluationFailed(e, current.goal));
       current.setPruned();
     } catch (AssertionError e) {
       Bugs.bug(new GoalEvaluationFailed(e, current.goal));
       current.setPruned();
     } catch (OutOfMemoryError e) {
       memoryHog = null;
       Runtime.getRuntime().gc();
       Bugs.bug(e);
       timeLimitReached();
       break;
     }
     if (fin > 0 && System.currentTimeMillis() > fin) {
       timeLimitReached();
       break;
     }
   }
   if (unfinishedGoals > 0) System.err.println("ACHTUNG UNFINISHED GOALS ATTACK!!!!!");
   else if (unfinishedGoals < 0) System.err.println("F**K F**K F**K");
   stats.queueRunDone(System.currentTimeMillis() - start);
   //        if (runTimes != null)
   //            runTimes.add(duration);
 }
 private void timeLimitReached() {
   System.out.println(" *** ANALYSIS TIMEOUT *** ");
   GoalState current;
   while ((current = queue.poll()) != null) prune(current);
 }