docs: @Override
      public AbstractPipelineOutput execute(final AbstractPipelineInput input)
              throws DITAOTException {
          if (fileInfoFilter == null) {
              fileInfoFilter = f -> f.format == null || f.format.equals(ATTR_FORMAT_VALUE_DITA) || f.format.equals(ATTR_FORMAT_VALUE_DITAMAP);
          }
          final Collection<FileInfo> fis = job.getFileInfo(fileInfoFilter).stream()
                  .filter(f -> f.hasKeyref)
                  .collect(Collectors.toSet());
          if (!fis.isEmpty()) {
              try {
                  final String cls = Optional
                          .ofNullable(job.getProperty("temp-file-name-scheme"))
                          .orElse(configuration.get("temp-file-name-scheme"));
                  tempFileNameScheme = (GenMapAndTopicListModule.TempFileNameScheme) Class.forName(cls).newInstance();
              } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                  throw new RuntimeException(e);
              }
              tempFileNameScheme.setBaseDir(job.getInputDir());
              initFilters();
  
              final Document doc = readMap();
  
              final KeyrefReader reader = new KeyrefReader();
              reader.setLogger(logger);
              final Job.FileInfo in = job.getFileInfo(fi -> fi.isInput).iterator().next();
              final URI mapFile = in.uri;
              logger.info("Reading " + job.tempDirURI.resolve(mapFile).toString());
              reader.read(job.tempDirURI.resolve(mapFile), doc);
  
              final KeyScope rootScope = reader.getKeyDefinition();
              final List<ResolveTask> jobs = collectProcessingTopics(fis, rootScope, doc);
              writeMap(doc);
  
              transtype = input.getAttribute(ANT_INVOKER_EXT_PARAM_TRANSTYPE);
              delayConrefUtils = transtype.equals(INDEX_TYPE_ECLIPSEHELP) ? new DelayConrefUtils() : null;
              for (final ResolveTask r: jobs) {
                  if (r.out != null) {
                      processFile(r);
                  }
              }
              for (final ResolveTask r: jobs) {
                  if (r.out == null) {
                      processFile(r);
                  }
              }
  
              // Store job configuration updates
              for (final URI file: normalProcessingRole) {
                  final FileInfo f = job.getFileInfo(file);
                  if (f != null) {
                      f.isResourceOnly = false;
                      job.add(f);
                  }
              }
  
              try {
                  job.write();
              } catch (final IOException e) {
                  throw new DITAOTException("Failed to store job state: " + e.getMessage(), e);
              }
          }
          return null;
      }