public bool ComposeAndSendMessage(VATRPChat chat, string text)
        {
            VATRPChat chatID = this.FindChat(chat);
            if ((chatID == null) || (chatID.Contact == null))
            {
                return false;
            }
            var declineMessage = text.StartsWith(VATRPChatMessage.DECLINE_PREFIX);
            var message = new VATRPChatMessage(MessageContentType.Text)
            {
                Direction = MessageDirection.Outgoing,
                Status = LinphoneChatMessageState.LinphoneChatMessageStateIdle,
                MessageTime = DateTime.Now,
                IsIncompleteMessage = false,
                Chat = chatID,
                IsDeclineMessage = declineMessage
            };

            message.Content = declineMessage ? text.Substring(VATRPChatMessage.DECLINE_PREFIX.Length) : text;

            // send message to linphone
            IntPtr msgPtr = IntPtr.Zero;
            _linphoneSvc.SendChatMessage(chat, text, ref msgPtr);
            if (msgPtr != IntPtr.Zero)
                message.MessageTime = Time.ConvertUtcTimeToLocalTime(LinphoneAPI.linphone_chat_message_get_time(msgPtr));

            message.NativePtr = msgPtr;

            chat.AddMessage(message, false);
            chat.UpdateLastMessage(false);

            chat.UnreadMsgCount = 0;
            chat.Contact.UnreadMsgCount = 0;

            OnConversationUnReadStateChanged(chat);
            this.OnConversationUpdated(chat, true);

            return true;
        }
        private void LoadMessages(VATRPChat chat, IntPtr chatRoomPtr)
        {
            IntPtr msgListPtr = LinphoneAPI.linphone_chat_room_get_history(chatRoomPtr, 0);
            if (msgListPtr != IntPtr.Zero)
            {
                MSList msMessagePtr;

                var loggedInContact = _contactSvc.FindLoggedInContact();
                if (loggedInContact == null)
                    return;
                do
                {
                    msMessagePtr.next = IntPtr.Zero;
                    msMessagePtr.prev = IntPtr.Zero;
                    msMessagePtr.data = IntPtr.Zero;

                    msMessagePtr = (MSList) Marshal.PtrToStructure(msgListPtr, typeof (MSList));
                    if (msMessagePtr.data != IntPtr.Zero)
                    {
                        IntPtr tmpPtr = LinphoneAPI.linphone_chat_message_get_from_address(msMessagePtr.data);
                        tmpPtr = LinphoneAPI.linphone_address_as_string(tmpPtr);
                        if (tmpPtr != IntPtr.Zero)
                        {
                            var fromParty = LinphoneAPI.PtrToStringUtf8(tmpPtr).TrimSipPrefix();
                            LinphoneAPI.ortp_free(tmpPtr);

                            tmpPtr = LinphoneAPI.linphone_chat_message_get_to_address(msMessagePtr.data);
                            if (tmpPtr != IntPtr.Zero)
                            {
                                tmpPtr = LinphoneAPI.linphone_address_as_string(tmpPtr);
                                var toParty = LinphoneAPI.PtrToStringUtf8(tmpPtr).TrimSipPrefix();
                                LinphoneAPI.ortp_free(tmpPtr);

                                string dn, un, host;
                                int port;

                                if (fromParty == loggedInContact.ID || toParty == loggedInContact.ID)
                                {
                                    bool isOutgoing = false;
                                    string remoteParty = fromParty;
                                    if (fromParty == loggedInContact.ID)
                                    {
                                        isOutgoing = true;
                                        remoteParty = toParty;
                                    }

                                    if (
                                        !VATRPCall.ParseSipAddressEx(remoteParty, out dn, out un,
                                            out host, out port))
                                        un = "";

                                    if (un.NotBlank())
                                    {
                                        var contactAddress = string.Format("{0}@{1}", un, host);
                                        var contactID = new ContactID(contactAddress, IntPtr.Zero);
                                        var contact = FindContact(contactID);

                                        if (contact == null)
                                        {
                                            contact = new VATRPContact(contactID)
                                            {
                                                DisplayName = dn,
                                                Fullname = un,
                                                SipUsername = un,
                                                RegistrationName = contactAddress
                                            };
                                            _contactSvc.AddContact(contact, "");
                                        }

                                        IntPtr msgPtr = LinphoneAPI.linphone_chat_message_get_text(msMessagePtr.data);
                                        var messageString = string.Empty;
                                        if (msgPtr != IntPtr.Zero)
                                            messageString = LinphoneAPI.PtrToStringUtf8(msgPtr);

                                        if (messageString.NotBlank())
                                        {
                                            var localTime =
                                                Time.ConvertUtcTimeToLocalTime(
                                                    LinphoneAPI.linphone_chat_message_get_time(msMessagePtr.data));
                                            var declineMessage = false;
                                            if (messageString.StartsWith(VATRPChatMessage.DECLINE_PREFIX))
                                            {
                                                messageString = messageString.Substring(VATRPChatMessage.DECLINE_PREFIX.Length);
                                                declineMessage = true;
                                            }
                                            var chatMessage = new VATRPChatMessage(MessageContentType.Text)
                                            {
                                                Direction =
                                                    isOutgoing
                                                        ? MessageDirection.Outgoing
                                                        : MessageDirection.Incoming,
                                                IsIncompleteMessage = false,
                                                MessageTime = localTime,
                                                Content = messageString,
                                                IsRTTMessage = false,
                                                IsDeclineMessage = declineMessage,
                                                IsRead = LinphoneAPI.linphone_chat_message_is_read(msMessagePtr.data) == 1,
                                                Status = LinphoneAPI.linphone_chat_message_get_state(msMessagePtr.data),
                                                Chat = chat
                                            };

                                            chat.AddMessage(chatMessage, false);
                                            chat.UpdateLastMessage(false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    msgListPtr = msMessagePtr.next;
                } while (msMessagePtr.next != IntPtr.Zero);

            }
        }
        public bool ComposeAndSendMessage(IntPtr callPtr, VATRPChat chat, char key, bool inCompleteMessage)
        {
            VATRPChat chatID = this.FindChat(chat);
            if ((chatID == null) || (chatID.Contact == null))
            {
                return false;
            }

            VATRPContact loggedContact = _contactSvc.FindLoggedInContact();

            var message = chat.SearchIncompleteMessage(MessageDirection.Outgoing);
            if (message == null)
            {
                if (key == '\r')
                    return false;

                message = new VATRPChatMessage(MessageContentType.Text)
                {
                    Direction = MessageDirection.Outgoing,
                    Status = LinphoneChatMessageState.LinphoneChatMessageStateIdle,
                    IsRTTMessage = true,
                    Chat = chatID
                };
                chatID.AddMessage(message, false);
            }
            else
            {
                message.MessageTime = DateTime.Now;
            }

            var rttCode = (uint) key;
            var createBubble = false;
            if (key != '\r')
            {
                var sb = new StringBuilder(message.Content);
                if (key == '\b')
                {
                    if (sb.Length > 0)
                        sb.Remove(sb.Length - 1, 1);
                }
                else
                    sb.Append(Convert.ToChar(rttCode));
                message.Content = sb.ToString();
                chat.UpdateLastMessage(false);
            }
            else
            {
                createBubble = true;
            }

            message.IsIncompleteMessage = !createBubble;

            // send message to linphone
            var chatPtr = chat.NativePtr;
            var msgPtr = message.NativePtr;
            _linphoneSvc.SendChar(rttCode, callPtr, ref chatPtr, ref msgPtr);

            chat.NativePtr = chatPtr;
            message.NativePtr = msgPtr;
            if (message.NativePtr != IntPtr.Zero)
                message.Status = _linphoneSvc.GetMessageStatus(message.NativePtr);

            if (createBubble)
            {
                // delete empty message
                if (!message.Content.NotBlank())
                    chatID.DeleteMessage(message);
            }
            this.OnConversationUpdated(chatID, true);
            return true;
        }