{"action":"created","comment":{"url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/comments/56824517","id":56824517,"diff_hunk":"@@ -0,0 +1,195 @@\n+package teammates.ui.controller;\n+\n+import teammates.common.datatransfer.FeedbackParticipantType;\n+import teammates.common.datatransfer.FeedbackQuestionAttributes;\n+import teammates.common.datatransfer.FeedbackSessionAttributes;\n+import teammates.common.datatransfer.FeedbackSessionQuestionsBundle;\n+import teammates.common.datatransfer.InstructorAttributes;\n+import teammates.common.exception.EntityDoesNotExistException;\n+import teammates.common.exception.InvalidParametersException;\n+import teammates.common.exception.UnauthorizedAccessException;\n+import teammates.common.util.Assumption;\n+import teammates.common.util.Const;\n+import teammates.common.util.HttpRequestHelper;\n+import teammates.common.util.StatusMessage;\n+import teammates.common.util.Const.StatusMessageColor;\n+import teammates.logic.api.GateKeeper;\n+\n+/**\n+ * The {@code InstructorEditInstructorFeedbackSaveAction} class handles incoming requests to \n+ * save the data after moderating the instructor.\n+ */\n+public class InstructorEditInstructorFeedbackSaveAction extends FeedbackSubmissionEditSaveAction {\n+    InstructorAttributes moderatedInstructor;\n+    \n+    /**\n+     * Verifies if the user is allowed to carry out the action.\n+     */\n+    @Override\n+    protected void verifyAccesibleForSpecificUser() {\n+        InstructorAttributes instructor = logic.getInstructorForGoogleId(courseId, account.googleId);\n+        FeedbackSessionAttributes session = logic.getFeedbackSession(feedbackSessionName, courseId);\n+\n+        new GateKeeper().verifyAccessible(instructor,\n+                session,\n+                false, \n+                Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS);\n+    }\n+    \n+    /**\n+     * Retrieves any additional parameters from request and set them accordingly.\n+     */\n+    @Override\n+    protected void setAdditionalParameters() {\n+        String moderatedInstructorEmail = getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_INSTRUCTOR);\n+        Assumption.assertPostParamNotNull(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_INSTRUCTOR, moderatedInstructorEmail);\n+\n+        moderatedInstructor = logic.getInstructorForEmail(courseId, moderatedInstructorEmail);\n+    }\n+    \n+    /**\n+     * Checks if the instructor only submitted responses that he/she should be submitting when moderating.\n+     */\n+    @Override\n+    protected void checkAdditionalConstraints() {\n+        // check the instructor did not submit responses to questions that he/she should not be able when moderating\n+        \n+        InstructorAttributes instructor = logic.getInstructorForGoogleId(courseId, account.googleId);\n+        int numOfQuestionsToGet = data.bundle.questionResponseBundle.size();\n+\n+        for (int questionIndx = 1; questionIndx <= numOfQuestionsToGet; questionIndx++) {\n+            String paramMapKey = Const.ParamsNames.FEEDBACK_QUESTION_ID + \"-\" + questionIndx;\n+            String questionId = HttpRequestHelper.getValueFromParamMap(requestParameters, paramMapKey);\n+            \n+            if (questionId == null) {\n+                // we do not throw an error if the question was not present on the page for instructors to edit\n+                continue;\n+            }\n+            \n+            FeedbackQuestionAttributes questionAttributes = data.bundle.getQuestionAttributes(questionId);\n+            \n+            if (questionAttributes == null) {\n+                statusToUser.add(new StatusMessage(\"The feedback session or questions may have changed while you were submitting. \"\n+                                                + \"Please check your responses to make sure they are saved correctly.\", StatusMessageColor.WARNING));\n+                isError = true;\n+                log.warning(\"Question not found. (deleted or invalid id passed?) id: \"+ questionId + \" index: \" + questionIndx);\n+                continue;\n+            }\n+            \n+            checkSessionQuestionAccessPermission(instructor, questionAttributes);\n+        }\n+    }\n+    \n+    /**\n+     * Checks the instructor's access to a particular question in the feedback session.\n+     * @param instructor the instructor to be checked\n+     * @param questionAttributes the question to be checked against\n+     */\n+    private void checkSessionQuestionAccessPermission(InstructorAttributes instructor, FeedbackQuestionAttributes questionAttributes) {\n+        boolean isGiverVisibleToInstructors = questionAttributes.showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS);\n+        boolean isRecipientVisibleToInstructors = questionAttributes.showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS);\n+        boolean isResponseVisibleToInstructors = questionAttributes.showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS);\n+        \n+        if (!isResponseVisibleToInstructors || !isGiverVisibleToInstructors || !isRecipientVisibleToInstructors) {\n+            isError = true;\n+            throw new UnauthorizedAccessException(\n+                    \"Feedback session [\" + feedbackSessionName + \n+                    \"] question [\" + questionAttributes.getId() + \"] is not accessible to instructor [\"+ instructor.email + \"]\");\n+        }\n+    }\n+\n+    @Override\n+    protected void appendRespondant() {\n+        try {\n+            logic.addInstructorRespondant(getUserEmailForCourse(), feedbackSessionName, courseId);\n+        } catch (InvalidParametersException | EntityDoesNotExistException e) {\n+            log.severe(\"Fail to append instructor respondant\");\n+        }\n+    }\n+    \n+    @Override\n+    protected void removeRespondant() {\n+        try {\n+            logic.deleteInstructorRespondant(getUserEmailForCourse(), feedbackSessionName, courseId);\n+        } catch (InvalidParametersException | EntityDoesNotExistException e) {\n+            log.severe(\"Fail to remove instructor respondant\");\n+        }\n+    }\n+\n+    /**\n+     * Retrieves the email of the user for the course.\n+     * @return the email of the user\n+     */\n+    @Override\n+    protected String getUserEmailForCourse() {\n+        return moderatedInstructor.email;\n+    }\n+    \n+    /**\n+     * Retrieves the user's team.\n+     * @return the name of the user's team\n+     */\n+    @Override\n+    protected String getUserTeamForCourse() {\n+        return Const.USER_TEAM_FOR_INSTRUCTOR;\n+    }\n+    \n+    /**\n+     * Retrieves the user's section for the course.\n+     * @return the name of the user's section\n+     */\n+    @Override\n+    protected String getUserSectionForCourse() {\n+        return Const.DEFAULT_SECTION;\n+    }\n+\n+    /**\n+     * Gets data bundle for the course specified.\n+     * @param userEmailForCourse the email of the user\n+     * @return FeedbackSessionQuestionsBundle object\n+     */\n+    @Override\n+    protected FeedbackSessionQuestionsBundle getDataBundle(String userEmailForCourse)\n+            throws EntityDoesNotExistException {\n+        return logic.getFeedbackSessionQuestionsBundleForInstructor(\n+                feedbackSessionName, courseId, userEmailForCourse);\n+    }\n+\n+    /**\n+     * Sets the message to log.\n+     */\n+    @Override\n+    protected void setStatusToAdmin() {\n+        statusToAdmin = \"Instructor moderated instructor session<br>\" +\n+                        \"Instructor: \" + account.email + \"<br>\" + \n+                        \"Moderated Instructor: \" + moderatedInstructor + \"<br>\" +\n+                        \"Session Name: \" + feedbackSessionName + \"<br>\" +\n+                        \"Course ID: \" + courseId;\n+    }\n+\n+    /**\n+     * Checks if the session is still open. However, since the instructor is moderating the session,\n+     * they can moderate it anytime. Therefore, it will be true forever.\n+     * @return true\n+     */\n+    @Override\n+    protected boolean isSessionOpenForSpecificUser(FeedbackSessionAttributes session) {\n+        // Feedback session closing date does not matter. Instructors can moderate at any time\n+        return true; \n+    }\n+\n+    /**\n+     * Creates the page to redirect.\n+     * @return RedirectResult object\n+     */\n+    @Override\n+    protected RedirectResult createSpecificRedirectResult() {\n+        RedirectResult result = createRedirectResult(Const.ActionURIs.INSTRUCTOR_EDIT_INSTRUCTOR_FEEDBACK_PAGE);\n+        \n+        result.responseParams.put(Const.ParamsNames.COURSE_ID, moderatedInstructor.courseId);\n+        result.responseParams.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);\n+        result.responseParams.put(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_STUDENT, moderatedInstructor.email);","path":"src/main/java/teammates/ui/controller/InstructorEditInstructorFeedbackSaveAction.java","position":191,"original_position":191,"commit_id":"749df4096f7ba1cc247c03f50bdb3c2bfd12fb2e","original_commit_id":"749df4096f7ba1cc247c03f50bdb3c2bfd12fb2e","user":{"login":"LowWeiLin","id":3910365,"avatar_url":"https://avatars.githubusercontent.com/u/3910365?v=3","gravatar_id":"","url":"https://api.github.com/users/LowWeiLin","html_url":"https://github.com/LowWeiLin","followers_url":"https://api.github.com/users/LowWeiLin/followers","following_url":"https://api.github.com/users/LowWeiLin/following{/other_user}","gists_url":"https://api.github.com/users/LowWeiLin/gists{/gist_id}","starred_url":"https://api.github.com/users/LowWeiLin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LowWeiLin/subscriptions","organizations_url":"https://api.github.com/users/LowWeiLin/orgs","repos_url":"https://api.github.com/users/LowWeiLin/repos","events_url":"https://api.github.com/users/LowWeiLin/events{/privacy}","received_events_url":"https://api.github.com/users/LowWeiLin/received_events","type":"User","site_admin":false},"body":"Creating a new constant FEEDBACK_SESSION_MODERATED_INSTRUCTOR may be more appropriate.","created_at":"2016-03-21T13:53:28Z","updated_at":"2016-03-21T13:53:28Z","html_url":"https://github.com/TEAMMATES/teammates/pull/5021#discussion_r56824517","pull_request_url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021","_links":{"self":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/comments/56824517"},"html":{"href":"https://github.com/TEAMMATES/teammates/pull/5021#discussion_r56824517"},"pull_request":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021"}}},"pull_request":{"url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021","id":63061181,"html_url":"https://github.com/TEAMMATES/teammates/pull/5021","diff_url":"https://github.com/TEAMMATES/teammates/pull/5021.diff","patch_url":"https://github.com/TEAMMATES/teammates/pull/5021.patch","issue_url":"https://api.github.com/repos/TEAMMATES/teammates/issues/5021","number":5021,"state":"open","locked":false,"title":"Allow moderating values on behalf of instructors #4274","user":{"login":"kennho","id":10682388,"avatar_url":"https://avatars.githubusercontent.com/u/10682388?v=3","gravatar_id":"","url":"https://api.github.com/users/kennho","html_url":"https://github.com/kennho","followers_url":"https://api.github.com/users/kennho/followers","following_url":"https://api.github.com/users/kennho/following{/other_user}","gists_url":"https://api.github.com/users/kennho/gists{/gist_id}","starred_url":"https://api.github.com/users/kennho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kennho/subscriptions","organizations_url":"https://api.github.com/users/kennho/orgs","repos_url":"https://api.github.com/users/kennho/repos","events_url":"https://api.github.com/users/kennho/events{/privacy}","received_events_url":"https://api.github.com/users/kennho/received_events","type":"User","site_admin":false},"body":"Fixes #4274 ","created_at":"2016-03-16T13:08:00Z","updated_at":"2016-03-21T13:53:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7fc4cc66d3dd2d070955dd05477561b0b806724c","assignee":{"login":"LowWeiLin","id":3910365,"avatar_url":"https://avatars.githubusercontent.com/u/3910365?v=3","gravatar_id":"","url":"https://api.github.com/users/LowWeiLin","html_url":"https://github.com/LowWeiLin","followers_url":"https://api.github.com/users/LowWeiLin/followers","following_url":"https://api.github.com/users/LowWeiLin/following{/other_user}","gists_url":"https://api.github.com/users/LowWeiLin/gists{/gist_id}","starred_url":"https://api.github.com/users/LowWeiLin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LowWeiLin/subscriptions","organizations_url":"https://api.github.com/users/LowWeiLin/orgs","repos_url":"https://api.github.com/users/LowWeiLin/repos","events_url":"https://api.github.com/users/LowWeiLin/events{/privacy}","received_events_url":"https://api.github.com/users/LowWeiLin/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/TEAMMATES/teammates/milestones/200","html_url":"https://github.com/TEAMMATES/teammates/milestones/V5.73","labels_url":"https://api.github.com/repos/TEAMMATES/teammates/milestones/200/labels","id":1630935,"number":200,"title":"V5.73","description":"","creator":{"login":"thyageshm","id":5160137,"avatar_url":"https://avatars.githubusercontent.com/u/5160137?v=3","gravatar_id":"","url":"https://api.github.com/users/thyageshm","html_url":"https://github.com/thyageshm","followers_url":"https://api.github.com/users/thyageshm/followers","following_url":"https://api.github.com/users/thyageshm/following{/other_user}","gists_url":"https://api.github.com/users/thyageshm/gists{/gist_id}","starred_url":"https://api.github.com/users/thyageshm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thyageshm/subscriptions","organizations_url":"https://api.github.com/users/thyageshm/orgs","repos_url":"https://api.github.com/users/thyageshm/repos","events_url":"https://api.github.com/users/thyageshm/events{/privacy}","received_events_url":"https://api.github.com/users/thyageshm/received_events","type":"User","site_admin":false},"open_issues":35,"closed_issues":44,"state":"open","created_at":"2016-03-08T16:12:11Z","updated_at":"2016-03-21T13:36:35Z","due_on":"2016-03-21T16:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021/commits","review_comments_url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021/comments","review_comment_url":"https://api.github.com/repos/TEAMMATES/teammates/pulls/comments{/number}","comments_url":"https://api.github.com/repos/TEAMMATES/teammates/issues/5021/comments","statuses_url":"https://api.github.com/repos/TEAMMATES/teammates/statuses/749df4096f7ba1cc247c03f50bdb3c2bfd12fb2e","head":{"label":"nus-fboa2016-TM:4274-allow-instructors-to-moderate-instructors","ref":"4274-allow-instructors-to-moderate-instructors","sha":"749df4096f7ba1cc247c03f50bdb3c2bfd12fb2e","user":{"login":"nus-fboa2016-TM","id":16642227,"avatar_url":"https://avatars.githubusercontent.com/u/16642227?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-fboa2016-TM","html_url":"https://github.com/nus-fboa2016-TM","followers_url":"https://api.github.com/users/nus-fboa2016-TM/followers","following_url":"https://api.github.com/users/nus-fboa2016-TM/following{/other_user}","gists_url":"https://api.github.com/users/nus-fboa2016-TM/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-fboa2016-TM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-fboa2016-TM/subscriptions","organizations_url":"https://api.github.com/users/nus-fboa2016-TM/orgs","repos_url":"https://api.github.com/users/nus-fboa2016-TM/repos","events_url":"https://api.github.com/users/nus-fboa2016-TM/events{/privacy}","received_events_url":"https://api.github.com/users/nus-fboa2016-TM/received_events","type":"Organization","site_admin":false},"repo":{"id":49403164,"name":"repo","full_name":"nus-fboa2016-TM/repo","owner":{"login":"nus-fboa2016-TM","id":16642227,"avatar_url":"https://avatars.githubusercontent.com/u/16642227?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-fboa2016-TM","html_url":"https://github.com/nus-fboa2016-TM","followers_url":"https://api.github.com/users/nus-fboa2016-TM/followers","following_url":"https://api.github.com/users/nus-fboa2016-TM/following{/other_user}","gists_url":"https://api.github.com/users/nus-fboa2016-TM/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-fboa2016-TM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-fboa2016-TM/subscriptions","organizations_url":"https://api.github.com/users/nus-fboa2016-TM/orgs","repos_url":"https://api.github.com/users/nus-fboa2016-TM/repos","events_url":"https://api.github.com/users/nus-fboa2016-TM/events{/privacy}","received_events_url":"https://api.github.com/users/nus-fboa2016-TM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nus-fboa2016-TM/repo","description":"This is the project website for the TEAMMATES feedback management tool for education","fork":true,"url":"https://api.github.com/repos/nus-fboa2016-TM/repo","forks_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/forks","keys_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/teams","hooks_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/hooks","issue_events_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/issues/events{/number}","events_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/events","assignees_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/assignees{/user}","branches_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/branches{/branch}","tags_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/tags","blobs_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/statuses/{sha}","languages_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/languages","stargazers_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/stargazers","contributors_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/contributors","subscribers_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/subscribers","subscription_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/subscription","commits_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/contents/{+path}","compare_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/merges","archive_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/downloads","issues_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/issues{/number}","pulls_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/pulls{/number}","milestones_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/milestones{/number}","notifications_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/labels{/name}","releases_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/releases{/id}","deployments_url":"https://api.github.com/repos/nus-fboa2016-TM/repo/deployments","created_at":"2016-01-11T05:00:54Z","updated_at":"2016-01-11T05:01:00Z","pushed_at":"2016-03-21T13:37:01Z","git_url":"git://github.com/nus-fboa2016-TM/repo.git","ssh_url":"git@github.com:nus-fboa2016-TM/repo.git","clone_url":"https://github.com/nus-fboa2016-TM/repo.git","svn_url":"https://github.com/nus-fboa2016-TM/repo","homepage":"http://teammatesv4.appspot.com/","size":144780,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"TEAMMATES:master","ref":"master","sha":"77de9aebe109f36f2305efc6bd228e04b16089af","user":{"login":"TEAMMATES","id":7374810,"avatar_url":"https://avatars.githubusercontent.com/u/7374810?v=3","gravatar_id":"","url":"https://api.github.com/users/TEAMMATES","html_url":"https://github.com/TEAMMATES","followers_url":"https://api.github.com/users/TEAMMATES/followers","following_url":"https://api.github.com/users/TEAMMATES/following{/other_user}","gists_url":"https://api.github.com/users/TEAMMATES/gists{/gist_id}","starred_url":"https://api.github.com/users/TEAMMATES/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TEAMMATES/subscriptions","organizations_url":"https://api.github.com/users/TEAMMATES/orgs","repos_url":"https://api.github.com/users/TEAMMATES/repos","events_url":"https://api.github.com/users/TEAMMATES/events{/privacy}","received_events_url":"https://api.github.com/users/TEAMMATES/received_events","type":"Organization","site_admin":false},"repo":{"id":19369035,"name":"teammates","full_name":"TEAMMATES/teammates","owner":{"login":"TEAMMATES","id":7374810,"avatar_url":"https://avatars.githubusercontent.com/u/7374810?v=3","gravatar_id":"","url":"https://api.github.com/users/TEAMMATES","html_url":"https://github.com/TEAMMATES","followers_url":"https://api.github.com/users/TEAMMATES/followers","following_url":"https://api.github.com/users/TEAMMATES/following{/other_user}","gists_url":"https://api.github.com/users/TEAMMATES/gists{/gist_id}","starred_url":"https://api.github.com/users/TEAMMATES/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TEAMMATES/subscriptions","organizations_url":"https://api.github.com/users/TEAMMATES/orgs","repos_url":"https://api.github.com/users/TEAMMATES/repos","events_url":"https://api.github.com/users/TEAMMATES/events{/privacy}","received_events_url":"https://api.github.com/users/TEAMMATES/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TEAMMATES/teammates","description":"This is the project website for the TEAMMATES feedback management tool for education","fork":false,"url":"https://api.github.com/repos/TEAMMATES/teammates","forks_url":"https://api.github.com/repos/TEAMMATES/teammates/forks","keys_url":"https://api.github.com/repos/TEAMMATES/teammates/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TEAMMATES/teammates/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TEAMMATES/teammates/teams","hooks_url":"https://api.github.com/repos/TEAMMATES/teammates/hooks","issue_events_url":"https://api.github.com/repos/TEAMMATES/teammates/issues/events{/number}","events_url":"https://api.github.com/repos/TEAMMATES/teammates/events","assignees_url":"https://api.github.com/repos/TEAMMATES/teammates/assignees{/user}","branches_url":"https://api.github.com/repos/TEAMMATES/teammates/branches{/branch}","tags_url":"https://api.github.com/repos/TEAMMATES/teammates/tags","blobs_url":"https://api.github.com/repos/TEAMMATES/teammates/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TEAMMATES/teammates/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TEAMMATES/teammates/git/refs{/sha}","trees_url":"https://api.github.com/repos/TEAMMATES/teammates/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TEAMMATES/teammates/statuses/{sha}","languages_url":"https://api.github.com/repos/TEAMMATES/teammates/languages","stargazers_url":"https://api.github.com/repos/TEAMMATES/teammates/stargazers","contributors_url":"https://api.github.com/repos/TEAMMATES/teammates/contributors","subscribers_url":"https://api.github.com/repos/TEAMMATES/teammates/subscribers","subscription_url":"https://api.github.com/repos/TEAMMATES/teammates/subscription","commits_url":"https://api.github.com/repos/TEAMMATES/teammates/commits{/sha}","git_commits_url":"https://api.github.com/repos/TEAMMATES/teammates/git/commits{/sha}","comments_url":"https://api.github.com/repos/TEAMMATES/teammates/comments{/number}","issue_comment_url":"https://api.github.com/repos/TEAMMATES/teammates/issues/comments{/number}","contents_url":"https://api.github.com/repos/TEAMMATES/teammates/contents/{+path}","compare_url":"https://api.github.com/repos/TEAMMATES/teammates/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TEAMMATES/teammates/merges","archive_url":"https://api.github.com/repos/TEAMMATES/teammates/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TEAMMATES/teammates/downloads","issues_url":"https://api.github.com/repos/TEAMMATES/teammates/issues{/number}","pulls_url":"https://api.github.com/repos/TEAMMATES/teammates/pulls{/number}","milestones_url":"https://api.github.com/repos/TEAMMATES/teammates/milestones{/number}","notifications_url":"https://api.github.com/repos/TEAMMATES/teammates/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TEAMMATES/teammates/labels{/name}","releases_url":"https://api.github.com/repos/TEAMMATES/teammates/releases{/id}","deployments_url":"https://api.github.com/repos/TEAMMATES/teammates/deployments","created_at":"2014-05-02T07:43:00Z","updated_at":"2016-03-20T17:50:29Z","pushed_at":"2016-03-21T13:36:33Z","git_url":"git://github.com/TEAMMATES/teammates.git","ssh_url":"git@github.com:TEAMMATES/teammates.git","clone_url":"https://github.com/TEAMMATES/teammates.git","svn_url":"https://github.com/TEAMMATES/teammates","homepage":"http://teammatesv4.appspot.com/","size":148492,"stargazers_count":73,"watchers_count":73,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":214,"mirror_url":null,"open_issues_count":503,"forks":214,"open_issues":503,"watchers":73,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021"},"html":{"href":"https://github.com/TEAMMATES/teammates/pull/5021"},"issue":{"href":"https://api.github.com/repos/TEAMMATES/teammates/issues/5021"},"comments":{"href":"https://api.github.com/repos/TEAMMATES/teammates/issues/5021/comments"},"review_comments":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021/comments"},"review_comment":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/TEAMMATES/teammates/pulls/5021/commits"},"statuses":{"href":"https://api.github.com/repos/TEAMMATES/teammates/statuses/749df4096f7ba1cc247c03f50bdb3c2bfd12fb2e"}}}}