/// <summary>
        /// Get User presence details in a batch.
        /// </summary>
        /// <param name="peoplePresenceData">Array of People Presence Data object used to get presence information.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns>People Presence Data model data filled with presence information.</returns>
        public async Task <List <PeoplePresenceData> > GetBatchUserPresenceAsync(PeoplePresenceData[] peoplePresenceData, string accessToken)
        {
            List <PeoplePresenceData> peoplePresenceDataList         = new List <PeoplePresenceData>();
            List <PeoplePresenceData> peoplePresenceDataBatchResults = new List <PeoplePresenceData>();

            foreach (PeoplePresenceData member in peoplePresenceData)
            {
                string id = member.Id;
                if (!this.memoryCache.TryGetValue(id, out PeoplePresenceData peoplePresence))
                {
                    peoplePresence = new PeoplePresenceData()
                    {
                        UserPrincipalName = member.UserPrincipalName,
                        Id = member.Id,
                    };
                    peoplePresenceDataList.Add(peoplePresence);
                }
                else
                {
                    peoplePresenceDataBatchResults.Add(peoplePresence);
                }
            }

            if (peoplePresenceDataList.Count > 0)
            {
                var presenceBatches = peoplePresenceDataList.SplitList(BatchSplitCount);
                GraphUtilityHelper graphClientBeta = new GraphUtilityHelper(accessToken);

                foreach (var presenceBatch in presenceBatches)
                {
                    peoplePresenceDataBatchResults.AddRange(await graphClientBeta.GetUserPresenceAsync(presenceBatch, this.logger));
                }
            }
            else
            {
                this.logger.LogInformation($"GetBatchUserPresenceAsync. Presence of all users found in memory.");
            }

            return(peoplePresenceDataBatchResults);
        }
        /// <summary>
        /// Get User presence details in a batch.
        /// </summary>
        /// <param name="peoplePresenceDataArray">Array of People Presence Data object used to get presence information.</param>
        /// <returns>People Presence Data model data filled with presence information.</returns>
        public async Task <List <PeoplePresenceData> > GetBatchUserPresenceAsync(PeoplePresenceData[] peoplePresenceDataArray)
        {
            List <PeoplePresenceData> peoplePresenceDataList            = new List <PeoplePresenceData>();
            List <PeoplePresenceData> peoplePresenceDataListReturnValue = new List <PeoplePresenceData>();

            foreach (PeoplePresenceData member in peoplePresenceDataArray)
            {
                string userPrincipalName = member.UserPrincipalName.ToLower();
                if (!this.memoryCache.TryGetValue(userPrincipalName, out PeoplePresenceData peoplePresenceDataObj))
                {
                    peoplePresenceDataObj = new PeoplePresenceData()
                    {
                        UserPrincipalName = member.UserPrincipalName,
                        Id = member.Id,
                    };
                    peoplePresenceDataList.Add(peoplePresenceDataObj);
                }
                else
                {
                    peoplePresenceDataListReturnValue.Add(peoplePresenceDataObj);
                }
            }

            if (peoplePresenceDataList.Count > 0)
            {
                this.telemetryClient.TrackEvent($"GetBatchUserPresenceAsync. Getting presence from MS Graph. User Count : {peoplePresenceDataList.Count()}, users :{JsonConvert.SerializeObject(peoplePresenceDataList)}");

                string[] scopes = { "Presence.Read.All" };

                MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Convert.ToInt32(this.configuration["CacheInterval"])), // cache will expire in 60 seconds or 1 minutes
                };

                var presenceBatches = peoplePresenceDataList.SplitList(19); // MS Graph batch limit is 20

                foreach (var presenceBatch in presenceBatches)
                {
                    try
                    {
                        List <MSGraphBatchRequest> allRequests = MSGraphBatchRequestCreator.CreateBatchRequestPayloadForPresence("/users/{0}/presence", "GET", presenceBatch);
                        MSGraphBatchRequestPayload payload     = new MSGraphBatchRequestPayload()
                        {
                            Requests = allRequests,
                        };

                        List <MSGraphBatchResponse <dynamic> > responses = await this.protectedApiCallHelper.CallGraphApiPostOnBehalfOfUser(scopes, MSGraphBatchAPI, JsonConvert.SerializeObject(payload));

                        if (responses != null)
                        {
                            foreach (var presenceInfo in responses)
                            {
                                try
                                {
                                    string             presenceStatus = presenceInfo.Body.availability;
                                    string             userAADId      = presenceInfo.Body.id;
                                    PeoplePresenceData peoplePresence = new PeoplePresenceData()
                                    {
                                        Availability      = presenceStatus.ToLower() == "available" ? "Online" : presenceStatus,
                                        UserPrincipalName = presenceInfo.Id.ToLower(),
                                        Id = userAADId,
                                    };

                                    this.memoryCache.Set(peoplePresence.UserPrincipalName, peoplePresence, options);

                                    peoplePresenceDataListReturnValue.Add(peoplePresence);
                                }
                                catch (Exception ex)
                                {
                                    if (presenceInfo != null)
                                    {
                                        this.telemetryClient.TrackTrace($"GetBatchUserPresenceAsync. An error occurred: {ex.Message}. PeoplePresenceDataJObject : {JsonConvert.SerializeObject(presenceInfo)}", SeverityLevel.Error);
                                        this.telemetryClient.TrackException(ex);
                                    }
                                    else
                                    {
                                        this.telemetryClient.TrackTrace($"GetBatchUserPresenceAsync. An error occurred: {ex.Message} ", SeverityLevel.Error);
                                        this.telemetryClient.TrackException(ex);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (presenceBatch != null)
                        {
                            this.telemetryClient.TrackTrace($"GetBatchUserPresenceAsync. An error occurred: {ex.Message}. PresenceBatch : {JsonConvert.SerializeObject(presenceBatch)}", SeverityLevel.Error);
                            this.telemetryClient.TrackException(ex);
                        }
                        else
                        {
                            this.telemetryClient.TrackTrace($"GetBatchUserPresenceAsync. An error occurred: {ex.Message} ", SeverityLevel.Error);
                            this.telemetryClient.TrackException(ex);
                        }
                    }
                }
            }
            else
            {
                this.telemetryClient.TrackEvent($"GetBatchUserPresenceAsync. Presence of all users found in memory.");
            }

            return(peoplePresenceDataListReturnValue);
        }
        /// <summary>
        /// Gets online members count in a distribution list.
        /// </summary>
        /// <param name="groupId">Distribution list id.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns><see cref="Task{TResult}"/>Online members count in distribution list.</returns>
        public async Task <int> GetDistributionListMembersOnlineCountAsync(string groupId, string accessToken)
        {
            try
            {
                int onlineMembersCount         = 0;
                GraphUtilityHelper graphClient = new GraphUtilityHelper(accessToken);
                var members = await this.GetMembersList(groupId, accessToken);

                var peoplePresenceDataList = new List <PeoplePresenceData>();

                foreach (DistributionListMember member in members)
                {
                    string id = member.UserObjectId;
                    if (!this.memoryCache.TryGetValue(id, out PeoplePresenceData peoplePresence))
                    {
                        peoplePresence = new PeoplePresenceData()
                        {
                            UserPrincipalName = member.UserPrincipalName,
                            Id = member.UserObjectId,
                        };
                        peoplePresenceDataList.Add(peoplePresence);
                    }
                    else
                    {
                        if (this.onlinePresenceOptions.Contains(peoplePresence.Availability))
                        {
                            onlineMembersCount++;
                        }
                    }
                }

                if (peoplePresenceDataList.Count > 0)
                {
                    MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(this.cacheOptions.Value.CacheInterval), // cache will expire in 300 seconds or 5 minutes
                    };

                    var presenceBatches = peoplePresenceDataList.SplitList(BatchSplitCount);

                    foreach (var presenceBatch in presenceBatches)
                    {
                        List <PeoplePresenceData> peoplePresenceResults = await graphClient.GetUserPresenceAsync(presenceBatch, this.logger);

                        for (int i = 0; i < peoplePresenceResults.Count; i++)
                        {
                            this.memoryCache.Set(peoplePresenceResults[i].Id, peoplePresenceResults[i], options);
                            if (this.onlinePresenceOptions.Contains(peoplePresenceResults[i].Availability.ToUpper()))
                            {
                                onlineMembersCount++;
                            }
                        }
                    }
                }
                else
                {
                    this.logger.LogInformation($"Presence of all users in group found in memory.");
                }

                return(onlineMembersCount);
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"GetDistributionListMembersOnlineCountAsync. An error occurred: {ex.Message}");
                throw;
            }
        }