/// <summary>
        /// Get information about a Google OAuth 2.0 token
        /// </summary>
        /// <param name="token">Google OAuth 2.0 token</param>
        /// <returns>Google OAuth 2.0 token information</returns>
        public static TokenInfoJson GetTokenInfo(TokenJson token)
        {
            TokenInfoJson tokenInfo;

            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
            if (token.access_token == null || token.access_token.Length == 0)
            {
                throw new ArgumentException("token");
            }
            string endpoint = _baseUrl + "v2/tokeninfo?access_token=" + token.access_token;

            using (WebClient client = new WebClient())
            {
                client.Encoding = System.Text.Encoding.UTF8;
                client.Headers[HttpRequestHeader.Authorization] = token.GetAuthorizationHeader();
                try
                {
                    var content = client.DownloadString(endpoint);
                    tokenInfo = JsonConvert.DeserializeObject <TokenInfoJson>(content);
                }
                catch (System.Net.WebException e)
                {
                    //invalid token
                    throw new ArgumentException("Unable to connect to Google", e);
                }
            }
            return(tokenInfo);
        }
        /// <summary>
        /// Revoke a Google OAuth 2.0 token so it can no longer be used to connect to Google. It's ok if the token is invalid or has already expired.
        /// </summary>
        /// <param name="token">Google OAuth 2.0 token</param>
        public static void RevokeToken(TokenJson token)
        {
            if (token != null && token.access_token != null && token.access_token.Length > 0)
            {
                string endpoint = "https://accounts.google.com/o/oauth2/revoke?token=" + token.access_token;

                using (WebClient client = new WebClient())
                {
                    client.Encoding = System.Text.Encoding.UTF8;
                    client.Headers[HttpRequestHeader.Authorization] = token.GetAuthorizationHeader();
                    try
                    {
                        var content = client.DownloadString(endpoint);
                    }
                    catch (System.Net.WebException e)
                    {
                        //ignore this exception; it means the token already expired or was invalid
                    }
                }
            }
        }
        /// <summary>
        /// Get the user's basic profile, as determined by Google
        /// </summary>
        /// <param name="token">A valid, unexpired access token provided by Google</param>
        /// <returns>A user's basic Google profile</returns>
        public static UserJson GetUserInfo(TokenJson token)
        {
            UserJson user;
            string   endpoint = _baseUrl + "v2/userinfo";

            using (WebClient client = new WebClient())
            {
                client.Encoding = System.Text.Encoding.UTF8;
                client.Headers[HttpRequestHeader.Authorization] = token.GetAuthorizationHeader();

                try
                {
                    var content = client.DownloadString(endpoint);
                    user = JsonConvert.DeserializeObject <UserJson>(content);
                }
                catch (System.Net.WebException e)
                {
                    throw new ArgumentException("Unable to connect to Google", e);
                }
            }
            return(user);
        }