protected boolean nextScanner(final boolean done) throws IOException {
    if (LOG.isTraceEnabled()) LOG.trace("nextScanner() -- ENTRY txID: " + ts.getTransactionId());
    if (this.interrupted) {
      if (LOG.isDebugEnabled())
        LOG.debug("nextScanner() resetting connection, txID: " + ts.getTransactionId());
      ttable.resetConnection();
      this.interrupted = false;
    }
    if (this.currentBeginKey != null) {
      if (LOG.isTraceEnabled())
        LOG.trace("nextScanner() currentBeginKey != null txID: " + ts.getTransactionId());
      if (doNotCloseOnLast) close();
      if ((this.currentEndKey == HConstants.EMPTY_END_ROW)
          || Bytes.equals(this.currentEndKey, HConstants.EMPTY_BYTE_ARRAY)
          || checkScanStopRow(this.currentEndKey)
          || done) {
        if (LOG.isTraceEnabled()) LOG.trace("endKey: " + Bytes.toString(this.currentEndKey));
        if (LOG.isTraceEnabled())
          LOG.trace("nextScanner() -- EXIT -- returning false txID: " + ts.getTransactionId());
        this.moreScanners = false;
        return false;
      } else this.currentBeginKey = TransactionManager.binaryIncrementPos(this.currentEndKey, 1);
    } else {
      // First call to nextScanner
      this.currentBeginKey = this.scan.getStartRow();
    }

    this.currentRegion = ttable.getRegionLocation(this.currentBeginKey).getRegionInfo();
    this.currentEndKey = this.currentRegion.getEndKey();

    if (LOG.isTraceEnabled()) LOG.trace("Region Info: " + currentRegion.getRegionNameAsString());
    if (this.currentEndKey != HConstants.EMPTY_END_ROW)
      this.currentEndKey = TransactionManager.binaryIncrementPos(currentRegion.getEndKey(), -1);

    this.closed = false;

    TrxRegionProtos.OpenScannerRequest.Builder requestBuilder = OpenScannerRequest.newBuilder();
    requestBuilder.setTransactionId(ts.getTransactionId());
    requestBuilder.setRegionName(ByteString.copyFromUtf8(currentRegion.getRegionNameAsString()));
    requestBuilder.setScan(ProtobufUtil.toScan(scan));
    TrxRegionProtos.OpenScannerRequest openRequest = requestBuilder.build();
    try {
      CoprocessorRpcChannel channel = ttable.coprocessorService(this.currentBeginKey);
      TrxRegionService.BlockingInterface trxService = TrxRegionService.newBlockingStub(channel);
      TrxRegionProtos.OpenScannerResponse response = trxService.openScanner(null, openRequest);
      String exception = response.getException();
      if (response.getHasException()) {
        String errMsg =
            "nextScanner encountered Exception txID: "
                + ts.getTransactionId()
                + " Exception: "
                + exception;
        LOG.error(errMsg);
        throw new IOException(errMsg);
      }
      this.scannerID = response.getScannerId();
    } catch (ServiceException se) {
      this.interrupted = true;
      String errMsg =
          "OpenScanner error encountered Service Exception, scannerID: "
              + this.scannerID
              + " "
              + se;
      LOG.error(errMsg);
      throw new IOException(errMsg);
    } catch (Throwable e) {
      String errMsg =
          "OpenScanner error on coprocessor call, scannerID: " + this.scannerID + " " + e;
      LOG.error(errMsg);
      throw new IOException(errMsg);
    }
    this.nextCallSeq = 0;
    if (LOG.isTraceEnabled())
      LOG.trace("nextScanner() -- EXIT -- returning true txID: " + ts.getTransactionId());
    return true;
  }