docs: public void compileInMemoryJarfileForUpdateClasses(InMemoryJarfile jarOutput,
              Catalog currentCatalog, HSQLInterface hsql)
                      throws IOException, ClassNotFoundException, VoltCompilerException
      {
          // clear out the warnings and errors
          m_warnings.clear();
          m_infos.clear();
          m_errors.clear();
  
          // do all the work to get the catalog
          Catalog catalog = currentCatalog.deepCopy();
          Cluster cluster = catalog.getClusters().get("cluster");
          Database db = cluster.getDatabases().get("database");
  
          // Get DDL from InMemoryJar
          byte[] ddlBytes = jarOutput.get(AUTOGEN_DDL_FILE_NAME);
          String canonicalDDL = new String(ddlBytes, Constants.UTF8ENCODING);
  
          try {
              CatalogMap<Procedure> procedures = db.getProcedures();
  
              // build a cache of previous SQL stmts
              m_previousCatalogStmts.clear();
              for (Procedure prevProc : procedures) {
                  for (Statement prevStmt : prevProc.getStatements()) {
                      addStatementToCache(prevStmt);
                  }
              }
  
              // Use the in-memory jar-file-provided class loader so that procedure
              // classes can be found and copied to the new file that gets written.
              ClassLoader classLoader = jarOutput.getLoader();
  
              for (Procedure procedure : procedures) {
                  if (! procedure.getHasjava()) {
                      // Skip the DDL statement stored procedures as @UpdateClasses does not affect them
                      continue;
                  }
                  // default procedure is also a single statement procedure
                  assert(procedure.getDefaultproc() == false);
  
                  if (procedure.getSystemproc()) {
                      // UpdateClasses does not need to update system procedures
                      continue;
                  }
  
                  // clear up the previous procedure contents before recompiling java user procedures
                  procedure.getStatements().clear();
                  procedure.getParameters().clear();
  
                  final String className = procedure.getClassname();
  
                  // Load the class given the class name
                  Class<?> procClass = classLoader.loadClass(className);
                  // get the short name of the class (no package)
                  String shortName = ProcedureCompiler.deriveShortProcedureName(className);
  
                  ProcedureAnnotation pa = (ProcedureAnnotation) procedure.getAnnotation();
                  if (pa == null) {
                      pa = new ProcedureAnnotation();
                      procedure.setAnnotation(pa);
                  }
  
                  // if the procedure is non-transactional, then take this special path here
                  if (VoltNonTransactionalProcedure.class.isAssignableFrom(procClass)) {
                      ProcedureCompiler.compileNTProcedure(this, procClass, procedure, jarOutput);
                      continue;
                  }
  
                  // if still here, that means the procedure is transactional
                  procedure.setTransactional(true);
  
                  // iterate through the fields and get valid sql statements
                  Map<String, SQLStmt> stmtMap = ProcedureCompiler.getSQLStmtMap(this, procClass);
                  Map<String, Object> fields = ProcedureCompiler.getFiledsMap(this, stmtMap, procClass, shortName);
                  Method procMethod = (Method) fields.get("@run");
                  assert(procMethod != null);
  
                  ProcedureCompiler.compileSQLStmtUpdatingProcedureInfomation(this, hsql, m_estimates, db, procedure,
                          procedure.getSinglepartition(), fields);
  
                  // set procedure parameter types
                  Class<?>[] paramTypes = ProcedureCompiler.setParameterTypes(this, procedure, shortName, procMethod);
  
                  ProcedurePartitionData partitionData = ProcedurePartitionData.extractPartitionData(procedure);
                  ProcedureCompiler.addPartitioningInfo(this, procedure, db, paramTypes, partitionData);
  
                  // put the compiled code for this procedure into the jarFile
                  // need to find the outermost ancestor class for the procedure in the event
                  // that it's actually an inner (or inner inner...) class.
                  // addClassToJar recursively adds all the children, which should include this
                  // class
                  Class<?> ancestor = procClass;
                  while (ancestor.getEnclosingClass() != null) {
                      ancestor = ancestor.getEnclosingClass();
                  }
                  addClassToJar(jarOutput, ancestor);
              }
  
              ////////////////////////////////////////////
              // allow gc to reclaim any cache memory here
              m_previousCatalogStmts.clear();
  
          } catch (final VoltCompilerException e) {
              throw e;
          }
  
          // generate the catalog report and write it to disk
          generateCatalogReport(catalog, canonicalDDL, standaloneCompiler, m_warnings, jarOutput);
  
          // WRITE CATALOG TO JAR HERE
          final String catalogCommands = catalog.serialize();
  
          byte[] catalogBytes = catalogCommands.getBytes(Constants.UTF8ENCODING);
  
          // Don't update buildinfo if it's already present, e.g. while upgrading.
          // Note when upgrading the version has already been updated by the caller.
          if (!jarOutput.containsKey(CatalogUtil.CATALOG_BUILDINFO_FILENAME)) {
              addBuildInfo(jarOutput);
          }
          jarOutput.put(CatalogUtil.CATALOG_FILENAME, catalogBytes);
  
          assert(!hasErrors());
          if (hasErrors()) {
              StringBuilder sb = new StringBuilder();
              for (Feedback fb : m_errors) {
                  sb.append(fb.getLogString());
              }
              throw new VoltCompilerException(sb.toString());
          }
      }