{"action":"created","comment":{"url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments/36031001","id":36031001,"diff_hunk":"@@ -0,0 +1,252 @@\n+﻿/*\n+Copyright 2015 Google Inc\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+You may obtain a copy of the License at\n+\n+    http://www.apache.org/licenses/LICENSE-2.0\n+\n+Unless required by applicable law or agreed to in writing, software\n+distributed under the License is distributed on an \"AS IS\" BASIS,\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+See the License for the specific language governing permissions and\n+limitations under the License.\n+*/\n+\n+using System;\n+using System.Collections;\n+using System.Collections.Generic;\n+using System.IO;\n+using System.Net;\n+using System.Net.Http;\n+using System.Threading;\n+using System.Threading.Tasks;\n+\n+using Newtonsoft.Json.Linq;\n+using Newtonsoft.Json;\n+\n+using Google.Apis.Auth.OAuth2.Flows;\n+using Google.Apis.Auth.OAuth2.Responses;\n+using Google.Apis.Http;\n+using Google.Apis.Logging;\n+using Google.Apis.Json;\n+using Google.Apis.Util;\n+\n+namespace Google.Apis.Auth.OAuth2\n+{\n+    /// <summary>\n+    /// Provides the Application Default Credential from the environment. \n+    /// An instance of this class represents the per-process state used to get and cache \n+    /// the credential and allows overriding the state and environment for testing purposes.\n+    /// </summary>\n+    internal class DefaultCredentialProvider\n+    {\n+        private static readonly ILogger Logger = ApplicationContext.Logger.ForType<DefaultCredentialProvider>();\n+\n+        /// <summary>Environment variable override which stores the default application credentials file path.</summary>\n+        public const string CredentialEnvironmentVariable = \"GOOGLE_APPLICATION_CREDENTIALS\";\n+\n+        /// <summary>Well known file which stores the default application credentials.</summary>\n+        private const string WellKnownCredentialsFile = \"application_default_credentials.json\";\n+\n+        /// <summary>Environment variable which contains the Application Data settings.</summary>\n+        private const string AppdataEnvironmentVariable = \"APPDATA\";\n+\n+        /// <summary>GCloud configuration directory in Windows, relative to %APPDATA%.</summary>\n+        private const string CloudSDKConfigDirectory = \"gcloud\";\n+\n+        /// <summary>Help link to the application default credentials feature.</summary>\n+        private const string HelpPermalink = \"https://developers.google.com/accounts/docs/application-default-credentials\";\n+\n+        private object lockObject = new object();\n+\n+        // These variables should only be accessed inside a synchronized block.\n+        private GoogleCredential cachedCredential = null;\n+        private bool checkedComputeEngine = false;\n+\n+        /// <summary>\n+        /// Returns the Application Default Credentials\n+        /// See <see cref=\"M:Google.Apis.Auth.OAuth2.GoogleAuth.GetApplicationDefaultCredential\"/> for details.\n+        /// </summary>\n+        public GoogleCredential GetApplicationDefaultCredential()\n+        {\n+            if (cachedCredential == null)\n+            {\n+                lock (lockObject)\n+                {\n+                    if (cachedCredential == null)\n+                    {\n+                        cachedCredential = GetDefaultCredentialUnsynchronized();\n+                    }\n+                }\n+            }\n+            if (cachedCredential != null)\n+            {\n+                return cachedCredential;\n+            }\n+\n+            throw new InvalidOperationException(String.Format(\"The Application Default Credentials are not available. They are available if running\"\n+                + \" in Google Compute Engine. Otherwise, the environment variable {0} must be defined\"\n+                + \" pointing to a file defining the credentials. See {1} for more information.\",\n+                CredentialEnvironmentVariable,\n+                HelpPermalink));\n+        }\n+\n+        /// <summary>Unsynchronized helper method to obtain the Application Default Credentials.</summary>\n+        private GoogleCredential GetDefaultCredentialUnsynchronized()\n+        {\n+            string credentialPath = null;\n+            \n+            // 1. First try the environment variable.\n+            try\n+            {\n+                credentialPath = GetEnvironmentVariable(CredentialEnvironmentVariable);\n+                if (!String.IsNullOrWhiteSpace(credentialPath))\n+                {\n+                    return CreateDefaultCredentialFromFile(credentialPath);\n+                }\n+            }\n+            catch (Exception e)\n+            {\n+                // Catching generic exception type because any corrupted file could manifest in different ways including \n+                // but not limited to the System, System.IO or from the Newtonsoft.Json namespace.\n+\n+                throw new InvalidOperationException(String.Format(\"Error reading credential file from location {0}: {1}\"\n+                                        + \"\\nPlease check the value of the Environment Variable {2}\",\n+                                        credentialPath,\n+                                        e.Message,\n+                                        CredentialEnvironmentVariable));\n+            }\n+\n+            // 2. Then try the well known file.\n+            try\n+            {\n+                credentialPath = GetWellKnownCredentialFilePath();\n+                if (!String.IsNullOrWhiteSpace(credentialPath))\n+                {\n+                    return CreateDefaultCredentialFromFile(credentialPath);\n+                }\n+            }\n+            catch (FileNotFoundException)\n+            {\n+                // File is not present, eat the exception and move on to the next check.\n+            }\n+            catch (IOException e)\n+            {\n+                throw new InvalidOperationException(String.Format(\"Error reading credential file from location {0}: {1}\"\n+                                  + \"\\nPlease rerun 'gcloud auth login' to regenerate credentials file.\",\n+                                  credentialPath,\n+                                  e.Message));\n+            }\n+\n+            // 3. Then try the compute engine, if not already checked.         \n+            if (!checkedComputeEngine)\n+            {\n+                Logger.Debug(\"Checking whether the application is running on ComputeEngine.\");\n+                bool isRunningOnComputeEngine = ComputeCredential.IsRunningOnComputeEngine().Result;\n+                checkedComputeEngine = true;\n+                if (isRunningOnComputeEngine)\n+                {\n+                    Logger.Debug(\"ComputeEngine check passed. Loading ComputeEngine Credentials.\");\n+                    return GoogleCredential.FromCredential(new ComputeCredential());\n+                }\n+            }\n+\n+            return null;\n+        }\n+\n+        /// <summary>Creates default credential from a JSON file.</summary>\n+        internal GoogleCredential CreateDefaultCredentialFromFile(string credentialPath)\n+        {\n+            Logger.Debug(String.Format(\"Loading Credential from file {0}\", credentialPath));\n+\n+            using (Stream stream = GetStream(credentialPath))\n+            {\n+                // TODO(jtattermusch): catch exception...\n+                JsonCredentialParameters credentialParameters =\n+                    NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(stream);\n+\n+                return CreateDefaultCredentialFromJson(credentialParameters);\n+            }\n+        }\n+\n+        /// <summary>Creates a default credential from JSON data. </summary>\n+        internal static GoogleCredential CreateDefaultCredentialFromJson(JsonCredentialParameters credentialParameters)\n+        {\n+            switch (credentialParameters.Type)\n+            {\n+                case JsonCredentialParameters.AuthorizedUserCredentialType:\n+                    return GoogleCredential.FromCredential(CreateUserCredentialFromJson(credentialParameters));\n+\n+                case JsonCredentialParameters.ServiceAccountCredentialType:\n+                    return GoogleCredential.FromCredential(CreateServiceAccountCredentialFromJson(credentialParameters));\n+                \n+                default:\n+                    throw new InvalidOperationException(String.Format(\"Error creating credential from JSON. Unrecognized credential type {0}.\", credentialParameters.Type));\n+            }\n+        }\n+\n+        internal static UserCredential CreateUserCredentialFromJson(JsonCredentialParameters credentialParameters)\n+        {\n+            if (credentialParameters.Type != JsonCredentialParameters.AuthorizedUserCredentialType ||\n+                string.IsNullOrEmpty(credentialParameters.ClientId) ||\n+                string.IsNullOrEmpty(credentialParameters.ClientSecret))\n+            {\n+                throw new ArgumentException(\"JSON data do not represent a valid user credential.\", \"credentialParameters\");\n+            }\n+\n+            var initializer = new GoogleAuthorizationCodeFlow.Initializer\n+            {\n+                ClientSecrets = new ClientSecrets\n+                {\n+                    ClientId = credentialParameters.ClientId,\n+                    ClientSecret = credentialParameters.ClientSecret\n+                }\n+            };\n+\n+            var token = new TokenResponse()\n+            {\n+                RefreshToken = credentialParameters.RefreshToken\n+            };\n+\n+            var flow = new GoogleAuthorizationCodeFlow(initializer);\n+            return new UserCredential(flow, \"ApplicationDefaultCredentials\", token);\n+        }\n+\n+        internal static ServiceAccountCredential CreateServiceAccountCredentialFromJson(JsonCredentialParameters credentialParameters)\n+        {\n+            if (credentialParameters.Type != JsonCredentialParameters.ServiceAccountCredentialType ||\n+                string.IsNullOrEmpty(credentialParameters.ClientEmail) ||\n+                string.IsNullOrEmpty(credentialParameters.PrivateKey))\n+            {\n+                throw new ArgumentException(\"JSON data do not represent a valid service account credential.\", \"credentialParameters\");\n+            }\n+            var initializer = new ServiceAccountCredential.Initializer(credentialParameters.ClientEmail);\n+            return new ServiceAccountCredential(initializer.FromPrivateKey(credentialParameters.PrivateKey));\n+        }\n+\n+        /// <summary> \n+        /// Helper method to return well known credential file path. This file is created by \n+        /// <a href=\"https://cloud.google.com/sdk/gcloud/reference/auth/login\">gcloud auth login</a>\n+        /// </summary>\n+        internal string GetWellKnownCredentialFilePath()\n+        {\n+            return Path.Combine(GetEnvironmentVariable(AppdataEnvironmentVariable) ?? \"\",","path":"Src/GoogleApis.Auth.DotNet4/OAuth2/DefaultCredentialProvider.cs","position":null,"original_position":235,"commit_id":"f445df289e94f51c17c8e7dc66fe77528d847ed8","original_commit_id":"a7d04817de18df273ee995f464fc712af7a65890","user":{"login":"jtattermusch","id":9939684,"avatar_url":"https://avatars.githubusercontent.com/u/9939684?v=3","gravatar_id":"","url":"https://api.github.com/users/jtattermusch","html_url":"https://github.com/jtattermusch","followers_url":"https://api.github.com/users/jtattermusch/followers","following_url":"https://api.github.com/users/jtattermusch/following{/other_user}","gists_url":"https://api.github.com/users/jtattermusch/gists{/gist_id}","starred_url":"https://api.github.com/users/jtattermusch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtattermusch/subscriptions","organizations_url":"https://api.github.com/users/jtattermusch/orgs","repos_url":"https://api.github.com/users/jtattermusch/repos","events_url":"https://api.github.com/users/jtattermusch/events{/privacy}","received_events_url":"https://api.github.com/users/jtattermusch/received_events","type":"User","site_admin":false},"body":"Done.","created_at":"2015-08-01T05:50:43Z","updated_at":"2015-08-01T05:50:43Z","html_url":"https://github.com/google/google-api-dotnet-client/pull/564#discussion_r36031001","pull_request_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564","_links":{"self":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments/36031001"},"html":{"href":"https://github.com/google/google-api-dotnet-client/pull/564#discussion_r36031001"},"pull_request":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564"}}},"pull_request":{"url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564","id":40382354,"html_url":"https://github.com/google/google-api-dotnet-client/pull/564","diff_url":"https://github.com/google/google-api-dotnet-client/pull/564.diff","patch_url":"https://github.com/google/google-api-dotnet-client/pull/564.patch","issue_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/564","number":564,"state":"open","locked":false,"title":"Application Default Credentials after API polishing","user":{"login":"jtattermusch","id":9939684,"avatar_url":"https://avatars.githubusercontent.com/u/9939684?v=3","gravatar_id":"","url":"https://api.github.com/users/jtattermusch","html_url":"https://github.com/jtattermusch","followers_url":"https://api.github.com/users/jtattermusch/followers","following_url":"https://api.github.com/users/jtattermusch/following{/other_user}","gists_url":"https://api.github.com/users/jtattermusch/gists{/gist_id}","starred_url":"https://api.github.com/users/jtattermusch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtattermusch/subscriptions","organizations_url":"https://api.github.com/users/jtattermusch/orgs","repos_url":"https://api.github.com/users/jtattermusch/repos","events_url":"https://api.github.com/users/jtattermusch/events{/privacy}","received_events_url":"https://api.github.com/users/jtattermusch/received_events","type":"User","site_admin":false},"body":"This PR contains code from #553, with the latest changes from upstream/master merged.\r\nI originally created this branch just to facilitate cleaning up the git history and to fix some of the style nits in the code.\r\n\r\nNevertheless, once I started editing the code, I realized there were some major issues with the API in the original pull request (perhaps introduced while addressing review comments)  - for example the object returned from GoogleAuth.GetApplicationDefaultCredentials() didn't expose the IsCreateScopedRequired property and accessing that property required guessing that the default credential is a service account credential in fact, explicitly typecasting it and only after that, you were able to access the IsCreateScopedRequired property - which makes no sense at all. I found other problems as well (those that are hard to catch in review until you actually start modifying the code).\r\n\r\nSo, because there were some concerns about the API in the past, i decided to take the app default credentials code (I haven't changed most of the code that implements the actual logic) and adjust the API layout.\r\n\r\nThe new API introduces a new type GoogleCredential (returned by GetApplicationDefaultCredentials()), which acts as a very thin wrapper for other credential types. That way, the API of the existing credential types could stay intact and GoogleCredential can still provide all the functionality needed. Arguably, the new design is cleaner and possibly allows more tweaking in the future if necessary.\r\n\r\nThe code is still not 100% finished, but I believe it is in good shape for an initial review (of the API and high level changes I've made).\r\n\r\n@vsubramani  @peleyal  for review","created_at":"2015-07-20T18:31:32Z","updated_at":"2015-08-01T05:50:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8b72ae3ec26f3246991d8759ec54eb25b6e75a53","assignee":{"login":"peleyal","id":3082873,"avatar_url":"https://avatars.githubusercontent.com/u/3082873?v=3","gravatar_id":"","url":"https://api.github.com/users/peleyal","html_url":"https://github.com/peleyal","followers_url":"https://api.github.com/users/peleyal/followers","following_url":"https://api.github.com/users/peleyal/following{/other_user}","gists_url":"https://api.github.com/users/peleyal/gists{/gist_id}","starred_url":"https://api.github.com/users/peleyal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peleyal/subscriptions","organizations_url":"https://api.github.com/users/peleyal/orgs","repos_url":"https://api.github.com/users/peleyal/repos","events_url":"https://api.github.com/users/peleyal/events{/privacy}","received_events_url":"https://api.github.com/users/peleyal/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564/commits","review_comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564/comments","review_comment_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/564/comments","statuses_url":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/f445df289e94f51c17c8e7dc66fe77528d847ed8","head":{"label":"jtattermusch:AppDefaultProgress","ref":"AppDefaultProgress","sha":"f445df289e94f51c17c8e7dc66fe77528d847ed8","user":{"login":"jtattermusch","id":9939684,"avatar_url":"https://avatars.githubusercontent.com/u/9939684?v=3","gravatar_id":"","url":"https://api.github.com/users/jtattermusch","html_url":"https://github.com/jtattermusch","followers_url":"https://api.github.com/users/jtattermusch/followers","following_url":"https://api.github.com/users/jtattermusch/following{/other_user}","gists_url":"https://api.github.com/users/jtattermusch/gists{/gist_id}","starred_url":"https://api.github.com/users/jtattermusch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtattermusch/subscriptions","organizations_url":"https://api.github.com/users/jtattermusch/orgs","repos_url":"https://api.github.com/users/jtattermusch/repos","events_url":"https://api.github.com/users/jtattermusch/events{/privacy}","received_events_url":"https://api.github.com/users/jtattermusch/received_events","type":"User","site_admin":false},"repo":{"id":38863126,"name":"google-api-dotnet-client","full_name":"jtattermusch/google-api-dotnet-client","owner":{"login":"jtattermusch","id":9939684,"avatar_url":"https://avatars.githubusercontent.com/u/9939684?v=3","gravatar_id":"","url":"https://api.github.com/users/jtattermusch","html_url":"https://github.com/jtattermusch","followers_url":"https://api.github.com/users/jtattermusch/followers","following_url":"https://api.github.com/users/jtattermusch/following{/other_user}","gists_url":"https://api.github.com/users/jtattermusch/gists{/gist_id}","starred_url":"https://api.github.com/users/jtattermusch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtattermusch/subscriptions","organizations_url":"https://api.github.com/users/jtattermusch/orgs","repos_url":"https://api.github.com/users/jtattermusch/repos","events_url":"https://api.github.com/users/jtattermusch/events{/privacy}","received_events_url":"https://api.github.com/users/jtattermusch/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jtattermusch/google-api-dotnet-client","description":"Google APIs Client Library for .NET","fork":true,"url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client","forks_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/forks","keys_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/teams","hooks_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/hooks","issue_events_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/issues/events{/number}","events_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/events","assignees_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/assignees{/user}","branches_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/branches{/branch}","tags_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/tags","blobs_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/statuses/{sha}","languages_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/languages","stargazers_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/stargazers","contributors_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/contributors","subscribers_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/subscribers","subscription_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/subscription","commits_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/contents/{+path}","compare_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/merges","archive_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/downloads","issues_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/issues{/number}","pulls_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/pulls{/number}","milestones_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/milestones{/number}","notifications_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/labels{/name}","releases_url":"https://api.github.com/repos/jtattermusch/google-api-dotnet-client/releases{/id}","created_at":"2015-07-10T05:41:46Z","updated_at":"2015-07-10T05:41:47Z","pushed_at":"2015-08-01T05:45:18Z","git_url":"git://github.com/jtattermusch/google-api-dotnet-client.git","ssh_url":"git@github.com:jtattermusch/google-api-dotnet-client.git","clone_url":"https://github.com/jtattermusch/google-api-dotnet-client.git","svn_url":"https://github.com/jtattermusch/google-api-dotnet-client","homepage":"https://developers.google.com/api-client-library/dotnet","size":8850,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"591ea827922ef4f5a2b32f5aad18a823bbfc0286","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":33947900,"name":"google-api-dotnet-client","full_name":"google/google-api-dotnet-client","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/google-api-dotnet-client","description":"Google APIs Client Library for .NET","fork":false,"url":"https://api.github.com/repos/google/google-api-dotnet-client","forks_url":"https://api.github.com/repos/google/google-api-dotnet-client/forks","keys_url":"https://api.github.com/repos/google/google-api-dotnet-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/google-api-dotnet-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/google-api-dotnet-client/teams","hooks_url":"https://api.github.com/repos/google/google-api-dotnet-client/hooks","issue_events_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/events{/number}","events_url":"https://api.github.com/repos/google/google-api-dotnet-client/events","assignees_url":"https://api.github.com/repos/google/google-api-dotnet-client/assignees{/user}","branches_url":"https://api.github.com/repos/google/google-api-dotnet-client/branches{/branch}","tags_url":"https://api.github.com/repos/google/google-api-dotnet-client/tags","blobs_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/{sha}","languages_url":"https://api.github.com/repos/google/google-api-dotnet-client/languages","stargazers_url":"https://api.github.com/repos/google/google-api-dotnet-client/stargazers","contributors_url":"https://api.github.com/repos/google/google-api-dotnet-client/contributors","subscribers_url":"https://api.github.com/repos/google/google-api-dotnet-client/subscribers","subscription_url":"https://api.github.com/repos/google/google-api-dotnet-client/subscription","commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/google-api-dotnet-client/contents/{+path}","compare_url":"https://api.github.com/repos/google/google-api-dotnet-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/google-api-dotnet-client/merges","archive_url":"https://api.github.com/repos/google/google-api-dotnet-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/google-api-dotnet-client/downloads","issues_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues{/number}","pulls_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls{/number}","milestones_url":"https://api.github.com/repos/google/google-api-dotnet-client/milestones{/number}","notifications_url":"https://api.github.com/repos/google/google-api-dotnet-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/google-api-dotnet-client/labels{/name}","releases_url":"https://api.github.com/repos/google/google-api-dotnet-client/releases{/id}","created_at":"2015-04-14T17:56:22Z","updated_at":"2015-07-28T16:29:38Z","pushed_at":"2015-08-01T05:45:19Z","git_url":"git://github.com/google/google-api-dotnet-client.git","ssh_url":"git@github.com:google/google-api-dotnet-client.git","clone_url":"https://github.com/google/google-api-dotnet-client.git","svn_url":"https://github.com/google/google-api-dotnet-client","homepage":"https://developers.google.com/api-client-library/dotnet","size":12722,"stargazers_count":46,"watchers_count":46,"language":"C#","has_issues":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":28,"mirror_url":null,"open_issues_count":98,"forks":28,"open_issues":98,"watchers":46,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564"},"html":{"href":"https://github.com/google/google-api-dotnet-client/pull/564"},"issue":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/issues/564"},"comments":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/issues/564/comments"},"review_comments":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564/comments"},"review_comment":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/564/commits"},"statuses":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/f445df289e94f51c17c8e7dc66fe77528d847ed8"}}}}