@Override
 public void maybeRemove(RemoveRandom r, ClientContext context) {
   int count = 0;
   int finalSize;
   synchronized (root) {
     while (true) {
       int found = -1;
       for (int i = 0; i < grabArrays.length; i++) {
         if (grabArrays[i] == r) {
           found = i;
           break;
         }
       }
       if (found != -1) {
         count++;
         if (count > 1)
           Logger.error(this, "Found " + r + " many times in " + this, new Exception("error"));
         removeElement(found);
       } else {
         break;
       }
     }
     finalSize = grabArrays.length;
   }
   if (count == 0) {
     // This is not unusual, it was e.g. removed because of being empty.
     // And it has already been removeFrom()'ed.
     if (logMINOR)
       Logger.minor(this, "Not in parent: " + r + " for " + this, new Exception("error"));
   }
   if (finalSize == 0 && parent != null) {
     parent.maybeRemove(this, context);
   }
 }
 @Override
 public void clearWakeupTime(ClientContext context) {
   if (logMINOR) Logger.minor(this, "clearCooldownTime() on " + this);
   synchronized (root) {
     wakeupTime = 0;
     if (parent != null) parent.clearWakeupTime(context);
   }
 }
 @Override
 public boolean reduceWakeupTime(long wakeupTime, ClientContext context) {
   if (logMINOR)
     Logger.minor(
         this, "reduceCooldownTime(" + (wakeupTime - System.currentTimeMillis()) + ") on " + this);
   boolean reachedRoot = false;
   synchronized (root) {
     if (this.wakeupTime > wakeupTime) {
       this.wakeupTime = wakeupTime;
       if (parent != null) parent.reduceWakeupTime(wakeupTime, context);
       else reachedRoot = true; // Even if it reduces it we need to wake it up.
     } else return false;
   }
   if (reachedRoot) root.wakeUp(context);
   return true;
 }