class ThemisScanner extends AbstractClientScanner {

  public Result next() throws IOException {
    long beginTs = System.nanoTime();
    Result pResult = null;
    boolean lockClean = false;
    try {
      pResult = this.scanner.next();
      if (pResult == null) {
        return null;
      }

      // if we encounter conflict locks, we need to clean lock for this row and read again
      if (ThemisCpUtil.isLockResult(pResult)) {
        lockClean = true;
        Get rowGet = createGetFromScan(scan, pResult.getRow());
        pResult = transaction.tryToCleanLockAndGetAgain(tableName, rowGet, pResult.list());
        // empty result indicates the current row has been erased, we should get next row
        if (pResult.isEmpty()) {
          return next();
        } else {
          return pResult;
        }
      }
      return pResult;
    } finally {
      ThemisStatistics.updateLatency(ThemisStatistics.getStatistics().nextLatency, beginTs);
      ThemisStatistics.logSlowOperation("themisNext", beginTs, "row=" + pResult + ", lockClean=" + lockClean);
    }
  }

  public  ThemisScanner(final byte[] tableName, final Scan scan, final Transaction transaction);

}