protected Audit waitForAuditToComplete(Audit audit) {
   LOGGER.debug(
       "WAIT FOR AUDIT TO COMPLETE:"
           + audit
           + ","
           + (long) (audit.getDateOfCreation().getTime() / 1000));
   Long token = new Date().getTime();
   this.getAuditExecutionList().put(audit, token);
   // while the audit is not seen as completed or crashed
   while (!this.getAuditCompletedList().containsKey(token)
       && !this.getAuditCrashedList().containsKey(token)) {
     try {
       Thread.sleep(500);
     } catch (InterruptedException ex) {
       LOGGER.error("", ex);
     }
   }
   if ((audit = this.getAuditCompletedList().get(token)) != null) {
     this.getAuditCompletedList().remove(token);
     return audit;
   }
   if ((audit = this.getAuditCrashedList().get(token).getKey()) != null) {
     this.getAuditCrashedList().remove(token);
     return audit;
   }
   return null;
 }
 /**
  * @param auditTimeoutThread
  * @param act
  * @return
  */
 private Audit submitAuditAndLaunch(AuditTimeoutThread auditTimeoutThread, Act act) {
   synchronized (auditTimeoutThread) {
     Future submitedThread = threadPoolTaskExecutor.submit(auditTimeoutThread);
     while (submitedThread != null && !submitedThread.isDone()) {
       try {
         Thread.sleep(500);
       } catch (InterruptedException ex) {
         LOGGER.error("", ex);
       }
       if (auditTimeoutThread.isDurationExceedsDelay()) {
         LOGGER.debug(
             "Audit Duration ExceedsDelay. The audit result "
                 + "is now managed in an asynchronous way.");
         break;
       }
     }
     if (null != auditTimeoutThread.getException()) {
       LOGGER.error("new KrashAuditException()");
       throw new KrashAuditException(auditTimeoutThread.getException());
     }
     return auditTimeoutThread.getAudit();
   }
 }