static ScanResponse doMetaScanResponse(
     final SortedMap<byte[], Pair<HRegionInfo, ServerName>> meta,
     final AtomicLong sequenceids,
     final ScanRequest request) {
   ScanResponse.Builder builder = ScanResponse.newBuilder();
   int max = request.getNumberOfRows();
   int count = 0;
   Map<byte[], Pair<HRegionInfo, ServerName>> tail =
       request.hasScan() ? meta.tailMap(request.getScan().getStartRow().toByteArray()) : meta;
   ClientProtos.Result.Builder resultBuilder = ClientProtos.Result.newBuilder();
   for (Map.Entry<byte[], Pair<HRegionInfo, ServerName>> e : tail.entrySet()) {
     // Can be 0 on open of a scanner -- i.e. rpc to setup scannerid only.
     if (max <= 0) break;
     if (++count > max) break;
     HRegionInfo hri = e.getValue().getFirst();
     ByteString row = HBaseZeroCopyByteString.wrap(hri.getRegionName());
     resultBuilder.clear();
     resultBuilder.addCell(getRegionInfo(row, hri));
     resultBuilder.addCell(getServer(row, e.getValue().getSecond()));
     resultBuilder.addCell(getStartCode(row));
     builder.addResults(resultBuilder.build());
     // Set more to false if we are on the last region in table.
     if (hri.getEndKey().length <= 0) builder.setMoreResults(false);
     else builder.setMoreResults(true);
   }
   // If no scannerid, set one.
   builder.setScannerId(
       request.hasScannerId() ? request.getScannerId() : sequenceids.incrementAndGet());
   return builder.build();
 }
 /**
  * Create Results from the cells using the cells meta data.
  *
  * @param cellScanner
  * @param response
  * @return results
  */
 public static Result[] getResults(CellScanner cellScanner, ScanResponse response)
     throws IOException {
   if (response == null) return null;
   // If cellscanner, then the number of Results to return is the count of elements in the
   // cellsPerResult list.  Otherwise, it is how many results are embedded inside the response.
   int noOfResults =
       cellScanner != null ? response.getCellsPerResultCount() : response.getResultsCount();
   Result[] results = new Result[noOfResults];
   for (int i = 0; i < noOfResults; i++) {
     if (cellScanner != null) {
       // Cells are out in cellblocks.  Group them up again as Results.  How many to read at a
       // time will be found in getCellsLength -- length here is how many Cells in the i'th Result
       int noOfCells = response.getCellsPerResult(i);
       boolean isPartial =
           response.getPartialFlagPerResultCount() > i
               ? response.getPartialFlagPerResult(i)
               : false;
       List<Cell> cells = new ArrayList<Cell>(noOfCells);
       for (int j = 0; j < noOfCells; j++) {
         try {
           if (cellScanner.advance() == false) {
             // We are not able to retrieve the exact number of cells which ResultCellMeta says us.
             // We have to scan for the same results again. Throwing DNRIOE as a client retry on
             // the
             // same scanner will result in OutOfOrderScannerNextException
             String msg =
                 "Results sent from server="
                     + noOfResults
                     + ". But only got "
                     + i
                     + " results completely at client. Resetting the scanner to scan again.";
             LOG.error(msg);
             throw new DoNotRetryIOException(msg);
           }
         } catch (IOException ioe) {
           // We are getting IOE while retrieving the cells for Results.
           // We have to scan for the same results again. Throwing DNRIOE as a client retry on the
           // same scanner will result in OutOfOrderScannerNextException
           LOG.error(
               "Exception while reading cells from result."
                   + "Resetting the scanner to scan again.",
               ioe);
           throw new DoNotRetryIOException("Resetting the scanner.", ioe);
         }
         cells.add(cellScanner.current());
       }
       results[i] = Result.create(cells, null, response.getStale(), isPartial);
     } else {
       // Result is pure pb.
       results[i] = ProtobufUtil.toResult(response.getResults(i));
     }
   }
   return results;
 }