docs: public String getStatData() throws IOException {
          Jenkins j = Jenkins.getInstance();
  
          JSONObject o = new JSONObject();
          o.put("stat",1);
          o.put("install", j.getLegacyInstanceId());
          o.put("servletContainer", j.servletContext.getServerInfo());
          o.put("version", Jenkins.VERSION);
  
          List<JSONObject> nodes = new ArrayList<>();
          for( Computer c : j.getComputers() ) {
              JSONObject  n = new JSONObject();
              if(c.getNode()==j) {
                  n.put("master",true);
                  n.put("jvm-vendor", System.getProperty("java.vm.vendor"));
                  n.put("jvm-name", System.getProperty("java.vm.name"));
                  n.put("jvm-version", System.getProperty("java.version"));
              }
              n.put("executors",c.getNumExecutors());
              DescriptorImpl descriptor = j.getDescriptorByType(DescriptorImpl.class);
              n.put("os", descriptor.get(c));
              nodes.add(n);
          }
          o.put("nodes",nodes);
  
          List<JSONObject> plugins = new ArrayList<>();
          for( PluginWrapper pw : j.getPluginManager().getPlugins() ) {
              if(!pw.isActive())  continue;   // treat disabled plugins as if they are uninstalled
              JSONObject p = new JSONObject();
              p.put("name",pw.getShortName());
              p.put("version",pw.getVersion());
              plugins.add(p);
          }
          o.put("plugins",plugins);
  
          JSONObject jobs = new JSONObject();
          // capture the descriptors as these should be small compared with the number of items
          // so we will walk all items only once and we can short-cut the search of descriptors
          TopLevelItemDescriptor[] descriptors = Items.all().toArray(new TopLevelItemDescriptor[0]);
          int[] counts = new int[descriptors.length];
          for (TopLevelItem item: j.allItems(TopLevelItem.class)) {
              TopLevelItemDescriptor d = item.getDescriptor();
              for (int i = 0; i < descriptors.length; i++) {
                  if (d == descriptors[i]) {
                      counts[i]++;
                      // no point checking any more, we found the match
                      break;
                  }
              }
          }
          for (int i = 0; i < descriptors.length; i++) {
              jobs.put(descriptors[i].getJsonSafeClassName(), counts[i]);
          }
          o.put("jobs",jobs);
  
          try {
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
  
              // json -> UTF-8 encode -> gzip -> encrypt -> base64 -> string
              try (OutputStream cipheros = new CombinedCipherOutputStream(baos,getKey(),"AES");
                   OutputStream zipos = new GZIPOutputStream(cipheros);
                   OutputStreamWriter w = new OutputStreamWriter(zipos, StandardCharsets.UTF_8)) {
                  o.write(w);
              }
  
              return new String(Base64.getEncoder().encode(baos.toByteArray()));
          } catch (GeneralSecurityException e) {
              throw new Error(e); // impossible
          }
      }