@Transactional
  public int process(InputStream inputStream, ModelClass modelClass, RecordHandler recordHandler, AuditFields auditFields)
      throws UploadException {

    CsvBeanReader csvBeanReader = null;
    String[] headers = null;

    try {
      csvBeanReader = new CsvBeanReader(modelClass, inputStream);
      headers = csvBeanReader.getHeaders();
      csvBeanReader.validateHeaders();
      Importable importedModel;

      while ((importedModel = csvBeanReader.readWithCellProcessors()) != null) {
        recordHandler.execute(importedModel, csvBeanReader.getRowNumber(), auditFields);
      }
      recordHandler.postProcess(auditFields);
    } catch (SuperCsvConstraintViolationException constraintException) {
      if (constraintException.getMessage().contains("^\\d{1,2}/\\d{1,2}/\\d{4}$")) {
        createHeaderException("incorrect.date.format", headers, constraintException);
      }

      createHeaderException("missing.mandatory", headers, constraintException);
    } catch (SuperCsvCellProcessorException processorException) {
      createHeaderException("incorrect.data.type", headers, processorException);
    } catch (SuperCsvException superCsvException) {
      if (csvBeanReader.length() > headers.length) {
        throw new UploadException("incorrect.file.format");
      }

      createDataException("column.do.not.match", headers, superCsvException);
    } catch (IOException e) {
      throw new UploadException(e.getStackTrace().toString());
    }

    return csvBeanReader.getRowNumber() - 1;
  }