{"action":"created","comment":{"url":"https://api.github.com/repos/saros-project/saros/pulls/comments/202287717","pull_request_review_id":136958005,"id":202287717,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMjI4NzcxNw==","diff_hunk":"@@ -0,0 +1,273 @@\n+package de.fu_berlin.inf.dpp.negotiation;\n+\n+import java.io.IOException;\n+import java.io.OutputStream;\n+import java.io.PipedInputStream;\n+import java.io.PipedOutputStream;\n+import java.util.ArrayList;\n+import java.util.Collections;\n+import java.util.Comparator;\n+import java.util.Deque;\n+import java.util.HashSet;\n+import java.util.LinkedHashSet;\n+import java.util.List;\n+import java.util.Set;\n+import java.util.concurrent.LinkedBlockingDeque;\n+\n+import org.apache.commons.io.IOUtils;\n+import org.apache.log4j.Logger;\n+import org.jivesoftware.smackx.filetransfer.FileTransfer;\n+import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;\n+\n+import de.fu_berlin.inf.dpp.activities.SPath;\n+import de.fu_berlin.inf.dpp.editor.AbstractSharedEditorListener;\n+import de.fu_berlin.inf.dpp.editor.IEditorManager;\n+import de.fu_berlin.inf.dpp.editor.ISharedEditorListener;\n+import de.fu_berlin.inf.dpp.editor.remote.UserEditorStateManager;\n+import de.fu_berlin.inf.dpp.exceptions.LocalCancellationException;\n+import de.fu_berlin.inf.dpp.exceptions.SarosCancellationException;\n+import de.fu_berlin.inf.dpp.filesystem.IChecksumCache;\n+import de.fu_berlin.inf.dpp.filesystem.IProject;\n+import de.fu_berlin.inf.dpp.filesystem.IWorkspace;\n+import de.fu_berlin.inf.dpp.monitoring.IProgressMonitor;\n+import de.fu_berlin.inf.dpp.negotiation.NegotiationTools.CancelOption;\n+import de.fu_berlin.inf.dpp.negotiation.stream.OutgoingStreamProtocol;\n+import de.fu_berlin.inf.dpp.net.IReceiver;\n+import de.fu_berlin.inf.dpp.net.ITransmitter;\n+import de.fu_berlin.inf.dpp.net.xmpp.JID;\n+import de.fu_berlin.inf.dpp.net.xmpp.XMPPConnectionService;\n+import de.fu_berlin.inf.dpp.session.ISarosSession;\n+import de.fu_berlin.inf.dpp.session.ISarosSessionManager;\n+import de.fu_berlin.inf.dpp.session.User;\n+import de.fu_berlin.inf.dpp.synchronize.StartHandle;\n+\n+/**\n+ * Share Projects to display them instant on client side using a stream based\n+ * solution.\n+ */\n+public class InstantOutgoingProjectNegotiation extends\n+    AbstractOutgoingProjectNegotiation {\n+\n+    private static final Logger log = Logger\n+        .getLogger(InstantOutgoingProjectNegotiation.class);\n+\n+    /** used as LIFO queue **/\n+    private final Deque<SPath> openedFiles = new LinkedBlockingDeque<SPath>();\n+\n+    private Set<SPath> transferList;\n+    private Set<SPath> transmittedFiles;\n+\n+    /** receive open editors to prioritize these files **/\n+    private final ISharedEditorListener listener = new AbstractSharedEditorListener() {\n+        @Override\n+        public void editorActivated(User user, SPath file) {\n+            fileOpened(file);\n+        }\n+    };\n+\n+    private List<StartHandle> stoppedUsers = null;\n+    private User remoteUser = null;\n+\n+    public InstantOutgoingProjectNegotiation(final JID peer, //\n+        final List<IProject> projects, //\n+        final ISarosSessionManager sessionManager, //\n+        final ISarosSession session, //\n+        final IEditorManager editorManager, //\n+        final IWorkspace workspace, //\n+        final IChecksumCache checksumCache, //\n+        final XMPPConnectionService connectionService, //\n+        final ITransmitter transmitter, //\n+        final IReceiver receiver) //\n+    {\n+        super(peer, TransferType.INSTANT, projects, sessionManager, session,\n+            editorManager, workspace, checksumCache, connectionService,\n+            transmitter, receiver);\n+    }\n+\n+    @Override\n+    protected void setup(IProgressMonitor monitor) throws IOException,\n+        LocalCancellationException {\n+        if (fileTransferManager == null)\n+            throw new LocalCancellationException(\n+                \"not connected to a XMPP server\",\n+                CancelOption.DO_NOT_NOTIFY_PEER);\n+\n+        /* get all opened editors */\n+        editorManager.addSharedEditorListener(listener);\n+        Set<SPath> openEditors = session.getComponent(\n+            UserEditorStateManager.class).getOpenEditors();\n+        for (SPath remoteOpenFile : openEditors)\n+            fileOpened(remoteOpenFile);\n+        for (SPath localOpenFile : editorManager.getOpenEditors())\n+            fileOpened(localOpenFile);\n+    }\n+\n+    @Override\n+    protected void prepareTransfer(IProgressMonitor monitor,\n+        List<FileList> fileLists) throws IOException,\n+        SarosCancellationException {\n+\n+        /* until further patch, lock the complete session */\n+        stoppedUsers = stopUsers(monitor);\n+        sendAndAwaitActivityQueueingActivation(monitor);\n+\n+        remoteUser = session.getUser(getPeer());\n+        if (remoteUser == null)\n+            throw new LocalCancellationException(null,\n+                CancelOption.DO_NOT_NOTIFY_PEER);\n+\n+        int fileCount = 0;\n+        for (final FileList list : fileLists) {\n+            fileCount += list.getPaths().size();\n+\n+            final String projectID = list.getProjectID();\n+            final IProject project = session.getProject(projectID);\n+\n+            if (project == null)\n+                throw new LocalCancellationException(\"project with id \"\n+                    + projectID + \" was unshared during synchronization\",\n+                    CancelOption.NOTIFY_PEER);\n+        }\n+\n+        createTransferList(fileLists, fileCount);\n+        transmittedFiles = new HashSet<SPath>(fileCount * 2);\n+    }\n+\n+    @Override\n+    protected void transfer(IProgressMonitor monitor, List<FileList> fileLists)\n+        throws SarosCancellationException, IOException {\n+        if (transferList.isEmpty())\n+            return;\n+\n+        log.debug(this + \": file transfer start\");\n+        assert fileTransferManager != null;\n+\n+        String message = \"Sending files to \" + getPeer().getName() + \"...\";\n+        monitor.beginTask(message, transferList.size());\n+\n+        /* use piped stream to communicate with transfer thread */\n+        PipedInputStream in = new PipedInputStream();\n+        OutputStream out = new PipedOutputStream(in);\n+\n+        String userID = getPeer().toString();\n+        OutgoingFileTransfer transfer;\n+        transfer = fileTransferManager.createOutgoingFileTransfer(userID);\n+\n+        try {\n+            OutgoingStreamProtocol osp;\n+            osp = new OutgoingStreamProtocol(out, session, monitor);\n+\n+            /* id in description needed to bypass SendFileAction handler */\n+            String streamName = TRANSFER_ID + getID();\n+            transfer.sendStream(in, streamName, 0, streamName);\n+\n+            awaitNegotation(transfer, monitor);\n+\n+            sendProjectConfigFiles(osp);\n+            sendRemainingPreferOpenedFirst(osp);\n+\n+            osp.close();\n+        } finally {\n+            IOUtils.closeQuietly(out);\n+        }\n+\n+        monitor.done();\n+        log.debug(this + \": file transfer done\");\n+    }\n+\n+    @Override\n+    protected void cleanup(IProgressMonitor monitor) {\n+        editorManager.removeSharedEditorListener(listener);\n+        session.userStartedQueuing(remoteUser);\n+\n+        if (stoppedUsers != null)\n+            startUsers(stoppedUsers);\n+\n+        super.cleanup(monitor);\n+    }\n+\n+    private void createTransferList(List<FileList> fileLists, int fileCount) {\n+        List<SPath> files = new ArrayList<SPath>(fileCount);\n+        for (final FileList list : fileLists) {\n+            IProject project = session.getProject(list.getProjectID());\n+            for (String file : list.getPaths()) {\n+                files.add(new SPath(project.getFile(file)));\n+            }\n+        }\n+\n+        /* sort hierarchy based, top files are seen first in project explorer */\n+        Collections.sort(files, new Comparator<SPath>() {\n+            @Override\n+            public int compare(SPath a, SPath b) {\n+                int lenA = a.getProjectRelativePath().segmentCount();\n+                int lenB = b.getProjectRelativePath().segmentCount();\n+                return Integer.valueOf(lenA).compareTo(Integer.valueOf(lenB));\n+            }\n+        });\n+\n+        /* LinkedHashSet for fast lookup while keeping sort order */\n+        transferList = new LinkedHashSet<SPath>(files);\n+    }\n+\n+    private void fileOpened(SPath file) {\n+        if (file != null) {\n+            openedFiles.addFirst(file);\n+            log.debug(this + \": added \" + file + \" to open files queue\");\n+        }\n+    }\n+\n+    private void sendProjectConfigFiles(OutgoingStreamProtocol osp)\n+        throws IOException, LocalCancellationException {\n+        /* TODO should be configurable in future */","path":"de.fu_berlin.inf.dpp.core/src/de/fu_berlin/inf/dpp/negotiation/InstantOutgoingProjectNegotiation.java","position":221,"original_position":221,"commit_id":"b42a0dcc0a8ec78948cbd917e341a6cd7d39ee91","original_commit_id":"b42a0dcc0a8ec78948cbd917e341a6cd7d39ee91","user":{"login":"saros-infrastructure","id":39915837,"node_id":"MDQ6VXNlcjM5OTE1ODM3","avatar_url":"https://avatars1.githubusercontent.com/u/39915837?v=4","gravatar_id":"","url":"https://api.github.com/users/saros-infrastructure","html_url":"https://github.com/saros-infrastructure","followers_url":"https://api.github.com/users/saros-infrastructure/followers","following_url":"https://api.github.com/users/saros-infrastructure/following{/other_user}","gists_url":"https://api.github.com/users/saros-infrastructure/gists{/gist_id}","starred_url":"https://api.github.com/users/saros-infrastructure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saros-infrastructure/subscriptions","organizations_url":"https://api.github.com/users/saros-infrastructure/orgs","repos_url":"https://api.github.com/users/saros-infrastructure/repos","events_url":"https://api.github.com/users/saros-infrastructure/events{/privacy}","received_events_url":"https://api.github.com/users/saros-infrastructure/received_events","type":"User","site_admin":false},"body":"![Code Smell](https://sonarsource.github.io/sonar-github/code_smell.png 'Code Smell') Code Smell: Complete the task associated to this TODO comment. ([squid:S1135](https://sonarcloud.io/organizations/saros/rules#rule_key=squid%3AS1135))\n\n[See it in SonarCloud](https://sonarcloud.io/project/issues?id=saros_complete&pullRequest=128&issues=AWSS35X1sk71k7lwr5eP&open=AWSS35X1sk71k7lwr5eP)\n\n[ISSUE_KEY]: AWSS35X1sk71k7lwr5eP","created_at":"2018-07-13T09:01:25Z","updated_at":"2018-07-13T09:01:26Z","html_url":"https://github.com/saros-project/saros/pull/128#discussion_r202287717","pull_request_url":"https://api.github.com/repos/saros-project/saros/pulls/128","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/saros-project/saros/pulls/comments/202287717"},"html":{"href":"https://github.com/saros-project/saros/pull/128#discussion_r202287717"},"pull_request":{"href":"https://api.github.com/repos/saros-project/saros/pulls/128"}}},"pull_request":{"url":"https://api.github.com/repos/saros-project/saros/pulls/128","id":201156877,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAxMTU2ODc3","html_url":"https://github.com/saros-project/saros/pull/128","diff_url":"https://github.com/saros-project/saros/pull/128.diff","patch_url":"https://github.com/saros-project/saros/pull/128.patch","issue_url":"https://api.github.com/repos/saros-project/saros/issues/128","number":128,"state":"open","locked":false,"title":"[FEATURE][CORE] Introduce Instant Session Start","user":{"login":"stefaus","id":12998930,"node_id":"MDQ6VXNlcjEyOTk4OTMw","avatar_url":"https://avatars3.githubusercontent.com/u/12998930?v=4","gravatar_id":"","url":"https://api.github.com/users/stefaus","html_url":"https://github.com/stefaus","followers_url":"https://api.github.com/users/stefaus/followers","following_url":"https://api.github.com/users/stefaus/following{/other_user}","gists_url":"https://api.github.com/users/stefaus/gists{/gist_id}","starred_url":"https://api.github.com/users/stefaus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefaus/subscriptions","organizations_url":"https://api.github.com/users/stefaus/orgs","repos_url":"https://api.github.com/users/stefaus/repos","events_url":"https://api.github.com/users/stefaus/events{/privacy}","received_events_url":"https://api.github.com/users/stefaus/received_events","type":"User","site_admin":false},"body":"This patch implements the core functionality of Instant Session Start,\r\nwhich is optional selectable for Project Negotiation. The main scope of\r\nthis feature is to decrease the waiting time for users, till the first\r\nfiles are provided and they can participate in a session.\r\n\r\nDeviant to previous approaches, this one uses a file stream based\r\nsolution. Compared to using Activities, this provides increased\r\nperformance, because of small overheads and better compresion\r\npossibilities, big files support and is for now, not interfering with\r\nexisting activity handling code.\r\n\r\nThis first Version implements a basic prioritisation, by first sending\r\nimportant eclipse project files, afterwards allways opened files first\r\nand remaining sorted by path hierarchy.\r\n\r\nFollowing features are excluded, to limit this rather big patch or are\r\nplanned for the future:\r\n\r\n - Proper handling of Activities, to remove editor lock\r\n\r\n - Compression (using a libary like zstd)\r\n\r\n - Configurable File Prioritisations\r\n\r\n - More progress infos (bandwith, remaining file size, time...)\r\n\r\n - Performance optimizations, refactoring of ProjectNegotiation\r\n\r\n - User interface enhancements\r\n\r\n - Priority file sending, while active file transmission","created_at":"2018-07-13T00:06:40Z","updated_at":"2018-07-13T09:01:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3d4ade42b0e8c416da831ef23afb90ef7ceaa61c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/saros-project/saros/pulls/128/commits","review_comments_url":"https://api.github.com/repos/saros-project/saros/pulls/128/comments","review_comment_url":"https://api.github.com/repos/saros-project/saros/pulls/comments{/number}","comments_url":"https://api.github.com/repos/saros-project/saros/issues/128/comments","statuses_url":"https://api.github.com/repos/saros-project/saros/statuses/b42a0dcc0a8ec78948cbd917e341a6cd7d39ee91","head":{"label":"saros-project:pr/instant/core","ref":"pr/instant/core","sha":"b42a0dcc0a8ec78948cbd917e341a6cd7d39ee91","user":{"login":"saros-project","id":1419284,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTkyODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1419284?v=4","gravatar_id":"","url":"https://api.github.com/users/saros-project","html_url":"https://github.com/saros-project","followers_url":"https://api.github.com/users/saros-project/followers","following_url":"https://api.github.com/users/saros-project/following{/other_user}","gists_url":"https://api.github.com/users/saros-project/gists{/gist_id}","starred_url":"https://api.github.com/users/saros-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saros-project/subscriptions","organizations_url":"https://api.github.com/users/saros-project/orgs","repos_url":"https://api.github.com/users/saros-project/repos","events_url":"https://api.github.com/users/saros-project/events{/privacy}","received_events_url":"https://api.github.com/users/saros-project/received_events","type":"Organization","site_admin":false},"repo":{"id":11182907,"node_id":"MDEwOlJlcG9zaXRvcnkxMTE4MjkwNw==","name":"saros","full_name":"saros-project/saros","owner":{"login":"saros-project","id":1419284,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTkyODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1419284?v=4","gravatar_id":"","url":"https://api.github.com/users/saros-project","html_url":"https://github.com/saros-project","followers_url":"https://api.github.com/users/saros-project/followers","following_url":"https://api.github.com/users/saros-project/following{/other_user}","gists_url":"https://api.github.com/users/saros-project/gists{/gist_id}","starred_url":"https://api.github.com/users/saros-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saros-project/subscriptions","organizations_url":"https://api.github.com/users/saros-project/orgs","repos_url":"https://api.github.com/users/saros-project/repos","events_url":"https://api.github.com/users/saros-project/events{/privacy}","received_events_url":"https://api.github.com/users/saros-project/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/saros-project/saros","description":"Saros Plugin","fork":false,"url":"https://api.github.com/repos/saros-project/saros","forks_url":"https://api.github.com/repos/saros-project/saros/forks","keys_url":"https://api.github.com/repos/saros-project/saros/keys{/key_id}","collaborators_url":"https://api.github.com/repos/saros-project/saros/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/saros-project/saros/teams","hooks_url":"https://api.github.com/repos/saros-project/saros/hooks","issue_events_url":"https://api.github.com/repos/saros-project/saros/issues/events{/number}","events_url":"https://api.github.com/repos/saros-project/saros/events","assignees_url":"https://api.github.com/repos/saros-project/saros/assignees{/user}","branches_url":"https://api.github.com/repos/saros-project/saros/branches{/branch}","tags_url":"https://api.github.com/repos/saros-project/saros/tags","blobs_url":"https://api.github.com/repos/saros-project/saros/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/saros-project/saros/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/saros-project/saros/git/refs{/sha}","trees_url":"https://api.github.com/repos/saros-project/saros/git/trees{/sha}","statuses_url":"https://api.github.com/repos/saros-project/saros/statuses/{sha}","languages_url":"https://api.github.com/repos/saros-project/saros/languages","stargazers_url":"https://api.github.com/repos/saros-project/saros/stargazers","contributors_url":"https://api.github.com/repos/saros-project/saros/contributors","subscribers_url":"https://api.github.com/repos/saros-project/saros/subscribers","subscription_url":"https://api.github.com/repos/saros-project/saros/subscription","commits_url":"https://api.github.com/repos/saros-project/saros/commits{/sha}","git_commits_url":"https://api.github.com/repos/saros-project/saros/git/commits{/sha}","comments_url":"https://api.github.com/repos/saros-project/saros/comments{/number}","issue_comment_url":"https://api.github.com/repos/saros-project/saros/issues/comments{/number}","contents_url":"https://api.github.com/repos/saros-project/saros/contents/{+path}","compare_url":"https://api.github.com/repos/saros-project/saros/compare/{base}...{head}","merges_url":"https://api.github.com/repos/saros-project/saros/merges","archive_url":"https://api.github.com/repos/saros-project/saros/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/saros-project/saros/downloads","issues_url":"https://api.github.com/repos/saros-project/saros/issues{/number}","pulls_url":"https://api.github.com/repos/saros-project/saros/pulls{/number}","milestones_url":"https://api.github.com/repos/saros-project/saros/milestones{/number}","notifications_url":"https://api.github.com/repos/saros-project/saros/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/saros-project/saros/labels{/name}","releases_url":"https://api.github.com/repos/saros-project/saros/releases{/id}","deployments_url":"https://api.github.com/repos/saros-project/saros/deployments","created_at":"2013-07-04T17:14:07Z","updated_at":"2018-07-12T14:28:10Z","pushed_at":"2018-07-13T08:52:17Z","git_url":"git://github.com/saros-project/saros.git","ssh_url":"git@github.com:saros-project/saros.git","clone_url":"https://github.com/saros-project/saros.git","svn_url":"https://github.com/saros-project/saros","homepage":"http://www.saros-project.org","size":138698,"stargazers_count":55,"watchers_count":55,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":26,"mirror_url":null,"archived":false,"open_issues_count":106,"license":null,"forks":26,"open_issues":106,"watchers":55,"default_branch":"master"}},"base":{"label":"saros-project:pr/instant/refactor-ftl","ref":"pr/instant/refactor-ftl","sha":"ee7036cf0444ff39a91d551ecc3f0c44e0b6520c","user":{"login":"saros-project","id":1419284,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTkyODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1419284?v=4","gravatar_id":"","url":"https://api.github.com/users/saros-project","html_url":"https://github.com/saros-project","followers_url":"https://api.github.com/users/saros-project/followers","following_url":"https://api.github.com/users/saros-project/following{/other_user}","gists_url":"https://api.github.com/users/saros-project/gists{/gist_id}","starred_url":"https://api.github.com/users/saros-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saros-project/subscriptions","organizations_url":"https://api.github.com/users/saros-project/orgs","repos_url":"https://api.github.com/users/saros-project/repos","events_url":"https://api.github.com/users/saros-project/events{/privacy}","received_events_url":"https://api.github.com/users/saros-project/received_events","type":"Organization","site_admin":false},"repo":{"id":11182907,"node_id":"MDEwOlJlcG9zaXRvcnkxMTE4MjkwNw==","name":"saros","full_name":"saros-project/saros","owner":{"login":"saros-project","id":1419284,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTkyODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1419284?v=4","gravatar_id":"","url":"https://api.github.com/users/saros-project","html_url":"https://github.com/saros-project","followers_url":"https://api.github.com/users/saros-project/followers","following_url":"https://api.github.com/users/saros-project/following{/other_user}","gists_url":"https://api.github.com/users/saros-project/gists{/gist_id}","starred_url":"https://api.github.com/users/saros-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saros-project/subscriptions","organizations_url":"https://api.github.com/users/saros-project/orgs","repos_url":"https://api.github.com/users/saros-project/repos","events_url":"https://api.github.com/users/saros-project/events{/privacy}","received_events_url":"https://api.github.com/users/saros-project/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/saros-project/saros","description":"Saros Plugin","fork":false,"url":"https://api.github.com/repos/saros-project/saros","forks_url":"https://api.github.com/repos/saros-project/saros/forks","keys_url":"https://api.github.com/repos/saros-project/saros/keys{/key_id}","collaborators_url":"https://api.github.com/repos/saros-project/saros/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/saros-project/saros/teams","hooks_url":"https://api.github.com/repos/saros-project/saros/hooks","issue_events_url":"https://api.github.com/repos/saros-project/saros/issues/events{/number}","events_url":"https://api.github.com/repos/saros-project/saros/events","assignees_url":"https://api.github.com/repos/saros-project/saros/assignees{/user}","branches_url":"https://api.github.com/repos/saros-project/saros/branches{/branch}","tags_url":"https://api.github.com/repos/saros-project/saros/tags","blobs_url":"https://api.github.com/repos/saros-project/saros/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/saros-project/saros/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/saros-project/saros/git/refs{/sha}","trees_url":"https://api.github.com/repos/saros-project/saros/git/trees{/sha}","statuses_url":"https://api.github.com/repos/saros-project/saros/statuses/{sha}","languages_url":"https://api.github.com/repos/saros-project/saros/languages","stargazers_url":"https://api.github.com/repos/saros-project/saros/stargazers","contributors_url":"https://api.github.com/repos/saros-project/saros/contributors","subscribers_url":"https://api.github.com/repos/saros-project/saros/subscribers","subscription_url":"https://api.github.com/repos/saros-project/saros/subscription","commits_url":"https://api.github.com/repos/saros-project/saros/commits{/sha}","git_commits_url":"https://api.github.com/repos/saros-project/saros/git/commits{/sha}","comments_url":"https://api.github.com/repos/saros-project/saros/comments{/number}","issue_comment_url":"https://api.github.com/repos/saros-project/saros/issues/comments{/number}","contents_url":"https://api.github.com/repos/saros-project/saros/contents/{+path}","compare_url":"https://api.github.com/repos/saros-project/saros/compare/{base}...{head}","merges_url":"https://api.github.com/repos/saros-project/saros/merges","archive_url":"https://api.github.com/repos/saros-project/saros/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/saros-project/saros/downloads","issues_url":"https://api.github.com/repos/saros-project/saros/issues{/number}","pulls_url":"https://api.github.com/repos/saros-project/saros/pulls{/number}","milestones_url":"https://api.github.com/repos/saros-project/saros/milestones{/number}","notifications_url":"https://api.github.com/repos/saros-project/saros/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/saros-project/saros/labels{/name}","releases_url":"https://api.github.com/repos/saros-project/saros/releases{/id}","deployments_url":"https://api.github.com/repos/saros-project/saros/deployments","created_at":"2013-07-04T17:14:07Z","updated_at":"2018-07-12T14:28:10Z","pushed_at":"2018-07-13T08:52:17Z","git_url":"git://github.com/saros-project/saros.git","ssh_url":"git@github.com:saros-project/saros.git","clone_url":"https://github.com/saros-project/saros.git","svn_url":"https://github.com/saros-project/saros","homepage":"http://www.saros-project.org","size":138698,"stargazers_count":55,"watchers_count":55,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":26,"mirror_url":null,"archived":false,"open_issues_count":106,"license":null,"forks":26,"open_issues":106,"watchers":55,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/saros-project/saros/pulls/128"},"html":{"href":"https://github.com/saros-project/saros/pull/128"},"issue":{"href":"https://api.github.com/repos/saros-project/saros/issues/128"},"comments":{"href":"https://api.github.com/repos/saros-project/saros/issues/128/comments"},"review_comments":{"href":"https://api.github.com/repos/saros-project/saros/pulls/128/comments"},"review_comment":{"href":"https://api.github.com/repos/saros-project/saros/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/saros-project/saros/pulls/128/commits"},"statuses":{"href":"https://api.github.com/repos/saros-project/saros/statuses/b42a0dcc0a8ec78948cbd917e341a6cd7d39ee91"}},"author_association":"NONE"}}
{"actor":{"display_login":"saros-infrastructure"}}