docs: public void writeXML(XMLOutput xmlOutput, boolean withMessages) throws IOException {
          xmlOutput.startTag("FindBugsSummary");
  
          xmlOutput.addAttribute("timestamp", new SimpleDateFormat(TIMESTAMP_FORMAT, Locale.ENGLISH).format(analysisTimestamp));
          xmlOutput.addAttribute("total_classes", String.valueOf(getNumClasses()));
          xmlOutput.addAttribute("referenced_classes", String.valueOf(referencedClasses));
  
          xmlOutput.addAttribute("total_bugs", String.valueOf(totalErrors[0]));
          xmlOutput.addAttribute("total_size", String.valueOf(getCodeSize()));
          xmlOutput.addAttribute("num_packages", String.valueOf(packageStatsMap.size()));
  
          if (java_version != null) {
              xmlOutput.addAttribute("java_version", java_version);
          }
          if (java_vm_version != null) {
              xmlOutput.addAttribute("vm_version", java_vm_version);
          }
          Footprint delta = new Footprint(baseFootprint);
          NumberFormat twoPlaces = NumberFormat.getInstance(Locale.ENGLISH);
          twoPlaces.setMinimumFractionDigits(2);
          twoPlaces.setMaximumFractionDigits(2);
          twoPlaces.setGroupingUsed(false);
          long cpuTime = delta.getCpuTime(); // nanoseconds
          if (cpuTime >= 0) {
              xmlOutput.addAttribute("cpu_seconds", twoPlaces.format(cpuTime / 1000000000.0));
          }
          long clockTime = delta.getClockTime(); // milliseconds
          if (clockTime >= 0) {
              xmlOutput.addAttribute("clock_seconds", twoPlaces.format(clockTime / 1000.0));
          }
          long peakMemory = delta.getPeakMemory(); // bytes
          if (peakMemory >= 0) {
              xmlOutput.addAttribute("peak_mbytes", twoPlaces.format(peakMemory / (1024.0 * 1024)));
          }
          xmlOutput.addAttribute("alloc_mbytes", twoPlaces.format(Runtime.getRuntime().maxMemory() / (1024.0 * 1024)));
          long gcTime = delta.getCollectionTime(); // milliseconds
          if (gcTime >= 0) {
              xmlOutput.addAttribute("gc_seconds", twoPlaces.format(gcTime / 1000.0));
          }
  
          BugCounts.writeBugPriorities(xmlOutput, totalErrors);
  
          xmlOutput.stopTag(false);
  
          if (withMessages && fileBugHashes != null) {
              for (String sourceFile : new TreeSet<>(fileBugHashes.getSourceFiles())) {
                  xmlOutput.startTag("FileStats");
                  xmlOutput.addAttribute("path", sourceFile);
                  xmlOutput.addAttribute("bugCount", String.valueOf(fileBugHashes.getBugCount(sourceFile)));
                  xmlOutput.addAttribute("size", String.valueOf(fileBugHashes.getSize(sourceFile)));
  
                  String hash = fileBugHashes.getHash(sourceFile);
                  if (hash != null) {
                      xmlOutput.addAttribute("bugHash", hash);
                  }
                  xmlOutput.stopTag(true);
  
              }
          }
  
          if (!OMIT_PACKAGE_STATS) {
              for (PackageStats stats : packageStatsMap.values()) {
                  stats.writeXML(xmlOutput);
              }
          }
  
          getProfiler().writeXML(xmlOutput);
          xmlOutput.closeTag("FindBugsSummary");
      }