public Response serve(IHTTPSession session) {
    Map<String, String> header = session.getHeaders();
    Map<String, String> parms = session.getParms();
    String uri = session.getUri();

    {
      if (uri.startsWith("/")) {
        int nextSlash = uri.indexOf("/", 1);
        String appName = uri.substring(1, nextSlash);

        StringBuilder b = new StringBuilder();
        b.append(session.getMethod()).append(" '").append(uri).append("' \n");

        Iterator<String> e = header.keySet().iterator();
        while (e.hasNext()) {
          String value = e.next();
          b.append("  HDR: '")
              .append(value)
              .append("' = '")
              .append(header.get(value))
              .append("'\n");
        }
        e = parms.keySet().iterator();
        while (e.hasNext()) {
          String value = e.next();
          b.append("  PRM: '")
              .append(value)
              .append("' = '")
              .append(header.get(value))
              .append("'\n");
        }
        WebLogger.getLogger(appName).i(t, b.toString());
      }
    }

    // Make sure we won't die of an exception later
    File root = new File(ODKFileUtils.getOdkFolder());
    try {
      ODKFileUtils.verifyExternalStorageAvailability();
      if (!root.exists() || !root.isDirectory()) {
        return getInternalErrorResponse(
            "given path is not a directory (" + root.getAbsolutePath() + ").");
      }
    } catch (Exception e) {
      return getInternalErrorResponse(
          "exception " + e.toString() + " accessing directory (" + root.getAbsolutePath() + ").");
    }
    return respond(Collections.unmodifiableMap(header), session, uri);
  }
 @Override
 public void onTerminate() {
   WebLogger.closeAll();
   super.onTerminate();
   Log.i(t, "onTerminate");
 }