{"action":"created","comment":{"url":"https://api.github.com/repos/cloudant/sync-android/pulls/comments/85772861","pull_request_review_id":6468204,"id":85772861,"diff_hunk":"@@ -0,0 +1,138 @@\n+package com.cloudant.sync.datastore;\n+\n+import com.cloudant.sync.datastore.encryption.KeyProvider;\n+import com.cloudant.sync.datastore.encryption.NullKeyProvider;\n+import com.cloudant.sync.event.EventBus;\n+import com.cloudant.sync.event.Subscribe;\n+import com.cloudant.sync.notifications.DatabaseClosed;\n+import com.cloudant.sync.notifications.DatabaseCreated;\n+import com.cloudant.sync.notifications.DatabaseDeleted;\n+import com.cloudant.sync.notifications.DatabaseOpened;\n+import com.cloudant.sync.query.IndexManager;\n+import com.cloudant.sync.query.IndexManagerImpl;\n+import com.cloudant.sync.util.Misc;\n+import com.sun.javafx.scene.shape.PathUtils;\n+\n+import org.apache.commons.io.FileUtils;\n+import org.apache.commons.io.FilenameUtils;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.sql.SQLException;\n+import java.util.ArrayList;\n+import java.util.Collections;\n+import java.util.HashMap;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ConcurrentMap;\n+\n+/**\n+ * Created by tomblench on 27/09/2016.\n+ */\n+\n+public class DocumentStore {\n+\n+    public final Database database;\n+    public final IndexManager query;\n+    protected final String databaseName; // only used for events\n+    private final File location; // needed for close\n+\n+    /* This map should only be accessed inside synchronized(openDatastores) blocks */\n+    private static final Map<File, DocumentStore> documentStores = new HashMap<File, DocumentStore>();\n+\n+    private static EventBus eventBus = new EventBus();\n+\n+    private DocumentStore(File location, KeyProvider keyProvider) throws DatastoreException, IOException, SQLException {\n+        this.location = location;\n+        this.databaseName = location.getName();\n+        this.database = new DatabaseImpl(location, keyProvider);\n+        // this will be used to observe purge() events from database and forward them to indexmanager\n+        this.database.getEventBus().register(this);\n+        this.query = new IndexManagerImpl(database);\n+    }\n+\n+    public static DocumentStore getInstance(File location) throws DatastoreNotCreatedException {\n+        return getInstance(location, new NullKeyProvider());\n+    }\n+\n+    public static DocumentStore getInstance(File location, KeyProvider provider) throws DatastoreNotCreatedException {\n+        boolean created = checkPathAndCreateIfNeeded(location);\n+        try {\n+            synchronized (documentStores) {\n+                DocumentStore ds = documentStores.get(location);\n+                if (ds == null) {\n+                    ds = new DocumentStore(location, provider);\n+                    documentStores.put(location, ds);\n+                    eventBus.post(new DatabaseOpened(ds.databaseName));\n+                }\n+                if (created) {\n+                    eventBus.post(new DatabaseCreated(ds.databaseName));\n+                }\n+                return ds;\n+            }\n+        }\n+        catch (IOException e) {\n+            throw new DatastoreNotCreatedException(\"Database not found: \" + location, e);\n+        } catch (SQLException e) {\n+            throw new DatastoreNotCreatedException(\"Database not initialized correctly: \" + location, e);\n+        } catch (DatastoreException e) {\n+            throw new DatastoreNotCreatedException(\"Datastore not initialized correctly: \" + location, e);\n+        }\n+    }\n+\n+    private static boolean checkPathAndCreateIfNeeded(File location) {\n+        //logger.fine(\"Datastore path: \" + directoryPath);\n+\n+        boolean created = false;\n+        if(!location.exists()){\n+            created = location.mkdir();\n+        }\n+\n+        Misc.checkArgument(location.isDirectory(), \"Input path is not a valid directory\");\n+        Misc.checkArgument(location.canWrite(), \"Datastore directory is not writable\");\n+        return created;\n+    }\n+\n+    public void close() {\n+        synchronized (documentStores) {\n+            DocumentStore ds = documentStores.get(location);\n+            if (ds != null) {\n+                System.out.println(\"removing \"+location);\n+                ((DatabaseImpl)database).close();\n+                ((IndexManagerImpl)query).close();","path":"cloudant-sync-datastore-core/src/main/java/com/cloudant/sync/datastore/DocumentStore.java","position":null,"original_position":103,"commit_id":"248a5a8d30a3dfd867a01d23a45f3ab416153cae","original_commit_id":"6a06822ca0c2c215d969b070a76de7a29d7326d7","user":{"login":"tomblench","id":6302842,"avatar_url":"https://avatars.githubusercontent.com/u/6302842?v=3","gravatar_id":"","url":"https://api.github.com/users/tomblench","html_url":"https://github.com/tomblench","followers_url":"https://api.github.com/users/tomblench/followers","following_url":"https://api.github.com/users/tomblench/following{/other_user}","gists_url":"https://api.github.com/users/tomblench/gists{/gist_id}","starred_url":"https://api.github.com/users/tomblench/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tomblench/subscriptions","organizations_url":"https://api.github.com/users/tomblench/orgs","repos_url":"https://api.github.com/users/tomblench/repos","events_url":"https://api.github.com/users/tomblench/events{/privacy}","received_events_url":"https://api.github.com/users/tomblench/received_events","type":"User","site_admin":false},"body":"Done in b05d5ef","created_at":"2016-10-31T16:10:33Z","updated_at":"2016-10-31T16:10:33Z","html_url":"https://github.com/cloudant/sync-android/pull/380#discussion_r85772861","pull_request_url":"https://api.github.com/repos/cloudant/sync-android/pulls/380","_links":{"self":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/comments/85772861"},"html":{"href":"https://github.com/cloudant/sync-android/pull/380#discussion_r85772861"},"pull_request":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/380"}}},"pull_request":{"url":"https://api.github.com/repos/cloudant/sync-android/pulls/380","id":90366173,"html_url":"https://github.com/cloudant/sync-android/pull/380","diff_url":"https://github.com/cloudant/sync-android/pull/380.diff","patch_url":"https://github.com/cloudant/sync-android/pull/380.patch","issue_url":"https://api.github.com/repos/cloudant/sync-android/issues/380","number":380,"state":"open","locked":false,"title":"Remove DatastoreManager","user":{"login":"tomblench","id":6302842,"avatar_url":"https://avatars.githubusercontent.com/u/6302842?v=3","gravatar_id":"","url":"https://api.github.com/users/tomblench","html_url":"https://github.com/tomblench","followers_url":"https://api.github.com/users/tomblench/followers","following_url":"https://api.github.com/users/tomblench/following{/other_user}","gists_url":"https://api.github.com/users/tomblench/gists{/gist_id}","starred_url":"https://api.github.com/users/tomblench/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tomblench/subscriptions","organizations_url":"https://api.github.com/users/tomblench/orgs","repos_url":"https://api.github.com/users/tomblench/repos","events_url":"https://api.github.com/users/tomblench/events{/privacy}","received_events_url":"https://api.github.com/users/tomblench/received_events","type":"User","site_admin":false},"body":"Part 4 of _n_ PRs for feature-284-refactor-datastore-indexmanager. See parent issue #284.\n\nThe overall theme for this PR is to remove the DatastoreManager and ensure that all of the key classes the user interacts with are named sensibly whilst we have the opportunity to introduce the breaking changes that this causes.\n\nThe DatastoreManager object introduces needless complexity for users of the API. Instead add static methods for getting/closing/deleting instances of DocumentStore on the DocumentStore object itself.\n\nChanged behaviour or removed arbitrary restrictions:\n- Removed datastore name. The user just passes in a path and that path is used to store db.sync etc\n- Due to above, there is a subtle change in behaviour around directory creation. If the user calls getInstance with \"/foo/bar/baz\", if \"/foo/bar/\" exists, \"baz\" will be created, then db.sync under that\n- Also due to above we need to explain how to construct a new path equivalent to the datastore location under the old API.\n- Removal of restriction on database names. Because it's just a plain path now, and it was a pointless restriction.\n- Some eventbus changes (see below)\n\nSome tests currently failing, including `EndToEndEncryptionTest`, which we can clean up later.\n\nOpen questions:\n- Is it correct to have a static `EventBus` on `DocumentStore`\n- What events should be posted on the `DocumentStore` eventbus vs `Database` instance eventbus. An example here would be the DatastoreClosed event.\n- What else should be renamed, should events be renamed?\n- Is there still a need for a method to list `DocumentStore`s? I have provided `listInstances`\n","created_at":"2016-10-21T11:17:15Z","updated_at":"2016-10-31T16:10:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"481866fdc36d124f7cac53d6d6efc25a215384da","assignee":{"login":"rhyshort","id":1616727,"avatar_url":"https://avatars.githubusercontent.com/u/1616727?v=3","gravatar_id":"","url":"https://api.github.com/users/rhyshort","html_url":"https://github.com/rhyshort","followers_url":"https://api.github.com/users/rhyshort/followers","following_url":"https://api.github.com/users/rhyshort/following{/other_user}","gists_url":"https://api.github.com/users/rhyshort/gists{/gist_id}","starred_url":"https://api.github.com/users/rhyshort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhyshort/subscriptions","organizations_url":"https://api.github.com/users/rhyshort/orgs","repos_url":"https://api.github.com/users/rhyshort/repos","events_url":"https://api.github.com/users/rhyshort/events{/privacy}","received_events_url":"https://api.github.com/users/rhyshort/received_events","type":"User","site_admin":false},"assignees":[{"login":"rhyshort","id":1616727,"avatar_url":"https://avatars.githubusercontent.com/u/1616727?v=3","gravatar_id":"","url":"https://api.github.com/users/rhyshort","html_url":"https://github.com/rhyshort","followers_url":"https://api.github.com/users/rhyshort/followers","following_url":"https://api.github.com/users/rhyshort/following{/other_user}","gists_url":"https://api.github.com/users/rhyshort/gists{/gist_id}","starred_url":"https://api.github.com/users/rhyshort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhyshort/subscriptions","organizations_url":"https://api.github.com/users/rhyshort/orgs","repos_url":"https://api.github.com/users/rhyshort/repos","events_url":"https://api.github.com/users/rhyshort/events{/privacy}","received_events_url":"https://api.github.com/users/rhyshort/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/cloudant/sync-android/milestones/3","html_url":"https://github.com/cloudant/sync-android/milestones/2.0.0","labels_url":"https://api.github.com/repos/cloudant/sync-android/milestones/3/labels","id":1857180,"number":3,"title":"2.0.0","description":"","creator":{"login":"rhyshort","id":1616727,"avatar_url":"https://avatars.githubusercontent.com/u/1616727?v=3","gravatar_id":"","url":"https://api.github.com/users/rhyshort","html_url":"https://github.com/rhyshort","followers_url":"https://api.github.com/users/rhyshort/followers","following_url":"https://api.github.com/users/rhyshort/following{/other_user}","gists_url":"https://api.github.com/users/rhyshort/gists{/gist_id}","starred_url":"https://api.github.com/users/rhyshort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhyshort/subscriptions","organizations_url":"https://api.github.com/users/rhyshort/orgs","repos_url":"https://api.github.com/users/rhyshort/repos","events_url":"https://api.github.com/users/rhyshort/events{/privacy}","received_events_url":"https://api.github.com/users/rhyshort/received_events","type":"User","site_admin":false},"open_issues":5,"closed_issues":4,"state":"open","created_at":"2016-06-30T11:40:20Z","updated_at":"2016-10-27T14:24:21Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/cloudant/sync-android/pulls/380/commits","review_comments_url":"https://api.github.com/repos/cloudant/sync-android/pulls/380/comments","review_comment_url":"https://api.github.com/repos/cloudant/sync-android/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cloudant/sync-android/issues/380/comments","statuses_url":"https://api.github.com/repos/cloudant/sync-android/statuses/248a5a8d30a3dfd867a01d23a45f3ab416153cae","head":{"label":"cloudant:284-refactor-datastore-indexmanager-4-remove-datastoremanager","ref":"284-refactor-datastore-indexmanager-4-remove-datastoremanager","sha":"248a5a8d30a3dfd867a01d23a45f3ab416153cae","user":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"repo":{"id":16811502,"name":"sync-android","full_name":"cloudant/sync-android","owner":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cloudant/sync-android","description":"A JSON-based document datastore for Android applications","fork":false,"url":"https://api.github.com/repos/cloudant/sync-android","forks_url":"https://api.github.com/repos/cloudant/sync-android/forks","keys_url":"https://api.github.com/repos/cloudant/sync-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloudant/sync-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloudant/sync-android/teams","hooks_url":"https://api.github.com/repos/cloudant/sync-android/hooks","issue_events_url":"https://api.github.com/repos/cloudant/sync-android/issues/events{/number}","events_url":"https://api.github.com/repos/cloudant/sync-android/events","assignees_url":"https://api.github.com/repos/cloudant/sync-android/assignees{/user}","branches_url":"https://api.github.com/repos/cloudant/sync-android/branches{/branch}","tags_url":"https://api.github.com/repos/cloudant/sync-android/tags","blobs_url":"https://api.github.com/repos/cloudant/sync-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloudant/sync-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloudant/sync-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloudant/sync-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloudant/sync-android/statuses/{sha}","languages_url":"https://api.github.com/repos/cloudant/sync-android/languages","stargazers_url":"https://api.github.com/repos/cloudant/sync-android/stargazers","contributors_url":"https://api.github.com/repos/cloudant/sync-android/contributors","subscribers_url":"https://api.github.com/repos/cloudant/sync-android/subscribers","subscription_url":"https://api.github.com/repos/cloudant/sync-android/subscription","commits_url":"https://api.github.com/repos/cloudant/sync-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloudant/sync-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloudant/sync-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloudant/sync-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloudant/sync-android/contents/{+path}","compare_url":"https://api.github.com/repos/cloudant/sync-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloudant/sync-android/merges","archive_url":"https://api.github.com/repos/cloudant/sync-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloudant/sync-android/downloads","issues_url":"https://api.github.com/repos/cloudant/sync-android/issues{/number}","pulls_url":"https://api.github.com/repos/cloudant/sync-android/pulls{/number}","milestones_url":"https://api.github.com/repos/cloudant/sync-android/milestones{/number}","notifications_url":"https://api.github.com/repos/cloudant/sync-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloudant/sync-android/labels{/name}","releases_url":"https://api.github.com/repos/cloudant/sync-android/releases{/id}","deployments_url":"https://api.github.com/repos/cloudant/sync-android/deployments","created_at":"2014-02-13T17:52:09Z","updated_at":"2016-10-25T09:44:25Z","pushed_at":"2016-10-31T16:01:44Z","git_url":"git://github.com/cloudant/sync-android.git","ssh_url":"git@github.com:cloudant/sync-android.git","clone_url":"https://github.com/cloudant/sync-android.git","svn_url":"https://github.com/cloudant/sync-android","homepage":"","size":25910,"stargazers_count":179,"watchers_count":179,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":55,"mirror_url":null,"open_issues_count":44,"forks":55,"open_issues":44,"watchers":179,"default_branch":"master"}},"base":{"label":"cloudant:feature-284-refactor-datastore-indexmanager","ref":"feature-284-refactor-datastore-indexmanager","sha":"6e473520f0194c1ba2eec948337688e582348a58","user":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"repo":{"id":16811502,"name":"sync-android","full_name":"cloudant/sync-android","owner":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cloudant/sync-android","description":"A JSON-based document datastore for Android applications","fork":false,"url":"https://api.github.com/repos/cloudant/sync-android","forks_url":"https://api.github.com/repos/cloudant/sync-android/forks","keys_url":"https://api.github.com/repos/cloudant/sync-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloudant/sync-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloudant/sync-android/teams","hooks_url":"https://api.github.com/repos/cloudant/sync-android/hooks","issue_events_url":"https://api.github.com/repos/cloudant/sync-android/issues/events{/number}","events_url":"https://api.github.com/repos/cloudant/sync-android/events","assignees_url":"https://api.github.com/repos/cloudant/sync-android/assignees{/user}","branches_url":"https://api.github.com/repos/cloudant/sync-android/branches{/branch}","tags_url":"https://api.github.com/repos/cloudant/sync-android/tags","blobs_url":"https://api.github.com/repos/cloudant/sync-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloudant/sync-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloudant/sync-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloudant/sync-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloudant/sync-android/statuses/{sha}","languages_url":"https://api.github.com/repos/cloudant/sync-android/languages","stargazers_url":"https://api.github.com/repos/cloudant/sync-android/stargazers","contributors_url":"https://api.github.com/repos/cloudant/sync-android/contributors","subscribers_url":"https://api.github.com/repos/cloudant/sync-android/subscribers","subscription_url":"https://api.github.com/repos/cloudant/sync-android/subscription","commits_url":"https://api.github.com/repos/cloudant/sync-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloudant/sync-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloudant/sync-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloudant/sync-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloudant/sync-android/contents/{+path}","compare_url":"https://api.github.com/repos/cloudant/sync-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloudant/sync-android/merges","archive_url":"https://api.github.com/repos/cloudant/sync-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloudant/sync-android/downloads","issues_url":"https://api.github.com/repos/cloudant/sync-android/issues{/number}","pulls_url":"https://api.github.com/repos/cloudant/sync-android/pulls{/number}","milestones_url":"https://api.github.com/repos/cloudant/sync-android/milestones{/number}","notifications_url":"https://api.github.com/repos/cloudant/sync-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloudant/sync-android/labels{/name}","releases_url":"https://api.github.com/repos/cloudant/sync-android/releases{/id}","deployments_url":"https://api.github.com/repos/cloudant/sync-android/deployments","created_at":"2014-02-13T17:52:09Z","updated_at":"2016-10-25T09:44:25Z","pushed_at":"2016-10-31T16:01:44Z","git_url":"git://github.com/cloudant/sync-android.git","ssh_url":"git@github.com:cloudant/sync-android.git","clone_url":"https://github.com/cloudant/sync-android.git","svn_url":"https://github.com/cloudant/sync-android","homepage":"","size":25910,"stargazers_count":179,"watchers_count":179,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":55,"mirror_url":null,"open_issues_count":44,"forks":55,"open_issues":44,"watchers":179,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/380"},"html":{"href":"https://github.com/cloudant/sync-android/pull/380"},"issue":{"href":"https://api.github.com/repos/cloudant/sync-android/issues/380"},"comments":{"href":"https://api.github.com/repos/cloudant/sync-android/issues/380/comments"},"review_comments":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/380/comments"},"review_comment":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cloudant/sync-android/pulls/380/commits"},"statuses":{"href":"https://api.github.com/repos/cloudant/sync-android/statuses/248a5a8d30a3dfd867a01d23a45f3ab416153cae"}}}}
{"actor":{"display_login":"tomblench"}}