docs: private void filterTopics(final Element topicref, final List<FilterUtils> filters) {
          final List<FilterUtils> fs = combineFilterUtils(topicref, filters);
  
          final String href = topicref.getAttribute(ATTRIBUTE_NAME_HREF);
          final Attr skipFilter = topicref.getAttributeNode(SKIP_FILTER);
          final URI srcAbsUri = job.tempDirURI.resolve(map.resolve(href));
          if (!fs.isEmpty() && skipFilter == null
                  && !filtered.contains(srcAbsUri)
                  && !href.isEmpty()
                  && !ATTR_SCOPE_VALUE_EXTERNAL.equals(topicref.getAttribute(ATTRIBUTE_NAME_SCOPE))
                  && !ATTR_PROCESSING_ROLE_VALUE_RESOURCE_ONLY.equals(topicref.getAttribute(ATTRIBUTE_NAME_PROCESSING_ROLE))
                  && isDitaFormat(topicref.getAttributeNode(ATTRIBUTE_NAME_FORMAT))) {
              final ProfilingFilter writer = new ProfilingFilter();
              writer.setLogger(logger);
              writer.setJob(job);
              writer.setFilterUtils(fs);
              writer.setCurrentFile(srcAbsUri);
              final List<XMLFilter> pipe = singletonList(writer);
  
              logger.info("Filtering " + srcAbsUri);
              try {
                  xmlUtils.transform(srcAbsUri, pipe);
              } catch (final DITAOTException e) {
                  logger.error("Failed to filter " + srcAbsUri + ": " + e.getMessage(), e);
              }
              filtered.add(srcAbsUri);
          }
          if (skipFilter != null) {
              topicref.removeAttributeNode(skipFilter);
          }
  
          for (final Element child: getChildElements(topicref, MAP_TOPICREF)) {
              if (DITAVAREF_D_DITAVALREF.matches(child)) {
                  continue;
              }
              filterTopics(child, fs);
          }
      }