@Override
  public synchronized @Nullable ChangeSetHolder readPrevious(int id, IntSet recursionGuard) {
    if (isCompletelyBroken) return null;

    int prevId = 0;
    try {
      prevId = id == -1 ? myStorage.getLastRecord() : doReadPrevSafely(id, recursionGuard);
      if (prevId == 0) return null;

      return doReadBlock(prevId);
    }
    catch (Throwable e) {
      String message = null;
      if (prevId != 0) {
        try {
          Pair<Long, Integer> prevOS = myStorage.getOffsetAndSize(prevId);
          long prevRecordTimestamp = myStorage.getTimestamp(prevId);
          int lastRecord = myStorage.getLastRecord();
          Pair<Long, Integer> lastOS = myStorage.getOffsetAndSize(lastRecord);
          long lastRecordTimestamp = myStorage.getTimestamp(lastRecord);

          message = "invalid record is: " + prevId + " offset: " + prevOS.first + " size: " + prevOS.second
                    + " (created " + DateFormat.getDateTimeInstance().format(prevRecordTimestamp) + ") "
                    + "last record is: " + lastRecord + " offset: " + lastOS.first + " size: " + lastOS.second
                    + " (created " + DateFormat.getDateTimeInstance().format(lastRecordTimestamp) + ")";
        }
        catch (Exception e1) {
          message = "cannot retrieve more debug info: " + e1.getMessage();
        }
      }

      handleError(e, message);
      return null;
    }
  }
@Override
  public synchronized @Nullable ChangeSetHolder readPrevious(int id, IntSet recursionGuard)