private static void generateAttrHelp(
     DescribableHelper.Schema schema, String attr, PrintWriter pw, int headerLevel)
     throws Exception {
   String help = schema.getHelp(attr);
   if (help != null) {
     pw.println(help);
   }
   DescribableHelper.ParameterType type = schema.parameters().get(attr);
   describeType(type, pw, headerLevel);
 }
 private static void generateHelp(DescribableHelper.Schema schema, PrintWriter pw, int headerLevel)
     throws Exception {
   String help = schema.getHelp(null);
   if (help != null) {
     pw.println(help);
   } // TODO else could use RequestDispatcher (as in Descriptor.doHelp) to serve template-based
     // help
   for (String attr : schema.mandatoryParameters()) {
     pw.println("<h" + headerLevel + "><code>" + attr + "</code></h" + headerLevel + ">");
     generateAttrHelp(schema, attr, pw, headerLevel);
   }
   for (String attr : schema.parameters().keySet()) {
     if (schema.mandatoryParameters().contains(attr)) {
       continue;
     }
     pw.println(
         "<h" + headerLevel + "><code>" + attr + "</code> (optional)</h" + headerLevel + ">");
     generateAttrHelp(schema, attr, pw, headerLevel);
   }
 }