static protected void packClassPathIntoZipFileRecursive(File dir,
                                                          String sofar,
                                                          ZipOutputStream zos)
  throws IOException {
    String files[] = dir.list();
    for (int i = 0; i < files.length; i++) {
      // ignore . .. and .DS_Store
      if (files[i].charAt(0) == '.') continue;

      File sub = new File(dir, files[i]);
      String nowfar = (sofar == null) ?
                                       files[i] : (sofar + "/" + files[i]);

                                       if (sub.isDirectory()) {
                                         packClassPathIntoZipFileRecursive(sub, nowfar, zos);

                                       } else {
                                         // don't add .jar and .zip files, since they only work
                                         // inside the root, and they're unpacked
                                         if (!files[i].toLowerCase().endsWith(".jar") &&
                                             !files[i].toLowerCase().endsWith(".zip") &&
                                             files[i].charAt(0) != '.') {
                                           ZipEntry entry = new ZipEntry(nowfar);
                                           zos.putNextEntry(entry);
                                           zos.write(Base.loadBytesRaw(sub));
                                           zos.closeEntry();
                                         }
                                       }
    }
  }