/**
   * Get list of author given query ( author name )
   *
   * @param query
   * @param page
   * @param maxresult
   * @param response
   * @return JSON Maps of response with researcher list
   * @throws IOException
   * @throws InterruptedException
   * @throws ExecutionException
   * @throws OAuthProblemException
   * @throws OAuthSystemException
   * @throws org.apache.http.ParseException
   */
  @SuppressWarnings("unchecked")
  @Transactional
  @RequestMapping(value = "/search", method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> getAuthorList(
      @RequestParam(value = "query", required = false) String query,
      @RequestParam(value = "queryType", required = false) String queryType,
      @RequestParam(value = "page", required = false) Integer startPage,
      @RequestParam(value = "maxresult", required = false) Integer maxresult,
      @RequestParam(value = "source", required = false) String source,
      @RequestParam(value = "addedAuthor", required = false) String addedAuthor,
      @RequestParam(value = "fulltextSearch", required = false) String fulltextSearch,
      @RequestParam(value = "persist", required = false) String persist,
      HttpServletRequest request,
      HttpServletResponse response)
      throws IOException, InterruptedException, ExecutionException, org.apache.http.ParseException,
          OAuthSystemException, OAuthProblemException {

    /* == Set Default Values== */
    if (query == null) query = "";
    if (queryType == null) queryType = "name";
    if (startPage == null) startPage = 0;
    if (maxresult == null) maxresult = 50;
    if (source == null) source = "internal";
    if (addedAuthor == null) addedAuthor = "no";
    if (fulltextSearch == null) fulltextSearch = "no";
    if (persist == null) persist = "no";

    // create JSON mapper for response
    Map<String, Object> responseMap = new LinkedHashMap<String, Object>();
    boolean persistResult = false;

    responseMap.put("query", query);
    if (!queryType.equals("name")) responseMap.put("queryType", queryType);
    responseMap.put("page", startPage);
    responseMap.put("maxresult", maxresult);
    responseMap.put("source", source);
    if (!fulltextSearch.equals("no")) responseMap.put("fulltextSearch", fulltextSearch);
    if (!persist.equals("no")) {
      responseMap.put("persist", persist);
      persistResult = true;
    }
    if (addedAuthor.equals("yes")) responseMap.put("addedAuthor", addedAuthor);

    Map<String, Object> authorsMap =
        researcherFeature
            .getResearcherSearch()
            .getResearcherMapByQuery(
                query,
                queryType,
                startPage,
                maxresult,
                source,
                addedAuthor,
                fulltextSearch,
                persistResult);

    // store in session
    if (source.equals("external") || source.equals("all")) {
      request.getSession().setAttribute("researchers", authorsMap.get("authors"));

      // recheck if session really has been updated
      // (there is a bug in spring session, which makes session is
      // not updated sometimes) - a little workaround
      boolean isSessionUpdated = false;
      while (!isSessionUpdated) {
        Object authors = request.getSession().getAttribute("researchers");
        if (authors.equals(authorsMap.get("authors"))) isSessionUpdated = true;
        else request.getSession().setAttribute("researchers", authorsMap.get("authors"));
      }

      log.info("\nRESEARCHER SESSION SEARCH");
      @SuppressWarnings("unchecked")
      List<Author> sessionAuthors = (List<Author>) request.getSession().getAttribute("researchers");
      // get author from session -> just for debug
      if (sessionAuthors != null && !sessionAuthors.isEmpty()) {
        for (Author sessionAuthor : sessionAuthors) {
          for (AuthorSource as : sessionAuthor.getAuthorSources()) {
            log.info(
                sessionAuthor.getId()
                    + "-"
                    + sessionAuthor.getName()
                    + " - "
                    + as.getSourceType()
                    + " -> "
                    + as.getSourceUrl());
          }
        }
      }
    }

    if (authorsMap != null && (Integer) authorsMap.get("totalCount") > 0) {
      responseMap.put("totalCount", (Integer) authorsMap.get("totalCount"));
      return researcherFeature
          .getResearcherSearch()
          .printJsonOutput(responseMap, (List<Author>) authorsMap.get("authors"));
    } else {
      responseMap.put("totalCount", 0);
      responseMap.put("count", 0);
      return responseMap;
    }
  }