{"action":"created","comment":{"url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/comments/39516396","id":39516396,"diff_hunk":"@@ -194,147 +172,392 @@ public GuideProbe getGuider() {\n         return guider;\n     }\n \n+    /**\n+     * Quick boolean method to determine if this object contains any targets, as calling getTargets().nonEmpty\n+     * is inefficient since it creates a new list.\n+     * @return true if there are any targets in this object, and false otherwise\n+     */\n+    public boolean containsTargets() {\n+        return bagsTarget.isDefined() || manualTargets.nonEmpty();\n+    }\n+\n+    /**\n+     * Determine if the targets contain the specified target.\n+     * This is the case if the given target has been selected by BAGS or manually.\n+     * @param target the target in question\n+     * @return true if either the BAGS target or a manual target, and false otherwise\n+     */\n     @Override\n-    public boolean containsTarget(SPTarget target) {\n-        return targetOptions.getOptions().contains(target);\n+    public boolean containsTarget(final SPTarget target) {\n+        return target != null && (bagsTarget.exists(target::equals) || manualTargets.contains(target));\n     }\n \n+    /**\n+     * Get a list of the targets. If a BAGS target has been specified, it will be prepended to the list of\n+     * manual targets\n+     * @return a list of all targets\n+     */\n     @Override\n     public ImList<SPTarget> getTargets() {\n-        return targetOptions.getOptions();\n+        if (bagsTarget.isDefined())\n+            return manualTargets.cons(bagsTarget.getValue());\n+        else\n+            return manualTargets;\n+    }\n+\n+    /**\n+     * Get a list of the manual targets only.\n+     * @return a list of the manual targets\n+     */\n+    public ImList<SPTarget> getManualTargets() {\n+        return manualTargets;\n     }\n \n+    /**\n+     * Create a deep clone of this instance.\n+     * @return the deep clone\n+     */\n     @Override\n     public GuideProbeTargets cloneTargets() {\n-        Option<Integer>   primaryIndex = targetOptions.getPrimaryIndex();\n-        ImList<SPTarget> clonedTargets = targetOptions.getOptions().map(new Function1<SPTarget, SPTarget>() {\n-            public SPTarget apply(final SPTarget target) {\n-                return target.clone();\n-            }\n-        });\n-        OptionsListImpl<SPTarget> clone = OptionsListImpl.create(primaryIndex, clonedTargets);\n-        return new GuideProbeTargets(guider, clone);\n+        final Option<SPTarget> bagsTargetClone = bagsTarget.map(SPTarget::clone);\n+        final ImList<SPTarget> manualTargetsClone = manualTargets.map(SPTarget::clone);\n+\n+        // Cases:\n+        // 1. Primary is None\n+        // 2. Primary is BAGS\n+        // 3. Primary is in manual list\n+        final Option<SPTarget> primaryTargetClone = primaryTarget.equals(bagsTarget) ?\n+                bagsTargetClone :\n+                primaryTarget.map(t -> manualTargetsClone.get(manualTargets.indexOf(t)));\n+\n+        return new GuideProbeTargets(guider, bagsTargetClone, primaryTargetClone, manualTargetsClone);\n     }\n \n+\n+    /**\n+     * Remove a target.\n+     * If it is the BAGS target, then create a new copy with BAGS target set to None.\n+     * If it is the primary target, then create a new copy with no primary target.\n+     * @param target the target to remove\n+     * @return a copy of this GuideProbeTargets with the target removed\n+     */\n     @Override\n-    public GuideProbeTargets removeTarget(SPTarget target) {\n-        return update(UpdateOps.remove(target));\n+    public GuideProbeTargets removeTarget(final SPTarget target) {\n+        if (!bagsTarget.exists(target::equals) && !manualTargets.contains(target))\n+            return this;\n+\n+        final Option<SPTarget> bagsTargetNew = possiblyRemoveTarget.apply(bagsTarget, target);\n+        final Option<SPTarget> primaryTargetNew = possiblyRemoveTarget.apply(primaryTarget, target);\n+        final ImList<SPTarget> manualTargetsNew = manualTargets.remove(target);\n+        return new GuideProbeTargets(guider, bagsTargetNew, primaryTargetNew, manualTargetsNew);\n+    }\n+\n+    /**\n+     * Remove a target. If is the primary target, we want to maintain a primary target, either as\n+     * the next candidate in the list if one is defined, or the previous candidate if one isn't (otherwise\n+     * None).\n+     * @param target the target to remove\n+     * @return a copy of this GuideProbeTargets with the target removed and a primary selected as per the description\n+     */\n+    public GuideProbeTargets removeTargetSelectPrimary(final SPTarget target) {\n+        // If no primary, or target is not primary, then regular removal is sufficient.\n+        if (!primaryTarget.exists(target::equals))\n+            return removeTarget(target);\n+\n+        final Option<SPTarget> bagsTargetNew = possiblyRemoveTarget.apply(bagsTarget, target);\n+        final ImList<SPTarget> manualTargetsNew = manualTargets.remove(target);\n+\n+        // We are removing the primary target, so determine the new primary if one can be chosen.\n+        final ImList<SPTarget> oldTargets = getTargets();\n+        final int oldIndex = oldTargets.indexOf(target);\n+        final int newIndex = oldIndex+1 < oldTargets.size() ? oldIndex+1\n+                : (oldIndex-1 >= 0 ? oldIndex-1 : -1);\n+        final Option<SPTarget> primaryTargetNew = newIndex == -1 ? NO_TARGET : new Some<>(oldTargets.get(newIndex));\n+        return new GuideProbeTargets(guider, bagsTargetNew, primaryTargetNew, manualTargetsNew);\n     }\n \n+    /**\n+     * Iterator to all of the SPTargets in this object, including the BAGS target (which leads).\n+     */\n     @Override\n     public Iterator<SPTarget> iterator() {\n-        return targetOptions.iterator();\n+        return getTargets().iterator();\n+    }\n+\n+    public Option<SPTarget> getBagsTarget() {\n+        return bagsTarget;\n     }\n \n     public Option<SPTarget> getPrimary() {\n-        return targetOptions.getPrimary();\n+        return primaryTarget;\n     }\n \n-    @Override\n-    public GuideProbeTargets selectPrimary(Option<SPTarget> primary) {\n-        return new GuideProbeTargets(guider, targetOptions.selectPrimary(primary));\n+    /**\n+     * Determine if the primary guide star is the guide star as selected by BAGS.\n+     * If the primary guide star is not selected, this returns false.\n+     * @return returns true if the primary guide star is the BAGS star, else false\n+     */\n+    public boolean primaryIsBagsTarget() {\n+        return primaryTarget.exists(t -> bagsTarget.exists(t::equals));\n     }\n \n-    @Override\n-    public GuideProbeTargets selectPrimary(SPTarget primary) {\n-        return new GuideProbeTargets(guider, targetOptions.selectPrimary(primary));\n+    /**\n+     * Determine if the primary guide star is a manual target.\n+     * If the primary guide star is not selected, this returns false.\n+     * @return returns true if the primary guide star is a manual target, else false\n+     */\n+    public boolean primaryIsManualTarget() {\n+        return primaryTarget.exists(manualTargets::contains);\n     }\n \n-    @Override\n-    public GuideProbeTargets setPrimary(SPTarget primary) {\n-        return new GuideProbeTargets(guider, targetOptions.setPrimary(primary));\n+    /**\n+     * Set the BAGS target. If the primary is the old BAGS target or unset, then the primary is set to the\n+     * new BAGS target automatically; otherwise, it is maintained.\n+     * @param targetOption the new BAGS target\n+     * @return a new GuideProbeTargets with the primary target and BAGS target as described\n+     */\n+    public GuideProbeTargets setBagsTarget(final Option<SPTarget> targetOption) {\n+        if (targetOption.equals(bagsTarget))\n+            return this;\n+\n+        final Option<SPTarget> primaryTargetNew = primaryIsBagsTarget() || primaryTarget.isEmpty() ? targetOption : primaryTarget;\n+        return new GuideProbeTargets(guider, targetOption, primaryTargetNew, manualTargets);\n     }\n \n-    @Override\n-    public Option<Integer> getPrimaryIndex() {\n-        return targetOptions.getPrimaryIndex();\n+    /**\n+     * Set the BAGS target. If the primary is the old BAGS target, then the primary is set to the\n+     * new BAGS target automatically; otherwise, it is maintained.\n+     * @param target the new BAGS target\n+     * @return a new GuideProbeTargets with the primary target and BAGS target as described\n+     */\n+    public GuideProbeTargets setBagsTarget(final SPTarget target) {\n+        return setBagsTarget(ImOption.apply(target));\n     }\n \n-    @Override\n-    public GuideProbeTargets setPrimaryIndex(Option<Integer> primary) {\n-        return new GuideProbeTargets(guider, targetOptions.setPrimaryIndex(primary));\n+    /**\n+     * Simply set the primary guide star indiscriminately to the BAGS guide star.\n+     * If there is no BAGS guide star, then primary is unset.\n+     * @return a new GuideProbeTargets with the primary target set as described\n+     */\n+    public GuideProbeTargets setPrimaryToBagsTarget() {\n+        if (primaryIsBagsTarget())\n+            return this;\n+        return new GuideProbeTargets(guider, bagsTarget, bagsTarget, manualTargets);\n     }\n \n-    @Override\n-    public GuideProbeTargets setPrimaryIndex(int primary) {\n-        return new GuideProbeTargets(guider, targetOptions.setPrimaryIndex(primary));\n+    /**\n+     * Select the primary guide star. This must already be either the BAGS guide star or in the\n+     * list of manual targets if it is defined.\n+     * @param targetOption the primary target to select, or None\n+     * @return a new GuideProbeTargets with the primary target as indicated\n+     */\n+    public GuideProbeTargets selectPrimary(final Option<SPTarget> targetOption) {\n+        if (targetOption.equals(primaryTarget))\n+            return this;\n+        return new GuideProbeTargets(guider, bagsTarget, targetOption, manualTargets);\n     }\n \n-    @Override\n-    public ImList<SPTarget> getOptions() {\n-        return targetOptions.getOptions();\n+    /**\n+     * Select the primary guide star. This must already be either the BAGS guide star or in the\n+     * list of manual targets.\n+     * @param target the primary target to select\n+     * @return a new GuideProbeTargets with the primary target as indicated\n+     */\n+    public GuideProbeTargets selectPrimary(final SPTarget target) {\n+        final Option<SPTarget> targetOption = target == null ? NO_TARGET : new Some<>(target);\n+        return selectPrimary(targetOption);\n     }\n \n-    @Override\n-    public GuideProbeTargets setOptions(ImList<SPTarget> newList) {\n-        return new GuideProbeTargets(guider, targetOptions.setOptions(newList));\n+    /**\n+     * Set the primary guide star. If it is not in the list, add it to the end of the list and mark it as the primary.\n+     * @param target the primary guide star.\n+     * @return the new GuideProbeTargets with the primary target as indicated.\n+     */\n+    public GuideProbeTargets setPrimary(final SPTarget target) {\n+        if (target == null)\n+            return new GuideProbeTargets(guider, bagsTarget, NO_TARGET, manualTargets);\n+\n+        final boolean alreadyInList = manualTargets.contains(target);\n+        if (alreadyInList && primaryTarget.exists(target::equals))\n+            return this;\n+\n+        final ImList<SPTarget> manualTargetsNew = alreadyInList ? manualTargets : manualTargets.append(target);\n+        return new GuideProbeTargets(guider, bagsTarget, new Some<>(target), manualTargetsNew);\n     }\n \n-    @Override\n-    public GuideProbeTargets update(Option<Integer> primaryIndex, ImList<SPTarget> list) {\n-        return new GuideProbeTargets(guider, targetOptions.update(primaryIndex, list));\n+    /**\n+     * Return the index of the primary target, if one exists, or None if there is no primary target.\n+     * Note that if a BAGS target exists, we count the BAGS target as index 0 and then begin counting the manual targets at index 1.\n+     * Otherwise, we begin counting the manual targets at index 0.\n+     * @return the index as described above, or None if no primary\n+     */\n+    public Option<Integer> getPrimaryIndex() {\n+        if (primaryIsBagsTarget())\n+            return new Some<>(0);\n+\n+        final int bagsIncrementor = bagsTarget.isEmpty() ? 0 : 1;\n+        return primaryTarget.map(t -> manualTargets.indexOf(t) + bagsIncrementor);\n     }\n \n-    @Override\n-    public GuideProbeTargets update(Op<SPTarget> op) {\n-        return new GuideProbeTargets(guider, targetOptions.update(op));\n+    /**\n+     * Set the primary target by index.\n+     * If no index is specified, return a new GuideProbeTargets with no primary.\n+     * If there is a BAGS star, we begin counting it as 0, and then the manual targets at index 1.\n+     * Otherwise, we begin counting the manual targets at index 0.\n+     * @param indexOption the optional index to use as the primary\n+     * @return the new GuideProbeTargets with the new primary as described above\n+     */\n+    public GuideProbeTargets setPrimaryIndex(final Option<Integer> indexOption) {\n+        // If the current primary is already as set, nothing to do.\n+        final Option<Integer> oldPrimaryIndex = getPrimaryIndex();\n+        if (indexOption.exists(i -> oldPrimaryIndex.exists(i::equals))\n+                || (indexOption.isEmpty() && oldPrimaryIndex.isEmpty()))\n+            return this;\n+\n+        if (indexOption.isEmpty())\n+            return new GuideProbeTargets(guider, bagsTarget, NO_TARGET, manualTargets);\n+\n+        return setPrimaryIndex(indexOption.getValue());\n+    }\n+\n+    /**\n+     * Set the primary target by index.\n+     * If there is a BAGS star, we begin counting it as 0, and then the manual targets at index 1.\n+     * Otherwise, we begin counting the manual targets at index 0.\n+     * @param index the index to use as the primary\n+     * @throws java.lang.IndexOutOfBoundsException if the index does not indicate a valid guide star","path":"bundle/edu.gemini.pot/src/main/java/edu/gemini/spModel/target/env/GuideProbeTargets.java","position":537,"original_position":537,"commit_id":"cf9c660bcc18243cd5e21e1f712fa8e30b0af4c1","original_commit_id":"cf9c660bcc18243cd5e21e1f712fa8e30b0af4c1","user":{"login":"cquiroz","id":3615303,"avatar_url":"https://avatars.githubusercontent.com/u/3615303?v=3","gravatar_id":"","url":"https://api.github.com/users/cquiroz","html_url":"https://github.com/cquiroz","followers_url":"https://api.github.com/users/cquiroz/followers","following_url":"https://api.github.com/users/cquiroz/following{/other_user}","gists_url":"https://api.github.com/users/cquiroz/gists{/gist_id}","starred_url":"https://api.github.com/users/cquiroz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cquiroz/subscriptions","organizations_url":"https://api.github.com/users/cquiroz/orgs","repos_url":"https://api.github.com/users/cquiroz/repos","events_url":"https://api.github.com/users/cquiroz/events{/privacy}","received_events_url":"https://api.github.com/users/cquiroz/received_events","type":"User","site_admin":false},"body":"Could you instead return `Option[GuideProbeTargets]`","created_at":"2015-09-15T14:28:11Z","updated_at":"2015-09-15T14:28:11Z","html_url":"https://github.com/gemini-hlsw/ocs/pull/545#discussion_r39516396","pull_request_url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545","_links":{"self":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/comments/39516396"},"html":{"href":"https://github.com/gemini-hlsw/ocs/pull/545#discussion_r39516396"},"pull_request":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545"}}},"pull_request":{"url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545","id":44676689,"html_url":"https://github.com/gemini-hlsw/ocs/pull/545","diff_url":"https://github.com/gemini-hlsw/ocs/pull/545.diff","patch_url":"https://github.com/gemini-hlsw/ocs/pull/545.patch","issue_url":"https://api.github.com/repos/gemini-hlsw/ocs/issues/545","number":545,"state":"open","locked":false,"title":"OCSADV-410A: Data model changes and changes to Target Editor for BAGS","user":{"login":"sraaphorst","id":8795653,"avatar_url":"https://avatars.githubusercontent.com/u/8795653?v=3","gravatar_id":"","url":"https://api.github.com/users/sraaphorst","html_url":"https://github.com/sraaphorst","followers_url":"https://api.github.com/users/sraaphorst/followers","following_url":"https://api.github.com/users/sraaphorst/following{/other_user}","gists_url":"https://api.github.com/users/sraaphorst/gists{/gist_id}","starred_url":"https://api.github.com/users/sraaphorst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sraaphorst/subscriptions","organizations_url":"https://api.github.com/users/sraaphorst/orgs","repos_url":"https://api.github.com/users/sraaphorst/repos","events_url":"https://api.github.com/users/sraaphorst/events{/privacy}","received_events_url":"https://api.github.com/users/sraaphorst/received_events","type":"User","site_admin":false},"body":"Apologies for the nightmare of a PR this is.\r\nThis comprises the first two milestones for BAGS (background AGS, i.e. AGS lookups done in the background).\r\n\r\nThe main elements changed here:\r\n* The `GuideProbeTargets` class has essentially been rewritten from the ground up to allow for both a primary guide star and a BAGS guide star. The old `GuideProbeTargets` used an `OptionsList` to contain a list of `SPTarget` with one designated optionally as the primary. Since this behaviour no longer makes sense as we need two \"special\" `SPTargets` that can significantly interact and place restrictions on each other, the entire class has been revamped.\r\n\r\n* The change has been propagated through the data model and through the test cases.\r\n\r\n* The Target Editor has been changed to accommodate the idea of an automatic guide star as selected by BAGS. This guide star should always appear at the top of the target list and not be able to be deleted or moved. Classes included in this change as `TelescopePosWidget` and `EdCompTargetList`, primarily.","created_at":"2015-09-10T14:46:11Z","updated_at":"2015-09-15T14:28:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"af5ae9eb0fa10270d3665a2c989c410ad425d83d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545/commits","review_comments_url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545/comments","review_comment_url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gemini-hlsw/ocs/issues/545/comments","statuses_url":"https://api.github.com/repos/gemini-hlsw/ocs/statuses/cf9c660bcc18243cd5e21e1f712fa8e30b0af4c1","head":{"label":"sraaphorst:feature/OCSADV-410","ref":"feature/OCSADV-410","sha":"cf9c660bcc18243cd5e21e1f712fa8e30b0af4c1","user":{"login":"sraaphorst","id":8795653,"avatar_url":"https://avatars.githubusercontent.com/u/8795653?v=3","gravatar_id":"","url":"https://api.github.com/users/sraaphorst","html_url":"https://github.com/sraaphorst","followers_url":"https://api.github.com/users/sraaphorst/followers","following_url":"https://api.github.com/users/sraaphorst/following{/other_user}","gists_url":"https://api.github.com/users/sraaphorst/gists{/gist_id}","starred_url":"https://api.github.com/users/sraaphorst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sraaphorst/subscriptions","organizations_url":"https://api.github.com/users/sraaphorst/orgs","repos_url":"https://api.github.com/users/sraaphorst/repos","events_url":"https://api.github.com/users/sraaphorst/events{/privacy}","received_events_url":"https://api.github.com/users/sraaphorst/received_events","type":"User","site_admin":false},"repo":{"id":24112855,"name":"ocs","full_name":"sraaphorst/ocs","owner":{"login":"sraaphorst","id":8795653,"avatar_url":"https://avatars.githubusercontent.com/u/8795653?v=3","gravatar_id":"","url":"https://api.github.com/users/sraaphorst","html_url":"https://github.com/sraaphorst","followers_url":"https://api.github.com/users/sraaphorst/followers","following_url":"https://api.github.com/users/sraaphorst/following{/other_user}","gists_url":"https://api.github.com/users/sraaphorst/gists{/gist_id}","starred_url":"https://api.github.com/users/sraaphorst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sraaphorst/subscriptions","organizations_url":"https://api.github.com/users/sraaphorst/orgs","repos_url":"https://api.github.com/users/sraaphorst/repos","events_url":"https://api.github.com/users/sraaphorst/events{/privacy}","received_events_url":"https://api.github.com/users/sraaphorst/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sraaphorst/ocs","description":"","fork":true,"url":"https://api.github.com/repos/sraaphorst/ocs","forks_url":"https://api.github.com/repos/sraaphorst/ocs/forks","keys_url":"https://api.github.com/repos/sraaphorst/ocs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sraaphorst/ocs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sraaphorst/ocs/teams","hooks_url":"https://api.github.com/repos/sraaphorst/ocs/hooks","issue_events_url":"https://api.github.com/repos/sraaphorst/ocs/issues/events{/number}","events_url":"https://api.github.com/repos/sraaphorst/ocs/events","assignees_url":"https://api.github.com/repos/sraaphorst/ocs/assignees{/user}","branches_url":"https://api.github.com/repos/sraaphorst/ocs/branches{/branch}","tags_url":"https://api.github.com/repos/sraaphorst/ocs/tags","blobs_url":"https://api.github.com/repos/sraaphorst/ocs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sraaphorst/ocs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sraaphorst/ocs/git/refs{/sha}","trees_url":"https://api.github.com/repos/sraaphorst/ocs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sraaphorst/ocs/statuses/{sha}","languages_url":"https://api.github.com/repos/sraaphorst/ocs/languages","stargazers_url":"https://api.github.com/repos/sraaphorst/ocs/stargazers","contributors_url":"https://api.github.com/repos/sraaphorst/ocs/contributors","subscribers_url":"https://api.github.com/repos/sraaphorst/ocs/subscribers","subscription_url":"https://api.github.com/repos/sraaphorst/ocs/subscription","commits_url":"https://api.github.com/repos/sraaphorst/ocs/commits{/sha}","git_commits_url":"https://api.github.com/repos/sraaphorst/ocs/git/commits{/sha}","comments_url":"https://api.github.com/repos/sraaphorst/ocs/comments{/number}","issue_comment_url":"https://api.github.com/repos/sraaphorst/ocs/issues/comments{/number}","contents_url":"https://api.github.com/repos/sraaphorst/ocs/contents/{+path}","compare_url":"https://api.github.com/repos/sraaphorst/ocs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sraaphorst/ocs/merges","archive_url":"https://api.github.com/repos/sraaphorst/ocs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sraaphorst/ocs/downloads","issues_url":"https://api.github.com/repos/sraaphorst/ocs/issues{/number}","pulls_url":"https://api.github.com/repos/sraaphorst/ocs/pulls{/number}","milestones_url":"https://api.github.com/repos/sraaphorst/ocs/milestones{/number}","notifications_url":"https://api.github.com/repos/sraaphorst/ocs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sraaphorst/ocs/labels{/name}","releases_url":"https://api.github.com/repos/sraaphorst/ocs/releases{/id}","created_at":"2014-09-16T18:48:19Z","updated_at":"2015-05-06T12:56:42Z","pushed_at":"2015-09-10T14:40:37Z","git_url":"git://github.com/sraaphorst/ocs.git","ssh_url":"git@github.com:sraaphorst/ocs.git","clone_url":"https://github.com/sraaphorst/ocs.git","svn_url":"https://github.com/sraaphorst/ocs","homepage":null,"size":267508,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"gemini-hlsw:develop","ref":"develop","sha":"4acc5acc8b3bcbe7471b0c545e5a8b3614786d23","user":{"login":"gemini-hlsw","id":8593735,"avatar_url":"https://avatars.githubusercontent.com/u/8593735?v=3","gravatar_id":"","url":"https://api.github.com/users/gemini-hlsw","html_url":"https://github.com/gemini-hlsw","followers_url":"https://api.github.com/users/gemini-hlsw/followers","following_url":"https://api.github.com/users/gemini-hlsw/following{/other_user}","gists_url":"https://api.github.com/users/gemini-hlsw/gists{/gist_id}","starred_url":"https://api.github.com/users/gemini-hlsw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gemini-hlsw/subscriptions","organizations_url":"https://api.github.com/users/gemini-hlsw/orgs","repos_url":"https://api.github.com/users/gemini-hlsw/repos","events_url":"https://api.github.com/users/gemini-hlsw/events{/privacy}","received_events_url":"https://api.github.com/users/gemini-hlsw/received_events","type":"Organization","site_admin":false},"repo":{"id":23963494,"name":"ocs","full_name":"gemini-hlsw/ocs","owner":{"login":"gemini-hlsw","id":8593735,"avatar_url":"https://avatars.githubusercontent.com/u/8593735?v=3","gravatar_id":"","url":"https://api.github.com/users/gemini-hlsw","html_url":"https://github.com/gemini-hlsw","followers_url":"https://api.github.com/users/gemini-hlsw/followers","following_url":"https://api.github.com/users/gemini-hlsw/following{/other_user}","gists_url":"https://api.github.com/users/gemini-hlsw/gists{/gist_id}","starred_url":"https://api.github.com/users/gemini-hlsw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gemini-hlsw/subscriptions","organizations_url":"https://api.github.com/users/gemini-hlsw/orgs","repos_url":"https://api.github.com/users/gemini-hlsw/repos","events_url":"https://api.github.com/users/gemini-hlsw/events{/privacy}","received_events_url":"https://api.github.com/users/gemini-hlsw/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gemini-hlsw/ocs","description":"Observatory Control Software","fork":false,"url":"https://api.github.com/repos/gemini-hlsw/ocs","forks_url":"https://api.github.com/repos/gemini-hlsw/ocs/forks","keys_url":"https://api.github.com/repos/gemini-hlsw/ocs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gemini-hlsw/ocs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gemini-hlsw/ocs/teams","hooks_url":"https://api.github.com/repos/gemini-hlsw/ocs/hooks","issue_events_url":"https://api.github.com/repos/gemini-hlsw/ocs/issues/events{/number}","events_url":"https://api.github.com/repos/gemini-hlsw/ocs/events","assignees_url":"https://api.github.com/repos/gemini-hlsw/ocs/assignees{/user}","branches_url":"https://api.github.com/repos/gemini-hlsw/ocs/branches{/branch}","tags_url":"https://api.github.com/repos/gemini-hlsw/ocs/tags","blobs_url":"https://api.github.com/repos/gemini-hlsw/ocs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gemini-hlsw/ocs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gemini-hlsw/ocs/git/refs{/sha}","trees_url":"https://api.github.com/repos/gemini-hlsw/ocs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gemini-hlsw/ocs/statuses/{sha}","languages_url":"https://api.github.com/repos/gemini-hlsw/ocs/languages","stargazers_url":"https://api.github.com/repos/gemini-hlsw/ocs/stargazers","contributors_url":"https://api.github.com/repos/gemini-hlsw/ocs/contributors","subscribers_url":"https://api.github.com/repos/gemini-hlsw/ocs/subscribers","subscription_url":"https://api.github.com/repos/gemini-hlsw/ocs/subscription","commits_url":"https://api.github.com/repos/gemini-hlsw/ocs/commits{/sha}","git_commits_url":"https://api.github.com/repos/gemini-hlsw/ocs/git/commits{/sha}","comments_url":"https://api.github.com/repos/gemini-hlsw/ocs/comments{/number}","issue_comment_url":"https://api.github.com/repos/gemini-hlsw/ocs/issues/comments{/number}","contents_url":"https://api.github.com/repos/gemini-hlsw/ocs/contents/{+path}","compare_url":"https://api.github.com/repos/gemini-hlsw/ocs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gemini-hlsw/ocs/merges","archive_url":"https://api.github.com/repos/gemini-hlsw/ocs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gemini-hlsw/ocs/downloads","issues_url":"https://api.github.com/repos/gemini-hlsw/ocs/issues{/number}","pulls_url":"https://api.github.com/repos/gemini-hlsw/ocs/pulls{/number}","milestones_url":"https://api.github.com/repos/gemini-hlsw/ocs/milestones{/number}","notifications_url":"https://api.github.com/repos/gemini-hlsw/ocs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gemini-hlsw/ocs/labels{/name}","releases_url":"https://api.github.com/repos/gemini-hlsw/ocs/releases{/id}","created_at":"2014-09-12T14:20:23Z","updated_at":"2015-07-13T13:36:36Z","pushed_at":"2015-09-15T13:54:21Z","git_url":"git://github.com/gemini-hlsw/ocs.git","ssh_url":"git@github.com:gemini-hlsw/ocs.git","clone_url":"https://github.com/gemini-hlsw/ocs.git","svn_url":"https://github.com/gemini-hlsw/ocs","homepage":"","size":277095,"stargazers_count":4,"watchers_count":4,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":7,"forks":13,"open_issues":7,"watchers":4,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545"},"html":{"href":"https://github.com/gemini-hlsw/ocs/pull/545"},"issue":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/issues/545"},"comments":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/issues/545/comments"},"review_comments":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545/comments"},"review_comment":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/pulls/545/commits"},"statuses":{"href":"https://api.github.com/repos/gemini-hlsw/ocs/statuses/cf9c660bcc18243cd5e21e1f712fa8e30b0af4c1"}}}}