static DbRetVal AppRecoverWrapCLS(DB_ENV* evp, ref DBT logrec, DB_LSN* lsnp, DB_RECOPS op) {
      Env env = null;
      try {
        env = (Env)((GCHandle)evp->api_internal).Target;

        // construct DbEntry for log_rec
        int size = unchecked((int)logrec.size);
        // we are not using a shared buffer - the call-back might take
        // a long time and we do not want to lock the buffer that long
        byte[] buffer = new byte[size];
        Marshal.Copy((IntPtr)logrec.data, buffer, 0, size);
        DbEntry logEntry = DbEntry.InOut(buffer, 0, size);
        logEntry.dbt.flags = logrec.flags;
        logEntry.dbt.dlen = logrec.dlen;
        logEntry.dbt.doff = logrec.doff;
        // construct Lsn
        Lsn? lsn;
        if (lsnp == null) lsn = null; else lsn = new Lsn(*lsnp);
        // call CLS compliant delegate - we assume it is not null
        CallbackStatus cs =  env.appRecoverCLS(env, ref logEntry, lsn, (RecoveryOps)op);
        return cs == CallbackStatus.Success ? DbRetVal.SUCCESS : DbRetVal.APP_RECOVER_FAILED;
      }
      catch (Exception ex) {
        Trace.WriteLine(ex.Message, "TxnRecover");
        return DbRetVal.APP_RECOVER_FAILED;
      }
    }
 static DbRetVal AppRecoverWrapFast(DB_ENV* evp, ref DBT logrec, DB_LSN* lsnp, DB_RECOPS op) {
   Env env = null;
   try {
     env = (Env)((GCHandle)evp->api_internal).Target;
     CallbackStatus cs = env.appRecoverFast(env, ref logrec, lsnp, (RecoveryOps)op);
     return cs == CallbackStatus.Success ? DbRetVal.SUCCESS : DbRetVal.APP_RECOVER_FAILED;
   }
   catch (Exception ex) {
     Trace.WriteLine(ex.Message, "TxnRecover");
     return DbRetVal.APP_RECOVER_FAILED;
   }
 }