/// <summary>
        /// This is a utility method for translating chatter mentioned users into a compatible format for ManyWho.
        /// </summary>
        public List <MentionedWhoAPI> ChatterUserInfoToMentionedUserAPI(List <ChatterUserInfo> chatterUserInfos)
        {
            List <MentionedWhoAPI> mentionedUsers = null;
            MentionedWhoAPI        mentionedUser  = null;

            if (chatterUserInfos != null &&
                chatterUserInfos.Count > 0)
            {
                mentionedUsers = new List <MentionedWhoAPI>();

                foreach (ChatterUserInfo chatterUserInfo in chatterUserInfos)
                {
                    // Convert the chatter user info over to a mentioned user
                    mentionedUser = new MentionedWhoAPI();

                    // 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)
                    {
                        mentionedUser.avatarUrl = chatterUserInfo.Photo.SmallPhotoUrl;
                    }

                    mentionedUser.fullName = chatterUserInfo.Name;
                    mentionedUser.id       = chatterUserInfo.Id;
                    mentionedUser.jobTitle = chatterUserInfo.Title;
                    mentionedUser.name     = chatterUserInfo.Name;

                    mentionedUsers.Add(mentionedUser);
                }
            }

            return(mentionedUsers);
        }
        /// <summary>
        /// Utility method for converting ManyWho messages into chatter messages.
        /// </summary>
        public ChatterNewMessageBody ConvertNewMessageAPIToChatterNewMessageBody(NewMessageAPI newMessage)
        {
            Dictionary <Int32, String> mentionsAndHashTags = null;
            List <MentionedWhoAPI>     mentionedUsers      = null;
            List <ChatterSegment>      chatterSegments     = null;
            List <Int32>  mentionsAndHashTagKeys           = null;
            List <String> messageFragments = null;
            String        messageText      = null;

            if (newMessage == null)
            {
                throw new ArgumentNullException("BadRequest", "The new message is null in the service request");
            }

            // Create a new list to hold our message segments
            chatterSegments = new List <ChatterSegment>();

            // Create a dictionary to hold all of the at mentions and hash tags
            mentionsAndHashTags = new Dictionary <Int32, String>();

            // Grab the list of at mentioned users and the text of the message
            mentionedUsers = newMessage.mentionedWhos;
            messageText    = newMessage.messageText;

            if (messageText != null &&
                messageText.Trim().Length > 0)
            {
                // Break the message up into individual words so we can query the list for hash tags
                messageFragments = messageText.Split(' ').ToList();

                // Now query the message fragments and filter out anything that is not a hash tag
                messageFragments = messageFragments.Where(x => (x.Contains('#') && x.Length > 1)).ToList();

                // If we have some hash tags, we need to add those to our list - they're posted to chatter in separate segments
                if (messageFragments != null &&
                    messageFragments.Count > 0)
                {
                    // Go through each of the tags and grab out the information cleanly so we can post it over to chatter correctly
                    foreach (String tag in messageFragments)
                    {
                        Int32 index = Regex.Match(messageText, SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_START + tag + SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_FINISH).Index;

                        while (mentionsAndHashTags.Select(x => x.Key).Contains(index))
                        {
                            String tagEntry = messageText.Substring(index + mentionsAndHashTags[index].Length);
                            index = Regex.Match(tagEntry, SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_START + tag + SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_FINISH).Index + index + mentionsAndHashTags[index].Length;
                        }

                        mentionsAndHashTags.Add(index, tag);
                    }
                }
            }

            // Go through the mentioned users and get the data out for chatter
            if (mentionedUsers != null &&
                mentionedUsers.Count > 0)
            {
                foreach (MentionedWhoAPI mentionedUser in mentionedUsers)
                {
                    // Grab the user information out nice and cleanly so we have it for chatter
                    Int32 index = messageText.IndexOf(mentionedUser.fullName);

                    while (mentionsAndHashTags.Select(x => x.Key).Contains(index))
                    {
                        var mentionedUserEntry = messageText.Substring(index + mentionsAndHashTags[index].Length);
                        index = Regex.Match(mentionedUserEntry, SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_START + mentionedUser.fullName + SalesforceServiceSingleton.CHATTER_HASH_TAG_OR_MENTION_FINISH).Index + index + mentionsAndHashTags[index].Length;
                    }

                    mentionsAndHashTags.Add(index, mentionedUser.fullName);
                }
            }

            // Get the keys out of our complete list and sort them numerically
            mentionsAndHashTagKeys = mentionsAndHashTags.Keys.ToList();
            mentionsAndHashTagKeys.Sort();

            if (mentionsAndHashTagKeys.Count > 0)
            {
                // Loop through keys and create the chatter segments
                for (var i = 0; i < mentionsAndHashTagKeys.Count; i++)
                {
                    // If the item is the first in the text string then only add the item, otherwise add the text and the item
                    if (mentionsAndHashTagKeys[i] != 0)
                    {
                        Int32 startIndex = i != 0 ? (mentionsAndHashTagKeys[i - 1] + mentionsAndHashTags[mentionsAndHashTagKeys[i - 1]].Length) : 0;
                        Int32 endIndex   = mentionsAndHashTagKeys[i] - startIndex;

                        chatterSegments.Add(new ChatterNewMessageSegment {
                            Type = ChatterMessageSegmentType.Text.ToString(), Text = messageText.Substring(startIndex, endIndex)
                        });
                    }

                    // Check to see if this entry is a hash tag
                    if (mentionsAndHashTags[mentionsAndHashTagKeys[i]].Contains('#'))
                    {
                        chatterSegments.Add(new ChatterHashTagSegment {
                            Type = ChatterMessageSegmentType.Hashtag.ToString(), Tag = mentionsAndHashTags[mentionsAndHashTagKeys[i]].Remove(0, 1)
                        });
                    }
                    else
                    {
                        // We have an at mentioned user, add that segment
                        MentionedWhoAPI clientMentionedUser = mentionedUsers.FirstOrDefault(x => x.fullName == mentionsAndHashTags[mentionsAndHashTagKeys[i]]);

                        if (clientMentionedUser != null)
                        {
                            chatterSegments.Add(new ChatterMentionsSegment {
                                Type = ChatterMessageSegmentType.Mention.ToString(), Id = clientMentionedUser.id
                            });
                        }
                    }

                    // Add the last bit of text as a final segment to the post
                    if (i == mentionsAndHashTagKeys.Count - 1)
                    {
                        Int32  startIndex = mentionsAndHashTagKeys[i] + mentionsAndHashTags[mentionsAndHashTagKeys[i]].Length;
                        String text       = messageText.Substring(startIndex);

                        if (String.IsNullOrWhiteSpace(text) == false)
                        {
                            chatterSegments.Add(new ChatterNewMessageSegment {
                                Type = ChatterMessageSegmentType.Text.ToString(), Text = text
                            });
                        }
                    }
                }
            }
            else
            {
                // We don't have any segments, so simply create one segment for the entire message
                chatterSegments.Add(new ChatterNewMessageSegment {
                    Type = ChatterMessageSegmentType.Text.ToString(), Text = messageText
                });
            }

            return(new ChatterNewMessageBody {
                MessageSegments = chatterSegments
            });
        }