private boolean startQueueTask(long qid, long sid, SyncTask task) {
   QueueExecutionInfo syncerInfo = m_syncers.get(qid);
   syncerInfo.m_lastAttempt = ApiStack.getInterface(ITime.class).currentTimeMillis();
   try {
     m_syncerExternals.runSync(task);
     syncerInfo.m_currentTask = task; // Task started
   } catch (Exception e) {
     ApiAlgs.getLog(this).error(e.getMessage(), e);
     syncerInfo.m_lastError = ApiStack.getInterface(ITime.class).currentTimeMillis();
     queueBL()
         .taskCompleted(new QSyncTaskResult(qid, sid, task.m_errorStatus, e)); // set error status
     return false;
   }
   return true;
 }
  public synchronized void onTaskCompleted(QSyncTaskResult result) {
    QueueExecutionInfo syncerInfo = m_syncers.get(result.qid);
    if (null == syncerInfo) {
      throw new EQueueNotRegistered(result.qid);
    }
    if (null == syncerInfo.m_currentTask) {
      throw new ETaskWasNotStarted(result.qid);
    }
    if (syncerInfo.m_lastAttempt < Math.max(syncerInfo.m_lastError, syncerInfo.m_lastSynced))
      throw new ETaskWasNotStarted(result.qid);
    queueBL().taskCompleted(result);

    if (QSyncTaskStatus.SYNCED.equals(result.status)) {
      syncerInfo.m_lastSynced = ApiStack.getInterface(ITime.class).currentTimeMillis();
    }

    if (EnumSet.of(QSyncTaskStatus.ERROR, QSyncTaskStatus.INITIAL_SYNC_ERROR)
        .contains(result.status)) {
      syncerInfo.m_lastError = ApiStack.getInterface(ITime.class).currentTimeMillis();
      syncerInfo.m_errorCounter++;
    } else {
      syncerInfo.m_missedExecutions = 0;
      syncerInfo.m_errorCounter = 0;
    }

    syncerInfo.m_currentTask = null;

    ApiAlgs.getLog(this).trace("task completed. Status: " + result.status);

    Long excludeQid = null;
    if (!result.status.equals(QSyncTaskStatus.SYNCED)) excludeQid = result.qid;
    startTasks(excludeQid);
  }