public ReaderHandler(LowLevelDbAccess lowLevelDbAccess, String webDir) {

    loginInfoDb = new LoginInfo.DB(lowLevelDbAccess);
    userDb = new User.DB(lowLevelDbAccess);
    feedDb = new Feed.DB(lowLevelDbAccess);
    articleDb = new Article.DB(lowLevelDbAccess);
    readArticlesCollDb = new ReadArticlesColl.DB(lowLevelDbAccess);
    userHelpers = new UserHelpers(loginInfoDb, userDb);

    setContextPath("/");

    File warPath = new File(webDir);
    setWar(warPath.getAbsolutePath());

    if (isInJar) {
      for (Map.Entry<String, String> entry : PATH_MAPPING.entrySet()) {
        addPrebuiltJsp(entry.getKey(), "jsp." + entry.getValue().replaceAll("_", "_005f") + "_jsp");
      }
    } else {
      for (Map.Entry<String, String> entry : PATH_MAPPING.entrySet()) {
        addServlet(
            new ServletHolder(new RedirectServlet("/" + entry.getValue() + ".jsp")),
            entry.getKey());
      }
    }

    setErrorHandler(new ReaderErrorHandler());
  }
  /**
   * Parses HTTP parameters in an appropriate format and return back map of values to predefined
   * list of names.
   *
   * @param req Request.
   * @return Map of parsed parameters.
   */
  @SuppressWarnings({"unchecked"})
  private Map<String, Object> parameters(ServletRequest req) {
    Map<String, String[]> params = req.getParameterMap();

    if (F.isEmpty(params)) return Collections.emptyMap();

    Map<String, Object> map = U.newHashMap(params.size());

    for (Map.Entry<String, String[]> entry : params.entrySet())
      map.put(entry.getKey(), parameter(entry.getValue()));

    return map;
  }