Message CreateMessage(int messageFolder)
        {
            Message message = IsDraft ? SourceMessage : new Message();
            var channel = (ChannelInstance)FromAccount.SelectedItem;

            if (IsDraft)
            {
                if (message.BodyHtmlStreamName.HasValue)
                {
                    // Delete old body stream
                    ClientState.Current.Storage.Delete("m", message.BodyHtmlStreamName.ToString());
                }

                message.To.Clear();
                message.CC.Clear();
                message.BCC.Clear();
            }

            if (channel == null)
                channel = MailChannels.First();

            if (SourceMessage != null)
            {
                message.InReplyTo = SourceMessage.MessageIdentifier;
                message.ConversationIdentifier = SourceMessage.ConversationIdentifier;
            }
            else
            {
                message.ConversationIdentifier = Guid.NewGuid().ToConversationId();
            }

            message.Context = ContextTextBox.Text;
            message.From = new SourceAddress(channel.InputChannel.SourceAdress, SettingsManager.ClientSettings.AppConfiguration.Fullname);
            message.TargetChannelId = channel.Configuration.ChannelId;
            message.To.AddRange(To);
            message.CC.AddRange(CC);
            message.BCC.AddRange(BCC);

            var access = new ClientMessageAccess(message, null, GetBodyStream());

            message.BodyHtmlStreamName = access.WriteBodyHtml();
            message.BodyPreview = access.GetBodyPreview();
            message.IsRead = true;
            message.DateSent = DateTime.Now;
            message.MessageFolder = messageFolder;
            message.DateSent = DateTime.Now;
            message.DateCreated = DateTime.Now;

            if (AddWaitingFor && !message.IsWaitingFor)
                message.AddLabel(new Label(LabelType.WaitingFor), false);
            else if (!AddWaitingFor && message.IsWaitingFor)
                message.RemoveLabel(message.LabelsList.First(l => l.LabelType == LabelType.WaitingFor), false);

            if (SourceMessage != null)
                SourceMessage.TrackAction(ActionType.ReplyForward);

            return message;
        }
        protected override void ExecuteCore()
        {
            try
            {
                Logger.Debug("Retreiving message {0} from {1}", LogSource.Receive, header, config.DisplayName);

                foreach (var channelMessage in channel.GetMessage(header))
                {
                    var message = new Message
                        {
                            MessageNumber = header.MessageNumber,
                            MessageIdentifier = channelMessage.MessageIdentifier,
                            From = channelMessage.From,
                            ReturnTo = channelMessage.ReturnTo,
                            To = channelMessage.To,
                            CC = channelMessage.CC,
                            BCC = channelMessage.BCC,
                            InReplyTo = channelMessage.InReplyTo,
                            Size = header.Size,
                            Context = channelMessage.Context,
                            ConversationIdentifier = channelMessage.ConversationId,
                            SourceFolder = channelMessage.SourceFolder,
                            Metadata = channelMessage.Metadata,
                            IsRead = channelMessage.IsRead,
                            IsStarred = channelMessage.IsStarred,
                            DateReceived = channelMessage.DateReceived,
                            DateSent = channelMessage.DateSent
                        };

                    message.Context = message.Context != null ? message.Context.Trim() : String.Empty;

                    string bodyText = channelMessage.BodyText.ReadString();
                    string bodyHtml = channelMessage.BodyHtml.ReadString();

                    var access = new ClientMessageAccess(message, bodyText, bodyHtml);

                    if (folder.ToStorageFolder() == Folders.SentItems)
                    {
                        // For sent items we sent the TargetChannelId
                        message.SourceChannelId = 0;
                        message.TargetChannelId = config.ChannelId;
                    }
                    else
                    {
                        // For all other items we sent the SourceChannelId
                        message.SourceChannelId = config.ChannelId;
                    }

                    // Create BodyPreview field from reader
                    message.BodyPreview = access.GetBodyPreview();
                    message.BodyHtmlStreamName = access.WriteBodyHtml();
                    message.BodyTextStreamName = access.WriteBodyText();
                    message.MessageFolder = folder.ToStorageFolder();
                    message.Metadata = header.Metadata;

                    // Fix for messages which have a timestamp in the future
                    if (message.DateReceived > DateTime.Now)
                        message.DateReceived = DateTime.Now;

                    // Set IsNew state for message
                    if (!message.IsRead)
                        message.IsNew = true;

                    // Save message
                    ClientState.Current.DataService.Save(message);

                    // Message received, process attachments
                    foreach (var attachment in channelMessage.Attachments)
                    {
                        var document = new Document
                            {
                                Filename = attachment.Filename,
                                TargetChannelId = attachment.TargetChannelId,
                                DocumentFolder = folder.ToStorageFolder(),
                                ContentType = attachment.ContentType,
                                ContentId = attachment.ContentId,
                                ContentStream = attachment.ContentStream,
                                SourceChannelId = config.ChannelId,
                                DateReceived = message.DateReceived,
                                DateSent = message.DateSent,
                                Message = message
                            };

                        EventBroker.Publish(AppEvents.DocumentReceived, document);

                        if (attachment.ContentStream != null)
                        {
                            attachment.ContentStream.Dispose();
                            attachment.ContentStream = null;
                        }
                    }

                    if (channelMessage.BodyText != null)
                        channelMessage.BodyText.Dispose();

                    if (channelMessage.BodyHtml != null)
                        channelMessage.BodyHtml.Dispose();

                    EventBroker.Publish(AppEvents.MessageStored, message);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("An error occured when trying to download header {0}. Exception = {1}", LogSource.BackgroundTask, header, ex);

                throw;
            }
        }
        void Send_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ClientStats.LogEvent("Quick reply all send");

            if (String.IsNullOrEmpty(QuickReplyAll.Text.Trim()))
                return;

            var newMessage = new Message();

            #region Create message

            var channel = message.SourceChannelId == 0 ?
                ChannelsManager.GetDefaultChannel() :
                ChannelsManager.GetChannelObject(Message.SourceChannelId);

            var recipients = new SourceAddressCollection();
            var sourceAddress = channel.InputChannel.GetSourceAddress();

            recipients.Add(Message.From);
            recipients.AddRange(Message.To);

            // Remove our own address from recipient list
            if (recipients.Contains(sourceAddress))
                recipients.Remove(sourceAddress);

            newMessage.InReplyTo = Message.MessageIdentifier;
            newMessage.ConversationIdentifier = Message.ConversationIdentifier;
            newMessage.Context = "Re: " + Message.Context;
            newMessage.From = channel.InputChannel.GetSourceAddress();
            newMessage.TargetChannelId = channel.Configuration.ChannelId;
            newMessage.To.AddRange(recipients);
            newMessage.CC.AddRange(Message.CC);

            var access = new ClientMessageAccess(newMessage, null,
                MessageBodyGenerator.CreateBodyTextForReply(Message, QuickReplyAll.Text.Nl2Br()));

            newMessage.BodyHtmlStreamName = access.WriteBodyHtml();
            newMessage.BodyPreview = access.GetBodyPreview();
            newMessage.IsRead = true;
            newMessage.DateSent = DateTime.Now;
            newMessage.MessageFolder = Folders.SentItems;
            newMessage.DateSent = DateTime.Now;
            newMessage.DateCreated = DateTime.Now;

            #endregion

            #region Send message

            ClientState.Current.DataService.Save(newMessage);

            // Add message to mailbox
            EventBroker.Publish(AppEvents.MessageStored, newMessage);

            // Save command
            CommandQueue.Enqueue(AppCommands.SendMessage, newMessage);

            if (!NetworkInterface.GetIsNetworkAvailable())
            {
                ClientState.Current.ShowMessage(
                    new AppMessage(Strings.MessageWillBeSentLater)
                        {
                            EntityId = newMessage.MessageId.Value,
                            EntityType = EntityType.Message
                        }, MessageType.Success);
            }

            QuickReplyAll.Text = String.Empty;

            message.TrackAction(ActionType.ReplyForward);

            #endregion
        }