docs: public boolean processTopics(final Map<String, SpecTopic> specTopics, final Map<String, SpecTopic> topicTargets,
              final TopicProvider topicDataProvider, final ServerSettingsProvider serverSettingsProvider) {
          // Check if the topics have already been processed. If so then don't re-process them.
          if (isTopicsProcessed()) return true;
  
          final Integer taskId = serverSettingsProvider.getServerSettings().getEntities().getTaskTagId();
  
          boolean successfullyLoaded = true;
          SpecTopic prevTopic = null;
          int count = 1;
          final LinkedList<String> processTopics = new LinkedList<String>(getTopicIds());
          for (final String uniqueTopicId : processTopics) {
              final SpecTopic specTopic = topics.get(uniqueTopicId);
  
              // If the topic is an existing or cloned topic then use the database information
              if (specTopic.isTopicAnExistingTopic() || specTopic.isTopicAClonedTopic() || specTopic.isTopicAClonedDuplicateTopic()) {
                  // Get the topic information from the database
                  final TopicWrapper topic;
                  if (specTopic.isTopicAClonedTopic()) {
                      topic = topicDataProvider.getTopic(Integer.parseInt(specTopic.getId().substring(1)), null);
                  } else if (specTopic.isTopicAClonedDuplicateTopic()) {
                      topic = topicDataProvider.getTopic(Integer.parseInt(specTopic.getId().substring(2)), null);
                  } else {
                      topic = topicDataProvider.getTopic(specTopic.getDBId(), null);
                  }
  
                  if (topic != null) {
                      // Add relationships if the topic is a task
                      if (topic.hasTag(taskId)) {
                          // Create a target if one doesn't already exist
                          if (specTopic.getTargetId() == null) {
                              // Create a randomly generated target id using the process topic count
                              String topicTargetId = ContentSpecUtilities.generateRandomTargetId(specTopic.getUniqueId(), count);
                              // Check that the topic id doesn't already exist. If it does then keep generating random numbers
                              // until a unique one is found
                              while (topicTargets.containsKey(topicTargetId)) {
                                  topicTargetId = ContentSpecUtilities.generateRandomTargetId(specTopic.getUniqueId(), count);
                              }
  
                              specTopic.setTargetId(topicTargetId);
                          }
  
                          if (prevTopic != null) {
                              specTopic.addRelationshipToProcessTopic(prevTopic, RelationshipType.PREVIOUS);
                              prevTopic.addRelationshipToProcessTopic(specTopic, RelationshipType.NEXT);
                          }
  
                          // Set the current topic as the previous topic
                          prevTopic = specTopic;
                      }
                  } else {
                      successfullyLoaded = false;
                  }
              } else {
                  // Not an existing or cloned topic
                  // The Topic is a duplicated topic so get the type from the original topic
                  String type = specTopic.getType();
                  if (specTopic.isTopicADuplicateTopic()) {
                      final SpecTopic referenceTopic = specTopics.get("N" + specTopic.getId().substring(1));
                      if (referenceTopic == null) {
                          continue;
                      }
                      type = referenceTopic.getType();
                  }
                  // Add relationships if the topic is a task
                  if (type.equals("Task")) {
                      // Create a target if one doesn't already exist
                      if (specTopic.getTargetId() == null) {
                          // Create a randomly generated target id using the process topic count
                          String topicTargetId = ContentSpecUtilities.generateRandomTargetId(specTopic.getUniqueId(), count);
                          // Check that the topic id doesn't already exist. If it does then keep generating random numbers until a
                          // unique one is found
                          while (topicTargets.containsKey(topicTargetId)) {
                              topicTargetId = ContentSpecUtilities.generateRandomTargetId(specTopic.getUniqueId(), count);
                          }
  
                          specTopic.setTargetId(topicTargetId);
                      }
  
                      if (prevTopic != null) {
                          specTopic.addRelationshipToProcessTopic(prevTopic, RelationshipType.PREVIOUS);
                          prevTopic.addRelationshipToProcessTopic(specTopic, RelationshipType.NEXT);
                      }
  
                      // Set the current topic as the previous topic
                      prevTopic = specTopic;
                  }
              }
              count++;
          }
  
          topicsProcessed = true;
  
          return successfullyLoaded;
      }