private static ClientSecrets getCalendarClientSecrets()
        {
            ClientSecrets provider = new ClientSecrets();

            if (Settings.Instance.UsingPersonalAPIkeys())
            {
                provider.ClientId     = Settings.Instance.PersonalClientIdentifier;
                provider.ClientSecret = Settings.Instance.PersonalClientSecret;
            }
            else
            {
                ApiKeyring apiKeyring = new ApiKeyring();

                if (Settings.Instance.Subscribed != null && Settings.Instance.Subscribed != DateTime.Parse("01-Jan-2000"))
                {
                    apiKeyring.PickKey(ApiKeyring.KeyType.Subscriber);
                }
                else
                {
                    apiKeyring.PickKey(ApiKeyring.KeyType.Standard);
                }

                provider.ClientId     = apiKeyring.Key.ClientId;
                provider.ClientSecret = apiKeyring.Key.ClientSecret;
            }
            return(provider);
        }
        private void getGaccountEmail(String accessToken)
        {
            String jsonString = "";

            log.Debug("Retrieving email address associated with Google account.");
            try {
                System.Net.WebClient wc = new System.Net.WebClient();
                wc.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0");
                jsonString = wc.DownloadString("https://www.googleapis.com/plus/v1/people/me?fields=emails&access_token=" + accessToken);
                JObject jo      = Newtonsoft.Json.Linq.JObject.Parse(jsonString);
                JToken  jtEmail = jo["emails"].Where(e => e.Value <String>("type") == "account").First();
                String  email   = jtEmail.Value <String>("value");

                if (Settings.Instance.GaccountEmail != email)
                {
                    if (!String.IsNullOrEmpty(Settings.Instance.GaccountEmail))
                    {
                        log.Debug("Looks like the Google account username value has been tampering with? :-O");
                    }
                    Settings.Instance.GaccountEmail = email;
                    log.Debug("Updating Google account username: "******"The remote server returned an error: (403) Forbidden.") || ex.Message == "Insufficient Permission")
                {
                    log.Warn(ex.Message);
                    String msg = ApiKeyring.ChangeKeys();
                    throw new System.ApplicationException(msg);
                }
                OGCSexception.Analyse(ex);
                if (ex.Message.ToLower().Contains("access denied"))
                {
                    MainForm.Instance.Logboxout("Failed to obtain Calendar access from Google - it's possible your access has been revoked."
                                                + "\r\nTry disconnecting your Google account and reauthenticating.");
                }
                throw ex;
            } catch (System.Exception ex) {
                log.Debug("JSON: " + jsonString);
                log.Error("Failed to retrieve Google account username.");
                OGCSexception.Analyse(ex);
                log.Debug("Using previously retrieved username: " + Settings.Instance.GaccountEmail_masked());
            }
        }
        private static ClientSecrets getCalendarClientSecrets()
        {
            ClientSecrets provider = new ClientSecrets();

            if (Settings.Instance.UsingPersonalAPIkeys())
            {
                provider.ClientId     = Settings.Instance.PersonalClientIdentifier;
                provider.ClientSecret = Settings.Instance.PersonalClientSecret;
            }
            else
            {
                ApiKeyring apiKeyring = new ApiKeyring();

                if (Settings.Instance.Subscribed != null && Settings.Instance.Subscribed != DateTime.Parse("01-Jan-2000"))
                {
                    if (apiKeyring.PickKey(ApiKeyring.KeyType.Subscriber) && apiKeyring.Key != null)
                    {
                        provider.ClientId     = apiKeyring.Key.ClientId;
                        provider.ClientSecret = apiKeyring.Key.ClientSecret;
                    }
                    else
                    {
                        provider.ClientId     = "550071650559-44lnvhdu5liq5kftj5t8k0aasgei5g7t.apps.googleusercontent.com";
                        provider.ClientSecret = "MGUFapefXClJa2ysS4WNGS4k";
                    }
                }
                else
                {
                    if (apiKeyring.PickKey(ApiKeyring.KeyType.Standard) && apiKeyring.Key != null)
                    {
                        provider.ClientId     = apiKeyring.Key.ClientId;
                        provider.ClientSecret = apiKeyring.Key.ClientSecret;
                    }
                    else
                    {
                        provider.ClientId     = "653617509806-2nq341ol8ejgqhh2ku4j45m7q2bgdimv.apps.googleusercontent.com";
                        provider.ClientSecret = "tAi-gZLWtasS58i8CcCwVwsq";
                    }
                }
            }
            return(provider);
        }
        public Boolean UserSubscriptionCheck()
        {
            List <Event> result    = new List <Event>();
            Events       request   = null;
            String       pageToken = null;
            Int16        pageNum   = 1;

            log.Debug("Retrieving all subscribers from past year.");
            try {
                do
                {
                    EventsResource.ListRequest lr = GoogleOgcs.Calendar.Instance.Service.Events.List("*****@*****.**");

                    lr.PageToken    = pageToken;
                    lr.SingleEvents = true;
                    lr.OrderBy      = EventsResource.ListRequest.OrderByEnum.StartTime;
                    lr.Q            = (Settings.Instance.GaccountEmail == null) ? "" : HashedGmailAccount;
                    request         = lr.Execute();
                    log.Debug("Page " + pageNum + " received.");

                    if (request != null)
                    {
                        pageToken = request.NextPageToken;
                        pageNum++;
                        if (request.Items != null)
                        {
                            result.AddRange(request.Items);
                        }
                    }
                } while (pageToken != null);

                if (String.IsNullOrEmpty(Settings.Instance.GaccountEmail))   //This gets retrieved via the above lr.Execute()
                {
                    log.Warn("User's Google account username is not present - cannot check if they have subscribed.");
                    return(false);
                }
            } catch (Google.Apis.Auth.OAuth2.Responses.TokenResponseException ex) {
                OGCSexception.AnalyseTokenResponse(ex);
            } catch (System.Exception ex) {
                log.Error(ex.Message);
                throw new ApplicationException("Failed to retrieve subscribers - cannot check if they have subscribed.");
            }

            log.Debug("Searching for subscription for: " + Settings.Instance.GaccountEmail_masked());
            List <Event> subscriptions = result.Where(x => x.Summary == HashedGmailAccount).ToList();

            if (subscriptions.Count == 0)
            {
                log.Fine("This user has never subscribed.");
                Settings.Instance.Subscribed = DateTime.Parse("01-Jan-2000");
                return(false);
            }
            else
            {
                Boolean  subscribed;
                Event    subscription      = subscriptions.Last();
                DateTime subscriptionStart = DateTime.Parse(subscription.Start.Date ?? subscription.Start.DateTime).Date;
                log.Debug("Last subscription date: " + subscriptionStart.ToString());
                Double subscriptionRemaining = (subscriptionStart.AddYears(1) - DateTime.Now.Date).TotalDays;
                if (subscriptionRemaining >= 0)
                {
                    if (subscriptionRemaining > 360)
                    {
                        MainForm.Instance.syncNote(MainForm.SyncNotes.RecentSubscription, null);
                    }
                    if (subscriptionRemaining < 28)
                    {
                        MainForm.Instance.syncNote(MainForm.SyncNotes.SubscriptionPendingExpire, subscriptionStart.AddYears(1));
                    }
                    subscribed = true;
                }
                else
                {
                    if (subscriptionRemaining > -14)
                    {
                        MainForm.Instance.syncNote(MainForm.SyncNotes.SubscriptionExpired, subscriptionStart.AddYears(1));
                    }
                    subscribed = false;
                }

                DateTime prevSubscriptionStart = Settings.Instance.Subscribed;
                if (subscribed)
                {
                    log.Info("User has an active subscription.");
                    Settings.Instance.Subscribed = subscriptionStart;
                }
                else
                {
                    log.Info("User has no active subscription.");
                    Settings.Instance.Subscribed = DateTime.Parse("01-Jan-2000");
                }

                //Check for any unmigrated entries
                if (subscriptions.Where(s => s.ExtendedProperties != null && s.ExtendedProperties.Shared != null &&
                                        s.ExtendedProperties.Shared.ContainsKey("migrated") && s.ExtendedProperties.Shared["migrated"] == "true").Count() < subscriptions.Count())
                {
                    MainForm.Instance.Console.CallGappScript("subscriber");
                }

                if (prevSubscriptionStart != Settings.Instance.Subscribed)
                {
                    if (prevSubscriptionStart == DateTime.Parse("01-Jan-2000") ||         //No longer a subscriber
                        Settings.Instance.Subscribed == DateTime.Parse("01-Jan-2000"))    //New subscriber
                    {
                        ApiKeyring.ChangeKeys();
                    }
                }
                return(subscribed);
            }
        }
        private void getGaccountEmail(String accessToken)
        {
            String jsonString = "";

            log.Debug("Retrieving email address associated with Google account.");
            try {
                System.Net.WebClient wc = new System.Net.WebClient();
                wc.Headers.Add("user-agent", Settings.Instance.Proxy.BrowserUserAgent);
                jsonString = wc.DownloadString("https://www.googleapis.com/plus/v1/people/me?fields=emails&access_token=" + accessToken);
                JObject jo      = Newtonsoft.Json.Linq.JObject.Parse(jsonString);
                JToken  jtEmail = jo["emails"].Where(e => e.Value <String>("type") == "account").First();
                String  email   = jtEmail.Value <String>("value");

                if (Settings.Instance.GaccountEmail != email)
                {
                    if (!String.IsNullOrEmpty(Settings.Instance.GaccountEmail))
                    {
                        log.Debug("Looks like the Google account username value has been tampering with? :-O");
                    }
                    Settings.Instance.GaccountEmail = email;
                    log.Debug("Updating Google account username: "******"Inner exception: " + ex.InnerException.Message);
                }
                if (ex.Response != null)
                {
                    log.Debug("Reading response.");
                    System.IO.Stream       stream = ex.Response.GetResponseStream();
                    System.IO.StreamReader sr     = new System.IO.StreamReader(stream);
                    log.Error(sr.ReadToEnd());
                }
                if (OGCSexception.GetErrorCode(ex) == "0x80131509")
                {
                    log.Warn(ex.Message);
                    System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(@"\b(403|Forbidden|Prohibited|Insufficient Permission)\b",
                                                                                                        System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                    if (rgx.IsMatch(ex.Message))
                    {
                        if (Settings.Instance.UsingPersonalAPIkeys())
                        {
                            String msg = "If you are using your own API keys, you must also enable the Google+ API.";
                            MessageBox.Show(msg, "Missing API Service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation);
                            throw new System.ApplicationException(msg);
                        }
                        else
                        {
                            if (getEmailAttempts > 1)
                            {
                                log.Error("Failed to retrieve Google account username.");
                                log.Debug("Using previously retrieved username: "******"access denied"))
                {
                    MainForm.Instance.Console.Update("Failed to obtain Calendar access from Google - it's possible your access has been revoked."
                                                     + "<br/>Try disconnecting your Google account and reauthorising OGCS.", Console.Markup.error);
                }
                throw ex;
            } catch (System.Exception ex) {
                log.Debug("JSON: " + jsonString);
                log.Error("Failed to retrieve Google account username.");
                OGCSexception.Analyse(ex);
                log.Debug("Using previously retrieved username: " + Settings.Instance.GaccountEmail_masked());
            }
        }