code: public String exportZipBase64() throws JSONException, IOException {
          Map<String,JSONObject> objectMap = JsonUtil.getJsonObjects(jsonable.getJson());
          JSONObject mdw = null;
          JSONObject contents = null;
          for (String name : objectMap.keySet()) {
              if ("mdw".equals(name))
                  mdw = objectMap.get(name);
              else if (contents == null)
                  contents = objectMap.get(name);
          }
          if (contents == null)
              throw new IOException("Cannot find expected contents property");
          else
              objectMap = JsonUtil.getJsonObjects(contents);
          if (mdw != null)
              objectMap.put(".mdw", mdw);
  
          byte[] buffer = new byte[ZIP_BUFFER_KB * 1024];
          ZipOutputStream zos = null;
          ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
          try {
              zos = new ZipOutputStream(outputStream);
              for (String name : objectMap.keySet()) {
                  JSONObject json = objectMap.get(name);
                  ZipEntry ze = new ZipEntry(name);
                  zos.putNextEntry(ze);
                  InputStream inputStream = new ByteArrayInputStream(json.toString(2).getBytes());
                  int len;
                  while ((len = inputStream.read(buffer)) > 0) {
                      zos.write(buffer, 0, len);
                  }
              }
          }
          finally {
              if (zos != null) {
                  zos.closeEntry();
                  zos.close();
              }
          }
          byte[] bytes = outputStream.toByteArray();
          return new String(Base64.encodeBase64(bytes));
      }
docs: Default behavior adds zip entries for each property on the first (non-mdw) top-level object.