{"action":"created","comment":{"url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/comments/30554128","id":30554128,"diff_hunk":"@@ -0,0 +1,54 @@\n+﻿using System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+\n+namespace Dynamo.Extensions\n+{\n+    /// <summary>\n+    /// An extension to the model layer of Dynamo\n+    /// </summary>\n+    public interface IExtension : IDisposable\n+    {\n+        /// <summary>\n+        /// A unique id for this extension instance.  \n+        /// \n+        /// There may be multiple instances of the same type, but the application \n+        /// will *not* allow two instances to coexist with the same id.\n+        /// </summary>\n+        Guid Id { get; }","path":"src/DynamoCore/Extensions/IExtension.cs","position":19,"original_position":19,"commit_id":"0197d7a0e061c9924d2b9ac476c9f39eb84b7548","original_commit_id":"0197d7a0e061c9924d2b9ac476c9f39eb84b7548","user":{"login":"pboyer","id":916345,"avatar_url":"https://avatars.githubusercontent.com/u/916345?v=3","gravatar_id":"","url":"https://api.github.com/users/pboyer","html_url":"https://github.com/pboyer","followers_url":"https://api.github.com/users/pboyer/followers","following_url":"https://api.github.com/users/pboyer/following{/other_user}","gists_url":"https://api.github.com/users/pboyer/gists{/gist_id}","starred_url":"https://api.github.com/users/pboyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pboyer/subscriptions","organizations_url":"https://api.github.com/users/pboyer/orgs","repos_url":"https://api.github.com/users/pboyer/repos","events_url":"https://api.github.com/users/pboyer/events{/privacy}","received_events_url":"https://api.github.com/users/pboyer/received_events","type":"User","site_admin":false},"body":"Okay - that's reasonable. ","created_at":"2015-05-18T22:35:50Z","updated_at":"2015-05-18T22:35:50Z","html_url":"https://github.com/DynamoDS/Dynamo/pull/4472#discussion_r30554128","pull_request_url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472","_links":{"self":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/comments/30554128"},"html":{"href":"https://github.com/DynamoDS/Dynamo/pull/4472#discussion_r30554128"},"pull_request":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472"}}},"pull_request":{"url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472","id":35369452,"html_url":"https://github.com/DynamoDS/Dynamo/pull/4472","diff_url":"https://github.com/DynamoDS/Dynamo/pull/4472.diff","patch_url":"https://github.com/DynamoDS/Dynamo/pull/4472.patch","issue_url":"https://api.github.com/repos/DynamoDS/Dynamo/issues/4472","number":4472,"state":"open","locked":false,"title":"Dynamo Extension Framework: Architecture and Base classes","user":{"login":"pboyer","id":916345,"avatar_url":"https://avatars.githubusercontent.com/u/916345?v=3","gravatar_id":"","url":"https://api.github.com/users/pboyer","html_url":"https://github.com/pboyer","followers_url":"https://api.github.com/users/pboyer/followers","following_url":"https://api.github.com/users/pboyer/following{/other_user}","gists_url":"https://api.github.com/users/pboyer/gists{/gist_id}","starred_url":"https://api.github.com/users/pboyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pboyer/subscriptions","organizations_url":"https://api.github.com/users/pboyer/orgs","repos_url":"https://api.github.com/users/pboyer/repos","events_url":"https://api.github.com/users/pboyer/events{/privacy}","received_events_url":"https://api.github.com/users/pboyer/received_events","type":"User","site_admin":false},"body":"## Purpose\r\n\r\nThis pull request contains the core data structures and interfaces for the **Dynamo Extension Framework**.  \r\n\r\nThe intent here is to move complex application development out of the core of the app and move towards a modular architecture for non-critical application components.\r\n\r\nThe architectural approach here is rather generic, but there are various considerations to the design that ought to be pointed out:\r\n\r\n##### Full-stack, but separated\r\n\r\nExtensions should be able to modify the `View` and `Model` layer.  Such applications could be separable, but do not need to conform to MVVM (e.g. there's no requirement to implement a `ViewModel`).  \r\n\r\nBecause these components are separable, it allows:\r\n1.  Graceful behavior when there is not a `View` Extension attached\r\n2.  Allows multiple `View` extensions to respond to a single `Model` extension.  \r\n\r\n##### Runtime reversibility\r\n\r\nExtensions should be dynamically removable, within the bounds of the limits of things like CLR assembly loading.  That is, we're not proposing to use `AppDomain`'s or process isolation, but it should be possible to unload an extension.\r\n\r\n##### Non-interaction\r\n\r\nExtensions are not expected to interact on the same layer.  Thus, there are no guarantees on lifetime method invocations (e.g. `Startup`, `Ready`)\r\n\r\n##### Allow duplicate types, but not identifiers\r\n\r\nThere can be multiple Extensions of the same `Type` during an active Dynamo session.  This allows for future Extensions to be implemented in a markup language or something similar, which would open up Extensions to non-programmer users.  \r\n\r\n##### Minimality, Extensibility\r\n\r\nWe should minimize the amount of API we expose and attempt to maintain that API in a stable form as long as possible.  \r\n\r\nThat said, we also want to allow for extensibility of the API in the future.  This is why the various data structures handed to the Extension's are in classes which might have additional parameters added in the future.  \r\n\r\n##### Package support\r\n\r\nIt should be possible for a client to bundle an Extension along with a package.  Thus, it needs to be possible to dynamically load an Extension at run time.  This could be done simply by extending the `PackageLoader` to look for such `ExtensionDefinition` files.   \r\n\r\n\r\n## Loading\r\n\r\nIn the typical case, an `ExtensionDefinition` file is provided by the client in order to define the `Extension` and represented as an XML file.  The `IExtensionLoader` implements the requirements for how these ought to be structured.  \r\n\r\nSpecifically, these files should be structured as `(Name)_ExtensionDefinition.xml` in user-configurable location, to be assigned in the `PathManager`.  Similarly, `ViewExtension` instances should be named with `(Name)_ViewExtensionDefinition.xml`.  **That is, the `PathManager` will need to be extended in order to support this capability.**\r\n\r\nThese files contain enough information to dynamically load and instantiate the `IExtension` from an `Assembly`.  However, note that this allows for the possibility for further expansion with \"simple\" extensions hosted inside of an `Extension` that do not require writing CLR code. \r\n\r\n\r\n## Extension Ownership\r\n\r\nThere are two types of Extension : `IExtension` and `IViewExtension`.  The former is expected to live in the `IExtensionManager` on the `DynamoModel` and the latter on the `IViewExtensionManager` on the `DynamoView.`  \r\n\r\nThat is, an Extension is an application-level construct.\r\n\r\n\r\n## Extension Lifetime\r\n\r\nThe full lifetime is as follows:\r\n\r\n1.  Instantiation of `Extension`'s (within `DynamoModel.Start`)\r\n2.  `Extension.Startup` (within `DynamoModel.Start`)\r\n3.  `Extension.Ready` (at the end of `DynamoModel.Start`)\r\n4.  Instantiation of `ViewExtensions`'s (within `DynamoView.Start`)\r\n5.  `ViewExtension.Loaded` (within `DynamoView.Start`)\r\n... user uses application ...\r\n6.  `ViewExtension.Shutdown` (within `DynamoView.WindowClosing`)\r\n7.  `Extension.Shutdown` (within `DynamoModel.Shutdown`)\r\n8.  `ViewExtension.Dispose` (within `DynamoView.Dispose`)\r\n9.  `Extension.Dispose` (within `DynamoModel.Dispose`)\r\n\r\n##### Instantiation\r\n\r\nWhen an extension is already present on the user machine in the directory specified in the `PathManager`, it should be instantiated inside of the `DynamoModel` constructor.  **Like all lifetime methods, it should be invoked while surrounded by a `try-catch` block in order to prevent failures and, where possible, to log or show information about the failure.**  \r\n\r\nThe same goes for a `ViewExtension`, except inside of the `DynamoView`.  \r\n\r\n##### Startup\r\n\r\nThe `IExtension.Startup` method should be called by `DynamoModel` immediately after instantiation.  This should also happen inside of the `DynamoModel` constructor. There is no guarantee to the extension implementor in which order the extensions will be loaded.  \r\n\r\nFurther, this method is not guaranteed to be invoked unless it is present at startup.  \r\n\r\nA `StartupParams` object is handed to the `Extension` that provides application level events and data structures.  \r\n\r\nA similar pattern is expected for the `View` layer, but note that the `StartupParams` object provides a handle to the `IExtensionManager` on the `Model` layer.  This gives the `View` object the opportunity to synchronize with a `Model` layer extension.  Alternatively, the `ViewExtension` could inject an `IExtension` in to the `Model` layer at this point via `IExtensionManager.Add`.  \r\n\r\n##### Ready / Loaded\r\n\r\nThis action should be executed after the `DynamoModel` is fully instantiated.  All application layer constructs are guaranteed to be loaded.\r\n\r\nThe same is true for `IViewExtension.Loaded`, except it will be executed with the guarantee that the `DynamoView` is already loaded.\r\n\r\n##### Shutdown\r\n\r\nThis is provided because sometimes an implementor will need to do something before disposal of the owner object.\r\n\r\n##### Dispose\r\n\r\nThis is provided for event handler cleanup, etc.  \r\n\r\n### Impact assessment\r\n\r\n- [ ] Changes the way 3rd party nodes work (Add ikeough to the reviewer list)\r\n- [ ] Includes migrations (Add ikeough to the reviewer list)\r\n- [ ] Changes a public interface (Add lukechurch to the reviewer list)\r\n- [ ] Affects which components of the system depends on which other components (Add pboyer to the reviewer list)\r\n- [x] Introduces new components (Add lukechurch to the reviewer list)\r\n- [ ] Has a performance impact (Add keyu to the reviewer list)\r\n- [ ] Changes the installer (Add sharadkjaiswal to the reviewer list)\r\n\r\n#### References\r\n\r\n\r\n#### Testing strategy\r\n\r\nThis pull request only represents the base classes, but is deliberately designed so as to support mocking of things like file systems and failure logic.  \r\n\r\n### Review staging\r\n\r\n- [x] Architectural Design Review\r\n- (n/a ?) UI Review\r\n\r\n### Reviewers\r\n\r\n@lukechurch \r\n\r\n### FYIs\r\n\r\n@ikeough @Benglin ","created_at":"2015-05-13T20:53:08Z","updated_at":"2015-05-18T22:35:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3dd36b76b35eb4b552d15d9b5210d148bb09bdc4","assignee":{"login":"lukechurch","id":2978182,"avatar_url":"https://avatars.githubusercontent.com/u/2978182?v=3","gravatar_id":"","url":"https://api.github.com/users/lukechurch","html_url":"https://github.com/lukechurch","followers_url":"https://api.github.com/users/lukechurch/followers","following_url":"https://api.github.com/users/lukechurch/following{/other_user}","gists_url":"https://api.github.com/users/lukechurch/gists{/gist_id}","starred_url":"https://api.github.com/users/lukechurch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukechurch/subscriptions","organizations_url":"https://api.github.com/users/lukechurch/orgs","repos_url":"https://api.github.com/users/lukechurch/repos","events_url":"https://api.github.com/users/lukechurch/events{/privacy}","received_events_url":"https://api.github.com/users/lukechurch/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472/commits","review_comments_url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472/comments","review_comment_url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DynamoDS/Dynamo/issues/4472/comments","statuses_url":"https://api.github.com/repos/DynamoDS/Dynamo/statuses/0197d7a0e061c9924d2b9ac476c9f39eb84b7548","head":{"label":"pboyer:exts","ref":"exts","sha":"0197d7a0e061c9924d2b9ac476c9f39eb84b7548","user":{"login":"pboyer","id":916345,"avatar_url":"https://avatars.githubusercontent.com/u/916345?v=3","gravatar_id":"","url":"https://api.github.com/users/pboyer","html_url":"https://github.com/pboyer","followers_url":"https://api.github.com/users/pboyer/followers","following_url":"https://api.github.com/users/pboyer/following{/other_user}","gists_url":"https://api.github.com/users/pboyer/gists{/gist_id}","starred_url":"https://api.github.com/users/pboyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pboyer/subscriptions","organizations_url":"https://api.github.com/users/pboyer/orgs","repos_url":"https://api.github.com/users/pboyer/repos","events_url":"https://api.github.com/users/pboyer/events{/privacy}","received_events_url":"https://api.github.com/users/pboyer/received_events","type":"User","site_admin":false},"repo":{"id":20731728,"name":"Dynamo","full_name":"pboyer/Dynamo","owner":{"login":"pboyer","id":916345,"avatar_url":"https://avatars.githubusercontent.com/u/916345?v=3","gravatar_id":"","url":"https://api.github.com/users/pboyer","html_url":"https://github.com/pboyer","followers_url":"https://api.github.com/users/pboyer/followers","following_url":"https://api.github.com/users/pboyer/following{/other_user}","gists_url":"https://api.github.com/users/pboyer/gists{/gist_id}","starred_url":"https://api.github.com/users/pboyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pboyer/subscriptions","organizations_url":"https://api.github.com/users/pboyer/orgs","repos_url":"https://api.github.com/users/pboyer/repos","events_url":"https://api.github.com/users/pboyer/events{/privacy}","received_events_url":"https://api.github.com/users/pboyer/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pboyer/Dynamo","description":"Visual Programming For Revit","fork":true,"url":"https://api.github.com/repos/pboyer/Dynamo","forks_url":"https://api.github.com/repos/pboyer/Dynamo/forks","keys_url":"https://api.github.com/repos/pboyer/Dynamo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pboyer/Dynamo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pboyer/Dynamo/teams","hooks_url":"https://api.github.com/repos/pboyer/Dynamo/hooks","issue_events_url":"https://api.github.com/repos/pboyer/Dynamo/issues/events{/number}","events_url":"https://api.github.com/repos/pboyer/Dynamo/events","assignees_url":"https://api.github.com/repos/pboyer/Dynamo/assignees{/user}","branches_url":"https://api.github.com/repos/pboyer/Dynamo/branches{/branch}","tags_url":"https://api.github.com/repos/pboyer/Dynamo/tags","blobs_url":"https://api.github.com/repos/pboyer/Dynamo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pboyer/Dynamo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pboyer/Dynamo/git/refs{/sha}","trees_url":"https://api.github.com/repos/pboyer/Dynamo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pboyer/Dynamo/statuses/{sha}","languages_url":"https://api.github.com/repos/pboyer/Dynamo/languages","stargazers_url":"https://api.github.com/repos/pboyer/Dynamo/stargazers","contributors_url":"https://api.github.com/repos/pboyer/Dynamo/contributors","subscribers_url":"https://api.github.com/repos/pboyer/Dynamo/subscribers","subscription_url":"https://api.github.com/repos/pboyer/Dynamo/subscription","commits_url":"https://api.github.com/repos/pboyer/Dynamo/commits{/sha}","git_commits_url":"https://api.github.com/repos/pboyer/Dynamo/git/commits{/sha}","comments_url":"https://api.github.com/repos/pboyer/Dynamo/comments{/number}","issue_comment_url":"https://api.github.com/repos/pboyer/Dynamo/issues/comments{/number}","contents_url":"https://api.github.com/repos/pboyer/Dynamo/contents/{+path}","compare_url":"https://api.github.com/repos/pboyer/Dynamo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pboyer/Dynamo/merges","archive_url":"https://api.github.com/repos/pboyer/Dynamo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pboyer/Dynamo/downloads","issues_url":"https://api.github.com/repos/pboyer/Dynamo/issues{/number}","pulls_url":"https://api.github.com/repos/pboyer/Dynamo/pulls{/number}","milestones_url":"https://api.github.com/repos/pboyer/Dynamo/milestones{/number}","notifications_url":"https://api.github.com/repos/pboyer/Dynamo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pboyer/Dynamo/labels{/name}","releases_url":"https://api.github.com/repos/pboyer/Dynamo/releases{/id}","created_at":"2014-06-11T16:06:09Z","updated_at":"2015-03-25T14:35:49Z","pushed_at":"2015-05-14T22:29:34Z","git_url":"git://github.com/pboyer/Dynamo.git","ssh_url":"git@github.com:pboyer/Dynamo.git","clone_url":"https://github.com/pboyer/Dynamo.git","svn_url":"https://github.com/pboyer/Dynamo","homepage":"http://dynamobim.org","size":761167,"stargazers_count":1,"watchers_count":1,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"DynamoDS:master","ref":"master","sha":"373dfc0b0720743ca21d0440d8d381b25d98e42b","user":{"login":"DynamoDS","id":6528209,"avatar_url":"https://avatars.githubusercontent.com/u/6528209?v=3","gravatar_id":"","url":"https://api.github.com/users/DynamoDS","html_url":"https://github.com/DynamoDS","followers_url":"https://api.github.com/users/DynamoDS/followers","following_url":"https://api.github.com/users/DynamoDS/following{/other_user}","gists_url":"https://api.github.com/users/DynamoDS/gists{/gist_id}","starred_url":"https://api.github.com/users/DynamoDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DynamoDS/subscriptions","organizations_url":"https://api.github.com/users/DynamoDS/orgs","repos_url":"https://api.github.com/users/DynamoDS/repos","events_url":"https://api.github.com/users/DynamoDS/events{/privacy}","received_events_url":"https://api.github.com/users/DynamoDS/received_events","type":"Organization","site_admin":false},"repo":{"id":3395179,"name":"Dynamo","full_name":"DynamoDS/Dynamo","owner":{"login":"DynamoDS","id":6528209,"avatar_url":"https://avatars.githubusercontent.com/u/6528209?v=3","gravatar_id":"","url":"https://api.github.com/users/DynamoDS","html_url":"https://github.com/DynamoDS","followers_url":"https://api.github.com/users/DynamoDS/followers","following_url":"https://api.github.com/users/DynamoDS/following{/other_user}","gists_url":"https://api.github.com/users/DynamoDS/gists{/gist_id}","starred_url":"https://api.github.com/users/DynamoDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DynamoDS/subscriptions","organizations_url":"https://api.github.com/users/DynamoDS/orgs","repos_url":"https://api.github.com/users/DynamoDS/repos","events_url":"https://api.github.com/users/DynamoDS/events{/privacy}","received_events_url":"https://api.github.com/users/DynamoDS/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DynamoDS/Dynamo","description":"Visual Programming","fork":false,"url":"https://api.github.com/repos/DynamoDS/Dynamo","forks_url":"https://api.github.com/repos/DynamoDS/Dynamo/forks","keys_url":"https://api.github.com/repos/DynamoDS/Dynamo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DynamoDS/Dynamo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DynamoDS/Dynamo/teams","hooks_url":"https://api.github.com/repos/DynamoDS/Dynamo/hooks","issue_events_url":"https://api.github.com/repos/DynamoDS/Dynamo/issues/events{/number}","events_url":"https://api.github.com/repos/DynamoDS/Dynamo/events","assignees_url":"https://api.github.com/repos/DynamoDS/Dynamo/assignees{/user}","branches_url":"https://api.github.com/repos/DynamoDS/Dynamo/branches{/branch}","tags_url":"https://api.github.com/repos/DynamoDS/Dynamo/tags","blobs_url":"https://api.github.com/repos/DynamoDS/Dynamo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DynamoDS/Dynamo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DynamoDS/Dynamo/git/refs{/sha}","trees_url":"https://api.github.com/repos/DynamoDS/Dynamo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DynamoDS/Dynamo/statuses/{sha}","languages_url":"https://api.github.com/repos/DynamoDS/Dynamo/languages","stargazers_url":"https://api.github.com/repos/DynamoDS/Dynamo/stargazers","contributors_url":"https://api.github.com/repos/DynamoDS/Dynamo/contributors","subscribers_url":"https://api.github.com/repos/DynamoDS/Dynamo/subscribers","subscription_url":"https://api.github.com/repos/DynamoDS/Dynamo/subscription","commits_url":"https://api.github.com/repos/DynamoDS/Dynamo/commits{/sha}","git_commits_url":"https://api.github.com/repos/DynamoDS/Dynamo/git/commits{/sha}","comments_url":"https://api.github.com/repos/DynamoDS/Dynamo/comments{/number}","issue_comment_url":"https://api.github.com/repos/DynamoDS/Dynamo/issues/comments{/number}","contents_url":"https://api.github.com/repos/DynamoDS/Dynamo/contents/{+path}","compare_url":"https://api.github.com/repos/DynamoDS/Dynamo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DynamoDS/Dynamo/merges","archive_url":"https://api.github.com/repos/DynamoDS/Dynamo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DynamoDS/Dynamo/downloads","issues_url":"https://api.github.com/repos/DynamoDS/Dynamo/issues{/number}","pulls_url":"https://api.github.com/repos/DynamoDS/Dynamo/pulls{/number}","milestones_url":"https://api.github.com/repos/DynamoDS/Dynamo/milestones{/number}","notifications_url":"https://api.github.com/repos/DynamoDS/Dynamo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DynamoDS/Dynamo/labels{/name}","releases_url":"https://api.github.com/repos/DynamoDS/Dynamo/releases{/id}","created_at":"2012-02-09T07:35:33Z","updated_at":"2015-05-18T20:35:47Z","pushed_at":"2015-05-18T22:02:25Z","git_url":"git://github.com/DynamoDS/Dynamo.git","ssh_url":"git@github.com:DynamoDS/Dynamo.git","clone_url":"https://github.com/DynamoDS/Dynamo.git","svn_url":"https://github.com/DynamoDS/Dynamo","homepage":"http://dynamobim.org","size":948587,"stargazers_count":221,"watchers_count":221,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":167,"mirror_url":null,"open_issues_count":612,"forks":167,"open_issues":612,"watchers":221,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472"},"html":{"href":"https://github.com/DynamoDS/Dynamo/pull/4472"},"issue":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/issues/4472"},"comments":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/issues/4472/comments"},"review_comments":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472/comments"},"review_comment":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/pulls/4472/commits"},"statuses":{"href":"https://api.github.com/repos/DynamoDS/Dynamo/statuses/0197d7a0e061c9924d2b9ac476c9f39eb84b7548"}}}}