public JSONObject loadTestAndAllQuestions(JSONRPC2Request req, HttpServletRequest request)
      throws Exception {
    JSONObject jsonResult = new JSONObject();
    JSONArray jsonAllQuestions = new JSONArray();
    JSONObject jsonTest = new JSONObject();

    // retrievers
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> tParams = np.getMap("test");
    NamedParamsRetriever testNp = new NamedParamsRetriever(tParams);
    int tid = testNp.getInt("id");

    // get data from DB
    MySQLDAO dao = new MySQLDAO();
    Test t = dao.loadTest(tid);
    QuestionsList allQuestions = QuestionController.loadAllQuestions();

    // set result
    jsonTest = t.toJSONObject();
    jsonAllQuestions = allQuestions.toJSONArray();
    jsonResult.put("test", jsonTest);
    jsonResult.put("questions", jsonAllQuestions);

    return jsonResult;
  }
  public JSONObject checkTest(JSONRPC2Request req, HttpServletRequest request)
      throws JSONRPC2Error, Exception {
    JSONObject jsonResult = new JSONObject();
    JSONArray jsonWrongQuestions = new JSONArray();
    QuestionsList wrongQuestions = new QuestionsList();

    // retrievers
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> tParams = np.getMap("test");
    NamedParamsRetriever testNp = new NamedParamsRetriever(tParams);

    // get guessed questions values
    QuestionsList guessQuestions = new QuestionsList();
    List<Object> questions = testNp.getList("questions");
    for (Object q : questions) {
      // set new retriever for each question
      NamedParamsRetriever questNp = new NamedParamsRetriever((Map<String, Object>) q);
      // retrieve values
      String answer = questNp.getString("answer");
      String body = questNp.getString("body");
      int id = questNp.getInt("id");
      // create question with the values and add it to the guessed questions
      Question quest = new Question();
      quest.setId(id);
      quest.setBody(body);
      quest.setAnswer(answer);
      guessQuestions.add(quest);
    }

    // get test
    int tid = testNp.getInt("id");
    MySQLDAO dao = new MySQLDAO();
    Test t = dao.loadTest(tid);

    // get true questions
    MySQLDAO questionsDao = new MySQLDAO();
    QuestionsList trueQuestions = questionsDao.loadQuestionsByTest(tid);

    // cycle through questions and find these with same id
    for (Question tq : trueQuestions) {
      for (Question gq : guessQuestions) {
        if (tq.getId() == gq.getId()) {
          // if answers are different, than there is mistake
          System.out.println("id match!");
          if (!tq.getAnswer().equals(gq.getAnswer())) {
            System.out.println("Wrong question!");
            wrongQuestions.add(gq);
          }
        }
      }
    }

    jsonWrongQuestions = wrongQuestions.toJSONArray();
    jsonResult.put("test", t);
    jsonResult.put("wrongQuestions", jsonWrongQuestions);

    return jsonResult;
  }
  public JSONArray loadQuestionsByTest(JSONRPC2Request req, HttpServletRequest request)
      throws Exception, JSONRPC2Error {
    JSONArray jsonTestQuestions = new JSONArray();

    // get testId
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> tParams = np.getMap("test");
    NamedParamsRetriever testNp = new NamedParamsRetriever(tParams);
    int testId = testNp.getInt("id");

    // get test questions
    MySQLDAO dao = new MySQLDAO();
    QuestionsList qByTest = dao.loadQuestionsByTest(testId);

    // set result
    jsonTestQuestions = qByTest.toJSONArray();

    return jsonTestQuestions;
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    // declare rpc objects
    JSONRPC2Request req = null;
    JSONRPC2Response resp = null;

    try {
      /*
       * Had to change this, since after switching to the JS json-rpc lib
       * the request has no params ("json=" in our case) and the whole payload is the request data itself
       */
      StringBuffer jb = new StringBuffer();
      String line = null;
      // Getting the request reader in order to load the whole request date into a single string
      BufferedReader reader = request.getReader();
      while ((line = reader.readLine()) != null) jb.append(line);

      // populate rpc objects
      req = JSONRPC2Request.parse(jb.toString());
      resp = new JSONRPC2Response(req.getID());

      // define jsonResult
      JSONObject jsonResult = new JSONObject();

      // retrieve request information
      String method = req.getMethod();
      System.out.println(req.getMethod());

      // find the requested method
      if (method.equals("login")) {
        // login user
        jsonResult = loginUser(request, response, req);
        System.out.println("json result: " + jsonResult.toString());
        // resp.setResult(jsonResult.toJSONString());
        resp.setResult(jsonResult);
      } else if (method.equals("register")) {
        // register user
        // TODO duplicates!
        jsonResult = registerUser(req, resp);
        System.out.println("json result to string: " + jsonResult.toString());
        resp.setResult(jsonResult);
      } else if (isLoggedIn(request)) {
        if (method.equals("logout")) {
          // logout user
          jsonResult = logoutUser(request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("loadAllQuestions")) {
          // return all questions as QuestionsList
          QuestionsList questions = QuestionController.loadAllQuestions();
          if (questions != null) {
            JSONObject jsonQuestions = new JSONObject();
            JSONArray allQuestions = questions.toJSONArray();
            jsonQuestions.put("allQuestions", allQuestions);
            System.out.println("jsonQuestions: " + jsonQuestions.toString());
            resp.setResult(jsonQuestions);
          } else {
            resp.setError(JSONRPC2Error.INTERNAL_ERROR);
          }
        } else if (method.equals("loadQuestion")) {
          jsonResult = loadQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("addQuestion")) {
          // add question
          jsonResult = addQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("deleteQuestion")) {
          // delete question
          jsonResult = deleteQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("udpateQuestion")) {
          // update question
          jsonResult = updateQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("loadTestAndAllQuestions")) {
          // return the test and all questions from the database
          jsonResult = loadTestAndAllQuestions(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("loadAllTests")) {
          // return all questions as QuestionsList
          TestsList tests = TestController.loadAllTests();
          if (tests != null) {
            JSONObject jsonTests = new JSONObject();
            JSONArray allTests = tests.toJSONArray();
            jsonTests.put("allTests", allTests);
            System.out.println("jsonTests: " + jsonTests.toString());
            resp.setResult(jsonTests);

          } else {
            resp.setError(JSONRPC2Error.INTERNAL_ERROR);
          }
        } else if (method.equals("loadQuestionsByTest")) {
          JSONArray testQuestions = new JSONArray();
          testQuestions = loadQuestionsByTest(req, request);
          jsonResult.put("testQuestions", testQuestions);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("addTest")) {
          // add question
          jsonResult = addTest(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("deleteTest")) {
          // delete question
          jsonResult = deleteTest(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("updateTest")) {
          // update question
          jsonResult = updateTest(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("addTestQuestion")) {
          // bind question to test
          jsonResult = addTestQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("removeTestQuestion")) {
          // delete question from test
          jsonResult = removeTestQuestion(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        } else if (method.equals("checkTest")) {
          // check if test is asnwered correctly
          jsonResult = checkTest(req, request);
          System.out.println("json result: " + jsonResult.toString());
          resp.setResult(jsonResult);
        }
        /*
        JSONObject json = new JSONObject();
        json.put("hi", "opa");
        resp.setResult(json.toJSONString());
        */
      }
    } catch (Throwable t) {
      JSONRPC2Error error = new JSONRPC2Error(1, t.getMessage());

      resp.setError(error);
    } finally {
      // dispatch result
      response.getWriter().print(resp.toJSONObject().toJSONString());
      System.out.println("final result: " + resp.toJSONObject().toJSONString());
    }
  }