/// <summary>
        /// This is a utility method for converting chatter user info into a Who.
        /// </summary>
        public WhoAPI ChatterUserInfoToWhoAPI(ChatterUserInfo chatterUserInfo)
        {
            WhoAPI who = null;

            // Convert the chatter user info over to a who
            who = new WhoAPI();

            // The chatter user info is not always a user, it can be an object (i.e. the user is following an object - that comes through as a follower)
            if (chatterUserInfo.Photo != null)
            {
                who.avatarUrl = chatterUserInfo.Photo.SmallPhotoUrl;
            }

            who.fullName = chatterUserInfo.Name;
            who.id       = chatterUserInfo.Id;

            return(who);
        }
        /// <summary>
        /// Utility method for getting the records and users the user is following.
        /// </summary>
        public List <WhoAPI> GetStuffAuthenticatedUserIsFollowing(HttpClient httpClient, String chatterBaseUrl)
        {
            WhoAPI                   who  = null;
            List <WhoAPI>            whos = null;
            HttpResponseMessage      httpResponseMessage    = null;
            ChatterFollowingResponse followingUsersresponse = null;

            // TODO: Need to add paging support to this as it currently only sends back the first page of results
            httpResponseMessage = httpClient.GetAsync(chatterBaseUrl + SalesforceServiceSingleton.CHATTER_URI_PART_API_VERSION + SalesforceServiceSingleton.CHATTER_URI_PART_FOLLOWING_ME).Result;

            if (httpResponseMessage.IsSuccessStatusCode == true)
            {
                // Get the followers from the response as the request was successful
                followingUsersresponse = httpResponseMessage.Content.ReadAsAsync <ChatterFollowingResponse>().Result;

                // Check to see if the user is in fact following anything
                if (followingUsersresponse.Following != null &&
                    followingUsersresponse.Following.Count > 0)
                {
                    whos = new List <WhoAPI>();

                    // Go through the list of following things and convert them to "whos"
                    foreach (ChatterFollowing chatterFollowing in followingUsersresponse.Following)
                    {
                        // The followed thing is in the subject
                        if (chatterFollowing.Subject != null)
                        {
                            who = this.ChatterUserInfoToWhoAPI(chatterFollowing.Subject);

                            whos.Add(who);
                        }
                    }
                }
            }
            else
            {
                // Throw an exception which will cause the calling method to retry - we don't have that here
                throw new ArgumentNullException("BadRequest", httpResponseMessage.ReasonPhrase);
            }

            return(whos);
        }
        /// <summary>
        /// This is a general purpose method for getting user information from chatter.
        /// </summary>
        public WhoAPI GetUserInfoById(INotifier notifier, IAuthenticatedWho authenticatedWho, String streamId, String id, SocialServiceRequestAPI socialServiceRequestAPI)
        {
            List <WhoAPI>       stuffAuthenticatedUserIsFollowing = null;
            ChatterUserInfo     chatterUserInfo     = null;
            HttpResponseMessage httpResponseMessage = null;
            HttpClient          httpClient          = null;
            WhoAPI who            = null;
            String chatterBaseUrl = null;
            String endpointUrl    = null;
            String adminEmail     = null;

            if (authenticatedWho == null)
            {
                throw new ArgumentNullException("BadRequest", "AuthenticatedWho is null.");
            }

            if (id == null ||
                id.Trim().Length == 0)
            {
                throw new ArgumentNullException("BadRequest", "Id for user is null or blank.");
            }

            if (streamId == null ||
                streamId.Trim().Length == 0)
            {
                throw new ArgumentNullException("BadRequest", "Stream identifier is null or blank.");
            }

            if (socialServiceRequestAPI == null)
            {
                throw new ArgumentNullException("BadRequest", "SocialServiceRequest is null.");
            }

            // We only need the chatter base url for this call
            chatterBaseUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_CHATTER_BASE_URL, socialServiceRequestAPI.configurationValues, true);
            adminEmail     = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_ADMIN_EMAIL, socialServiceRequestAPI.configurationValues, true);

            // We enclose the request in a for loop to handle http errors
            for (int i = 0; i < SalesforceHttpUtils.MAXIMUM_RETRIES; i++)
            {
                try
                {
                    // Create a new client object
                    httpClient = SalesforceHttpUtils.CreateHttpClient(SalesforceHttpUtils.GetAuthenticationDetails(authenticatedWho.Token).Token);

                    // Create the endpoint url
                    endpointUrl = chatterBaseUrl + SalesforceServiceSingleton.CHATTER_URI_PART_API_VERSION + SalesforceServiceSingleton.CHATTER_URI_PART_USERS + "/" + id;

                    // Call the get method on the chatter API to grab the user information
                    httpResponseMessage = httpClient.GetAsync(endpointUrl).Result;

                    // Check the status of the response and respond appropriately
                    if (httpResponseMessage.IsSuccessStatusCode)
                    {
                        // Grab the chatter user info from the result
                        chatterUserInfo = httpResponseMessage.Content.ReadAsAsync <ChatterUserInfo>().Result;

                        // Convert the chatter user info over to a who
                        who = this.ChatterUserInfoToWhoAPI(chatterUserInfo);

                        // Get the stuff this user is following
                        stuffAuthenticatedUserIsFollowing = this.GetStuffAuthenticatedUserIsFollowing(httpClient, chatterBaseUrl);

                        // Check to see if the authenticated user is also the id
                        if (id.Equals(SalesforceServiceSingleton.CHATTER_ME, StringComparison.InvariantCultureIgnoreCase) == false)
                        {
                            // Check to see if the currently authenticated user is following the provided user id
                            if (stuffAuthenticatedUserIsFollowing != null &&
                                stuffAuthenticatedUserIsFollowing.Any(x => x.id == id) == true)
                            {
                                // The authenticated user is following the provided user id
                                who.isFollower = true;
                            }
                        }
                        else
                        {
                            // If the authenticated user is the same as the provided id, the "is following" refers to the stream
                            if (stuffAuthenticatedUserIsFollowing != null &&
                                stuffAuthenticatedUserIsFollowing.Any(x => x.id == streamId) == true)
                            {
                                // We are following this stream
                                who.isFollower = true;
                            }
                        }

                        // We successfully executed the request, we can break out of the retry loop
                        break;
                    }
                    else
                    {
                        // Make sure we handle the lack of success properly
                        BaseHttpUtils.HandleUnsuccessfulHttpResponseMessage(notifier, authenticatedWho, i, httpResponseMessage, endpointUrl);
                    }
                }
                catch (Exception exception)
                {
                    // Make sure we handle the exception properly
                    BaseHttpUtils.HandleHttpException(notifier, authenticatedWho, i, exception, endpointUrl);
                }
                finally
                {
                    // Clean up the objects from the request
                    BaseHttpUtils.CleanUpHttp(httpClient, null, httpResponseMessage);
                }
            }

            return(who);
        }