@Restricted(DoNotUse.class) // accessed via REST API
 public HttpResponse doGenerateSnippet(StaplerRequest req, @QueryParameter String json)
     throws Exception {
   // TODO JENKINS-31458 is there not an easier way to do this?
   JSONObject jsonO = JSONObject.fromObject(json);
   Jenkins j = Jenkins.getActiveInstance();
   Class<?> c = j.getPluginManager().uberClassLoader.loadClass(jsonO.getString("stapler-class"));
   StepDescriptor descriptor = (StepDescriptor) j.getDescriptor(c.asSubclass(Step.class));
   Object o;
   try {
     o = descriptor.newInstance(req, jsonO);
   } catch (RuntimeException x) { // e.g. IllegalArgumentException
     return HttpResponses.plainText(Functions.printThrowable(x));
   }
   try {
     String groovy = object2Groovy(o);
     if (descriptor.isAdvanced()) {
       String warning = Messages.Snippetizer_this_step_should_not_normally_be_used_in();
       groovy = "// " + warning + "\n" + groovy;
     }
     return HttpResponses.plainText(groovy);
   } catch (UnsupportedOperationException x) {
     Logger.getLogger(CpsFlowExecution.class.getName())
         .log(Level.WARNING, "failed to render " + json, x);
     return HttpResponses.plainText(x.getMessage());
   }
 }
 @Override
 public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException {
   // TODO f:dropdownDescriptorSelector does not seem to work sensibly: the super method uses
   // RequestImpl.bindJSON and ignores any StepDescriptor.newInstance override.
   // Cf. Snippetizer.doGenerateSnippet, which also seems to lack a standard way of parsing
   // part of a form using databinding.
   JSONObject s = formData.getJSONObject("s");
   Jenkins j = Jenkins.getActiveInstance();
   Class<?> c;
   try {
     c = j.getPluginManager().uberClassLoader.loadClass(s.getString("stapler-class"));
   } catch (ClassNotFoundException x) {
     throw new FormException(x, "s");
   }
   Descriptor<?> descriptor = j.getDescriptor(c.asSubclass(Step.class));
   return new StepBuilder((Step) descriptor.newInstance(req, s));
 }