{"action":"created","comment":{"url":"https://api.github.com/repos/zanata/zanata-server/pulls/comments/37493400","id":37493400,"diff_hunk":"@@ -438,4 +489,451 @@ public void resetPageData() {\n     protected String getMessage(String key, Object... args) {\n         return msgs.format(key, args);\n     }\n+\n+    public Map<HPerson, Collection<ProjectRole>> getMemberRoles() {\n+        return getPersonRoles().asMap();\n+    }\n+\n+    private ListMultimap<HPerson, ProjectRole> getPersonRoles() {\n+        if (personRoles == null) {\n+            populatePersonRoles();\n+        }\n+        return personRoles;\n+    }\n+\n+    private void populatePersonRoles() {\n+        personRoles = ArrayListMultimap.create();\n+        for (HProjectMember membership : getProject().getMembers()) {\n+            personRoles.put(membership.getPerson(), membership.getRole());\n+        }\n+    }\n+\n+    private Map<HPerson, ListMultimap<HLocale, LocaleRole>> getPersonLocaleRoles() {\n+        if (personLocaleRoles == null) {\n+            populatePersonLocaleRoles();\n+        }\n+        return personLocaleRoles;\n+    }\n+\n+    private void populatePersonLocaleRoles() {\n+        personLocaleRoles = Maps.newHashMap();\n+\n+        for (HProjectLocaleMember membership :  getProject().getLocaleMembers()) {\n+            final HPerson person = membership.getPerson();\n+            if (!personLocaleRoles.containsKey(person)) {\n+                final ListMultimap<HLocale, LocaleRole> localeRoles = ArrayListMultimap.create();\n+                personLocaleRoles.put(person, localeRoles);\n+            }\n+            personLocaleRoles.get(person).put(membership.getLocale(),\n+                    membership.getRole());\n+        }\n+    }\n+\n+    public List<HPerson> getAllMembers() {\n+        return Lists.newArrayList(getMemberRoles().keySet());\n+    }\n+\n+    public boolean isTranslator(HPerson person) {\n+        ListMultimap<HLocale, LocaleRole>\n+            map = getPersonLocaleRoles().get(person);\n+        return map != null && !map.isEmpty();\n+\n+    }\n+    public boolean isMaintainer(HPerson person) {\n+        List<ProjectRole> roles = getPersonRoles().get(person);\n+        return (roles == null || roles.isEmpty()) ? false :\n+            roles.contains(ProjectRole.Maintainer) ||\n+                roles.contains(TranslationMaintainer);\n+    }\n+\n+    /**\n+     * Get display names for all of a person's project and locale roles\n+     */\n+    public List<String> allRoleDisplayNames(HPerson person) {\n+        List<String> displayNames = Lists.newArrayList();\n+        displayNames.addAll(projectRoleDisplayNames(person));\n+        displayNames.addAll(languageRoleDisplayNames(person));\n+        return displayNames;\n+    }\n+\n+    /**\n+     * Get a list of the display name for every project-related role for a\n+     * person.\n+     */\n+    public Collection<String> projectRoleDisplayNames(HPerson person) {\n+        final Collection<ProjectRole> rolesForPerson = getMemberRoles().get(person);\n+        Collection<ProjectRole> roles;\n+        if (rolesForPerson == null) {\n+            roles = Lists.newArrayList();\n+        } else {\n+            roles = Lists.newArrayList(rolesForPerson);\n+        }\n+\n+        // Maintainer role includes TranslationMaintainer privileges, so do not\n+        // show the lower-permission role.\n+        if (roles.contains(Maintainer)) {\n+            roles.remove(TranslationMaintainer);\n+        }\n+\n+        return Collections2.transform(roles,\n+                new Function<ProjectRole, String>() {\n+                    @Override\n+                    public String apply(ProjectRole role) {\n+                        return projectRoleDisplayName(role);\n+                    }\n+                });\n+    }\n+\n+    /**\n+     * Get a list of the display name for every language-related role for a\n+     * person.\n+     */\n+    public Collection<String> languageRoleDisplayNames(HPerson person) {\n+        final ListMultimap<HLocale, LocaleRole>\n+                localeRolesMultimap = getPersonLocaleRoles().get(person);\n+\n+        if (localeRolesMultimap == null) {\n+            return Collections.EMPTY_LIST;\n+        }\n+\n+        return Collections2.transform(localeRolesMultimap.asMap().entrySet(),\n+                TO_LOCALE_ROLES_DISPLAY_STRING);\n+    }\n+\n+    private final Function<Map.Entry<HLocale, Collection<LocaleRole>>, String>\n+            TO_LOCALE_ROLES_DISPLAY_STRING =\n+            new Function<Map.Entry<HLocale, Collection<LocaleRole>>, String>() {\n+                @Nullable @Override public String apply(\n+                        @Nullable\n+                        Map.Entry<HLocale, Collection<LocaleRole>> entry) {\n+                    final String localeName = entry.getKey().retrieveDisplayName();\n+\n+                    final Collection<String> roleNames =\n+                            Collections2.transform(entry.getValue(), TO_DISPLAY_NAME);\n+\n+                    return localeName + \" \" + Joiner.on(\", \").join(roleNames);\n+                }\n+            };\n+\n+    private final Function<LocaleRole, String> TO_DISPLAY_NAME =\n+            new Function<LocaleRole, String>() {\n+                @Nullable @Override\n+                public String apply(\n+                        @Nullable LocaleRole role) {\n+                    return localeRoleDisplayName(role);\n+                }\n+            };\n+\n+    public String projectRoleDisplayName(ProjectRole role) {\n+        switch (role) {\n+            case Maintainer:\n+                return msgs.get(\"jsf.Maintainer\");\n+            case TranslationMaintainer:\n+                return msgs.get(\"jsf.TranslationMaintainer\");\n+            default:\n+                return \"\";\n+        }\n+    }\n+\n+    public String localeRoleDisplayName(LocaleRole role) {\n+        switch (role) {\n+            case Translator:\n+                return msgs.get(\"jsf.Translator\");\n+            case Reviewer:\n+                return msgs.get(\"jsf.Reviewer\");\n+            case Coordinator:\n+                return msgs.get(\"jsf.Coordinator\");\n+            default:\n+                return \"\";\n+        }\n+    }\n+\n+    /**\n+     * Prepare the permission dialog to update permissions for the given person.\n+     *\n+     * @param person to show in permission dialog\n+     */\n+    public void setPersonForPermissionDialog(HPerson person) {\n+        List<ProjectRole> projectRoles = getPersonRoles().get(person);\n+        ListMultimap<HLocale, LocaleRole> localeRoles =\n+            getPersonLocaleRoles().get(person);\n+\n+        permissionDialogData =\n+            new PersonProjectMemberships(person, projectRoles, localeRoles);\n+\n+        List<HLocale> locales =\n+                localeServiceImpl.getSupportedLanguageByProject(getProject().getSlug());\n+\n+        permissionDialogData.ensureLocalesPresent(locales);\n+    }\n+\n+    /**\n+     * Indicate whether any of the permissions are selected in the person\n+     * permission dialog.\n+     *\n+     * @return false if no permissions are selected in the dialog, otherwise true\n+     */\n+    public boolean anyPermissionsSelected() {\n+        return permissionDialogData != null && permissionDialogData.hasAnyPermissions();\n+    }\n+\n+    /**\n+     * Update role membership for a project-specific role based on the current\n+     * checkbox value.\n+     *\n+     * @param role the role to assign or remove for the current person\n+     * @param checked the current checkbox value\n+     */\n+    public void bindProjectPermissionRole(String role, boolean checked) {\n+        if(StringUtils.equalsIgnoreCase(role, ProjectRole.TranslationMaintainer.name())) {\n+            permissionDialogData.setTranslationMaintainer(checked);\n+        } else if(StringUtils.equalsIgnoreCase(role, ProjectRole.Maintainer.name())) {\n+            permissionDialogData.setMaintainer(checked);\n+        }\n+    }\n+\n+    /**\n+     * Update role membership for a locale-specific role based on the current\n+     * checkbox value.\n+     *\n+     * @param localeRole represents both the locale and the role\n+     *                   format: {localeId}:{role}. e.g en-US:Reviewer\n+     * @param checked the current checkbox value\n+     */\n+    public void bindTranslationPermissionRole(String localeRole, boolean checked) {\n+        String[] localeRoleList = StringUtils.split(localeRole, ':');\n+        HLocale hLocale = localeServiceImpl.getByLocaleId(localeRoleList[0]);\n+        String role = localeRoleList[1];\n+\n+        for (PersonProjectMemberships.LocaleRoles localeRoles: permissionDialogData.getLocaleRoles()) {\n+            if(localeRoles.getLocale().equals(hLocale)) {\n+                if (StringUtils.equalsIgnoreCase(role, LocaleRole.Translator.name())) {\n+                    localeRoles.setTranslator(checked);\n+                } else if (StringUtils.equalsIgnoreCase(role, LocaleRole.Reviewer.name())) {\n+                    localeRoles.setReviewer(checked);\n+                } else if (StringUtils.equalsIgnoreCase(role, LocaleRole.Coordinator.name())) {\n+                    localeRoles.setCoordinator(checked);\n+                }\n+                return;\n+            }\n+        }\n+\n+        // No LocaleRoles for the given locale, so create a new one.\n+        List<LocaleRole> roleList = Lists.newArrayList(LocaleRole.valueOf(role));\n+        permissionDialogData.addLocaleRoles(hLocale, roleList);\n+    }\n+\n+    /**\n+     * Save the permissions selections from permissionDialogData to the database.\n+     */\n+    public void savePermissionDialogSelections() {\n+        PersonProjectMemberships data = permissionDialogData;\n+\n+        if (data == null) {\n+            log.error(\"Tried to save permissionDialogData but it is null\");\n+            return;\n+        }\n+\n+        project = projectDAO.findById(getProject().getId());\n+\n+        // Hibernate will have problems working with detached HPerson and HLocale\n+        // so they are all attached before any persistence is attempted.\n+        HPerson person = personDAO.findById(data.getPerson().getId());\n+        data.setPerson(person);\n+        for (PersonProjectMemberships.LocaleRoles roles : data.getLocaleRoles()) {\n+            roles.setLocale(localeServiceImpl\n+                    .getByLocaleId(roles.getLocale().getLocaleId()));\n+        }\n+\n+        final boolean canManageMembers = identity.hasPermission(project, \"manage-members\");\n+        final boolean canManageTransMembers = identity.hasPermission(project, \"manage-translation-members\");\n+        final boolean canChangeAnyMembers = canManageMembers || canManageTransMembers;\n+\n+        if (canManageMembers) {\n+            project.updateProjectPermissions(data);\n+        }\n+        if (canManageTransMembers) {\n+            project.updateLocalePermissions(data);\n+        }\n+\n+        if (canChangeAnyMembers) {\n+            projectDAO.makePersistent(project);\n+\n+            // Roles may have changed, so role lists are cleared so they will be regenerated\n+            personRoles = null;\n+            personLocaleRoles = null;\n+            project = null;\n+\n+            // Person may have no roles left and no longer belong in the list, so\n+            // ensure the list of people is refreshed.\n+            peopleFilterComparator.clearAllMembers();\n+            peopleFilterComparator.sortPeopleList();\n+        }\n+    }\n+\n+    private final class PeopleFilterComparator extends InMemoryListFilter<HPerson>\n+        implements Comparator<HPerson> {\n+\n+        private final ProjectRolePredicate projectRolePredicate =\n+                new ProjectRolePredicate();\n+\n+        private final ProjectLocalePredicate projectLocalePredicate =\n+                new ProjectLocalePredicate();\n+\n+        private SortingType sortingType;\n+\n+        @Getter\n+        @Setter\n+        private boolean showMembersInGroup;\n+\n+        private List<HPerson> allMembers;\n+\n+        public PeopleFilterComparator(SortingType sortingType) {\n+            this.sortingType = sortingType;\n+        }\n+\n+        @Override\n+        public int compare(HPerson o1, HPerson o2) {\n+            SortingType.SortOption selectedSortOption =\n+                sortingType.getSelectedSortOption();\n+\n+            if (!selectedSortOption.isAscending()) {\n+                HPerson temp = o1;\n+                o1 = o2;\n+                o2 = temp;\n+            }\n+\n+            if (selectedSortOption.equals(SortingType.SortOption.ROLE)) {\n+                setShowMembersInGroup(true);\n+            } else {\n+                setShowMembersInGroup(false);\n+                return o1.getName().toLowerCase()\n+                    .compareTo(o2.getName().toLowerCase());\n+            }\n+\n+            // FIXME aeng: this is either confusing, or it is a logic error.\n+            //       If the sort option is ROLE, this method will always return 0.\n+            //       Please add an explanation of why this is, or fix the logic.\n+            return 0;","path":"zanata-war/src/main/java/org/zanata/action/ProjectHomeAction.java","position":490,"original_position":490,"commit_id":"acbe4ae9e6dac26c25ed45e34cee06901063e8e4","original_commit_id":"acbe4ae9e6dac26c25ed45e34cee06901063e8e4","user":{"login":"davidmason","id":482026,"avatar_url":"https://avatars.githubusercontent.com/u/482026?v=3","gravatar_id":"","url":"https://api.github.com/users/davidmason","html_url":"https://github.com/davidmason","followers_url":"https://api.github.com/users/davidmason/followers","following_url":"https://api.github.com/users/davidmason/following{/other_user}","gists_url":"https://api.github.com/users/davidmason/gists{/gist_id}","starred_url":"https://api.github.com/users/davidmason/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidmason/subscriptions","organizations_url":"https://api.github.com/users/davidmason/orgs","repos_url":"https://api.github.com/users/davidmason/repos","events_url":"https://api.github.com/users/davidmason/events{/privacy}","received_events_url":"https://api.github.com/users/davidmason/received_events","type":"User","site_admin":false},"body":"Can anyone figure out why this should behave this way? I suspect that maybe people are purposely not sorted when they are grouped, but it does not say so anywhere (and I would expect the people to be sorted alphabetically within groups).","created_at":"2015-08-20T04:07:15Z","updated_at":"2015-08-20T04:07:15Z","html_url":"https://github.com/zanata/zanata-server/pull/933#discussion_r37493400","pull_request_url":"https://api.github.com/repos/zanata/zanata-server/pulls/933","_links":{"self":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/comments/37493400"},"html":{"href":"https://github.com/zanata/zanata-server/pull/933#discussion_r37493400"},"pull_request":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/933"}}},"pull_request":{"url":"https://api.github.com/repos/zanata/zanata-server/pulls/933","id":42766671,"html_url":"https://github.com/zanata/zanata-server/pull/933","diff_url":"https://github.com/zanata/zanata-server/pull/933.diff","patch_url":"https://github.com/zanata/zanata-server/pull/933.patch","issue_url":"https://api.github.com/repos/zanata/zanata-server/issues/933","number":933,"state":"open","locked":false,"title":"New Project Roles  ZNTA-524","user":{"login":"davidmason","id":482026,"avatar_url":"https://avatars.githubusercontent.com/u/482026?v=3","gravatar_id":"","url":"https://api.github.com/users/davidmason","html_url":"https://github.com/davidmason","followers_url":"https://api.github.com/users/davidmason/followers","following_url":"https://api.github.com/users/davidmason/following{/other_user}","gists_url":"https://api.github.com/users/davidmason/gists{/gist_id}","starred_url":"https://api.github.com/users/davidmason/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidmason/subscriptions","organizations_url":"https://api.github.com/users/davidmason/orgs","repos_url":"https://api.github.com/users/davidmason/repos","events_url":"https://api.github.com/users/davidmason/events{/privacy}","received_events_url":"https://api.github.com/users/davidmason/received_events","type":"User","site_admin":false},"body":"https://zanata.atlassian.net/browse/ZNTA-524","created_at":"2015-08-19T01:00:43Z","updated_at":"2015-08-20T04:07:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e1ba0419c520fa1b52fa1dc17522cb7058417d72","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/zanata/zanata-server/pulls/933/commits","review_comments_url":"https://api.github.com/repos/zanata/zanata-server/pulls/933/comments","review_comment_url":"https://api.github.com/repos/zanata/zanata-server/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zanata/zanata-server/issues/933/comments","statuses_url":"https://api.github.com/repos/zanata/zanata-server/statuses/acbe4ae9e6dac26c25ed45e34cee06901063e8e4","head":{"label":"zanata:project-roles-ui","ref":"project-roles-ui","sha":"acbe4ae9e6dac26c25ed45e34cee06901063e8e4","user":{"login":"zanata","id":637455,"avatar_url":"https://avatars.githubusercontent.com/u/637455?v=3","gravatar_id":"","url":"https://api.github.com/users/zanata","html_url":"https://github.com/zanata","followers_url":"https://api.github.com/users/zanata/followers","following_url":"https://api.github.com/users/zanata/following{/other_user}","gists_url":"https://api.github.com/users/zanata/gists{/gist_id}","starred_url":"https://api.github.com/users/zanata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zanata/subscriptions","organizations_url":"https://api.github.com/users/zanata/orgs","repos_url":"https://api.github.com/users/zanata/repos","events_url":"https://api.github.com/users/zanata/events{/privacy}","received_events_url":"https://api.github.com/users/zanata/received_events","type":"Organization","site_admin":false},"repo":{"id":1461609,"name":"zanata-server","full_name":"zanata/zanata-server","owner":{"login":"zanata","id":637455,"avatar_url":"https://avatars.githubusercontent.com/u/637455?v=3","gravatar_id":"","url":"https://api.github.com/users/zanata","html_url":"https://github.com/zanata","followers_url":"https://api.github.com/users/zanata/followers","following_url":"https://api.github.com/users/zanata/following{/other_user}","gists_url":"https://api.github.com/users/zanata/gists{/gist_id}","starred_url":"https://api.github.com/users/zanata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zanata/subscriptions","organizations_url":"https://api.github.com/users/zanata/orgs","repos_url":"https://api.github.com/users/zanata/repos","events_url":"https://api.github.com/users/zanata/events{/privacy}","received_events_url":"https://api.github.com/users/zanata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zanata/zanata-server","description":"Zanata is a web-based system for translators to translate documentation and software online using a web browser.","fork":false,"url":"https://api.github.com/repos/zanata/zanata-server","forks_url":"https://api.github.com/repos/zanata/zanata-server/forks","keys_url":"https://api.github.com/repos/zanata/zanata-server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zanata/zanata-server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zanata/zanata-server/teams","hooks_url":"https://api.github.com/repos/zanata/zanata-server/hooks","issue_events_url":"https://api.github.com/repos/zanata/zanata-server/issues/events{/number}","events_url":"https://api.github.com/repos/zanata/zanata-server/events","assignees_url":"https://api.github.com/repos/zanata/zanata-server/assignees{/user}","branches_url":"https://api.github.com/repos/zanata/zanata-server/branches{/branch}","tags_url":"https://api.github.com/repos/zanata/zanata-server/tags","blobs_url":"https://api.github.com/repos/zanata/zanata-server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zanata/zanata-server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zanata/zanata-server/git/refs{/sha}","trees_url":"https://api.github.com/repos/zanata/zanata-server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zanata/zanata-server/statuses/{sha}","languages_url":"https://api.github.com/repos/zanata/zanata-server/languages","stargazers_url":"https://api.github.com/repos/zanata/zanata-server/stargazers","contributors_url":"https://api.github.com/repos/zanata/zanata-server/contributors","subscribers_url":"https://api.github.com/repos/zanata/zanata-server/subscribers","subscription_url":"https://api.github.com/repos/zanata/zanata-server/subscription","commits_url":"https://api.github.com/repos/zanata/zanata-server/commits{/sha}","git_commits_url":"https://api.github.com/repos/zanata/zanata-server/git/commits{/sha}","comments_url":"https://api.github.com/repos/zanata/zanata-server/comments{/number}","issue_comment_url":"https://api.github.com/repos/zanata/zanata-server/issues/comments{/number}","contents_url":"https://api.github.com/repos/zanata/zanata-server/contents/{+path}","compare_url":"https://api.github.com/repos/zanata/zanata-server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zanata/zanata-server/merges","archive_url":"https://api.github.com/repos/zanata/zanata-server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zanata/zanata-server/downloads","issues_url":"https://api.github.com/repos/zanata/zanata-server/issues{/number}","pulls_url":"https://api.github.com/repos/zanata/zanata-server/pulls{/number}","milestones_url":"https://api.github.com/repos/zanata/zanata-server/milestones{/number}","notifications_url":"https://api.github.com/repos/zanata/zanata-server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zanata/zanata-server/labels{/name}","releases_url":"https://api.github.com/repos/zanata/zanata-server/releases{/id}","created_at":"2011-03-10T00:24:47Z","updated_at":"2015-08-15T21:56:28Z","pushed_at":"2015-08-20T04:05:07Z","git_url":"git://github.com/zanata/zanata-server.git","ssh_url":"git@github.com:zanata/zanata-server.git","clone_url":"https://github.com/zanata/zanata-server.git","svn_url":"https://github.com/zanata/zanata-server","homepage":"http://zanata.org","size":241003,"stargazers_count":111,"watchers_count":111,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":30,"mirror_url":null,"open_issues_count":16,"forks":30,"open_issues":16,"watchers":111,"default_branch":"master"}},"base":{"label":"zanata:integration/master","ref":"integration/master","sha":"9d0387e55e5d21439555d5f18c44cb9326175541","user":{"login":"zanata","id":637455,"avatar_url":"https://avatars.githubusercontent.com/u/637455?v=3","gravatar_id":"","url":"https://api.github.com/users/zanata","html_url":"https://github.com/zanata","followers_url":"https://api.github.com/users/zanata/followers","following_url":"https://api.github.com/users/zanata/following{/other_user}","gists_url":"https://api.github.com/users/zanata/gists{/gist_id}","starred_url":"https://api.github.com/users/zanata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zanata/subscriptions","organizations_url":"https://api.github.com/users/zanata/orgs","repos_url":"https://api.github.com/users/zanata/repos","events_url":"https://api.github.com/users/zanata/events{/privacy}","received_events_url":"https://api.github.com/users/zanata/received_events","type":"Organization","site_admin":false},"repo":{"id":1461609,"name":"zanata-server","full_name":"zanata/zanata-server","owner":{"login":"zanata","id":637455,"avatar_url":"https://avatars.githubusercontent.com/u/637455?v=3","gravatar_id":"","url":"https://api.github.com/users/zanata","html_url":"https://github.com/zanata","followers_url":"https://api.github.com/users/zanata/followers","following_url":"https://api.github.com/users/zanata/following{/other_user}","gists_url":"https://api.github.com/users/zanata/gists{/gist_id}","starred_url":"https://api.github.com/users/zanata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zanata/subscriptions","organizations_url":"https://api.github.com/users/zanata/orgs","repos_url":"https://api.github.com/users/zanata/repos","events_url":"https://api.github.com/users/zanata/events{/privacy}","received_events_url":"https://api.github.com/users/zanata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zanata/zanata-server","description":"Zanata is a web-based system for translators to translate documentation and software online using a web browser.","fork":false,"url":"https://api.github.com/repos/zanata/zanata-server","forks_url":"https://api.github.com/repos/zanata/zanata-server/forks","keys_url":"https://api.github.com/repos/zanata/zanata-server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zanata/zanata-server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zanata/zanata-server/teams","hooks_url":"https://api.github.com/repos/zanata/zanata-server/hooks","issue_events_url":"https://api.github.com/repos/zanata/zanata-server/issues/events{/number}","events_url":"https://api.github.com/repos/zanata/zanata-server/events","assignees_url":"https://api.github.com/repos/zanata/zanata-server/assignees{/user}","branches_url":"https://api.github.com/repos/zanata/zanata-server/branches{/branch}","tags_url":"https://api.github.com/repos/zanata/zanata-server/tags","blobs_url":"https://api.github.com/repos/zanata/zanata-server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zanata/zanata-server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zanata/zanata-server/git/refs{/sha}","trees_url":"https://api.github.com/repos/zanata/zanata-server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zanata/zanata-server/statuses/{sha}","languages_url":"https://api.github.com/repos/zanata/zanata-server/languages","stargazers_url":"https://api.github.com/repos/zanata/zanata-server/stargazers","contributors_url":"https://api.github.com/repos/zanata/zanata-server/contributors","subscribers_url":"https://api.github.com/repos/zanata/zanata-server/subscribers","subscription_url":"https://api.github.com/repos/zanata/zanata-server/subscription","commits_url":"https://api.github.com/repos/zanata/zanata-server/commits{/sha}","git_commits_url":"https://api.github.com/repos/zanata/zanata-server/git/commits{/sha}","comments_url":"https://api.github.com/repos/zanata/zanata-server/comments{/number}","issue_comment_url":"https://api.github.com/repos/zanata/zanata-server/issues/comments{/number}","contents_url":"https://api.github.com/repos/zanata/zanata-server/contents/{+path}","compare_url":"https://api.github.com/repos/zanata/zanata-server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zanata/zanata-server/merges","archive_url":"https://api.github.com/repos/zanata/zanata-server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zanata/zanata-server/downloads","issues_url":"https://api.github.com/repos/zanata/zanata-server/issues{/number}","pulls_url":"https://api.github.com/repos/zanata/zanata-server/pulls{/number}","milestones_url":"https://api.github.com/repos/zanata/zanata-server/milestones{/number}","notifications_url":"https://api.github.com/repos/zanata/zanata-server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zanata/zanata-server/labels{/name}","releases_url":"https://api.github.com/repos/zanata/zanata-server/releases{/id}","created_at":"2011-03-10T00:24:47Z","updated_at":"2015-08-15T21:56:28Z","pushed_at":"2015-08-20T04:05:07Z","git_url":"git://github.com/zanata/zanata-server.git","ssh_url":"git@github.com:zanata/zanata-server.git","clone_url":"https://github.com/zanata/zanata-server.git","svn_url":"https://github.com/zanata/zanata-server","homepage":"http://zanata.org","size":241003,"stargazers_count":111,"watchers_count":111,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":30,"mirror_url":null,"open_issues_count":16,"forks":30,"open_issues":16,"watchers":111,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/933"},"html":{"href":"https://github.com/zanata/zanata-server/pull/933"},"issue":{"href":"https://api.github.com/repos/zanata/zanata-server/issues/933"},"comments":{"href":"https://api.github.com/repos/zanata/zanata-server/issues/933/comments"},"review_comments":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/933/comments"},"review_comment":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zanata/zanata-server/pulls/933/commits"},"statuses":{"href":"https://api.github.com/repos/zanata/zanata-server/statuses/acbe4ae9e6dac26c25ed45e34cee06901063e8e4"}}}}