docs: protected TopicWrapper createTopicEntity(final DataProviderFactory providerFactory, final ITopicNode topicNode,
              final String docBookVersion, final LocaleWrapper locale) throws ProcessingException {
          LOG.debug("Processing topic: {}", topicNode.getText());
  
          // Duplicates reference another new or cloned topic and should not have a different new/updated underlying topic
          if (topicNode.isTopicAClonedDuplicateTopic() || topicNode.isTopicADuplicateTopic()) return null;
  
          final TagProvider tagProvider = providerFactory.getProvider(TagProvider.class);
          final TopicSourceURLProvider topicSourceURLProvider = providerFactory.getProvider(TopicSourceURLProvider.class);
  
          if (isShuttingDown.get()) {
              return null;
          }
  
          // If the spec topic is a clone or new topic then it will have changed no mater what else is done, since it's a new topic
          boolean changed = topicNode.isTopicAClonedTopic() || topicNode.isTopicANewTopic();
          final TopicWrapper topic = getTopicForTopicNode(providerFactory, topicNode);
  
          // Check if the topic is null, if so throw an exception as it shouldn't be at this stage
          if (topic == null) {
              throw new ProcessingException("Creating a topic failed.");
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              return null;
          }
  
          // Process the topic and add or remove any tags
          if (processTopicTags(tagProvider, topicNode, topic)) {
              changed = true;
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              return null;
          }
  
          // Process and set the assigned writer for new and cloned topics
          if (!topicNode.isTopicAnExistingTopic() && !isNullOrEmpty(topicNode.getAssignedWriter(true))) {
              processAssignedWriter(tagProvider, topicNode, topic);
              changed = true;
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              return null;
          }
  
          // Process and set the source urls for new and cloned topics
          if (topicNode instanceof SpecTopic && !topicNode.isTopicAnExistingTopic()) {
              if (processTopicSourceUrls(topicSourceURLProvider, (SpecTopic) topicNode, topic)) changed = true;
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              return null;
          }
  
          if (!topicNode.isTopicAnExistingTopic()) {
              // Process and set the docbook version
              if (docBookVersion.equals(
                      CommonConstants.DOCBOOK_45_TITLE) && (topic.getXmlFormat() == null || topic.getXmlFormat() != CommonConstants
                      .DOCBOOK_45)) {
                  topic.setXmlFormat(CommonConstants.DOCBOOK_45);
                  changed = true;
              } else if (docBookVersion.equals(
                      CommonConstants.DOCBOOK_50_TITLE) && (topic.getXmlFormat() == null || topic.getXmlFormat() != CommonConstants
                      .DOCBOOK_50)) {
                  topic.setXmlFormat(CommonConstants.DOCBOOK_50);
                  changed = true;
              }
  
              // Process and set the locale
              if (locale != null && !locale.equals(topic.getLocale())) {
                  topic.setLocale(locale);
                  changed = true;
              }
          }
  
          // Check if the app should be shutdown
          if (isShuttingDown.get()) {
              return null;
          }
  
          if (changed) {
              // Set the CSP Property Tag ID for new/updated so that we can track the newly created topic
              if (topicNode.isTopicAClonedTopic() || topicNode.isTopicANewTopic()) {
                  setCSPPropertyForTopic(topic, topicNode, providerFactory.getProvider(PropertyTagProvider.class));
              }
  
              return topic;
          } else {
              return null;
          }
      }