public JSONObject updateQuestion(JSONRPC2Request req, HttpServletRequest request)
      throws JSONRPC2Error, Exception {
    JSONObject jsonUpdateQuestion = new JSONObject();

    // get question
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> qParams = np.getMap("question");
    NamedParamsRetriever questionNp = new NamedParamsRetriever(qParams);
    int questionId = questionNp.getInt("id");
    String questionBody = questionNp.getString("body");
    String questionAnswer = questionNp.getString("answer");

    int qOwnerId = questionNp.getInt("ownerId");

    User u = getCurrentUser(request);

    // check if this is the owner of the question
    if (u.getId() == qOwnerId) {
      // update question in database
      Question qUpdated =
          QuestionController.updateQuestion(questionId, questionBody, questionAnswer);

      // return result
      jsonUpdateQuestion.put("question", qUpdated.toJSONObject());
      return jsonUpdateQuestion;
    } else {
      throw new Exception("no privileges");
    }
  }
  public JSONObject deleteQuestion(JSONRPC2Request req, HttpServletRequest request)
      throws JSONRPC2Error, Exception {
    // create json object for the result
    JSONObject jsonDeleteQuestion = new JSONObject();

    // get question id
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> qParams = np.getMap("question");
    NamedParamsRetriever questionNp = new NamedParamsRetriever(qParams);
    int questionId = questionNp.getInt("id");
    int qOwnwerId = questionNp.getInt("ownerId");

    User u = getCurrentUser(request);

    // check for user privilleges
    if (u.getId() == qOwnwerId) {
      // remove question from database

      QuestionController.deleteQuestion(questionId);

      // send result
      return jsonDeleteQuestion;
    } else {

      System.out.println("current user id: " + u.getId());
      System.out.println("question owner id: " + qOwnwerId);
      throw new Exception("no privileges");
    }
  }
  public JSONObject addQuestion(JSONRPC2Request req, HttpServletRequest request)
      throws JSONRPC2Error {
    // json object for the result
    JSONObject jsonAddQuestion = new JSONObject();

    // get question
    System.out.println(req.toString());
    Map<String, Object> params = req.getNamedParams();
    NamedParamsRetriever np = new NamedParamsRetriever(params);
    Map<String, Object> qParams = np.getMap("question");
    NamedParamsRetriever questionNp = new NamedParamsRetriever(qParams);
    String body = questionNp.getString("body");
    String answer = questionNp.getString("answer");

    // get user
    User u = getCurrentUser(request);
    int userID = (int) u.getId();
    System.out.println("current user id" + userID);

    // return ID of Question if added successfully
    Question q = QuestionController.addQuestion(body, answer, userID);

    jsonAddQuestion.put("question", q.toJSONObject());

    return jsonAddQuestion;
  }
  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;
  }
  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());
    }
  }