{"action":"created","comment":{"url":"https://api.github.com/repos/threadly/threadly/pulls/comments/26321937","id":26321937,"diff_hunk":"@@ -769,50 +606,207 @@ private static double getTruePercent(Collection<Boolean> list) {\n   }\n   \n   /**\n-   * Called at the start of execution to track statistics around task execution.\n+   * <p>This class primarily holds the structures used to store the statistics.  These can not be \n+   * maintained in the parent class since sub classes need to be able to access them.  This is to \n+   * help facilitate allowing the parent class to be garbage collected freely despite references \n+   * to subclasses from other thread garbage collection roots.</p>\n    * \n-   * @param taskWrapper Wrapper that is about to be executed\n-   */\n-  protected void trackTaskStart(Wrapper taskWrapper) {\n-    runningTasks.put(taskWrapper, taskWrapper.startTime = Clock.accurateForwardProgressingMillis());\n+   * @author jent - Mike Jensen\n+   * @since 3.5.0\n+   */\n+  protected static class StatsManager {\n+    protected final AtomicInteger totalHighPriorityExecutions;\n+    protected final AtomicInteger totalLowPriorityExecutions;\n+    protected final ConcurrentHashMap<Wrapper, Long> runningTasks;\n+    protected final ConcurrentArrayList<Long> runTimes;\n+    protected final ConcurrentArrayList<Boolean> lowPriorityWorkerAvailable;\n+    protected final ConcurrentArrayList<Boolean> highPriorityWorkerAvailable;\n+    protected final ConcurrentArrayList<Long> lowPriorityExecutionDelay;\n+    protected final ConcurrentArrayList<Long> highPriorityExecutionDelay;\n+    \n+    protected StatsManager() {\n+      totalHighPriorityExecutions = new AtomicInteger(0);\n+      totalLowPriorityExecutions = new AtomicInteger(0);\n+      runningTasks = new ConcurrentHashMap<Wrapper, Long>();\n+      int endPadding = MAX_WINDOW_SIZE * 2;\n+      runTimes = new ConcurrentArrayList<Long>(0, endPadding);\n+      lowPriorityWorkerAvailable = new ConcurrentArrayList<Boolean>(0, endPadding);\n+      highPriorityWorkerAvailable = new ConcurrentArrayList<Boolean>(0, endPadding);\n+      lowPriorityExecutionDelay = new ConcurrentArrayList<Long>(0, endPadding);\n+      highPriorityExecutionDelay = new ConcurrentArrayList<Long>(0, endPadding);\n+    }\n+\n+    /**\n+     * Called at the start of execution to track statistics around task execution.\n+     * \n+     * @param taskWrapper Wrapper that is about to be executed\n+     */\n+    protected void trackTaskStart(Wrapper taskWrapper) {\n+      runningTasks.put(taskWrapper, taskWrapper.startTime = Clock.accurateForwardProgressingMillis());\n+      \n+      switch (taskWrapper.priority) {\n+        case High:\n+          totalHighPriorityExecutions.incrementAndGet();\n+          break;\n+        case Low:\n+          totalLowPriorityExecutions.incrementAndGet();\n+          break;\n+        default:\n+          throw new UnsupportedOperationException();\n+      }\n+    }\n+    \n+    /**\n+     * Used to track how long tasks are tacking to complete.\n+     * \n+     * @param taskWrapper wrapper for task that completed\n+     */\n+    protected void trackTaskFinish(Wrapper taskWrapper) {\n+      long finishTime = Clock.accurateForwardProgressingMillis();\n+      synchronized (runTimes.getModificationLock()) {\n+        runTimes.add(finishTime - taskWrapper.startTime);\n+        trimList(runTimes);\n+      }\n+      runningTasks.remove(taskWrapper);\n+    }\n     \n-    switch (taskWrapper.priority) {\n-      case High:\n-        totalHighPriorityExecutions.incrementAndGet();\n-        break;\n-      case Low:\n-        totalLowPriorityExecutions.incrementAndGet();\n-        break;\n-      default:\n-        throw new UnsupportedOperationException();\n+    /**\n+     * Reduces the list size to be within the max window size.\n+     * \n+     * Should have the list synchronized/locked before calling.\n+     * \n+     * @param list LinkedList to check size of.\n+     */\n+    @SuppressWarnings(\"rawtypes\")\n+    protected static void trimList(Deque list) {\n+      while (list.size() > MAX_WINDOW_SIZE) {\n+        list.removeFirst();\n+      }\n     }\n   }\n   \n   /**\n-   * Used to track how long tasks are tacking to complete.\n+   * <p>An extending class of {@link WorkerPool}, allowing us to gather statistics about how \n+   * workers are used in the executor.  An example of such statistics are how long tasks are \n+   * delayed from their desired execution.  Another example is how often a worker can be reused vs \n+   * how often they have to be created.</p>\n    * \n-   * @param taskWrapper wrapper for task that completed\n+   * @author jent - Mike Jensen\n+   * @since 3.5.0\n    */\n-  protected void trackTaskFinish(Wrapper taskWrapper) {\n-    long finishTime = Clock.accurateForwardProgressingMillis();\n-    synchronized (runTimes.getModificationLock()) {\n-      runTimes.add(finishTime - taskWrapper.startTime);\n-      trimList(runTimes);\n+  protected static class StatisticWorkerPool extends WorkerPool {","path":"src/main/java/org/threadly/concurrent/PrioritySchedulerStatisticTracker.java","position":583,"original_position":583,"commit_id":"1d57c34208b769b531f2bc8c1c44e8a370888e72","original_commit_id":"1d57c34208b769b531f2bc8c1c44e8a370888e72","user":{"login":"jentfoo","id":2165757,"avatar_url":"https://avatars.githubusercontent.com/u/2165757?v=3","gravatar_id":"","url":"https://api.github.com/users/jentfoo","html_url":"https://github.com/jentfoo","followers_url":"https://api.github.com/users/jentfoo/followers","following_url":"https://api.github.com/users/jentfoo/following{/other_user}","gists_url":"https://api.github.com/users/jentfoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jentfoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jentfoo/subscriptions","organizations_url":"https://api.github.com/users/jentfoo/orgs","repos_url":"https://api.github.com/users/jentfoo/repos","events_url":"https://api.github.com/users/jentfoo/events{/privacy}","received_events_url":"https://api.github.com/users/jentfoo/received_events","type":"User","site_admin":false},"body":"I am open to suggestions...I can't figure out how to reuse more code since we end up collecting stats at multiple points in the run task functions.","created_at":"2015-03-12T17:04:28Z","updated_at":"2015-03-12T17:04:28Z","html_url":"https://github.com/threadly/threadly/pull/129#discussion_r26321937","pull_request_url":"https://api.github.com/repos/threadly/threadly/pulls/129","_links":{"self":{"href":"https://api.github.com/repos/threadly/threadly/pulls/comments/26321937"},"html":{"href":"https://github.com/threadly/threadly/pull/129#discussion_r26321937"},"pull_request":{"href":"https://api.github.com/repos/threadly/threadly/pulls/129"}}},"pull_request":{"url":"https://api.github.com/repos/threadly/threadly/pulls/129","id":31052383,"html_url":"https://github.com/threadly/threadly/pull/129","diff_url":"https://github.com/threadly/threadly/pull/129.diff","patch_url":"https://github.com/threadly/threadly/pull/129.patch","issue_url":"https://api.github.com/repos/threadly/threadly/issues/129","number":129,"state":"open","locked":false,"title":"This resolves issue #124","user":{"login":"jentfoo","id":2165757,"avatar_url":"https://avatars.githubusercontent.com/u/2165757?v=3","gravatar_id":"","url":"https://api.github.com/users/jentfoo","html_url":"https://github.com/jentfoo","followers_url":"https://api.github.com/users/jentfoo/followers","following_url":"https://api.github.com/users/jentfoo/following{/other_user}","gists_url":"https://api.github.com/users/jentfoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jentfoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jentfoo/subscriptions","organizations_url":"https://api.github.com/users/jentfoo/orgs","repos_url":"https://api.github.com/users/jentfoo/repos","events_url":"https://api.github.com/users/jentfoo/events{/privacy}","received_events_url":"https://api.github.com/users/jentfoo/received_events","type":"User","site_admin":false},"body":"This makes it so that garbage collection of PriorityScheduler, PrioritySchedulerStatisticTracker, and the Profiler will make sure started threads are stopped and also able to be garbage collected.  I had previously solved this in the SingleThreadScheduler (which was easier than these classes were).\r\n\r\nIn general the strategy to solve this was make the inner classes which were not static, to actually be static.  This required shared memory from the parent classes with those inner classes be encapsilated in a new inner class that will just store that data (also static).  This is necessary because non-static classes referenced by threads will hold a reference to their parent classes, preventing them from having the finalizer called on them.  Once we can ensure the finalizer will be called, that finalizer goes through the operation needed to stop/shutdown the running threads (in a graceful way).  Once those threads are shut down these static classes can also be collected.\r\n\r\nThis does increase the jar size, and in some ways makes the code cleaner, and in other ways makes it more complicated.  I am not super happy with these changes but I do think this bug fix is important.","created_at":"2015-03-12T16:23:43Z","updated_at":"2015-03-12T17:04:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cc0031e5fd25639a11778e407c27e24c8545efc1","assignee":{"login":"lwahlmeier","id":4663016,"avatar_url":"https://avatars.githubusercontent.com/u/4663016?v=3","gravatar_id":"","url":"https://api.github.com/users/lwahlmeier","html_url":"https://github.com/lwahlmeier","followers_url":"https://api.github.com/users/lwahlmeier/followers","following_url":"https://api.github.com/users/lwahlmeier/following{/other_user}","gists_url":"https://api.github.com/users/lwahlmeier/gists{/gist_id}","starred_url":"https://api.github.com/users/lwahlmeier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lwahlmeier/subscriptions","organizations_url":"https://api.github.com/users/lwahlmeier/orgs","repos_url":"https://api.github.com/users/lwahlmeier/repos","events_url":"https://api.github.com/users/lwahlmeier/events{/privacy}","received_events_url":"https://api.github.com/users/lwahlmeier/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/threadly/threadly/milestones/29","html_url":"https://github.com/threadly/threadly/milestones/3.5.0%20Release","labels_url":"https://api.github.com/repos/threadly/threadly/milestones/29/labels","id":1015490,"number":29,"title":"3.5.0 Release","description":"Changes/improvements included in this release:\r\n * Added \"SchedulingUtils\" class.  This class provides static implementations to help in calculating the delay for an absolute time (either minute for the current or next our, or a specific hour/minute within the day).  This can be useful when needing to schedule something (likely with scheduleAtFixedRate) to run at a regular time of day.\r\n * Reduced locking in NoThreadScheduler (which improves SingleThreadScheduler as well)\r\n * Added shutdown(Now)AndAwaitTermination feature to SingleThreadScheduler.  This feature allows you to wait till the worker thread joins to the thread issuing the shutdown call (thus ensuring cache coherency)\r\n * Added hasStopped() to \"AbstractService\".  This will be false while new and while running, it will only transition once stop() or stopIfRunning() has been called (and is running).  This can be used to check the state of services which may be able to accept requests/input before they are running (and ideally would handle those requests once started).\r\n * Fixed issue #126 via pull request #128.  This defect in the SingleThreadScheduler would cause it so that if the execution thread was being started while ANOTHER thread was also trying to execute a task, it would get a RejectedExecutionException even though the scheduler had not been shut down.\r\n * Fixed issue where allowing garbage collection of SingleThreadScheduler, PriorityScheduler, PrioritySchedulerStatisticTracker, or Profiler....could cause constructed threads to be leaked (and not stopped or collected).  This was fixed first for SingleThreadScheduler which was trivial, but then later fixed for the others in issue #124 and pull request #129\r\n * Updated build system to use gradle 2.3","creator":{"login":"jentfoo","id":2165757,"avatar_url":"https://avatars.githubusercontent.com/u/2165757?v=3","gravatar_id":"","url":"https://api.github.com/users/jentfoo","html_url":"https://github.com/jentfoo","followers_url":"https://api.github.com/users/jentfoo/followers","following_url":"https://api.github.com/users/jentfoo/following{/other_user}","gists_url":"https://api.github.com/users/jentfoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jentfoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jentfoo/subscriptions","organizations_url":"https://api.github.com/users/jentfoo/orgs","repos_url":"https://api.github.com/users/jentfoo/repos","events_url":"https://api.github.com/users/jentfoo/events{/privacy}","received_events_url":"https://api.github.com/users/jentfoo/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":3,"state":"open","created_at":"2015-03-10T20:57:29Z","updated_at":"2015-03-12T16:43:48Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/threadly/threadly/pulls/129/commits","review_comments_url":"https://api.github.com/repos/threadly/threadly/pulls/129/comments","review_comment_url":"https://api.github.com/repos/threadly/threadly/pulls/comments{/number}","comments_url":"https://api.github.com/repos/threadly/threadly/issues/129/comments","statuses_url":"https://api.github.com/repos/threadly/threadly/statuses/1d57c34208b769b531f2bc8c1c44e8a370888e72","head":{"label":"jentfoo:issue_124-leaked_threads_when_pool_garbage_collected","ref":"issue_124-leaked_threads_when_pool_garbage_collected","sha":"1d57c34208b769b531f2bc8c1c44e8a370888e72","user":{"login":"jentfoo","id":2165757,"avatar_url":"https://avatars.githubusercontent.com/u/2165757?v=3","gravatar_id":"","url":"https://api.github.com/users/jentfoo","html_url":"https://github.com/jentfoo","followers_url":"https://api.github.com/users/jentfoo/followers","following_url":"https://api.github.com/users/jentfoo/following{/other_user}","gists_url":"https://api.github.com/users/jentfoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jentfoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jentfoo/subscriptions","organizations_url":"https://api.github.com/users/jentfoo/orgs","repos_url":"https://api.github.com/users/jentfoo/repos","events_url":"https://api.github.com/users/jentfoo/events{/privacy}","received_events_url":"https://api.github.com/users/jentfoo/received_events","type":"User","site_admin":false},"repo":{"id":11236509,"name":"threadly","full_name":"jentfoo/threadly","owner":{"login":"jentfoo","id":2165757,"avatar_url":"https://avatars.githubusercontent.com/u/2165757?v=3","gravatar_id":"","url":"https://api.github.com/users/jentfoo","html_url":"https://github.com/jentfoo","followers_url":"https://api.github.com/users/jentfoo/followers","following_url":"https://api.github.com/users/jentfoo/following{/other_user}","gists_url":"https://api.github.com/users/jentfoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jentfoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jentfoo/subscriptions","organizations_url":"https://api.github.com/users/jentfoo/orgs","repos_url":"https://api.github.com/users/jentfoo/repos","events_url":"https://api.github.com/users/jentfoo/events{/privacy}","received_events_url":"https://api.github.com/users/jentfoo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jentfoo/threadly","description":"A library of tools to assist with concurrent java development, with a large focus on testability.","fork":true,"url":"https://api.github.com/repos/jentfoo/threadly","forks_url":"https://api.github.com/repos/jentfoo/threadly/forks","keys_url":"https://api.github.com/repos/jentfoo/threadly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jentfoo/threadly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jentfoo/threadly/teams","hooks_url":"https://api.github.com/repos/jentfoo/threadly/hooks","issue_events_url":"https://api.github.com/repos/jentfoo/threadly/issues/events{/number}","events_url":"https://api.github.com/repos/jentfoo/threadly/events","assignees_url":"https://api.github.com/repos/jentfoo/threadly/assignees{/user}","branches_url":"https://api.github.com/repos/jentfoo/threadly/branches{/branch}","tags_url":"https://api.github.com/repos/jentfoo/threadly/tags","blobs_url":"https://api.github.com/repos/jentfoo/threadly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jentfoo/threadly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jentfoo/threadly/git/refs{/sha}","trees_url":"https://api.github.com/repos/jentfoo/threadly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jentfoo/threadly/statuses/{sha}","languages_url":"https://api.github.com/repos/jentfoo/threadly/languages","stargazers_url":"https://api.github.com/repos/jentfoo/threadly/stargazers","contributors_url":"https://api.github.com/repos/jentfoo/threadly/contributors","subscribers_url":"https://api.github.com/repos/jentfoo/threadly/subscribers","subscription_url":"https://api.github.com/repos/jentfoo/threadly/subscription","commits_url":"https://api.github.com/repos/jentfoo/threadly/commits{/sha}","git_commits_url":"https://api.github.com/repos/jentfoo/threadly/git/commits{/sha}","comments_url":"https://api.github.com/repos/jentfoo/threadly/comments{/number}","issue_comment_url":"https://api.github.com/repos/jentfoo/threadly/issues/comments{/number}","contents_url":"https://api.github.com/repos/jentfoo/threadly/contents/{+path}","compare_url":"https://api.github.com/repos/jentfoo/threadly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jentfoo/threadly/merges","archive_url":"https://api.github.com/repos/jentfoo/threadly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jentfoo/threadly/downloads","issues_url":"https://api.github.com/repos/jentfoo/threadly/issues{/number}","pulls_url":"https://api.github.com/repos/jentfoo/threadly/pulls{/number}","milestones_url":"https://api.github.com/repos/jentfoo/threadly/milestones{/number}","notifications_url":"https://api.github.com/repos/jentfoo/threadly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jentfoo/threadly/labels{/name}","releases_url":"https://api.github.com/repos/jentfoo/threadly/releases{/id}","created_at":"2013-07-07T16:52:34Z","updated_at":"2015-03-12T15:32:47Z","pushed_at":"2015-03-12T16:23:08Z","git_url":"git://github.com/jentfoo/threadly.git","ssh_url":"git@github.com:jentfoo/threadly.git","clone_url":"https://github.com/jentfoo/threadly.git","svn_url":"https://github.com/jentfoo/threadly","homepage":"threadly.org","size":5221,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"threadly:unstable_staging","ref":"unstable_staging","sha":"df5d5068de4b1339c3a44808344a0abbf7a3fdf5","user":{"login":"threadly","id":4627301,"avatar_url":"https://avatars.githubusercontent.com/u/4627301?v=3","gravatar_id":"","url":"https://api.github.com/users/threadly","html_url":"https://github.com/threadly","followers_url":"https://api.github.com/users/threadly/followers","following_url":"https://api.github.com/users/threadly/following{/other_user}","gists_url":"https://api.github.com/users/threadly/gists{/gist_id}","starred_url":"https://api.github.com/users/threadly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/threadly/subscriptions","organizations_url":"https://api.github.com/users/threadly/orgs","repos_url":"https://api.github.com/users/threadly/repos","events_url":"https://api.github.com/users/threadly/events{/privacy}","received_events_url":"https://api.github.com/users/threadly/received_events","type":"Organization","site_admin":false},"repo":{"id":9874976,"name":"threadly","full_name":"threadly/threadly","owner":{"login":"threadly","id":4627301,"avatar_url":"https://avatars.githubusercontent.com/u/4627301?v=3","gravatar_id":"","url":"https://api.github.com/users/threadly","html_url":"https://github.com/threadly","followers_url":"https://api.github.com/users/threadly/followers","following_url":"https://api.github.com/users/threadly/following{/other_user}","gists_url":"https://api.github.com/users/threadly/gists{/gist_id}","starred_url":"https://api.github.com/users/threadly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/threadly/subscriptions","organizations_url":"https://api.github.com/users/threadly/orgs","repos_url":"https://api.github.com/users/threadly/repos","events_url":"https://api.github.com/users/threadly/events{/privacy}","received_events_url":"https://api.github.com/users/threadly/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/threadly/threadly","description":"A library of tools to assist with safe concurrent java development.  Providing a unique priority based thread pool, and ways to distrbute threaded work safely.","fork":false,"url":"https://api.github.com/repos/threadly/threadly","forks_url":"https://api.github.com/repos/threadly/threadly/forks","keys_url":"https://api.github.com/repos/threadly/threadly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/threadly/threadly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/threadly/threadly/teams","hooks_url":"https://api.github.com/repos/threadly/threadly/hooks","issue_events_url":"https://api.github.com/repos/threadly/threadly/issues/events{/number}","events_url":"https://api.github.com/repos/threadly/threadly/events","assignees_url":"https://api.github.com/repos/threadly/threadly/assignees{/user}","branches_url":"https://api.github.com/repos/threadly/threadly/branches{/branch}","tags_url":"https://api.github.com/repos/threadly/threadly/tags","blobs_url":"https://api.github.com/repos/threadly/threadly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/threadly/threadly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/threadly/threadly/git/refs{/sha}","trees_url":"https://api.github.com/repos/threadly/threadly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/threadly/threadly/statuses/{sha}","languages_url":"https://api.github.com/repos/threadly/threadly/languages","stargazers_url":"https://api.github.com/repos/threadly/threadly/stargazers","contributors_url":"https://api.github.com/repos/threadly/threadly/contributors","subscribers_url":"https://api.github.com/repos/threadly/threadly/subscribers","subscription_url":"https://api.github.com/repos/threadly/threadly/subscription","commits_url":"https://api.github.com/repos/threadly/threadly/commits{/sha}","git_commits_url":"https://api.github.com/repos/threadly/threadly/git/commits{/sha}","comments_url":"https://api.github.com/repos/threadly/threadly/comments{/number}","issue_comment_url":"https://api.github.com/repos/threadly/threadly/issues/comments{/number}","contents_url":"https://api.github.com/repos/threadly/threadly/contents/{+path}","compare_url":"https://api.github.com/repos/threadly/threadly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/threadly/threadly/merges","archive_url":"https://api.github.com/repos/threadly/threadly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/threadly/threadly/downloads","issues_url":"https://api.github.com/repos/threadly/threadly/issues{/number}","pulls_url":"https://api.github.com/repos/threadly/threadly/pulls{/number}","milestones_url":"https://api.github.com/repos/threadly/threadly/milestones{/number}","notifications_url":"https://api.github.com/repos/threadly/threadly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/threadly/threadly/labels{/name}","releases_url":"https://api.github.com/repos/threadly/threadly/releases{/id}","created_at":"2013-05-05T21:38:11Z","updated_at":"2015-03-12T15:30:55Z","pushed_at":"2015-03-12T15:32:39Z","git_url":"git://github.com/threadly/threadly.git","ssh_url":"git@github.com:threadly/threadly.git","clone_url":"https://github.com/threadly/threadly.git","svn_url":"https://github.com/threadly/threadly","homepage":"threadly.org","size":12341,"stargazers_count":30,"watchers_count":30,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":6,"mirror_url":null,"open_issues_count":8,"forks":6,"open_issues":8,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/threadly/threadly/pulls/129"},"html":{"href":"https://github.com/threadly/threadly/pull/129"},"issue":{"href":"https://api.github.com/repos/threadly/threadly/issues/129"},"comments":{"href":"https://api.github.com/repos/threadly/threadly/issues/129/comments"},"review_comments":{"href":"https://api.github.com/repos/threadly/threadly/pulls/129/comments"},"review_comment":{"href":"https://api.github.com/repos/threadly/threadly/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/threadly/threadly/pulls/129/commits"},"statuses":{"href":"https://api.github.com/repos/threadly/threadly/statuses/1d57c34208b769b531f2bc8c1c44e8a370888e72"}}}}