docs: private void processFile(final Reference ref) throws DITAOTException {
          currentFile = ref.filename;
          assert currentFile.isAbsolute();
          logger.info("Processing " + currentFile);
          final String[] params = { currentFile.toString() };
  
          try {
              XMLReader xmlSource = getXmlReader(ref.format);
              for (final XMLFilter f: getProcessingPipe(currentFile)) {
                  f.setParent(xmlSource);
                  f.setEntityResolver(CatalogUtils.getCatalogResolver());
                  xmlSource = f;
              }
              xmlSource.setContentHandler(nullHandler);
  
              xmlSource.parse(currentFile.toString());
  
              if (listFilter.isValidInput()) {
                  processParseResult(currentFile);
                  categorizeCurrentFile(ref);
              } else if (!currentFile.equals(rootFile)) {
                  logger.warn(MessageUtils.getMessage("DOTJ021W", params).toString());
                  failureList.add(currentFile);
              }
          } catch (final RuntimeException e) {
              throw e;
          } catch (final SAXParseException sax) {
              final Exception inner = sax.getException();
              if (inner != null && inner instanceof DITAOTException) {
                  throw (DITAOTException) inner;
              }
              if (currentFile.equals(rootFile)) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ012F", params).toString() + ": " + sax.getMessage(), sax);
              } else if (processingMode == Mode.STRICT) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ013E", params).toString() + ": " + sax.getMessage(), sax);
              } else {
                  logger.error(MessageUtils.getMessage("DOTJ013E", params).toString() + ": " + sax.getMessage(), sax);
              }
              failureList.add(currentFile);
          } catch (final FileNotFoundException e) {
              if (!exists(currentFile)) {
                  if (currentFile.equals(rootFile)) {
                      throw new DITAOTException(MessageUtils.getMessage("DOTA069F", params).toString(), e);
                  } else if (processingMode == Mode.STRICT) {
                      throw new DITAOTException(MessageUtils.getMessage("DOTX008E", params).toString(), e);
                  } else {
                      logger.error(MessageUtils.getMessage("DOTX008E", params).toString());
                  }
              } else if (currentFile.equals(rootFile)) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ078F", params).toString() + " Cannot load file: " + e.getMessage(), e);
              } else if (processingMode == Mode.STRICT) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ079E", params).toString() + " Cannot load file: " + e.getMessage(), e);
              } else {
                  logger.error(MessageUtils.getMessage("DOTJ079E", params).toString() + " Cannot load file: " + e.getMessage());
              }
              failureList.add(currentFile);
          } catch (final Exception e) {
              if (currentFile.equals(rootFile)) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ012F", params).toString() + ": " + e.getMessage(),  e);
              } else if (processingMode == Mode.STRICT) {
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ013E", params).toString() + ": " + e.getMessage(), e);
              } else {
                  logger.error(MessageUtils.getMessage("DOTJ013E", params).toString() + ": " + e.getMessage(), e);
              }
              failureList.add(currentFile);
          }
  
          if (!listFilter.isValidInput() && currentFile.equals(rootFile)) {
              if (validate) {
                  // stop the build if all content in the input file was filtered out.
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ022F", params).toString());
              } else {
                  // stop the build if the content of the file is not valid.
                  throw new DITAOTException(MessageUtils.getMessage("DOTJ034F", params).toString());
              }
          }
  
          doneList.add(currentFile);
          listFilter.reset();
          keydefFilter.reset();
  
      }