@Override
 public void cancelAllTasks() {
   int[] keys = activeTasks.keys();
   for (int key : keys) {
     ParallelTaskInfo info = activeTasks.get(key);
     if (info != null) {
       info.stop();
       activeTasks.remove(key, info);
     }
   }
 }
 @Override
 public void cancelTasks(Object plugin) {
   int[] keys = activeTasks.keys();
   for (int key : keys) {
     ParallelTaskInfo info = activeTasks.get(key);
     if (info != null) {
       if (info.getTask().getOwner() == plugin) {
         info.stop();
         activeTasks.remove(key, info);
       }
     }
   }
 }
 @Override
 public void cancelTask(int taskId) {
   ParallelTaskInfo info = activeTasks.remove(taskId);
   if (info != null) {
     info.stop();
   }
 }
 protected Task schedule(SpoutTask task) {
   ParallelTaskInfo info = new ParallelTaskInfo(task);
   if (task.getPeriod() > 0) {
     activeTasks.put(task.getTaskId(), info);
   }
   newTasks.add(task);
   return task;
 }
 public void heartbeat(long delta) {
   if (engine != null) {
     TickStage.checkStage(TickStage.TICKSTART);
   } else {
     TickStage.checkStage(TickStage.STAGE1);
   }
   SpoutRegion region;
   SpoutTask task;
   while ((task = newTasks.poll()) != null) {
     int taskId = task.getTaskId();
     ParallelTaskInfo info = activeTasks.get(taskId);
     if (info == null) {
       info = new ParallelTaskInfo(task);
       ParallelTaskInfo previous = activeTasks.putIfAbsent(taskId, info);
       if (previous != null) {
         info = previous;
       }
       task.setParallelInfo(info);
     }
     Collection<? extends World> worlds = (this.world == null) ? engine.getWorlds() : world;
     for (World w : worlds) {
       SpoutWorld sw = (SpoutWorld) w;
       for (Region r : sw.getRegions()) {
         info.add((SpoutRegion) r);
       }
     }
   }
   while ((region = newRegions.poll()) != null) {
     for (ParallelTaskInfo info : activeTasks.values(ParallelTaskInfo.EMPTY_ARRAY)) {
       info.add(region);
     }
   }
   while ((region = deadRegions.poll()) != null) {
     while (newRegions.remove(region)) {;
     }
     for (ParallelTaskInfo info : activeTasks.values(ParallelTaskInfo.EMPTY_ARRAY)) {
       while (info.remove(region)) {;
       }
     }
   }
 }