docs: public boolean processContentSpec(final ContentSpec contentSpec, final String username, final ContentSpecParser.ParsingMode mode,
              final LogMessageWrapper logMessage) {
          boolean editing = false;
          if (mode == ContentSpecParser.ParsingMode.EDITED) {
              editing = true;
          } else if (mode == ContentSpecParser.ParsingMode.EITHER && contentSpec.getId() != null) {
              editing = true;
          }
  
          final ProcessorData processorData = new ProcessorData();
          processorData.setContentSpec(contentSpec);
          processorData.setUsername(username);
          processorData.setLogMessage(logMessage);
  
          // Set the log details user if one isn't set
          if (logMessage != null && username != null && logMessage.getUser() == null) {
              logMessage.setUser(serverEntities.getUnknownUserId().toString());
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              shutdown.set(true);
              return false;
          }
  
          // Check that the content spec is valid and if it is then continue to processing the content spec.
          if (processingOptions.isValidate() && !doValidationPass(processorData)) {
              return false;
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              shutdown.set(true);
              return false;
          }
  
          // If we aren't validating then save the content specification
          if (!processingOptions.isValidateOnly()) {
              LOG.info("Saving the Content Specification to the server...");
              if (saveContentSpec(providerFactory, processorData, editing)) {
                  log.info(ProcessorConstants.INFO_SUCCESSFUL_SAVE_MSG);
              } else {
                  log.error(ProcessorConstants.ERROR_PROCESSING_ERROR_MSG);
                  return false;
              }
          }
  
          return true;
      }