docs: public void updateByXml(Source source) throws IOException {
          checkPermission(CONFIGURE);
          XmlFile configXmlFile = getConfigFile();
          final AtomicFileWriter out = new AtomicFileWriter(configXmlFile.getFile());
          try {
              try {
                  XMLUtils.safeTransform(source, new StreamResult(out));
                  out.close();
              } catch (TransformerException | SAXException e) {
                  throw new IOException("Failed to persist config.xml", e);
              }
  
              // try to reflect the changes by reloading
              Object o = new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshalNullingOut(this);
              if (o!=this) {
                  // ensure that we've got the same job type. extending this code to support updating
                  // to different job type requires destroying & creating a new job type
                  throw new IOException("Expecting "+this.getClass()+" but got "+o.getClass()+" instead");
              }
  
              Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable<Void,IOException>() {
                  @Override public Void call() throws IOException {
                      onLoad(getParent(), getRootDir().getName());
                      return null;
                  }
              });
              Jenkins.getInstance().rebuildDependencyGraphAsync();
  
              // if everything went well, commit this new version
              out.commit();
              SaveableListener.fireOnChange(this, getConfigFile());
  
          } finally {
              out.abort(); // don't leave anything behind
          }
      }