/// <summary>
        /// Starts a new conversation with the given user by adding their message to the database.
        /// returns the Id of the newly created conversation. Increments the unread count of the 
        /// user the message was sent to.
        /// </summary>
        public async Task<int> StartConversation(int from, int to, string subject, string message)
        {
            var db = new OkbDbContext();
            Message msg;
            ConversationMap mapMe, mapOther;

            //// New conversation
            var conv = new Conversation { Subject = subject };
            db.Conversations.Add(conv);

            msg = new Message
            {
                Conversation = conv,
                From = from,
                MessageText = message,
                Timestamp = DateTime.Now
            };
            db.Messages.Add(msg);

            //My copy of the conversation
            mapMe = new ConversationMap
            {
                Conversation = conv,
                LastMessage = msg,
                Other = to,
                ProfileId = from,
                HasBeenRead = true,
                HasReplies = false
            };
            db.ConversationMap.Add(mapMe);

            //Other's copy of the conversation
            mapOther = new ConversationMap
            {
                Conversation = conv,
                LastMessage = msg,
                Other = from,
                ProfileId = to,
                HasBeenRead = false,
                HasReplies = true
            };
            db.ConversationMap.Add(mapOther);

            await db.SaveChangesAsync();

            //Everything OK - we can increment the unread count
            IncrementUnreadCount(to);

            return conv.Id; //return new conversation Id
        }
        /// <summary>
        /// 
        /// Adds a new message to the Messages table.  Creates a new converation if necessary.
        ///  - Updates the LastMessage to point to new message in the ConversationMap table. 
        ///  - Sets the HasBeenRead and HasReply flags
        /// 
        /// Returns the conversation Id the message was added to
        /// </summary>
        public async Task<int> AddMessageAsync(int from, int to, string text, int? convId = null)
        {
            var db = new OkbDbContext();
            Message msg;
            ConversationMap mapMe, mapOther;

            if (convId==null)
            {
                //// New conversation
                var conv = new Conversation { Subject = "Hi" };
                db.Conversations.Add(conv);

                msg = new Message
                {
                    Conversation = conv,
                    From = from,
                    MessageText = text,
                    Timestamp = DateTime.Now
                };
                db.Messages.Add(msg);

                //My copy of the conversation
                mapMe = new ConversationMap
                {
                    Conversation = conv,
                    LastMessage = msg,
                    Other = to,
                    ProfileId = from,
                    HasBeenRead = true,
                    HasReplies = false
                };
                db.ConversationMap.Add(mapMe);

                //Other's copy of the conversation
                mapOther = new ConversationMap
                {
                    Conversation = conv,
                    LastMessage = msg,
                    Other = from,
                    ProfileId = to,
                    HasBeenRead = false,
                    HasReplies = true
                };
                db.ConversationMap.Add(mapOther);

                await db.SaveChangesAsync();

                return conv.Id; //return new conversation Id
            }

            //// Add to existing conversation
            msg = new Message
            {
                ConversationId = (int)convId,
                From = from,
                MessageText = text,
                Timestamp = DateTime.Now
            };
            db.Messages.Add(msg);

            //Update last message in conversation
            mapMe = db.ConversationMap.Find(from, convId);
            mapMe.HasBeenRead = true;

            mapOther = db.ConversationMap.Find(to, convId);
            mapOther.HasBeenRead = false;

            if (!mapMe.HasReplies || !mapOther.HasReplies)
            {
                //Conversation doesn't have replies.  Check if this message is a reply 
                //and set flag accordingly.
                if(mapMe.LastMessage.From != from)
                {
                    //the last message isn't from me
                    mapMe.HasReplies = true;
                    mapOther.HasReplies = true;
                }
            }

            mapMe.LastMessage = msg;
            mapOther.LastMessage = msg;

            await db.SaveChangesAsync();

            return (int)convId; //return passed in conversation Id
        }
        /// <summary>
        /// 
        /// Deletes the conversation for a user from ConversationMap.  Decrements the 
        /// message count for the user by the number of messages in conversation.
        /// 
        /// </summary>
        public async Task DeleteConversationAsync(int id, int convId)
        {
            var db = new OkbDbContext();

            //TODO: Get number of messages in conversation
            //var query = from msg in db.Messages.AsNoTracking()
            //            where msg.ConversationId == convId
            //            select msg;

            //var count = query.Count();

            //Delete conversation
            var toDelete = new ConversationMap { ConversationId = convId, ProfileId = id };
            db.ConversationMap.Attach(toDelete);
            db.ConversationMap.Remove(toDelete);

            //TODO: Decrement message count for user

            await db.SaveChangesAsync();
        }
        /// <summary>
        /// Reply to an existing conversation. We don't need the "to" field since we only
        /// store the "from" field for each message. Increments the unread count for the
        /// user sent to if the message was previously unread. 
        /// </summary>
        public async Task Reply(int from, int convId, string message)
        {
            var db = new OkbDbContext();
            Message msg;
            ConversationMap mapMe, mapOther;
            bool incUnreadFlag = false;

            //// Add to existing conversation
            msg = new Message
            {
                ConversationId = convId,
                From = from,
                MessageText = message,
                Timestamp = DateTime.Now
            };
            db.Messages.Add(msg);

            //Update last message in conversation
            mapMe = db.ConversationMap.Find(from, convId);
            mapMe.HasBeenRead = true;

            mapOther = db.ConversationMap.Find(mapMe.Other, convId);

            if (mapOther==null)
            {
                //conversation doesn't exist for other user - they deleted it
                mapOther = new ConversationMap
                {
                    ConversationId = convId,
                    ProfileId = mapMe.Other,
                    Other = from,
                    HasBeenRead = false,
                    HasReplies = true 
                };
                db.ConversationMap.Add(mapOther);
                incUnreadFlag = true;
            }

            //Increment unread count for "to" user if convesation was previously unread
            if (mapOther.HasBeenRead)
            {
                incUnreadFlag = true;
            }
                        
            mapOther.HasBeenRead = false;
            mapOther.HasBeenEmailed = false;

            if (!mapMe.HasReplies || !mapOther.HasReplies)
            {
                //Conversation doesn't have replies.  Check if this message is a reply 
                //and set flag accordingly.
                if (mapMe.LastMessage.From != from)
                {
                    //the last message isn't from me
                    mapMe.HasReplies = true;
                    mapOther.HasReplies = true;
                }
            }

            mapMe.LastMessage = msg;
            mapOther.LastMessage = msg;

            await db.SaveChangesAsync();

            //do this last in case we have any db errors
            if (incUnreadFlag)
            {
                IncrementUnreadCount(mapMe.Other);
            }
        }