docs: protected void processMap(final FileInfo fi) {
          this.map = fi.uri;
          currentFile = job.tempDirURI.resolve(map);
          ditavalFile = Optional.of(new File(job.tempDir, FILE_NAME_MERGED_DITAVAL))
                  .filter(File::exists)
                  .map(File::toURI)
                  .orElse(null);
  
          logger.info("Processing " + currentFile);
          final Document doc;
          try {
              logger.debug("Reading " + currentFile);
              doc = builder.parse(new InputSource(currentFile.toString()));
          } catch (final SAXException | IOException e) {
              logger.error("Failed to parse " + currentFile, e);
              return;
          }
  
          logger.debug("Split branches and generate copy-to");
          splitBranches(doc.getDocumentElement(), Branch.EMPTY);
          logger.debug("Filter map");
          filterBranches(doc.getDocumentElement());
          logger.debug("Rewrite duplicate topic references");
          rewriteDuplicates(doc.getDocumentElement());
  
          logger.debug("Writing " + currentFile);
          Result result = null;
          try {
              Transformer serializer = TransformerFactory.newInstance().newTransformer();
              result = new StreamResult(currentFile.toString());
              serializer.transform(new DOMSource(doc), result);
          } catch (final TransformerConfigurationException | TransformerFactoryConfigurationError e) {
              throw new RuntimeException(e);
          } catch (final TransformerException e) {
              logger.error("Failed to serialize " + map.toString() + ": " + e.getMessage(), e);
          } finally {
              try {
                  close(result);
              } catch (final IOException e) {
                  logger.error("Failed to close result stream for " + map.toString() + ": " + e.getMessage(), e);
              }
          }
      }