src/messaging/qfsengine_symbian.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/messaging/qfsengine_symbian.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,2851 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmessageservice.h"
+#include "qmessageservice_symbian_p.h"
+#include "qfsengine_symbian_p.h"
+#include "qmessage_symbian_p.h"
+#include "messagingutil_p.h"
+#include "qmessageaccount.h"
+#include "qmessageaccount_p.h"
+#include "qmessageaccountfilter.h"
+#include "qmessageaccountfilter_p.h"
+#include "qmessagecontentcontainer_symbian_p.h"
+#include "qmessagefolder.h"
+#include "qmessagefolder_p.h"
+#include "qmessagefolderfilter.h"
+#include "qmessagefolderfilter_p.h"
+#include "qmessageaccountsortorder_p.h"
+#include "qmessagestore_symbian_p.h"
+#include "qmessagefoldersortorder_p.h"
+#include "qmessagesortorder_p.h"
+
+#include <emailinterfacefactory.h>
+#include <QTextCodec>
+#include <emailapidefs.h>
+#include <memailmailbox.h>
+#include <memailfolder.h>
+#include <memailmessage.h>
+#include <memailaddress.h>
+#include <memailcontent.h>
+#include <mmessageiterator.h>
+
+using namespace EmailInterface;
+
+QTM_BEGIN_NAMESPACE
+
+using namespace SymbianHelpers;
+
+Q_GLOBAL_STATIC(CFSEngine,fsEngine);
+
+CFSEngine::CFSEngine()
+{
+    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(cleanupFSBackend()));
+
+    TRAPD(err, {
+        m_factory = CEmailInterfaceFactory::NewL(); 
+        m_ifPtr = m_factory->InterfaceL(KEmailClientApiInterface);
+    });
+    
+    Q_UNUSED(err);
+    m_clientApi = static_cast<MEmailClientApi*>(m_ifPtr);
+#ifdef FREESTYLEMAILBOXOBSERVERUSED
+    TRAPD(err2, setPluginObserversL());
+    Q_UNUSED(err2);
+#endif
+}
+
+CFSEngine::~CFSEngine()
+{
+
+}
+
+void CFSEngine::cleanupFSBackend()
+{
+    m_mtmAccountList.clear();
+    for (TInt i = 0; i < m_attachments.Count(); i++){
+        m_attachments[i]->Release();
+    }
+    m_attachments.Reset();
+    for (TInt i = 0; i < m_mailboxes.Count(); i++){
+        m_mailboxes[i]->Release();
+    }
+    m_mailboxes.Reset();
+    m_clientApi->Release();
+    delete m_factory;
+}
+
+CFSEngine* CFSEngine::instance()
+{   
+    return fsEngine();
+}
+
+bool CFSEngine::accountLessThan(const QMessageAccountId accountId1, const QMessageAccountId accountId2)
+{
+    CFSEngine* freestyleEngine = fsEngine();
+    return QMessageAccountSortOrderPrivate::lessThan(freestyleEngine->m_currentAccountOrdering,
+        freestyleEngine->account(accountId1),
+        freestyleEngine->account(accountId2));
+}
+
+void CFSEngine::orderAccounts(QMessageAccountIdList& accountIds, const QMessageAccountSortOrder &sortOrder) const
+{
+    Q_UNUSED(accountIds);
+    m_currentAccountOrdering = sortOrder;
+    qSort(accountIds.begin(), accountIds.end(), CFSEngine::accountLessThan);
+}
+
+bool CFSEngine::folderLessThan(const QMessageFolderId folderId1, const QMessageFolderId folderId2)
+{
+    CFSEngine* freestyleEngine = fsEngine();
+    return QMessageFolderSortOrderPrivate::lessThan(freestyleEngine->m_currentFolderOrdering,
+            freestyleEngine->folder(folderId1),
+            freestyleEngine->folder(folderId2));
+}
+
+void CFSEngine::orderFolders(QMessageFolderIdList& folderIds,  const QMessageFolderSortOrder &sortOrder) const
+{
+    m_currentFolderOrdering = sortOrder;
+    qSort(folderIds.begin(), folderIds.end(), CFSEngine::folderLessThan);
+}
+
+bool CFSEngine::messageLessThan(const QMessage& message1, const QMessage& message2)
+{
+    CFSEngine* freestyleEngine = fsEngine();
+    return QMessageSortOrderPrivate::lessThan(freestyleEngine->m_currentMessageOrdering, message1, message2);
+}
+
+void CFSEngine::orderMessages(QMessageIdList& messageIds, const QMessageSortOrder &sortOrder) const
+{
+    m_currentMessageOrdering = sortOrder;
+    QList<QMessage> messages;
+    for (int i=0; i < messageIds.count(); i++) {
+        messages.append(message(messageIds[i]));
+    }
+    qSort(messages.begin(), messages.end(), CFSEngine::messageLessThan);
+    messageIds.clear();
+    for (int i=0; i < messages.count(); i++) {
+        messageIds.append(messages[i].id());
+    }
+}
+
+void CFSEngine::setMtmAccountIdList(QMessageAccountIdList accountList)
+{
+    for (TInt i = 0; i < accountList.count(); i++) {
+        m_mtmAccountList.append(stripIdPrefix(accountList[i]));
+    }
+}
+
+QMessageAccountIdList CFSEngine::queryAccounts(const QMessageAccountFilter &filter, const QMessageAccountSortOrder &sortOrder, uint limit, uint offset) const
+{
+    QMessageAccountIdList accountIds;
+
+    TRAPD(err, updateEmailAccountsL());
+    Q_UNUSED(err);
+    
+    QMessageAccountFilterPrivate* privateMessageAccountFilter = QMessageAccountFilterPrivate::implementation(filter);
+    if (filter.isEmpty()) {
+        if (!privateMessageAccountFilter->_notFilter) {
+            // All accounts are returned for empty filter
+            foreach (QMessageAccount value, m_accounts) {                
+                accountIds.append(value.id());
+            }
+        }
+    } else {
+        if (privateMessageAccountFilter->_valid) {
+            foreach (QMessageAccount value, m_accounts) {
+                if (privateMessageAccountFilter->filter(value)) {
+                    accountIds.append(value.id());
+                }
+            }
+        } else {
+            foreach (QMessageAccount value, m_accounts) {
+                if (privateMessageAccountFilter->filter(value)) {
+                    accountIds.append(value.id());
+                }
+            }
+        }
+    }
+    
+    if (!sortOrder.isEmpty()) {
+        orderAccounts(accountIds, sortOrder);
+    }
+
+    applyOffsetAndLimitToAccountIds(accountIds, offset, limit);
+
+    return accountIds;
+}
+
+void CFSEngine::applyOffsetAndLimitToAccountIds(QMessageAccountIdList& idList, int offset, int limit) const
+{
+    if (offset > 0) {
+        if (offset > idList.count()) {
+            idList.clear();
+        } else {
+            for (int i = 0; i < offset; i++) {
+                idList.removeFirst();
+            }
+        }
+    }
+    if (limit > 0) {
+        for (int i = idList.count()-1; i >= limit; i--) {
+            idList.removeAt(i);
+        }
+    }
+}
+
+int CFSEngine::countAccounts(const QMessageAccountFilter &filter) const
+{
+    return queryAccounts(filter, QMessageAccountSortOrder(), 0, 0).count();
+}
+
+QMessageAccount CFSEngine::account(const QMessageAccountId &id) const
+{
+    TRAPD(err, updateEmailAccountsL());
+    Q_UNUSED(err)
+    return m_accounts[id.toString()];
+}
+
+QMessageAccountId CFSEngine::defaultAccount(QMessage::Type type) const
+{
+    // TODO
+    Q_UNUSED(type);
+    return QMessageAccountId();
+}
+
+QMessageAccountIdList CFSEngine::accountsByType(QMessage::Type type) const
+{
+    QMessageAccountIdList accountIds = QMessageAccountIdList();
+    
+    foreach (QMessageAccount value, m_accounts) {
+        if ((value.messageTypes() & type) == (int)type) {
+            accountIds.append(value.id());
+        }
+    }
+    
+    return accountIds;
+}
+
+
+void CFSEngine::updateEmailAccountsL() const
+{
+    QStringList keys = m_accounts.keys();
+    RMailboxPtrArray mailboxes;
+    CleanupResetAndRelease<MEmailMailbox>::PushL(mailboxes);
+    
+    m_clientApi->GetMailboxesL(mailboxes);
+    
+    for (TInt i = 0; i < mailboxes.Count(); i++) {
+        MEmailMailbox *mailbox = mailboxes[i];
+        QString idAsString = QString::number(mailbox->MailboxId().iId);
+        QString fsIdAsString = addIdPrefix(idAsString, SymbianHelpers::EngineTypeFreestyle);
+        TBool overlap = false;
+        for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
+            if (idAsString == m_mtmAccountList[j].toString())
+                overlap = true;
+        }
+        if (!m_accounts.contains(fsIdAsString) && !overlap) {     
+            QMessageAccount account = QMessageAccountPrivate::from(
+                                      QMessageAccountId(fsIdAsString),
+                                      QString::fromUtf16(mailbox->MailboxName().Ptr(), mailbox->MailboxName().Length()),
+                                      0,
+                                      0,
+                                      QMessage::Email);
+          
+            m_accounts.insert(fsIdAsString, account);
+            
+        } else {
+            keys.removeOne(fsIdAsString);
+        }
+        mailbox->Release();
+    }  
+    
+    mailboxes.Reset();
+    CleanupStack::PopAndDestroy();
+    
+    for (int i=0; i < keys.count(); i++) {
+        m_accounts.remove(keys[i]);
+    }   
+}
+
+#ifdef FREESTYLEMAILBOXOBSERVERUSED
+void CFSEngine::setPluginObserversL()
+{
+    m_clientApi->GetMailboxesL(m_mailboxes);    
+    for (TInt i = 0; i < m_mailboxes.Count(); i++) {
+        MEmailMailbox *mailbox = m_mailboxes[i];
+        mailbox->RegisterObserverL(*this);
+    }  
+}
+
+void CFSEngine::NewMessageEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aNewMessages, const TFolderId& aParentFolderId)
+{
+    QMessageManager::NotificationFilterIdSet matchingFilters;
+    QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Added;
+  
+    for (TInt i = 0; i < aNewMessages.Count(); i++) {
+        TMessageId messageId(aNewMessages[i]);
+        notificationL(aMailbox, messageId, aParentFolderId, notificationType);
+    }
+}
+
+void CFSEngine::MessageChangedEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aChangedMessages, const TFolderId& aParentFolderId)
+{
+    QMessageManager::NotificationFilterIdSet matchingFilters;
+    QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Updated;
+  
+    for (TInt i = 0; i < aChangedMessages.Count(); i++) {
+        TMessageId messageId(aChangedMessages[i]);
+        notificationL(aMailbox, messageId, aParentFolderId, notificationType);
+    }
+}
+
+void CFSEngine::MessageDeletedEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aDeletedMessages, const TFolderId& aParentFolderId)
+{
+    // TODO: add filter handling
+    QMessageManager::NotificationFilterIdSet matchingFilters;
+    QMap<int, QMessageFilter> filters(m_filters);
+    QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();  
+    QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Removed;
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(aMailbox);
+    MEmailFolder* folder = mailbox->FolderL(aParentFolderId); 
+    QString idAsString = QString::number(mailbox->MailboxId().iId);
+    for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
+        if (idAsString == m_mtmAccountList[j].toString())
+            return;
+    } 
+    for (TInt i = 0; i < aDeletedMessages.Count(); i++) {
+        for ( ; it != end; ++it) {
+            // Empty filter matches to all messages
+            matchingFilters.insert(it.key());
+        }
+        TMessageId messageId(aDeletedMessages[i]);
+        ipMessageStorePrivate->messageNotification(notificationType, 
+                            QMessageId(addIdPrefix(QString::number(messageId.iId), SymbianHelpers::EngineTypeFreestyle)), 
+                            matchingFilters);
+    }
+    folder->Release();
+    mailbox->Release();
+}
+
+void CFSEngine::notificationL(const TMailboxId& aMailbox, const TMessageId& aMessageId, 
+                                const TFolderId& aParentFolderId, QMessageStorePrivate::NotificationType aNotificationType)
+{
+    Q_UNUSED(aParentFolderId);
+    QMessageManager::NotificationFilterIdSet matchingFilters;
+    // Copy the filter map to protect against modification during traversal
+    QMap<int, QMessageFilter> filters(m_filters);
+    QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();
+    QMessage message;
+    QMessageId realMessageId = QMessageId(addIdPrefix(QString::number(aMessageId.iId), SymbianHelpers::EngineTypeFreestyle));
+    bool messageRetrieved = false;    
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(aMailbox);
+    CleanupReleasePushL(*mailbox);
+    QString idAsString = QString::number(mailbox->MailboxId().iId);
+    for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
+        if (idAsString == m_mtmAccountList[j].toString()) {
+            CleanupStack::Pop(mailbox);
+            return;
+        }
+    }   
+    for ( ; it != end; ++it) {
+        const QMessageFilter &filter(it.value());
+        if (!messageRetrieved) {
+            MEmailMessage* fsMessage = mailbox->MessageL(aMessageId);
+            CleanupReleasePushL(*fsMessage);
+            
+            if (!fsMessage) {
+                CleanupStack::Pop(fsMessage);
+                CleanupStack::Pop(mailbox);
+                return;
+            }
+            message = CreateQMessageL(fsMessage);
+            messageRetrieved = true;
+            CleanupStack::Pop(fsMessage);
+        }
+
+        if (filter.isEmpty()) {
+            // Empty filter matches to all messages
+            matchingFilters.insert(it.key());
+        } else {
+            if (message.type() == QMessage::NoType) {
+                matchingFilters.clear();
+                continue;
+            }
+        }
+        QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
+        if (privateMessageFilter->filter(message)) {
+            matchingFilters.insert(it.key());
+        }
+        
+    }
+    int c = matchingFilters.count();
+    QString id = realMessageId.toString();
+    if (matchingFilters.count() > 0)
+        ipMessageStorePrivate->messageNotification(aNotificationType, realMessageId, matchingFilters);
+    
+    CleanupStack::Pop(mailbox);   
+}
+
+#endif
+
+MEmailMessage* CFSEngine::createFSMessageL(const QMessage &message, const MEmailMailbox* mailbox)
+{
+    MEmailMessage* fsMessage = mailbox->CreateDraftMessageL();
+    CleanupReleasePushL(*fsMessage);
+    
+    switch (message.priority()) {
+        case QMessage::HighPriority:
+            fsMessage->SetFlag(EmailInterface::EFlag_Important);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Low);
+            break;
+        case QMessage::NormalPriority:
+            fsMessage->ResetFlag(EmailInterface::EFlag_Important);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Low);
+            break;
+        case QMessage::LowPriority:
+            fsMessage->SetFlag(EmailInterface::EFlag_Low);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Important);
+            break;            
+        }
+        if (message.status() & QMessage::Read) {
+            fsMessage->SetFlag(EmailInterface::EFlag_Read);
+        } else {
+            fsMessage->ResetFlag(EmailInterface::EFlag_Read);
+        }
+    
+    MEmailAddress* sender = mailbox->AddressL();
+    sender->SetRole(MEmailAddress::ESender);
+    fsMessage->SetReplyToAddressL(*sender);
+        
+    QList<QMessageAddress> toList(message.to());
+    if (toList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray toAddress;
+        for (int i = 0; i < toList.size(); ++i) {
+            qreceiver = toList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();
+            address->SetAddressL(receiver);
+            address->SetDisplayNameL(receiver);
+            address->SetRole(MEmailAddress::ETo);
+            toAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::ETo, toAddress);
+    }
+    
+    QList<QMessageAddress> ccList(message.cc());
+    if (ccList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray ccAddress;
+        for (int i = 0; i < ccList.size(); ++i) {
+            qreceiver = ccList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();
+            address->SetDisplayNameL(receiver);
+            address->SetRole(MEmailAddress::ECc);
+            address->SetAddressL(receiver);
+            ccAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::ECc, ccAddress);
+    }
+        
+    QList<QMessageAddress> bccList(message.bcc());
+    if (bccList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray bccAddress;
+        for (int i = 0; i < bccList.size(); ++i) {
+            qreceiver = bccList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();
+            address->SetDisplayNameL(receiver);
+            address->SetRole(MEmailAddress::EBcc);
+            address->SetAddressL(receiver);
+            bccAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::EBcc, bccAddress);
+    }
+    if (message.bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
+        // Message contains only body (not attachments)
+        QString messageBody = message.textContent();
+        if (!messageBody.isEmpty()) {
+            QByteArray type = message.contentType();
+            QByteArray subType = message.contentSubType();
+            MEmailMessageContent* content = fsMessage->ContentL();
+            MEmailTextContent* textContent = content->AsTextContentOrNull();
+            if (textContent) {
+                if (type == "text" && subType == "plain") {
+                    textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
+                } 
+               else if (type == "text" && subType == "html") {
+                    textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
+                }
+            }
+            else
+                fsMessage->SetPlainTextBodyL(TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
+        }
+    } else {
+        // Message contains body and attachments
+        QMessageContentContainerIdList contentIds = message.contentIds();
+        foreach (QMessageContentContainerId id, contentIds){
+            QMessageContentContainer container = message.find(id);
+            MEmailMessageContent* content = fsMessage->ContentL(); 
+            QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
+            if (pPrivateContainer->_id == message.bodyId()) {
+                // ContentContainer is body
+                if (!container.textContent().isEmpty()) {               
+                    MEmailTextContent* textContent = content->AsTextContentOrNull();
+                    if (textContent) {
+                        QByteArray type = container.contentType();
+                        QByteArray subType = container.contentSubType();
+                        if (type == "text" && subType == "plain") {
+                            textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
+                        }
+                        else if (type == "text" && subType == "html") {
+                            textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
+                        } 
+                    }
+                    else
+                        fsMessage->SetPlainTextBodyL(TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
+                }
+            } else {
+                // ContentContainer is attachment
+                QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
+                // Replace Qt style path separator "/" with Symbian path separator "\"
+                filePath.replace(QByteArray("/"), QByteArray("\\"));
+                QString temp_path = QString(filePath);
+                TPtrC16 attachmentPath(KNullDesC);
+                attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
+                fsMessage->AddAttachmentL(attachmentPath);
+            }        
+        }
+    }
+    fsMessage->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
+    
+    QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+    privateMessage->_id = QMessageId(addIdPrefix(QString::number(fsMessage->MessageId().iId),SymbianHelpers::EngineTypeFreestyle));
+    
+    fsMessage->SaveChangesL();
+    CleanupStack::Pop(fsMessage);
+    return fsMessage;
+}
+
+bool CFSEngine::addMessage(QMessage* message)
+{
+    TMailboxId mailboxId(stripIdPrefix(message->parentAccountId().toString()).toInt());
+    MEmailMailbox* mailbox = NULL;
+    TRAPD(mailerr, mailbox = m_clientApi->MailboxL(mailboxId));
+    if (mailerr != KErrNone)
+        return false;
+
+    MEmailMessage* fsMessage = NULL;
+    TRAPD(err, fsMessage = createFSMessageL(*message, mailbox));
+    if (fsMessage)
+        fsMessage->Release();
+    if (mailbox)
+        mailbox->Release();
+    
+    if (err != KErrNone)
+        return false;
+    else
+        return true;
+}
+
+bool CFSEngine::updateMessage(QMessage* message)
+{
+    TRAPD(err, updateMessageL(message));
+    if (err != KErrNone)
+        return false;
+    else
+        return true;
+}
+
+void CFSEngine::updateMessageL(QMessage* message)
+{
+    TMailboxId mailboxId(stripIdPrefix(message->parentAccountId().toString()).toInt());
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+    CleanupReleasePushL(*mailbox);
+  
+    TMessageId messageId(message->id().toString().toInt(),
+                            message->parentFolderId().toString().toInt(), 
+                            mailboxId);
+    MEmailMessage* fsMessage = mailbox->MessageL(messageId);
+    CleanupReleasePushL(*fsMessage);
+    
+    switch (message->priority()) {
+        case QMessage::HighPriority:
+            fsMessage->SetFlag(EmailInterface::EFlag_Important);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Low);
+            break;
+        case QMessage::NormalPriority:
+            fsMessage->ResetFlag(EmailInterface::EFlag_Important);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Low);
+            break;
+        case QMessage::LowPriority:
+            fsMessage->SetFlag(EmailInterface::EFlag_Low);
+            fsMessage->ResetFlag(EmailInterface::EFlag_Important);
+            break;            
+        }
+        if (message->status() & QMessage::Read) {
+            fsMessage->SetFlag(EmailInterface::EFlag_Read);
+        } else {
+            fsMessage->ResetFlag(EmailInterface::EFlag_Read);
+        }
+        
+    MEmailAddress* sender = mailbox->AddressL();
+    sender->SetRole(MEmailAddress::ESender);
+    fsMessage->SetReplyToAddressL(*sender);
+        
+    QList<QMessageAddress> toList(message->to());
+    if (toList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray toAddress;
+        for (int i = 0; i < toList.size(); ++i) {
+            qreceiver = toList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();
+            address->SetAddressL(receiver);
+            toAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::ETo, toAddress);
+    }
+    
+    QList<QMessageAddress> ccList(message->cc());
+    if (ccList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray ccAddress;
+        for (int i = 0; i < ccList.size(); ++i) {
+            qreceiver = ccList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();;
+            address->SetAddressL(receiver);
+            ccAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::ECc, ccAddress);
+    }
+        
+    QList<QMessageAddress> bccList(message->bcc());
+    if (bccList.count() > 0) {
+        TPtrC16 receiver(KNullDesC);
+        QString qreceiver;
+        REmailAddressArray bccAddress;
+        for (int i = 0; i < bccList.size(); ++i) {
+            qreceiver = bccList.at(i).addressee();
+            receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
+            MEmailAddress* address = mailbox->AddressL();;
+            address->SetAddressL(receiver);
+            bccAddress.Append(address);
+        }
+        fsMessage->SetRecipientsL(MEmailAddress::EBcc, bccAddress);
+    }
+    
+    if (message->bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
+        // Message contains only body (not attachments)
+        QString messageBody = message->textContent();
+        if (!messageBody.isEmpty()) {
+            MEmailMessageContent* content = fsMessage->ContentL();
+            MEmailTextContent* textContent = content->AsTextContentOrNull();
+            textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(message->textContent().utf16())));
+            // TODO:
+            }
+    } else {
+        // Message contains body and attachments
+        QMessageContentContainerIdList contentIds = message->contentIds();
+        foreach (QMessageContentContainerId id, contentIds){
+            QMessageContentContainer container = message->find(id);
+            QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
+            if (pPrivateContainer->_id == message->bodyId()) {
+                // ContentContainer is body
+                if (!container.textContent().isEmpty()) {
+                    MEmailMessageContent* content = fsMessage->ContentL();
+                    MEmailTextContent* textContent = content->AsTextContentOrNull();
+                    QByteArray type = container.contentType();
+                    QByteArray subType = container.contentSubType();
+                    if (type == "text" && subType == "plain") {
+                        textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
+                    }
+                    else if (type == "text" && subType == "html") {
+                        textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
+                    }
+                }
+            } else {
+                // ContentContainer is attachment
+                QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
+                // Replace Qt style path separator "/" with Symbian path separator "\"
+                filePath.replace(QByteArray("/"), QByteArray("\\"));
+                QString temp_path = QString(filePath);
+                TPtrC16 attachmentPath(KNullDesC);
+                attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
+                fsMessage->AddAttachmentL(attachmentPath);
+            }        
+        }
+    }
+    
+    fsMessage->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message->subject().utf16())));
+    fsMessage->SaveChangesL();
+    CleanupStack::PopAndDestroy(fsMessage);
+    CleanupStack::PopAndDestroy(mailbox);
+}
+
+bool CFSEngine::removeMessage(const QMessageId &id, QMessageManager::RemovalOption option)
+{
+    Q_UNUSED(option);
+    bool retVal = false;
+    foreach (QMessageAccount account, m_accounts) {
+        MEmailMessage* message = NULL;
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+        
+        TMessageId messageId(
+            stripIdPrefix(id.toString()).toInt(),
+            0, 
+            mailboxId);
+        
+        TRAPD(err, message = mailbox->MessageL(messageId));
+
+        if (err == KErrNone) {
+            TFolderId folderId(message->ParentFolderId());
+            TRAPD(err2,
+                MEmailFolder* folder = mailbox->FolderL(folderId);
+                REmailMessageIdArray messageIds;
+                messageIds.Append(message->MessageId());
+                folder->DeleteMessagesL(messageIds);
+                folder->Release();
+                );
+            if (err2 == KErrNone)
+                retVal = true;
+            mailbox->Release();
+            break; // no need to continue
+        }
+        mailbox->Release();
+    }
+    return retVal;
+}
+
+bool CFSEngine::showMessage(const QMessageId &id)
+{
+    bool retVal = false;
+    foreach (QMessageAccount account, m_accounts) {
+        MEmailMessage* message = NULL;
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+        
+        TMessageId messageId(
+            stripIdPrefix(id.toString()).toInt(),
+            0, 
+            mailboxId);
+        
+        TRAPD(err, message = mailbox->MessageL(messageId));
+
+        if (err == KErrNone) {
+            TRAPD(err2, message->ShowMessageViewerL());
+            if (err2 == KErrNone)
+                retVal = true;
+            message->Release();
+            mailbox->Release();
+            break; // no need to continue
+        }
+        mailbox->Release();
+    } 
+    return retVal;
+}
+
+bool CFSEngine::composeMessage(const QMessage &message)
+{
+    bool retVal = false;
+    MEmailMailbox* mailbox = NULL;
+    TMailboxId mailboxId(stripIdPrefix(message.parentAccountId().toString()).toInt());
+    TRAPD(err, mailbox = m_clientApi->MailboxL(mailboxId));
+    if (err == KErrNone) {
+        TRAPD(err2, mailbox->EditNewMessageL());
+        if (err2 == KErrNone)
+            retVal = true;
+        mailbox->Release();
+    }
+    return retVal;
+}
+
+bool CFSEngine::retrieve(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id)
+{
+    Q_UNUSED(id);
+    m_privateService = &privateService;
+    bool retVal = false;
+    foreach (QMessageAccount account, m_accounts) {
+        MEmailMessage* message = NULL;
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        MEmailMailbox* mailbox = NULL;
+        TRAPD(mailboxError, mailbox = m_clientApi->MailboxL(mailboxId));
+        if (mailboxError == KErrNone) {       
+            TMessageId mId(
+                stripIdPrefix(messageId.toString()).toInt(),
+                0, 
+                mailboxId);
+            
+            TRAPD(err, message = mailbox->MessageL(mId));
+            if (err == KErrNone) {
+                MEmailMessageContent* content = NULL;
+                TRAPD(contentError, content = message->ContentL());
+                if (contentError == KErrNone) {
+                    TRAPD(err, retrieveAttachmentsL(message));
+                        if (err == KErrNone)
+                            retVal = true;
+                        }
+                }
+                message->Release();
+                mailbox->Release();
+                break; // no need to continue
+        }
+        mailbox->Release();
+    } 
+    return retVal;
+}
+
+bool CFSEngine::retrieveBody(QMessageServicePrivate& privateService, const QMessageId& id)
+{
+    bool retVal = false;
+    m_privateService = &privateService;
+    foreach (QMessageAccount account, m_accounts) {
+        MEmailMessage* message = NULL;
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        MEmailMailbox* mailbox = NULL;
+        TRAPD(mailBoxError, mailbox = m_clientApi->MailboxL(mailboxId));
+        if (mailBoxError == KErrNone) {
+            TMessageId messageId(
+                stripIdPrefix(id.toString()).toInt(),
+                0, 
+                mailboxId);
+            
+            TRAPD(err, message = mailbox->MessageL(messageId));
+            if (err == KErrNone) {
+                MEmailMessageContent* content = NULL;
+                TRAPD(contentError, content = message->ContentL());
+                if (contentError == KErrNone) { 
+                    TRAPD(err, retrieveTotalBodyL(content));
+                    if (err == KErrNone)
+                        retVal = true;
+                    }
+                }
+                message->Release();
+                mailbox->Release();
+                break; // no need to continue
+            }
+            mailbox->Release();
+        } 
+    return retVal;
+}
+
+void CFSEngine::retrieveTotalBodyL(MEmailMessageContent* aContent)
+{
+    MEmailMultipart* mPart = aContent->AsMultipartOrNull();
+    if (mPart) {
+        TInt partCount = 0;
+        TRAPD(err, partCount = mPart->PartCountL());
+            if (err == KErrNone) {
+                for (TInt i = 0; i < partCount; i++) {
+                    MEmailMessageContent* content = NULL;
+                    TRAPD(err2, content = mPart->PartByIndexL(i));
+                    if (err2 == KErrNone) {
+                        retrieveTotalBodyL(content);
+                        content->Release();
+                    }
+                }
+            }
+            return;
+        }
+ 
+    MEmailTextContent* textContent = aContent->AsTextContentOrNull();
+    if (textContent) { 
+        TInt availableSize = textContent->AvailableSize();
+        TInt totalSize = textContent->TotalSize();
+        if (totalSize > availableSize) {
+            TRAPD(textErr, textContent->FetchL(*this));
+            Q_UNUSED(textErr);
+        }      
+    }   
+    return;
+}
+
+void CFSEngine::retrieveAttachmentsL(MEmailMessage* aMessage)
+{
+    for (TInt i = 0; i < m_attachments.Count(); i++) {
+        m_attachments[i]->Release();
+    }
+    m_attachments.Reset();
+    TInt count = aMessage->GetAttachmentsL(m_attachments);
+    for(TInt i = 0; i < count; i++) {
+        MEmailAttachment* att = m_attachments[i];
+        int totalSize = att->TotalSize();
+        int availableSize = att->AvailableSize();
+        if (totalSize > availableSize) {
+            TRAPD(err, att->FetchL(*this));
+            Q_UNUSED(err);
+        }
+    }
+}
+
+bool CFSEngine::retrieveHeader(QMessageServicePrivate& privateService, const QMessageId& id)
+{
+    Q_UNUSED(id);
+    Q_UNUSED(privateService);
+    return false;
+}
+
+void CFSEngine::DataFetchedL(const TInt aResult)
+{
+    if (aResult == KErrNone)
+        m_privateService->setFinished(true);
+    else
+        m_privateService->setFinished(false);      
+}
+
+bool CFSEngine::exportUpdates(const QMessageAccountId &id)
+{
+    TRAPD(err, exportUpdatesL(id));
+    if (err != KErrNone) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+void CFSEngine::exportUpdatesL(const QMessageAccountId &id)
+{
+    TMailboxId mailboxId(stripIdPrefix(id.toString()).toInt());
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+    mailbox->SynchroniseL(*this);
+    mailbox->Release();
+}
+
+void CFSEngine::MailboxSynchronisedL(TInt aResult)
+{
+    Q_UNUSED(aResult);
+}
+
+bool CFSEngine::removeMessages(const QMessageFilter& /*filter*/, QMessageManager::RemovalOption /*option*/)
+{
+    return false;
+}
+
+void CFSEngine::handleNestedFiltersFromMessageFilter(QMessageFilter &filter) const
+{
+    QMessageFilterPrivate* pMFFilter = QMessageFilterPrivate::implementation(filter);
+    if (pMFFilter->_filterList.count() > 0) {
+        int filterListCount = pMFFilter->_filterList.count();
+        for (int i=0; i < filterListCount; i++) {
+            for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
+                QMessageFilterPrivate* pMFFilter2 = QMessageFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
+                if (pMFFilter2->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
+                    QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
+                    QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
+                    if (accountIds.count() > 0) {
+                        pMFFilter->_filterList[i].removeAt(j);
+                        if (cmp == QMessageDataComparator::Includes) {
+                            for (int x = 0; x < accountIds.count(); x++) {
+                                if (x == 0) {
+                                    if (x+1 < accountIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
+                                    }
+                                    pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                    qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                                } else {
+                                    if (x+1 < accountIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
+                                    } else {
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
+                                    }
+                                }
+                            }
+                        } else { // Excludes
+                            for (int x = 0; x < accountIds.count(); x++) {
+                                pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
+                            }
+                            qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                        }
+                    } else {
+                        delete pMFFilter2->_accountFilter;
+                        pMFFilter2->_accountFilter = 0;
+                        pMFFilter2->_field = QMessageFilterPrivate::Id;
+                        qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                    }
+                } else if (pMFFilter2->_field == QMessageFilterPrivate::ParentFolderIdFilter) { 
+                    QMessageFolderIdList folderIds = queryFolders(*pMFFilter2->_folderFilter, QMessageFolderSortOrder(), 0, 0);
+                    QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
+                    if (folderIds.count() > 0) {
+                        pMFFilter->_filterList[i].removeAt(j);
+                        if (cmp == QMessageDataComparator::Includes) {
+                            for (int x = 0; x < folderIds.count(); x++) {
+                                if (x == 0) {
+                                    if (x+1 < folderIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
+                                    }
+                                    pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
+                                    qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                                } else {
+                                    if (x+1 < folderIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
+                                    } else {
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
+                                    }
+                                }
+                            }
+                        } else { // Excludes
+                            for (int x = 0; x < folderIds.count(); x++) {
+                                pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::NotEqual));
+                            }
+                            qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                        }
+                    } else {
+                        delete pMFFilter2->_folderFilter;
+                        pMFFilter2->_folderFilter = 0;
+                        pMFFilter2->_field = QMessageFilterPrivate::Id;
+                        qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
+                    }
+                } else {
+                    break;
+                }
+            }
+        }
+    } else {
+        if (pMFFilter->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
+            QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
+            QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
+            if (accountIds.count() > 0) {
+                for (int i=0; i < accountIds.count(); i++) {
+                    if (i == 0) {
+                        delete pMFFilter->_accountFilter;
+                        pMFFilter->_accountFilter = 0;
+                        pMFFilter->_field = QMessageFilterPrivate::ParentAccountId;
+                        pMFFilter->_value = accountIds[0].toString();
+                        pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
+                        if (cmp == QMessageDataComparator::Includes) {
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
+                        }
+                    } else {
+                        if (cmp == QMessageDataComparator::Includes) {
+                            filter |= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            filter &= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
+                        }
+                    }
+                }
+            } else {
+                delete pMFFilter->_accountFilter;
+                pMFFilter->_accountFilter = 0;
+                pMFFilter->_field = QMessageFilterPrivate::Id;
+            }
+        } else if (pMFFilter->_field == QMessageFilterPrivate::ParentFolderIdFilter) {
+            QMessageFolderIdList folderIds = queryFolders(*pMFFilter->_folderFilter, QMessageFolderSortOrder(), 0, 0);
+            QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
+            if (folderIds.count() > 0) {
+                for (int i=0; i < folderIds.count(); i++) {
+                    if (i == 0) {
+                        delete pMFFilter->_folderFilter;
+                        pMFFilter->_folderFilter = 0;
+                        pMFFilter->_field = QMessageFilterPrivate::ParentFolderId;
+                        pMFFilter->_value = folderIds[0].toString();
+                        pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
+                        if (cmp == QMessageDataComparator::Includes) {
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
+                        }
+                    } else {
+                        if (cmp == QMessageDataComparator::Includes) {
+                            filter |= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            filter &= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::NotEqual);
+                        }
+                    }
+                }
+            } else {
+                delete pMFFilter->_folderFilter;
+                pMFFilter->_folderFilter = 0;
+                pMFFilter->_field = QMessageFilterPrivate::Id;
+            }
+        }
+    }
+}
+
+bool CFSEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
+{
+    TRAPD(err, queryMessagesL(privateService, filter, sortOrder, limit, offset));
+    if (err != KErrNone) {
+        return false;
+    }
+    return true;
+}
+
+
+void CFSEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
+{
+    
+    FSMessageQueryInfo queryInfo;
+    queryInfo.operationId = ++m_operationIds;
+    if (queryInfo.operationId == 100000) {
+        queryInfo.operationId = 1;
+    }
+    queryInfo.isQuery = true;
+    queryInfo.filter = filter;
+    queryInfo.sortOrder = sortOrder;
+    queryInfo.offset = offset;
+    queryInfo.limit = limit;
+    queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
+    queryInfo.privateService = &privateService;
+    queryInfo.currentFilterListIndex = 0;
+    m_messageQueries.append(queryInfo);
+
+    handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
+    
+    QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
+    if (pf->_filterList.count() == 0) {
+        queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
+            m_messageQueries[m_messageQueries.count()-1].sortOrder);
+    } else {
+        queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], m_messageQueries[m_messageQueries.count()-1].sortOrder);
+    }
+}
+
+bool CFSEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
+{
+    TRAPD(err, queryMessagesL(privateService, filter, body, matchFlags, sortOrder, limit, offset));
+    if (err != KErrNone) {
+        return false;
+    }
+    return true;
+}
+
+void CFSEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
+{
+    FSMessageQueryInfo queryInfo;
+    queryInfo.operationId = ++m_operationIds;
+    if (queryInfo.operationId == 100000) {
+        queryInfo.operationId = 1;
+    }
+    queryInfo.isQuery = true;
+    queryInfo.body = body;
+    queryInfo.matchFlags = matchFlags;
+    queryInfo.filter = filter;
+    queryInfo.sortOrder = sortOrder;
+    queryInfo.offset = offset;
+    queryInfo.limit = limit;
+    queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
+    queryInfo.privateService = &privateService;
+    queryInfo.currentFilterListIndex = 0;
+    m_messageQueries.append(queryInfo);
+    
+    handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
+    
+    QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
+    if (pf->_filterList.count() == 0) {
+        queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
+                                                        m_messageQueries[m_messageQueries.count()-1].sortOrder,
+                                                        body,
+                                                        matchFlags);
+    } else {
+        queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0],
+                                                        m_messageQueries[m_messageQueries.count()-1].sortOrder,
+                                                        body,
+                                                        matchFlags);
+    }
+}
+
+bool CFSEngine::countMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter)
+{
+    TRAPD(err, countMessagesL(privateService, filter));
+    if (err != KErrNone) {
+        return false;
+    }
+    return true;
+}
+
+void CFSEngine::countMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter)
+{
+    FSMessageQueryInfo queryInfo;
+    queryInfo.operationId = ++m_operationIds;
+    if (queryInfo.operationId == 100000) {
+        queryInfo.operationId = 1;
+    }
+    queryInfo.isQuery = false;
+    queryInfo.matchFlags = 0;
+    queryInfo.filter = filter;
+    queryInfo.sortOrder = QMessageSortOrder();
+    queryInfo.offset = 0;
+    queryInfo.limit = 0;
+    queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
+    queryInfo.privateService = &privateService;
+    queryInfo.currentFilterListIndex = 0;
+    queryInfo.count = 0;
+    m_messageQueries.append(queryInfo);
+    
+    handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
+    
+    QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
+    if (pf->_filterList.count() == 0) {
+        queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
+            m_messageQueries[m_messageQueries.count()-1].sortOrder);
+    } else {
+        queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], m_messageQueries[m_messageQueries.count()-1].sortOrder);
+    }
+}
+
+void CFSEngine::filterAndOrderMessagesReady(bool success, int operationId, QMessageIdList ids, int numberOfHandledFilters,
+                                             bool resultSetOrdered)
+{
+    int index=0;
+    for (; index < m_messageQueries.count(); index++) {
+        if (m_messageQueries[index].operationId == operationId) {
+            break;
+        }
+    }
+    
+    if (success) {
+        // If there are unhandled filters, loop through all filters and do filtering for ids using unhandled filters.
+        QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[index].filter);
+        if (pf->_filterList.count() > 0) {
+            if (pf->_filterList[m_messageQueries[index].currentFilterListIndex].count() > numberOfHandledFilters) {
+                for (int i=0; i < ids.count(); i++) {
+                    QMessage msg = message(ids[i]);
+                    for (int j=numberOfHandledFilters; j < pf->_filterList[m_messageQueries[index].currentFilterListIndex].count(); j++) {
+                        QMessageFilterPrivate* pf2 = QMessageFilterPrivate::implementation(pf->_filterList[m_messageQueries[index].currentFilterListIndex][j]);
+                        if (!pf2->filter(msg)) {
+                            ids.removeAt(i);
+                            i--;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        if (pf->_filterList.count() > 0) {
+            // Filter contains filterlist (or filterlists), not just one single filter 
+            if (m_messageQueries[index].currentFilterListIndex == 0) {
+                m_messageQueries[index].ids << ids;
+                m_messageQueries[index].count = ids.count(); 
+            } else {
+                // Append new ids to resultset
+                for (int i=0; i < ids.count(); i++) {
+                    if (!m_messageQueries[index].ids.contains(ids[i])) {
+                        m_messageQueries[index].ids.append(ids[i]);
+                        m_messageQueries[index].count++;; 
+                    }
+                }
+            }
+            
+            m_messageQueries[index].currentFilterListIndex++;
+            if (m_messageQueries[index].currentFilterListIndex < pf->_filterList.count()) {
+                // There are still unhandled filter lists left
+                m_messageQueries[index].findOperation->filterAndOrderMessages(pf->_filterList[m_messageQueries[index].currentFilterListIndex],
+                                                                             m_messageQueries[index].sortOrder,
+                                                                             m_messageQueries[index].body,
+                                                                             m_messageQueries[index].matchFlags);
+                return;
+            } else {
+                // All filters successfully handled
+                if (m_messageQueries[index].isQuery) {
+                    if (!m_messageQueries[index].sortOrder.isEmpty()) {
+                        // Make sure that messages are correctly ordered
+                        orderMessages(m_messageQueries[index].ids, m_messageQueries[index].sortOrder);
+                    }
+                    applyOffsetAndLimitToMsgIds(m_messageQueries[index].ids,
+                                                m_messageQueries[index].offset,
+                                                m_messageQueries[index].limit);
+                    m_messageQueries[index].privateService->messagesFound(m_messageQueries[index].ids, true, true);
+
+                    //emit m_messageQueries[index].privateService->messagesFound(m_messageQueries[index].ids);
+                } else {
+                    m_messageQueries[index].privateService->messagesCounted(m_messageQueries[index].count);
+                }
+            }
+        } else {
+            // There was only one single filter to handle
+            if (numberOfHandledFilters == 0) {
+                // The one and only filter was not handled
+                // => Do filtering for all returned messages
+                for (int i=ids.count()-1; i >= 0; i--) {
+                    QMessage msg = message(ids[i]);
+                    if (!pf->filter(msg)) {
+                        ids.removeAt(i);
+                    }
+                }
+            }
+            // => All filters successfully handled
+            if (m_messageQueries[index].isQuery) {
+                // Make sure that messages are correctly ordered
+                if (!m_messageQueries[index].sortOrder.isEmpty() && !resultSetOrdered) {
+                    orderMessages(ids, m_messageQueries[index].sortOrder);
+                }
+                // Handle offest & limit
+                applyOffsetAndLimitToMsgIds(ids, m_messageQueries[index].offset, m_messageQueries[index].limit);
+                //emit m_messageQueries[index].privateService->messagesFound(ids);
+                m_messageQueries[index].privateService->messagesFound(ids, true, true);
+            } else {
+                m_messageQueries[index].privateService->messagesCounted(ids.count());
+            }
+        }
+    } else {
+        m_messageQueries[index].privateService->_active = false;
+        if (m_messageQueries[index].privateService->_error == QMessageManager::NoError) {
+            m_messageQueries[index].privateService->_error = QMessageManager::RequestIncomplete;
+        }
+    }
+
+    delete m_messageQueries[index].findOperation;
+    m_messageQueries.removeAt(index);
+}
+
+void CFSEngine::applyOffsetAndLimitToMsgIds(QMessageIdList& idList, int offset, int limit) const
+{
+    if (offset > 0) {
+        if (offset > idList.count()) {
+            idList.clear();
+        } else {
+            for (int i = 0; i < offset; i++) {
+                idList.removeFirst();
+            }
+        }
+    }
+    if (limit > 0) {
+        for (int i = idList.count()-1; i >= limit; i--) {
+            idList.removeAt(i);
+        }
+    }
+}
+
+QMessageManager::NotificationFilterId CFSEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore,
+                                                                           const QMessageFilter &filter, QMessageManager::NotificationFilterId aId)
+{
+    ipMessageStorePrivate = &aPrivateStore;
+    iListenForNotifications = true;    
+
+    int filterId = aId;
+    if (filterId == 0)
+        filterId = ++m_filterId;
+    m_filters.insert(filterId, filter);
+    return filterId;
+}
+
+void CFSEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId)
+{
+    m_filters.remove(notificationFilterId);
+    if (m_filters.count() == 0) {
+        iListenForNotifications = false;
+    }
+}
+void CFSEngine::handleNestedFiltersFromFolderFilter(QMessageFolderFilter &filter) const
+{
+    QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(filter);
+    if (pMFFilter->_filterList.count() > 0) {
+        int filterListCount = pMFFilter->_filterList.count();
+        for (int i=0; i < filterListCount; i++) {
+            for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
+                QMessageFolderFilterPrivate* pMFFilter2 = QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
+                if (pMFFilter2->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
+                    QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
+                    QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
+                    if (accountIds.count() > 0) {
+                        pMFFilter->_filterList[i].removeAt(j);
+                        if (cmp == QMessageDataComparator::Includes) {
+                            for (int x = 0; x < accountIds.count(); x++) {
+                                if (x == 0) {
+                                    if (x+1 < accountIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
+                                    }
+                                    pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                    qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
+                                } else {
+                                    if (x+1 < accountIds.count()) {
+                                        pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFolderFilterPrivate::lessThan);
+                                    } else {
+                                        pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
+                                        qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFolderFilterPrivate::lessThan);
+                                    }
+                                }
+                            }
+                        } else { // Excludes
+                            for (int x = 0; x < accountIds.count(); x++) {
+                                pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
+                            }
+                            qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
+                        }
+                    } else {
+                        delete pMFFilter2->_accountFilter;
+                        pMFFilter2->_accountFilter = 0;
+                        pMFFilter2->_field = QMessageFolderFilterPrivate::Id;
+                        qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
+                    }
+                } else {
+                    break;
+                }
+            }
+        }
+    } else {
+        if (pMFFilter->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
+            QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
+            QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
+            if (accountIds.count() > 0) {
+                for (int i=0; i < accountIds.count(); i++) {
+                    if (i == 0) {
+                        delete pMFFilter->_accountFilter;
+                        pMFFilter->_accountFilter = 0;
+                        pMFFilter->_field = QMessageFolderFilterPrivate::ParentAccountId;
+                        pMFFilter->_value = accountIds[0].toString();
+                        pMFFilter->_comparatorType = QMessageFolderFilterPrivate::Equality;
+                        if (cmp == QMessageDataComparator::Includes) {
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
+                        }
+                    } else {
+                        if (cmp == QMessageDataComparator::Includes) {
+                            filter |= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
+                        } else { // Excludes
+                            filter &= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
+                        }
+                    }
+                }
+            } else {
+                delete pMFFilter->_accountFilter;
+                pMFFilter->_accountFilter = 0;
+                pMFFilter->_field = QMessageFolderFilterPrivate::Id;
+            }
+        }
+    }
+}
+
+QMessageFolderIdList CFSEngine::queryFolders(const QMessageFolderFilter &filter, const QMessageFolderSortOrder &sortOrder, uint limit, uint offset) const
+{
+    QMessageFolderIdList ids;
+    
+    QMessageFolderFilter copyOfFilter = filter;
+
+    handleNestedFiltersFromFolderFilter(copyOfFilter);
+    
+    QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(copyOfFilter);
+
+    if (pMFFilter->_filterList.count() > 0) {
+        for (int i=0; i < pMFFilter->_filterList.count(); i++) {
+            bool filterHandled;
+            QMessageFolderIdList ids2 = filterMessageFolders(pMFFilter->_filterList[i][0], filterHandled);
+            for (int x=ids2.count()-1; x >= 0; x--) {
+                QMessageFolder mf = folder(ids2[x]);
+                int j = filterHandled ? 1 : 0;
+                for (; j < pMFFilter->_filterList[i].count(); j++) {
+                    if (!QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j])->filter(mf)) {
+                        ids2.removeAt(x);
+                        break;
+                    }
+                }
+            }
+            for (int j=0; j < ids2.count(); j++) {
+                if (!ids.contains(ids2[j])) {
+                   ids.append(ids2[j]);
+                }
+            }
+        }
+    } else {
+        bool filterHandled;
+        ids = filterMessageFolders(copyOfFilter, filterHandled);
+        if (!filterHandled) {
+            for (int i=ids.count()-1; i >= 0; i--) {
+                if (!QMessageFolderFilterPrivate::implementation(copyOfFilter)->filter(ids[i])) {
+                    ids.removeAt(i);
+                }
+            }
+        }
+    }
+    
+    if (!sortOrder.isEmpty()) {
+        orderFolders(ids, sortOrder);
+    }
+    
+    applyOffsetAndLimitToMsgFolderIds(ids, offset, limit);
+    
+    return ids;
+}
+
+void CFSEngine::applyOffsetAndLimitToMsgFolderIds(QMessageFolderIdList& idList, int offset, int limit) const
+{
+    if (offset > 0) {
+        if (offset > idList.count()) {
+            idList.clear();
+        } else {
+            for (int i = 0; i < offset; i++) {
+                idList.removeFirst();
+            }
+        }
+    }
+    if (limit > 0) {
+        for (int i = idList.count()-1; i >= limit; i--) {
+            idList.removeAt(i);
+        }
+    }
+}
+
+int CFSEngine::countFolders(const QMessageFolderFilter &filter) const
+{
+    return queryFolders(filter, QMessageFolderSortOrder(), 0, 0).count();
+}
+
+QMessageFolder CFSEngine::folder(const QMessageFolderId &id) const
+{
+    //return QMessageFolder();
+    
+    QMessageFolder folder;
+    TRAPD(err, folder = folderL(id));
+    Q_UNUSED(err)
+       
+    return folder;
+}
+
+QMessageFolder CFSEngine::folderL(const QMessageFolderId &id) const
+{
+    QMessageFolder folder;
+    MEmailMailbox* mailbox = NULL;
+    QMessageFolderId parentId;
+    QMessageAccountId accountId;
+
+    // get account containing folder
+    TRAPD(err, updateEmailAccountsL());
+    Q_UNUSED(err)
+    foreach (QMessageAccount value, m_accounts) {
+        accountId = value.id();
+        QMessageFolderIdList ids = folderIdsByAccountIdL(accountId);
+        if (ids.contains(id)) {
+            TMailboxId mailboxId(stripIdPrefix(accountId.toString()).toInt());
+            mailbox = m_clientApi->MailboxL(mailboxId);
+            CleanupReleasePushL(*mailbox);
+            TFolderId folderId(stripIdPrefix(id.toString()).toInt(), mailbox->MailboxId());
+            MEmailFolder* emailFolder = mailbox->FolderL(folderId);
+            CleanupReleasePushL(*emailFolder);
+            QString name = QString::fromUtf16(emailFolder->Name().Ptr(), emailFolder->Name().Length());
+            folder = QMessageFolderPrivate::from(id, accountId, parentId, name, name);
+            CleanupStack::PopAndDestroy(emailFolder);
+            CleanupStack::PopAndDestroy(mailbox);
+            break;
+        }
+    }
+    return folder;
+}
+
+QMessageFolderIdList CFSEngine::filterMessageFolders(const QMessageFolderFilter& filter, bool& filterHandled) const
+{
+    QMessageFolderIdList ids;
+    TRAPD(err, ids = filterMessageFoldersL(filter, filterHandled));
+    Q_UNUSED(err)
+    return ids;
+}
+
+QMessageFolderIdList CFSEngine::filterMessageFoldersL(const QMessageFolderFilter& filter, bool& filterHandled) const
+{
+    filterHandled = false;
+    QMessageFolderIdList ids;
+    
+    if (filter.isEmpty()) {
+        QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
+        if (!pf->_notFilter) {
+            ids = allFolders();
+        }
+        filterHandled = true;
+    } else {
+        QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
+        if (!pf->_valid) {
+            return QMessageFolderIdList();
+        }
+    
+        switch (pf->_field) {
+        case QMessageFolderFilterPrivate::Id:
+            {
+            if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (pf->_value.toString().length() > QString(SymbianHelpers::mtmPrefix).length()) {
+                    bool folderOk = false;
+                    MEmailMailbox* mailbox = NULL;
+                    MEmailFolder* folder = NULL;;
+                    if (fsFolderL(QMessageFolderId(pf->_value.toString()), mailbox, folder)) {
+                        folderOk = true;
+                        // cleanup
+                        folder->Release();
+                        mailbox->Release();
+                    }
+                    if (cmp == QMessageDataComparator::Equal) {
+                        if (folderOk) {
+                            ids.append(QMessageFolderId(pf->_value.toString()));
+                        }
+                    } else { // NotEqual
+                        ids = allFolders();
+                        if (folderOk) {
+                            ids.removeOne(QMessageFolderId(pf->_value.toString()));
+                        }
+                    }
+                } else {
+                    if (cmp == QMessageDataComparator::NotEqual) {
+                        ids = allFolders();
+                    }
+                }
+                filterHandled = true;
+            } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (pf->_ids.count() > 0) { // QMessageIdList
+                    QMessageFolderIdList ids2;
+                    for (int i=0; i < pf->_ids.count(); i++) {
+                        MEmailMailbox* mailbox = NULL;
+                        MEmailFolder* folder = NULL;
+                        if (fsFolderL(QMessageFolderId(pf->_ids[i]), mailbox, folder)) {
+                            ids2.append(pf->_ids[i]);
+                            // cleanup
+                            folder->Release();
+                            mailbox->Release();
+                        }
+                    }
+                    if (cmp == QMessageDataComparator::Includes) {
+                        ids << ids2;
+                    } else { // Excludes
+                        ids = allFolders();
+                        for (int i=0; i < ids2.count(); i++) {
+                            ids.removeOne(ids2[i]);
+                        }
+                    }
+                    filterHandled = true;
+                } else {
+                    // Empty QMessageIdList as a list
+                    if (cmp == QMessageDataComparator::Excludes) {
+                        ids = allFolders();
+                    }
+                    filterHandled = true;
+                
+                    // QMessageFilter 
+                    /*if (cmp == QMessageDataComparator::Includes) {
+                        // TODO:
+                    } else { // Excludes
+                        // TODO:
+                    }*/
+                }
+            }
+            break;
+            }
+        case QMessageFolderFilterPrivate::Name:
+            {
+            if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    // TODO:
+                } else { // NotEqual
+                    // TODO:
+                }
+            } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    // TODO:
+                } else { // Excludes
+                    if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
+                        filterHandled = true;
+                    }
+                }
+            }
+            break;
+            }
+        case QMessageFolderFilterPrivate::Path:
+            {
+            if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    // TODO:
+                } else { // NotEqual
+                    // TODO:
+                }
+            } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    // TODO:
+                } else { // Excludes
+                    if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
+                        filterHandled = true;
+                    }
+                }
+            }
+            break;
+            }
+        case QMessageFolderFilterPrivate::ParentAccountId:
+            {
+            if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    if (pf->_value.toString().length() > 0) {
+                        ids = folderIdsByAccountIdL(QMessageAccountId(pf->_value.toString()));
+                    }
+                } else { // NotEqual
+                    ids = allFolders();
+                    if (pf->_value.toString().length() > 0) {
+                        QMessageFolderIdList ids2 = folderIdsByAccountIdL(QMessageAccountId(pf->_value.toString()));
+                        for (int i = 0; i < ids2.count(); i++) {
+                            ids.removeOne(ids2[i]);
+                        }
+                    }
+                }
+                filterHandled = true;
+            } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    // TODO:
+                } else { // Excludes
+                    // TODO:
+                }
+            }
+            break;
+            }
+        case QMessageFolderFilterPrivate::ParentFolderId:
+            {
+            if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    MEmailMailbox* mailbox = NULL;
+                    MEmailFolder* parentFolder = NULL;
+                    if (fsFolderL(QMessageFolderId(pf->_value.toString()), mailbox, parentFolder)) {
+                        CleanupReleasePushL(*mailbox);
+                        CleanupReleasePushL(*parentFolder);
+
+                        RFolderArray subfolders;
+                        
+                        parentFolder->GetSubfoldersL(subfolders);
+                        CleanupClosePushL(subfolders);
+
+                        for(TInt i=0; i < subfolders.Count(); i++) {
+                            MEmailFolder *subFolder = subfolders[i];
+                            
+                            ids.append(QMessageFolderId(addIdPrefix(
+                                QString::number(subFolder->FolderId().iId), 
+                                SymbianHelpers::EngineTypeFreestyle)));
+                            
+                            subFolder->Release();
+                        }
+                        
+                        CleanupStack::PopAndDestroy(&subfolders);
+                        CleanupStack::PopAndDestroy(parentFolder);
+                        CleanupStack::PopAndDestroy(mailbox);
+                    }
+                } else { // NotEqual
+                    // TODO:
+                }
+            } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    // TODO:
+                } else { // Excludes
+                    // TODO:
+                }
+            }
+            break;
+            }
+        case QMessageFolderFilterPrivate::AncestorFolderIds:
+            {
+                if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
+                    QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                    if (!pf->_value.isNull()) { // QMessageFolderId
+                        if (cmp == QMessageDataComparator::Includes) {
+                            // TODO:
+                        } else { // Excludes
+                            // TODO:
+                        }
+                    } else { // QMessageFolderFilter
+                        if (cmp == QMessageDataComparator::Includes) {
+                            // TODO:
+                        } else { // Excludes
+                            // TODO:
+                        }
+                    }
+                }
+                break;
+            }
+        case QMessageFolderFilterPrivate::ParentAccountIdFilter:
+        case QMessageFolderFilterPrivate::None:
+            break;        
+        }
+    }
+    
+    if (!filterHandled) {
+        ids = allFolders();
+    }
+
+    return ids;
+}
+
+
+QMessageFolderIdList CFSEngine::allFolders() const
+{
+    QMessageFolderIdList ids;
+    TRAPD(err, updateEmailAccountsL());
+    Q_UNUSED(err)
+    foreach (QMessageAccount value, m_accounts) {
+        QMessageFolderIdList ids2 = folderIdsByAccountId(value.id());
+        ids << ids2;
+    }
+    return ids;
+}
+
+QMessageFolderIdList CFSEngine::folderIdsByAccountId(const QMessageAccountId& accountId) const
+{
+    QMessageFolderIdList idList;
+    TRAPD(err, idList << folderIdsByAccountIdL(accountId))
+    Q_UNUSED(err);
+    return idList;
+}
+
+QMessageFolderIdList CFSEngine::folderIdsByAccountIdL(const QMessageAccountId& accountId) const
+{
+    QMessageFolderIdList folderIds;
+    
+    if (idType(accountId) != EngineTypeFreestyle)
+        return QMessageFolderIdList();
+    
+    QMessageAccount messageAccount = account(accountId);
+    
+    TMailboxId mailboxId(stripIdPrefix(accountId.toString()).toInt());
+    MEmailMailbox* mailbox = NULL;
+    mailbox = m_clientApi->MailboxL(mailboxId);
+
+    if (mailbox == NULL)
+        return QMessageFolderIdList();
+
+    CleanupReleasePushL(*mailbox);
+
+    RFolderArray folders;
+    
+    mailbox->GetFoldersL(folders);
+    CleanupClosePushL(folders);
+
+    for(TInt i=0; i < folders.Count(); i++) {
+        MEmailFolder *mailFolder = folders[i];
+        
+        QString fsIdAsString = addIdPrefix(QString::number(mailFolder->FolderId().iId), SymbianHelpers::EngineTypeFreestyle);
+        folderIds.append(QMessageFolderId(fsIdAsString));
+
+        //TODO: Support for subfolders?
+        mailFolder->Release();
+    }
+    
+    CleanupStack::PopAndDestroy(&folders);
+    CleanupStack::PopAndDestroy(mailbox);
+    
+    return folderIds;
+}
+
+bool CFSEngine::fsFolderL(const QMessageFolderId& id, MEmailMailbox* mailbox, MEmailFolder* folder) const
+{
+    Q_UNUSED(folder);
+    MEmailFolder* fsFolder = NULL;
+    foreach (QMessageAccount account, m_accounts) {
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        mailbox = m_clientApi->MailboxL(mailboxId);
+        
+        TFolderId folderId(
+            stripIdPrefix(id.toString()).toInt(),
+            mailboxId);
+            
+        TRAPD(err, folder = mailbox->FolderL(folderId));
+        if (err == KErrNone) {               
+            CleanupReleasePushL(*fsFolder);
+            return true;
+        }
+        mailbox->Release();
+    }
+    mailbox = NULL;
+    folder = NULL;
+    return false;
+}
+
+
+QMessage CFSEngine::message(const QMessageId& id) const
+{
+    QMessage message = QMessage();
+    TRAPD(err, message = messageL(id));
+    Q_UNUSED(err);
+    return message;
+}
+
+QMessage CFSEngine::messageL(const QMessageId& id) const
+{
+    QMessage message = QMessage();
+    foreach (QMessageAccount account, m_accounts) {
+        TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
+        MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+        CleanupReleasePushL(*mailbox);
+        
+        TMessageId messageId(
+            stripIdPrefix(id.toString()).toInt(),
+            0, //stripIdPrefix(folderId.toString()).toInt(), 
+            mailboxId);
+            
+        MEmailMessage* fsMessage = NULL;
+        
+        TRAPD(err, fsMessage = mailbox->MessageL(messageId));
+        if (err == KErrNone) {
+            CleanupReleasePushL(*fsMessage);
+            message = CreateQMessageL(fsMessage);
+            
+            QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+            privateMessage->_id = id; 
+            privateMessage->_modified = false;
+                
+            CleanupStack::PopAndDestroy(fsMessage);
+            CleanupStack::PopAndDestroy(mailbox);
+            return message;
+        }
+        CleanupStack::PopAndDestroy(mailbox);
+    }
+    return message;
+}
+
+bool CFSEngine::sendEmail(QMessage &message)
+{
+    TMailboxId mailboxId(stripIdPrefix(message.parentAccountId().toString()).toInt());
+    MEmailMailbox* mailbox = NULL;
+    TRAPD(mailerr, mailbox = m_clientApi->MailboxL(mailboxId));
+    Q_UNUSED(mailerr);
+    
+    MEmailMessage* fsMessage = NULL;
+    TRAPD(err,
+        fsMessage = createFSMessageL(message, mailbox);
+        fsMessage->SaveChangesL();
+        fsMessage->SendL(); 
+    );
+
+    if (fsMessage)
+        fsMessage->Release();
+    if (mailbox)
+        mailbox->Release();
+
+    if (err != KErrNone)
+        return false;
+    else
+        return true;
+}
+
+QMessage CFSEngine::CreateQMessageL(MEmailMessage* aMessage) const
+{
+    QMessage message;
+    int size = 0;
+    message.setType(QMessage::Email);
+
+    message.setDate(symbianTTimetoQDateTime(aMessage->Date()));
+    message.setReceivedDate(symbianTTimetoQDateTime(aMessage->Date()));
+    
+    const TFolderId& folderId = aMessage->ParentFolderId();
+    TMailboxId mailboxId = folderId.iMailboxId;
+    const QMessageAccountId accountId = QMessageAccountId(QString::number(mailboxId.iId));
+    message.setParentAccountId(accountId);
+    QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+    privateMessage->_parentFolderId = QMessageFolderId(QString::number(folderId.iId));
+    
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+    MEmailFolder* folder = mailbox->FolderL(folderId);
+    QMessagePrivate::setStandardFolder(message, QMessage::InboxFolder);
+    if (folder->FolderType() == EDrafts) {
+        QMessagePrivate::setStandardFolder(message, QMessage::DraftsFolder);
+    } else if (folder->FolderType() == EDeleted) {
+        QMessagePrivate::setStandardFolder(message, QMessage::TrashFolder);
+    } else if (folder->FolderType() == ESent) {
+        QMessagePrivate::setStandardFolder(message, QMessage::SentFolder);
+    }
+    folder->Release();
+    mailbox->Release();
+
+    if (aMessage->Flags() & EFlag_Read) {
+        privateMessage->_status = privateMessage->_status | QMessage::Read; 
+    }
+
+    if (aMessage->Flags() & EFlag_Important) {
+        message.setPriority(QMessage::HighPriority); 
+    } else if (aMessage->Flags() & EFlag_Low) {
+        message.setPriority(QMessage::LowPriority);
+    } else {
+        message.setPriority(QMessage::NormalPriority);
+    }
+
+    // bodytext and attachment(s)
+    MEmailMessageContent* content = aMessage->ContentL();
+    if (content) {
+       AddContentToMessage(content, &message);
+    }
+   
+    REmailAttachmentArray attachments;                  
+    CleanupResetAndRelease<MEmailAttachment>::PushL(attachments);
+    TInt count = aMessage->GetAttachmentsL(attachments);
+    if (count > 0)
+        privateMessage->_status = privateMessage->_status | QMessage::HasAttachments;  
+    
+    for(TInt i = 0; i < count; i++) {
+        TInt availableSize = attachments[i]->AvailableSize();       
+        QByteArray name = QString::fromUtf16(attachments[i]->FileNameL().Ptr(), attachments[i]->FileNameL().Length()).toLocal8Bit();
+        QByteArray mimeType; // TODO: email client api doesn't offer information about attachment mimetype
+        QByteArray mimeSubType; // TODO;
+        int size = attachments[i]->TotalSize();
+        QMessageContentContainer attachment = QMessageContentContainerPrivate::from(
+                                                aMessage->MessageId().iId, 
+                                                attachments[i]->Id().iId, 
+                                                name, mimeType, 
+                                                mimeSubType, size);
+        addAttachmentToMessage(message, attachment);       
+    }
+    CleanupStack::PopAndDestroy();
+    attachments.Close();
+    
+    //from
+    TPtrC from = aMessage->SenderAddressL()->Address();
+    if (from.Length() > 0) {
+        message.setFrom(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(from.Ptr(), from.Length())));
+        QMessagePrivate::setSenderName(message, QString::fromUtf16(from.Ptr(), from.Length()));
+    }
+    
+    //to
+    REmailAddressArray toRecipients;
+    CleanupResetAndRelease<MEmailAddress>::PushL(toRecipients);
+
+    aMessage->GetRecipientsL(MEmailAddress::ETo, toRecipients);
+    QList<QMessageAddress> toList;
+    for(TInt i = 0; i < toRecipients.Count(); i++) {
+        TPtrC to = toRecipients[i]->Address();
+        toList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(to.Ptr(), to.Length())));
+    }
+    message.setTo(toList);
+    CleanupStack::PopAndDestroy(&toRecipients);
+    toRecipients.Close();
+    
+    //cc
+    REmailAddressArray ccRecipients;
+    CleanupResetAndRelease<MEmailAddress>::PushL(ccRecipients);
+    aMessage->GetRecipientsL(MEmailAddress::ECc, ccRecipients);
+    QList<QMessageAddress> ccList;
+    for(TInt i = 0; i < ccRecipients.Count(); i++) {
+        TPtrC cc = ccRecipients[i]->Address();
+        ccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(cc.Ptr(), cc.Length())));
+    }
+    message.setCc(ccList); 
+    CleanupStack::PopAndDestroy(&ccRecipients);
+    ccRecipients.Close();
+    
+    //bcc
+    REmailAddressArray bccRecipients;
+    CleanupResetAndRelease<MEmailAddress>::PushL(bccRecipients);
+    aMessage->GetRecipientsL(MEmailAddress::EBcc, bccRecipients);
+    QList<QMessageAddress> bccList;
+    for(TInt i = 0; i < bccRecipients.Count(); i++) {
+        TPtrC bcc = bccRecipients[i]->Address();
+        bccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(bcc.Ptr(), bcc.Length())));
+    }
+    message.setBcc(bccList);
+    CleanupStack::PopAndDestroy(&bccRecipients);
+    bccRecipients.Close();
+    
+    // Read message subject   
+    TPtrC subject = aMessage->Subject();
+    if (subject.Length() > 0) {
+        message.setSubject(QString::fromUtf16(subject.Ptr(), subject.Length()));
+    }
+    // TODO: size
+    privateMessage->_size = size;
+
+    return message;    
+}
+
+void CFSEngine::AddContentToMessage(MEmailMessageContent* aContent, QMessage* aMessage) const
+{
+    MEmailMultipart* mPart = aContent->AsMultipartOrNull();
+    if (mPart) {
+    TInt partCount = 0;
+    TRAPD(err, partCount = mPart->PartCountL());
+        if (err == KErrNone) {
+            for (TInt i = 0; i < partCount-1; i++) {
+                MEmailMessageContent* content = NULL;
+                TRAPD(err2, content = mPart->PartByIndexL(i));
+                if (err2 == KErrNone) {
+                    AddContentToMessage(content, aMessage);
+                    content->Release();
+                }
+            }
+        }
+        return;
+    }
+ 
+    MEmailTextContent* textContent = aContent->AsTextContentOrNull();
+    if (textContent) { 
+        TInt availableSize = textContent->AvailableSize();
+        TRAPD(err, 
+            TPtrC body = textContent->ContentL(); 
+            QString text = QString::fromUtf16(body.Ptr(), body.Length());
+            if (textContent->TextType() == MEmailTextContent::EPlainText) {
+                aMessage->setBody(text, "text/plain");
+            }
+            else if (textContent->TextType() == MEmailTextContent::EHtmlText) {
+                aMessage->setBody(text, "text/html");
+            }
+            );
+        Q_UNUSED(err);
+        return;
+    }
+}
+
+void CFSEngine::addAttachmentToMessage(QMessage& message, QMessageContentContainer& attachment) const
+{
+    QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+    QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message);
+    
+    if (container->_attachments.isEmpty()) {
+        QMessageContentContainerId existingBodyId(message.bodyId());
+        if (existingBodyId == QMessageContentContainerPrivate::bodyContentId()) {
+            // The body content is in the message itself - move it to become the first attachment
+            QMessageContentContainer newBody(message);
+            QMessageContentContainerPrivate::implementation(newBody)->setDerivedMessage(0);
+    
+            container->setContentType("multipart", "mixed", "");
+            privateMessage->_bodyId = container->prependContent(newBody);
+        } else {
+            // This message is now multipart
+            container->setContentType("multipart", "mixed", "");
+        }
+    
+        container->_available = true;
+    }
+    
+    container->appendContent(attachment);
+    
+    bool haveAttachments = !container->_attachments.isEmpty();
+    message.setStatus(QMessage::HasAttachments,haveAttachments);
+    
+    privateMessage->_modified = true;
+}
+
+QDateTime CFSEngine::symbianTTimetoQDateTime(const TTime& time) const
+{
+    TDateTime dateTime = time.DateTime();
+    QDate qdate = QDate(dateTime.Year(), static_cast<int>(dateTime.Month())+1, dateTime.Day()+1);
+    QTime qtime = QTime(dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond()/1000 );
+    return QDateTime(qdate, qtime, Qt::UTC);
+}
+
+TTime CFSEngine::qDateTimeToSymbianTTime(const QDateTime& date) const
+{
+    TDateTime dateTime;
+    dateTime.SetYear(date.date().year());
+    dateTime.SetMonth(static_cast<TMonth>(date.date().month()-1));
+    dateTime.SetDay(date.date().day()-1);
+    dateTime.SetHour(date.time().hour());
+    dateTime.SetMinute(date.time().minute());
+    dateTime.SetSecond(date.time().second());
+    dateTime.SetMicroSecond(date.time().msec()*1000);
+    return TTime(dateTime);
+}
+
+TFolderType CFSEngine::standardFolderId(QMessage::StandardFolder standardFolder)
+{
+    switch(standardFolder) {
+        case QMessage::InboxFolder: return EInbox;
+        case QMessage::OutboxFolder: return EOutbox;
+        case QMessage::DraftsFolder: return EDrafts;
+        case QMessage::SentFolder: return ESent;
+        case QMessage::TrashFolder: return EDeleted;
+        default: return EOther;
+    }
+}
+
+CFSMessagesFindOperation::CFSMessagesFindOperation(CFSEngine& aOwner, int aOperationId)
+    : m_owner(aOwner), 
+      m_operationId(aOperationId),
+      m_resultCorrectlyOrdered(false),
+      m_receiveNewMessages(false),
+      m_activeSearchCount(0),
+      m_searchField(None)
+{
+    TRAPD(err,
+            m_factory = CEmailInterfaceFactory::NewL(); 
+            m_interfacePtr = m_factory->InterfaceL(KEmailClientApiInterface); 
+            m_clientApi = static_cast<MEmailClientApi*>(m_interfacePtr); 
+        );
+    Q_UNUSED(err);
+}
+
+CFSMessagesFindOperation::~CFSMessagesFindOperation()
+{
+    foreach(FSSearchOperation operation, m_searchOperations) {
+        operation.m_search->Release();
+        operation.m_mailbox->Release();
+    }
+    
+    m_receiveNewMessages = false;
+    m_clientApi->Release();
+    delete m_factory;
+
+}
+
+void CFSMessagesFindOperation::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder,
+                                                    QString body, QMessageDataComparator::MatchFlags matchFlags)
+{
+    m_filterList.clear();
+    m_filterList.append(filter);
+    filterAndOrderMessages(m_filterList, sortOrder, body, matchFlags);
+}
+
+void CFSMessagesFindOperation::filterAndOrderMessages(const QMessageFilterPrivate::SortedMessageFilterList& filters,
+                                                    const QMessageSortOrder& sortOrder,
+                                                    QString body,
+                                                    QMessageDataComparator::MatchFlags matchFlags)
+{
+    TRAPD(err, filterAndOrderMessagesL(filters, sortOrder, body, matchFlags));
+    if (err != KErrNone) {
+        //something has failed -> return empty list
+        m_idList = QMessageIdList();
+        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+    }
+}
+
+void CFSMessagesFindOperation::filterAndOrderMessagesL(const QMessageFilterPrivate::SortedMessageFilterList& filters,
+                                                    const QMessageSortOrder& sortOrder,
+                                                    QString body,
+                                                    QMessageDataComparator::MatchFlags matchFlags)
+{
+    m_numberOfHandledFilters = 0;
+    
+    TEmailSortCriteria sortCriteria = TEmailSortCriteria();
+    m_excludeIdList = QMessageIdList();
+
+    m_matchFlags = matchFlags;
+    
+    if (filters.count() == 0) {
+        m_idList = QMessageIdList();
+        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+        return;
+    }
+    
+    QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
+
+    // Set sortOrder
+    if (!sortOrder.isEmpty() ) {
+        QMessageSortOrderPrivate* privateMessageOrdering = QMessageSortOrderPrivate::implementation(sortOrder);
+        QPair<QMessageSortOrderPrivate::Field, Qt::SortOrder> fieldOrder = privateMessageOrdering->_fieldOrderList.at(0);
+        switch (fieldOrder.first) {
+            case QMessageSortOrderPrivate::Type:
+                break;
+            case QMessageSortOrderPrivate::Sender:
+                sortCriteria.iField = TEmailSortCriteria::EBySender;
+                break;
+            case QMessageSortOrderPrivate::Recipients:
+                sortCriteria.iField = TEmailSortCriteria::EByRecipient;
+                break;
+            case QMessageSortOrderPrivate::Subject:
+                sortCriteria.iField = TEmailSortCriteria::EBySubject;
+                break;
+            case QMessageSortOrderPrivate::TimeStamp:
+                sortCriteria.iField = TEmailSortCriteria::EByDate;
+                break;
+            case QMessageSortOrderPrivate::ReceptionTimeStamp:
+                sortCriteria.iField = TEmailSortCriteria::EBySender;
+                break;
+            case QMessageSortOrderPrivate::Read:
+                sortCriteria.iField = TEmailSortCriteria::EByUnread;
+                break;
+            case QMessageSortOrderPrivate::HasAttachments:
+                sortCriteria.iField = TEmailSortCriteria::EByAttachment;
+                break;
+            case QMessageSortOrderPrivate::Incoming:
+                //TODO:
+                break;
+            case QMessageSortOrderPrivate::Removed:
+                //TODO:
+                break;
+            case QMessageSortOrderPrivate::Priority:
+                sortCriteria.iField = TEmailSortCriteria::EByPriority;
+                break;
+            case QMessageSortOrderPrivate::Size:
+                sortCriteria.iField = TEmailSortCriteria::EBySize;
+                break;
+        }
+        sortCriteria.iAscending = fieldOrder.second == Qt::AscendingOrder?true:false;
+    } else {
+        // This is a workaroud for getFolderSpecificMessagesL crashing when default TEmailSortCriteria (EDontCare) is set
+        sortCriteria.iField = TEmailSortCriteria::EByDate;
+    }
+
+    if ((filters.count() == 1) &&
+        (pf->_field == QMessageFilterPrivate::None) &&
+        (pf->_filterList.count() == 0)) {
+        if (pf->_notFilter) {
+            // There is only one filter: empty ~QMessageFilter()
+            // => return empty QMessageIdList 
+            m_idList = QMessageIdList();
+            QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+        } else {
+            // There is only one filter: empty QMessageFilter()
+            // => return all messages
+            getAllMessagesL(sortCriteria);
+        }
+        m_numberOfHandledFilters++;
+        return;
+    }
+
+    if (!body.isEmpty()) {
+        m_searchField = Body;
+        m_searchKey = body;
+    }
+    
+    switch (pf->_field) {
+    
+        case QMessageFilterPrivate::ParentFolderId: {
+            if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
+                QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+                return;
+            }
+            if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageFolderId
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    m_numberOfHandledFilters++;
+                    QMessageFolder messageFolder = m_owner.folder(QMessageFolderId(pf->_value.toString()));
+                    getFolderSpecificMessagesL(messageFolder, sortCriteria);
+                    m_resultCorrectlyOrdered = true;
+                    QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+                } else { // NotEqual
+                    // TODO:
+                }
+            } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessageFolderFilter
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    // TODO:
+                } else { // Excludes
+                    // TODO:
+                }
+            }
+            break;
+        }
+        case QMessageFilterPrivate::Id: {
+            if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
+                QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+                return;
+            }
+            m_numberOfHandledFilters++;
+            if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageId
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (!pf->_value.isNull() && pf->_value.toString().length() > QString(SymbianHelpers::freestylePrefix).length()) {
+                    if (cmp == QMessageDataComparator::Equal) {
+                        QMessage message = m_owner.message(QMessageId(pf->_value.toString()));
+                        m_idList.clear();
+                        m_idList.append(message.id());
+                        m_resultCorrectlyOrdered = true;
+                        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+
+                    } else { // NotEqual
+                        m_excludeIdList.clear();
+                        m_excludeIdList.append(QMessageId(pf->_value.toString()));
+                        getAllMessagesL(sortCriteria);
+                    }
+                } else {
+                    if (cmp == QMessageDataComparator::NotEqual) {
+                        getAllMessagesL(sortCriteria);
+                    }
+                }
+            } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (pf->_ids.count() > 0) { // QMessageIdList
+                    if (cmp == QMessageDataComparator::Includes) {
+                        for (int i=0; i < pf->_ids.count(); i++) {
+                            QMessage message = m_owner.message(QMessageId(pf->_ids[i].toString()));
+                            m_idList.append(message.id());
+                        }
+                        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+                    } else { // Excludes
+                        for (int i=0; i < pf->_ids.count(); i++) {
+                            m_excludeIdList.clear();
+                            m_excludeIdList.append(QMessageId(pf->_ids[i].toString()));
+                            getAllMessagesL(sortCriteria);
+                        }
+                        getAllMessagesL(sortCriteria);
+                    }
+                } else {
+                    //ipEntrySelection = new(ELeave)CMsvEntrySelection;
+                    if (cmp == QMessageDataComparator::Excludes) {
+                        getAllMessagesL(sortCriteria);
+                    }
+                    /*// QMessageFilter
+                    if (cmp == QMessageDataComparator::Includes) {
+                        // TODO:
+                    } else { // Excludes
+                        // TODO:
+                    }*/
+                }
+            }
+            break;
+            }
+        case QMessageFilterPrivate::ParentAccountId: {
+            if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
+                QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+                return;
+            }
+            if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageAccountId
+                m_numberOfHandledFilters++;
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    QMessageAccount messageAccount = m_owner.account(pf->_value.toString());
+                    getAccountSpecificMessagesL(messageAccount, sortCriteria);
+                    m_resultCorrectlyOrdered = true;
+                } else { // NotEqual
+                    QStringList exludedAccounts;
+                    exludedAccounts << pf->_value.toString();
+                    
+                    QMessageFilterPrivate* privateFilter = NULL;
+                    for (int i=m_numberOfHandledFilters; i < filters.count(); i++) {
+                        privateFilter = QMessageFilterPrivate::implementation(filters[i]);
+                        if (privateFilter->_field == QMessageFilterPrivate::ParentAccountId &&
+                            privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
+                            cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
+                            if (cmp == QMessageDataComparator::NotEqual) {
+                                exludedAccounts << privateFilter->_value.toString();
+                                m_numberOfHandledFilters++;
+                            } else {
+                                break;
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+
+                    privateFilter = NULL;
+                    if (filters.count() > m_numberOfHandledFilters) {
+                        privateFilter = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
+                        if (privateFilter->_field == QMessageFilterPrivate::StandardFolder &&
+                            privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
+                            cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
+                            if (cmp == QMessageDataComparator::Equal) {
+                                m_numberOfHandledFilters++;
+                            }
+                        } else {
+                            privateFilter = NULL;
+                        }
+                    }
+                    
+                    foreach (QMessageAccount value, m_owner.m_accounts) {
+                        if (!exludedAccounts.contains(value.id().toString())) {
+                            getAccountSpecificMessagesL(value, sortCriteria);
+                        }
+                    }
+                }
+            }
+            break;
+        }
+            
+        case QMessageFilterPrivate::AncestorFolderIds: {
+            m_numberOfHandledFilters++;
+            if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (!pf->_value.isNull()) { // QMessageFolderId
+                    if (cmp == QMessageDataComparator::Includes) {
+                        // TODO:
+                    } else { // Excludes
+                        // TODO:
+                    }
+                } else { // QMessageFolderFilter
+                    if (cmp == QMessageDataComparator::Includes) {
+                        // TODO:
+                    } else { // Excludes
+                        // TODO:
+                    }
+                }
+            }
+            break;
+            }
+        case QMessageFilterPrivate::Type: {
+            m_numberOfHandledFilters++;
+            QMessageFilterPrivate* privateFilter = NULL;
+            // Check if next filter is StandardFolder filter 
+            if (filters.count() > m_numberOfHandledFilters) {
+                privateFilter = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
+                if (privateFilter->_field != QMessageFilterPrivate::StandardFolder) {
+                    privateFilter = NULL;
+                } else {
+                    m_numberOfHandledFilters++;
+                }
+            }
+            if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessage::Type
+                QMessage::Type type = static_cast<QMessage::Type>(pf->_value.toInt()); 
+                QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Equal) {
+                    QMessageAccountIdList accountIds = m_owner.accountsByType(type);
+                    for (int i = 0; i < accountIds.count(); i++) {
+                        QMessageAccount messageAccount = m_owner.account(accountIds[i]);
+                        getAccountSpecificMessagesL(messageAccount, sortCriteria);
+                    }
+                } else { // NotEqual
+                    foreach (QMessageAccount value, m_owner.m_accounts) {
+                        if (!(value.messageTypes() & type)) {
+                            getAccountSpecificMessagesL(value, sortCriteria);
+                        }
+                    }
+                }
+            } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessage::TypeFlags
+                QMessage::TypeFlags typeFlags = static_cast<QMessage::TypeFlags>(pf->_value.toInt());
+                QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                if (cmp == QMessageDataComparator::Includes) {
+                    foreach (QMessageAccount value, m_owner.m_accounts) {
+                        if (value.messageTypes() | typeFlags) {
+                            getAccountSpecificMessagesL(value, sortCriteria);
+                        }
+                    }
+
+                } else { // Excludes
+                    foreach (QMessageAccount value, m_owner.m_accounts) {
+                        if (!(value.messageTypes() & typeFlags)) {
+                            getAccountSpecificMessagesL(value, sortCriteria);
+                        }
+                    }
+                }
+            }
+            break;
+            }
+        case QMessageFilterPrivate::StandardFolder: {
+            m_numberOfHandledFilters++;
+            QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+            QMessage::StandardFolder standardFolder = static_cast<QMessage::StandardFolder>(pf->_value.toInt());
+            TFolderType stdFolder = m_owner.standardFolderId(standardFolder);
+
+            if (cmp == QMessageDataComparator::Equal) {
+                foreach (QMessageAccount messageAccount, m_owner.m_accounts) {
+                    TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
+                    MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+                    CleanupReleasePushL(*mailbox);
+                    MEmailFolder* folder = mailbox->FolderByTypeL(stdFolder);
+                    CleanupReleasePushL(*folder);
+                    QMessageFolder standardFolder = m_owner.folder(
+                        QMessageFolderId(QString::number(folder->FolderId().iId)));
+                    getFolderSpecificMessagesL(standardFolder, sortCriteria);
+                    m_activeSearchCount++;
+                    CleanupStack::PopAndDestroy(folder);
+                    CleanupStack::PopAndDestroy(mailbox);
+                }
+                m_resultCorrectlyOrdered = true;
+                QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+            } else { // NotEqual
+                foreach (QMessageAccount messageAccount, m_owner.m_accounts) {
+                    TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
+                    MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
+                    CleanupReleasePushL(*mailbox);
+                    QMessage::StandardFolder i = QMessage::InboxFolder;
+                    while (i <= QMessage::TrashFolder) {
+                        if (i != standardFolder) {
+                            MEmailFolder* folder = mailbox->FolderByTypeL(m_owner.standardFolderId(i));
+                            CleanupReleasePushL(*folder);
+                            QMessageFolder standardFolder = m_owner.folder(
+                                QMessageFolderId(QString::number(folder->FolderId().iId)));
+                            getFolderSpecificMessagesL(standardFolder, sortCriteria);
+                            CleanupStack::PopAndDestroy(folder);
+                        }
+                        i = static_cast<QMessage::StandardFolder>(static_cast<int>(i) + 1);
+                    }
+                    CleanupStack::PopAndDestroy(mailbox);    
+                }
+                QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+            }
+            break;
+            }
+
+        case QMessageFilterPrivate::Sender: 
+        case QMessageFilterPrivate::Recipients: 
+        case QMessageFilterPrivate::Subject: 
+        case QMessageFilterPrivate::Status:
+        case QMessageFilterPrivate::Priority:
+        case QMessageFilterPrivate::Size:
+        case QMessageFilterPrivate::ParentAccountIdFilter:
+        case QMessageFilterPrivate::ParentFolderIdFilter: 
+        case QMessageFilterPrivate::TimeStamp:
+        case QMessageFilterPrivate::ReceptionTimeStamp:
+        case QMessageFilterPrivate::None:
+        default:
+            break;
+    
+    }
+
+    if (body.isEmpty()) {
+        if (m_numberOfHandledFilters < filters.count()) {
+            pf = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
+            switch (pf->_field) {
+                case QMessageFilterPrivate::Sender: {
+                    m_searchField = Sender;
+                    if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
+                        QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                        if (cmp == QMessageDataComparator::Equal) {
+                            if (pf->_value.toString().length() > 0) {
+                                m_searchKey = pf->_value.toString();
+                                m_numberOfHandledFilters++;
+                            }
+                        } else { // NotEqual
+                            // TODO:
+                        }
+                    } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
+                        QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                        if (cmp == QMessageDataComparator::Includes) {
+                            // TODO:
+                        } else { // Excludes
+                            // TODO:
+                        }
+                    }
+                    break;
+                }
+    
+                case QMessageFilterPrivate::Recipients: {
+                    m_searchField = Recipients;
+                    if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
+                        QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                        if (cmp == QMessageDataComparator::Includes) {
+                            if (pf->_value.toString().length() > 0) {
+                                m_searchKey = pf->_value.toString();
+                                m_numberOfHandledFilters++;
+                            }
+                        } else { // Excludes
+                            //TODO:
+                        }
+                    }
+                    break;
+                }
+    
+                case QMessageFilterPrivate::Subject: {
+                    m_searchField = Subject;
+                    if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
+                        QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+                        if (cmp == QMessageDataComparator::Equal) {
+                            if (pf->_value.toString().length() > 0) {
+                                m_searchKey = pf->_value.toString();
+                                m_numberOfHandledFilters++;
+                            }
+                        } else { // NotEqual
+                            // TODO:
+                        }
+                    } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
+                        QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
+                        if (cmp == QMessageDataComparator::Includes) {
+                            // TODO:
+                        } else { // Excludes
+                            // TODO:
+                        }
+                    }
+                    break;
+                }
+                case QMessageFilterPrivate::TimeStamp:
+                case QMessageFilterPrivate::ReceptionTimeStamp:
+                case QMessageFilterPrivate::Status:
+                case QMessageFilterPrivate::Priority:
+                case QMessageFilterPrivate::Size:
+                case QMessageFilterPrivate::ParentAccountIdFilter:
+                case QMessageFilterPrivate::ParentFolderIdFilter: 
+                case QMessageFilterPrivate::Id:
+                case QMessageFilterPrivate::ParentFolderId:
+                case QMessageFilterPrivate::AncestorFolderIds:
+                case QMessageFilterPrivate::ParentAccountId:
+                case QMessageFilterPrivate::Type:
+                case QMessageFilterPrivate::StandardFolder:
+                case QMessageFilterPrivate::None:
+                default:
+                    break;
+            }
+            if (m_activeSearchCount == 0)
+                getAllMessagesL(sortCriteria);
+        }
+    }
+    if (m_activeSearchCount == 0)
+        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+}
+
+void CFSMessagesFindOperation::getAllMessagesL(TEmailSortCriteria& sortCriteria)
+{
+    // Get all messages from every known account
+    foreach (QMessageAccount value, m_owner.m_accounts) {
+        getAccountSpecificMessagesL(value, sortCriteria);
+    }
+    if (m_activeSearchCount == 0)
+        QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+}
+
+void CFSMessagesFindOperation::getAccountSpecificMessagesL(QMessageAccount& messageAccount, TEmailSortCriteria& sortCriteria)
+{
+    TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
+    FSSearchOperation operation;
+    operation.m_mailbox = m_clientApi->MailboxL(mailboxId);
+    operation.m_search = operation.m_mailbox->MessageSearchL();
+    operation.m_search->AddSearchKeyL(_L("*"));
+    operation.m_search->SetSortCriteriaL( sortCriteria );
+    operation.m_search->StartSearchL( *this ); // this implements MEmailSearchObserver
+    m_activeSearchCount++;
+    m_searchOperations.append(operation);
+}
+
+
+void CFSMessagesFindOperation::getFolderSpecificMessagesL(QMessageFolder& messageFolder, TEmailSortCriteria sortCriteria)
+{
+    m_activeSearchCount++;
+    RSortCriteriaArray sortCriteriaArray;
+    CleanupClosePushL(sortCriteriaArray);
+    TFolderId folderId(stripIdPrefix(messageFolder.id().toString()).toInt(), 
+        stripIdPrefix(messageFolder.parentAccountId().toString()).toInt());
+    MEmailMailbox* mailbox = m_clientApi->MailboxL(stripIdPrefix(messageFolder.parentAccountId().toString()).toInt());
+    CleanupReleasePushL(*mailbox);
+    MEmailFolder *mailFolder = mailbox->FolderL(folderId);
+    CleanupReleasePushL(*mailFolder);
+        
+    sortCriteriaArray.Append(sortCriteria);
+    
+    MMessageIterator* msgIterator = mailFolder->MessagesL(sortCriteriaArray);
+    CleanupReleasePushL(*msgIterator);
+        
+    MEmailMessage* msg = NULL;
+    while ( NULL != (msg = msgIterator->NextL())) {
+        QMessageId messageId(addIdPrefix(QString::number(msg->MessageId().iId), SymbianHelpers::EngineTypeFreestyle));
+        if (!m_excludeIdList.contains(messageId)) {
+            m_idList.append(messageId);   
+        }
+        msg->Release();
+    }
+
+    CleanupStack::PopAndDestroy(msgIterator);
+    CleanupStack::PopAndDestroy(mailFolder);
+    CleanupStack::PopAndDestroy(mailbox);
+    CleanupStack::PopAndDestroy(&sortCriteriaArray);
+}
+
+void CFSMessagesFindOperation::HandleResultL(MEmailMessage* aMessage)
+{
+    QMessageId messageId(addIdPrefix(QString::number(aMessage->MessageId().iId), SymbianHelpers::EngineTypeFreestyle));
+    if (!m_excludeIdList.contains(messageId)) {
+        m_idList.append(messageId);   
+    }
+    aMessage->Release();
+}
+
+void CFSMessagesFindOperation::SearchCompletedL()
+{
+    if (m_receiveNewMessages) {
+        m_receiveNewMessages = false;
+    } else {
+        m_activeSearchCount--;
+        if (m_activeSearchCount <= 0) {
+            QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
+        }
+    }
+}
+    
+void CFSMessagesFindOperation::SearchCompleted()
+{
+    if (m_searchField != None) { 
+        QMessageIdList idList;
+        foreach (QMessageId messageId, m_idList) {
+            if (fillsSearchKeyCriteria(messageId))
+                idList.append(messageId);   
+        }
+        m_idList = idList;
+    }
+    m_owner.filterAndOrderMessagesReady(true, m_operationId, m_idList, 1, m_resultCorrectlyOrdered);
+}
+
+bool CFSMessagesFindOperation::fillsSearchKeyCriteria(QMessageId& messageId)
+{
+    QMessage message = m_owner.message(messageId);
+    
+    Qt::CaseSensitivity caseSensitivity = (m_matchFlags & QMessageDataComparator::MatchCaseSensitive) ?
+        Qt::CaseSensitive:Qt::CaseInsensitive;
+    
+    switch (m_searchField) {
+    case Sender: {
+        return message.from().addressee().contains(m_searchKey, caseSensitivity);
+    }
+    case Recipients: {
+        foreach (QMessageAddress toRecipient, message.to()) {
+            if (toRecipient.addressee().contains(m_searchKey, caseSensitivity))
+                return true;
+        }
+        foreach (QMessageAddress ccRecipient, message.cc()) {
+            if (ccRecipient.addressee().contains(m_searchKey, caseSensitivity))
+                return true;
+        }
+        foreach (QMessageAddress bccRecipient, message.bcc()) {
+            if (bccRecipient.addressee().contains(m_searchKey, caseSensitivity))
+                return true;
+        }
+        return false;
+    }
+    case Subject: {
+        return message.subject().contains(m_searchKey, caseSensitivity);
+    }
+    case Body: {
+        if (message.bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
+            // Message contains only body (not attachments)
+            QString messageBody = message.textContent();
+            return messageBody.contains(m_searchKey, caseSensitivity);
+        } else {
+            // Message contains body and attachments
+            QMessageContentContainerIdList contentIds = message.contentIds();
+            foreach (QMessageContentContainerId id, contentIds){
+                QMessageContentContainer container = message.find(id);
+                QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
+                if (pPrivateContainer->_id == message.bodyId()) {
+                    // ContentContainer is body
+                    return container.textContent().contains(m_searchKey, caseSensitivity);
+                }
+            }
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    return false;
+}
+
+#include "moc_qfsengine_symbian_p.cpp"
+
+QTM_END_NAMESPACE