docs: protected boolean doesTopicMatch(final SpecTopic specTopic, final CSNodeWrapper node, boolean matchTypes) {
          if (!EntityUtilities.isNodeATopic(node)) return false;
  
          // Check if the node/topic type matches
          if (matchTypes) {
              boolean matches = true;
              switch (specTopic.getTopicType()) {
                  case INITIAL_CONTENT:
                      matches = node.getNodeType().equals(CommonConstants.CS_NODE_INITIAL_CONTENT_TOPIC);
                      break;
                  case NORMAL:
                      matches = node.getNodeType().equals(CommonConstants.CS_NODE_TOPIC);
                      break;
                  case FEEDBACK:
                  case LEGAL_NOTICE:
                  case REVISION_HISTORY:
                  case AUTHOR_GROUP:
                  case ABSTRACT:
                      matches = node.getNodeType().equals(CommonConstants.CS_NODE_META_DATA_TOPIC);
                      break;
              }
  
              if (!matches) {
                  return false;
              }
          }
  
          // If the unique id is not from the parser, in which case it will start with a number than use the unique id to compare
          if (specTopic.getUniqueId() != null && specTopic.getUniqueId().matches("^\\d.*")) {
              return specTopic.getUniqueId().equals(Integer.toString(node.getId()));
          } else {
              // Check the parent has the same name
              if (specTopic.getParent() != null && node.getParent() != null && node.getParent() instanceof Level) {
                  if (!((Level) specTopic.getParent()).getTitle().equals(node.getParent().getTitle())) {
                      return false;
                  }
              }
  
              // Since a content spec doesn't contain the database ids for the nodes use what is available to see if the topics match
              return specTopic.getDBId().equals(node.getEntityId());
          }
      }