@Override
 public void onSuccess(Object keyNum, ObjectContainer container, ClientContext context) {
   if (logMINOR) Logger.minor(this, "Succeeded (" + this + "): " + token);
   if (persistent) container.activate(parent, 1);
   if (parent.isCancelled()) {
     fail(new InsertException(InsertException.CANCELLED), container, context);
     return;
   }
   synchronized (this) {
     if (extraInserts > 0) {
       if (++completedInserts <= extraInserts) {
         if (logMINOR)
           Logger.minor(
               this,
               "Completed inserts "
                   + completedInserts
                   + " of extra inserts "
                   + extraInserts
                   + " on "
                   + this);
         if (persistent) container.store(this);
         return; // Let it repeat until we've done enough inserts. It hasn't been unregistered yet.
       }
     }
     if (finished) {
       // Normal with persistence.
       Logger.normal(this, "Block already completed: " + this);
       return;
     }
     finished = true;
   }
   if (persistent) {
     container.store(this);
     container.activate(sourceData, 1);
   }
   if (freeData) {
     sourceData.free();
     if (persistent) sourceData.removeFrom(container);
     sourceData = null;
     if (persistent) container.store(this);
   }
   parent.completedBlock(false, container, context);
   unregister(container, context, getPriorityClass(container));
   if (persistent) container.activate(cb, 1);
   if (logMINOR) Logger.minor(this, "Calling onSuccess for " + cb);
   cb.onSuccess(this, container, context);
   if (persistent) container.deactivate(cb, 1);
 }
  @Override
  public void onFailure(
      LowLevelPutException e, Object keyNum, ObjectContainer container, ClientContext context) {
    synchronized (this) {
      if (finished) return;
    }
    if (persistent) container.activate(errors, 1);
    if (parent.isCancelled()) {
      fail(new InsertException(InsertException.CANCELLED), container, context);
      return;
    }
    if (logMINOR) Logger.minor(this, "onFailure() on " + e + " for " + this);

    switch (e.code) {
      case LowLevelPutException.COLLISION:
        fail(new InsertException(InsertException.COLLISION), container, context);
        return;
      case LowLevelPutException.INTERNAL_ERROR:
        fail(new InsertException(InsertException.INTERNAL_ERROR), container, context);
        return;
      case LowLevelPutException.REJECTED_OVERLOAD:
        errors.inc(InsertException.REJECTED_OVERLOAD);
        break;
      case LowLevelPutException.ROUTE_NOT_FOUND:
        errors.inc(InsertException.ROUTE_NOT_FOUND);
        break;
      case LowLevelPutException.ROUTE_REALLY_NOT_FOUND:
        errors.inc(InsertException.ROUTE_REALLY_NOT_FOUND);
        break;
      default:
        Logger.error(this, "Unknown LowLevelPutException code: " + e.code);
        errors.inc(InsertException.INTERNAL_ERROR);
    }
    if (persistent) container.activate(ctx, 1);
    if (e.code == LowLevelPutException.ROUTE_NOT_FOUND
        || e.code == LowLevelPutException.ROUTE_REALLY_NOT_FOUND) {
      consecutiveRNFs++;
      if (logMINOR)
        Logger.minor(
            this,
            "Consecutive RNFs: " + consecutiveRNFs + " / " + ctx.consecutiveRNFsCountAsSuccess);
      if (consecutiveRNFs == ctx.consecutiveRNFsCountAsSuccess) {
        if (logMINOR)
          Logger.minor(this, "Consecutive RNFs: " + consecutiveRNFs + " - counting as success");
        onSuccess(keyNum, container, context);
        return;
      }
    } else consecutiveRNFs = 0;
    if (logMINOR) Logger.minor(this, "Failed: " + e);
    retries++;
    if ((retries > ctx.maxInsertRetries) && (ctx.maxInsertRetries != -1)) {
      fail(InsertException.construct(persistent ? errors.clone() : errors), container, context);
      if (persistent) container.deactivate(ctx, 1);
      return;
    }
    if (persistent) {
      container.store(this);
      container.deactivate(ctx, 1);
    }
    getScheduler(context).registerInsert(this, persistent, false, container);
  }