private async Task AddReplyComments(FacebookProcessResult result, List <FbComment> replyComments)
        {
            if (!replyComments.Any())
            {
                return;
            }

            replyComments = replyComments.OrderBy(t => t.created_time).ToList();
            using (var uow = UnitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
            {
                using (CurrentUnitOfWork.SetSiteId(_account.SiteId))
                {
                    List <SocialUser> senders = await _socialUserService.GetOrCreateSocialUsers(_account.Token, replyComments.Select(t => t.from).ToList());

                    var postIds       = replyComments.Select(t => t.PostId).Distinct().ToList();
                    var conversations = _conversationService.FindAll().Where(t => postIds.Contains(t.OriginalId)).ToList();

                    var parentIds = replyComments.Select(t => t.parent.id).Distinct().ToList();
                    var parents   = _messageService.FindAll().Where(t => parentIds.Contains(t.OriginalId)).ToList();

                    foreach (var replyComment in replyComments)
                    {
                        var sender = senders.FirstOrDefault(t => t.OriginalId == replyComment.from.id);
                        if (sender == null)
                        {
                            continue;
                        }

                        var conversation = conversations.FirstOrDefault(t => t.OriginalId == replyComment.PostId);
                        if (conversation == null)
                        {
                            continue;
                        }

                        var parent = parents.FirstOrDefault(t => t.OriginalId == replyComment.parent.id);
                        if (parent == null)
                        {
                            continue;
                        }

                        var message = _fbConverter.ConvertToMessage(replyComment);
                        message.Source         = MessageSource.FacebookPostReplyComment;
                        message.SenderId       = sender.Id;
                        message.ReceiverId     = parent.SenderId;
                        message.ParentId       = parent.Id;
                        message.ConversationId = conversation.Id;
                        conversation.Messages.Add(message);
                        conversation.Status = ConversationStatus.PendingInternal;
                        conversation.LastMessageSenderId = message.SenderId;
                        conversation.LastMessageSentTime = message.SendTime;
                        conversation.TryToMakeWallPostVisible(_account);
                        result.WithNewMessage(message);
                    }
                    uow.Complete();
                }
            }
        }
        private async Task AddConversations(List <FbConversation> fbConversations)
        {
            if (!fbConversations.Any())
            {
                return;
            }

            using (var uow = UnitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
            {
                using (CurrentUnitOfWork.SetSiteId(_account.SiteId))
                {
                    List <SocialUser> senders   = new List <SocialUser>();
                    List <SocialUser> receivers = new List <SocialUser>();

                    foreach (var fbconversation in fbConversations)
                    {
                        var existingConversation = _conversationService.GetUnClosedConversation(fbconversation.Id);
                        if (existingConversation != null)
                        {
                            fbconversation.Messages.data = fbconversation.Messages.data.OrderBy(t => t.SendTime).ToList();
                            foreach (var fbMessage in fbconversation.Messages.data)
                            {
                                if (fbMessage.SendTime < existingConversation.LastMessageSentTime)
                                {
                                    continue;
                                }

                                var sender = await _socialUserService.GetOrCreateFacebookUser(_account.Token, fbMessage.SenderId);

                                var receiver = await _socialUserService.GetOrCreateFacebookUser(_account.Token, fbMessage.ReceiverId);

                                Message message = _fbConverter.ConvertMessage(fbMessage, sender, receiver);
                                message.ConversationId                   = existingConversation.Id;
                                existingConversation.IfRead              = false;
                                existingConversation.Status              = sender.Id != _account.SocialUser.Id ? ConversationStatus.PendingInternal : ConversationStatus.PendingExternal;
                                existingConversation.Subject             = GetSubject(message.Content);
                                existingConversation.LastMessageSenderId = message.SenderId;
                                existingConversation.LastMessageSentTime = message.SendTime;
                                existingConversation.Messages.Add(message);
                                _conversationService.Update(existingConversation);
                                await CurrentUnitOfWork.SaveChangesAsync();
                            }
                        }
                        else
                        {
                            Conversation conversation = new Conversation();
                            conversation.OriginalId      = fbconversation.Id;
                            conversation.Source          = ConversationSource.FacebookMessage;
                            conversation.Priority        = ConversationPriority.Normal;
                            conversation.Status          = ConversationStatus.New;
                            fbconversation.Messages.data = fbconversation.Messages.data.OrderBy(t => t.SendTime).ToList();

                            if (fbconversation.Messages.data.All(t => t.SenderId == _account.SocialUser.OriginalId))
                            {
                                continue;
                            }

                            foreach (var fbMessage in fbconversation.Messages.data)
                            {
                                var sender = await _socialUserService.GetOrCreateFacebookUser(_account.Token, fbMessage.SenderId);

                                var receiver = await _socialUserService.GetOrCreateFacebookUser(_account.Token, fbMessage.ReceiverId);

                                Message message = _fbConverter.ConvertMessage(fbMessage, sender, receiver);

                                conversation.Subject             = GetSubject(message.Content);
                                conversation.LastMessageSenderId = message.SenderId;
                                conversation.LastMessageSentTime = message.SendTime;

                                conversation.Messages.Add(message);

                                if (_account.ConversationAgentId.HasValue && _account.ConversationPriority.HasValue)
                                {
                                    conversation.AgentId  = _account.ConversationAgentId.Value;
                                    conversation.Priority = _account.ConversationPriority.Value;
                                }

                                if (_account.ConversationDepartmentId.HasValue && _account.ConversationPriority.HasValue)
                                {
                                    conversation.DepartmentId = _account.ConversationDepartmentId.Value;
                                    conversation.Priority     = _account.ConversationPriority.Value;
                                }
                            }
                            _conversationService.Insert(conversation);
                            await CurrentUnitOfWork.SaveChangesAsync();
                        }
                    }
                    uow.Complete();
                }
            }
        }
        private async Task AddPosts(FacebookProcessResult result, List <FbPost> posts)
        {
            if (!posts.Any())
            {
                return;
            }

            var socialAccounts = _socialUserService.FindAll().Where(t => t.Source == SocialUserSource.Facebook && t.Type == SocialUserType.IntegrationAccount).ToList();

            posts = posts.OrderBy(t => t.created_time).ToList();

            using (var uow = UnitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
            {
                using (CurrentUnitOfWork.SetSiteId(_account.SiteId))
                {
                    List <SocialUser> senders = await _socialUserService.GetOrCreateSocialUsers(_account.Token, posts.Select(t => t.from).ToList());

                    foreach (var post in posts)
                    {
                        var sender = senders.FirstOrDefault(t => t.OriginalId == post.from.id);
                        if (sender == null)
                        {
                            continue;
                        }

                        var firstMessage = _fbConverter.ConvertToMessage(post);
                        firstMessage.SenderId = sender.Id;
                        var recipient = GetRecipient(post, socialAccounts);
                        if (recipient != null)
                        {
                            // a post @ multiple social accounts.
                            if (recipient.Id != _account.Id)
                            {
                                return;
                            }

                            firstMessage.ReceiverId = recipient.Id;
                        }

                        if (recipient == null && firstMessage.SenderId != _account.Id)
                        {
                            firstMessage.ReceiverId = _account.Id;
                        }

                        var conversation = new Conversation
                        {
                            OriginalId          = post.id,
                            Source              = ConversationSource.FacebookVisitorPost,
                            Priority            = ConversationPriority.Normal,
                            Status              = ConversationStatus.New,
                            Subject             = GetSubject(post.message),
                            LastMessageSenderId = firstMessage.SenderId,
                            LastMessageSentTime = firstMessage.SendTime
                        };
                        conversation.Messages.Add(firstMessage);

                        if (sender.OriginalId == _account.SocialUser.OriginalId)
                        {
                            conversation.Source   = ConversationSource.FacebookWallPost;
                            conversation.IsHidden = true;
                        }

                        if (_account.ConversationAgentId.HasValue && _account.ConversationPriority.HasValue)
                        {
                            conversation.AgentId  = _account.ConversationAgentId.Value;
                            conversation.Priority = _account.ConversationPriority.Value;
                        }

                        if (_account.ConversationDepartmentId.HasValue && _account.ConversationPriority.HasValue)
                        {
                            conversation.DepartmentId = _account.ConversationDepartmentId.Value;
                            conversation.Priority     = _account.ConversationPriority.Value;
                        }

                        if (conversation.Source == ConversationSource.FacebookWallPost && !_account.IfConvertWallPostToConversation)
                        {
                            continue;
                        }

                        if (conversation.Source == ConversationSource.FacebookVisitorPost && !_account.IfConvertVisitorPostToConversation)
                        {
                            continue;
                        }

                        await _conversationService.InsertAsync(conversation);

                        result.WithNewConversation(conversation);
                    }
                    uow.Complete();
                }
            }
        }