docs: private List<Object> readAndProcess() {
  
          List<Object> chunkToWrite = new ArrayList<Object>();
          Object itemRead = null;
          Object itemProcessed = null;
  
          while (true) {
              currentItemStatus = new SingleItemStatus();
              itemRead = readItem();
  
              if (currentChunkStatus.wasMarkedForRollbackWithRetry()) {
                  break;
              }
  
              if (!currentItemStatus.isSkipped() && !currentChunkStatus.hasReadNull()) {
                  itemProcessed = processItem(itemRead);
  
                  if (currentChunkStatus.wasMarkedForRollbackWithRetry()) {
                      break;
                  }
  
                  if (!currentItemStatus.isSkipped() && !currentItemStatus.isFiltered()) {
                      chunkToWrite.add(itemProcessed);
                  }
              }
  
              // Break out of the loop to deliver one-at-a-time processing after rollback.
              // No point calling isReadyToCheckpoint(), we know we're done.  Let's not
              // complicate the checkpoint algorithm to hold this logic, just break right here.
              if (currentChunkStatus.isRetryingAfterRollback()) {
                  break;
              }
  
              // This will force the current item to finish processing on a stop request
              if (runtimeStepExecution.getBatchStatus().equals(BatchStatus.STOPPING)) {
                  currentChunkStatus.markStopping();
                  break;
              }
  
              // Try the in memory map first, then the DB if not found
              BatchStatus status = getBatchKernelService().getBatchStatus(runtimeWorkUnitExecution.getTopLevelExecutionId());
  
              if (null == status) {
                  logger.finer("Local BatchStatus not found, querying DB");
                  JobExecutionEntity jobExecution = getPersistenceManagerService().getJobExecution(runtimeWorkUnitExecution.getTopLevelExecutionId());
                  status = jobExecution.getBatchStatus();
              }
  
              // This will force the current item to finish processing if top level job is stopping or stopped
              if (status.equals(BatchStatus.STOPPING) || status.equals(BatchStatus.STOPPED)) {
                  currentChunkStatus.markStopping();
                  // The call below is important since the STOP may have been done against a top-level job executing remotely
                  // (at the time of this writing that implies the current object controls a partition level chunk).
                  // The above call breaks us out of the chunk loop.  The call below sets the step-level status to STOPPING (ultimately STOPPED)
                  // so it doesn't wrongly leave us with a COMPLETED partition.
                  markStepStopping();
                  break;
              }
  
              // The spec, in Sec. 11.10, Chunk with Custom Checkpoint Processing, clearly
              // outlines that this gets called even when we've already read a null (which
              // arguably is pointless).   But we'll follow the spec.
              if (checkpointManager.isReadyToCheckpoint()) {
                  break;
              }
  
              // last record in readerProxy reached
              if (currentChunkStatus.hasReadNull()) {
                  break;
              }
          }
          return chunkToWrite;
      }