qtmobility/src/messaging/qmtmengine_symbian.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
child 15 1f895d8a5b2b
--- a/qtmobility/src/messaging/qmtmengine_symbian.cpp	Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/src/messaging/qmtmengine_symbian.cpp	Wed Jun 23 19:08:38 2010 +0300
@@ -77,9 +77,9 @@
 #include <smuthdr.h>
 #include <mtuireg.h> // CMtmUiRegistry
 #include <mtmuibas.h> // CBaseMtmUi
-#include <SendUiConsts.h>
+#include <senduiconsts.h>
 #include <sendui.h>    // SendUi API
-#include <CMessageData.h> //CMessageData
+#include <cmessagedata.h> //CMessageData
 #include <apgcli.h>
 #include <rsendas.h>
 #include <rsendasmessage.h>
@@ -276,13 +276,13 @@
             }
         }
     }
-    
+
     if (!sortOrder.isEmpty()) {
         orderAccounts(accountIds, sortOrder);
     }
-    
+
     applyOffsetAndLimitToAccountIds(accountIds, offset, limit);
-        
+    
     return accountIds;
 }
 
@@ -703,27 +703,33 @@
 void CMTMEngine::showMessageL(const QMessageId &id)
 {
     long int messageId = SymbianHelpers::stripIdPrefix(id.toString()).toLong();
-    
+
     CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
     CleanupStack::PushL(pEntry);
-    CBaseMtm* mtm = ipClientMtmReg->NewMtmL(pEntry->Entry().iMtm);
-    CleanupStack::PushL(mtm);
-    
-    CMtmUiRegistry* mtmUiRegistry = CMtmUiRegistry::NewL(*ipMsvSession);
-    CleanupStack::PushL(mtmUiRegistry); 
-
-    CBaseMtmUi* ui = mtmUiRegistry->NewMtmUiL(*mtm); 
-    CleanupStack::PushL(ui);
-    
-    ui->BaseMtm().SwitchCurrentEntryL(messageId);
-    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
-    waiter->Start(); 
-    CMsvOperation* op = ui->OpenL(waiter->iStatus);
-    CleanupStack::PushL(op);
-    
-    CActiveScheduler::Start();
-
-    CleanupStack::PopAndDestroy(6); // op,waiter,ui,mtmuiregistry,mtm,pEntry
+
+    CBaseMtm* pMtm = ipClientMtmReg->NewMtmL(pEntry->Entry().iMtm);
+    CleanupStack::PushL(pMtm);
+    
+    CMtmUiRegistry* pMtmUiRegistry = CMtmUiRegistry::NewL(*ipMsvSession);
+    CleanupStack::PushL(pMtmUiRegistry); 
+
+    CBaseMtmUi* pMtmUi = pMtmUiRegistry->NewMtmUiL(*pMtm); 
+    CleanupStack::PushL(pMtmUi);
+    
+    pMtmUi->BaseMtm().SwitchCurrentEntryL(messageId);
+
+    QMTMWait mtmWait;
+    
+    CMsvOperation* pMsvOperation = pMtmUi->OpenL(mtmWait.iStatus);
+    
+    mtmWait.start();
+
+    delete pMsvOperation;
+    
+    CleanupStack::PopAndDestroy(pMtmUi);
+    CleanupStack::PopAndDestroy(pMtmUiRegistry);
+    CleanupStack::PopAndDestroy(pMtm);
+    CleanupStack::PopAndDestroy(pEntry);
 }
 
 bool CMTMEngine::composeMessage(const QMessage &message)
@@ -957,325 +963,125 @@
     return true;
 }
 
-bool CMTMEngine::retrieve(const QMessageId &messageId, const QMessageContentContainerId& id)
+bool CMTMEngine::retrieve(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id)
 {
-    TRAPD(err, retrieveL(messageId, id));
+    TRAPD(err, retrieveL(privateService, messageId, id));
         if (err != KErrNone)
             return false;
         else
             return true;
 }
 
-void CMTMEngine::retrieveL(const QMessageId &messageId, const QMessageContentContainerId& id)
+void CMTMEngine::retrieveL(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id)
 {
     Q_UNUSED(id); // all attachments are retrieved (cannot retrieve only one)
     
-    long int messId = SymbianHelpers::stripIdPrefix(messageId.toString()).toLong();
-    
-    CMsvEntry* pEntry = ipMsvSession->GetEntryL(messId);
+    long int msgId = SymbianHelpers::stripIdPrefix(messageId.toString()).toLong();
+    
+    CMsvEntry* pEntry = ipMsvSession->GetEntryL(msgId);
     CleanupStack::PushL(pEntry);
     
-    CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
-    CleanupStack::PushL(sel);
-    
-    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
-
+    CAsynchronousMTMOperation* pMTMOperation = NULL;
     if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){    
-        TPckgBuf<TInt> parameter;
-        
-        ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
-        
-        sel->AppendL(messId);
-        
-        CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        TImImap4GetPartialMailInfo info;
-        info.iPartialMailOptions = EAttachmentsOnly;
-        TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
-
-        CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
-                                                    *sel, bodyInfo, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        if (wait->iStatus.Int() != KErrNone) { 
-            if (wait->iStatus.Int() == KErrNotFound){
-                // TODO: set messagestatus removed
-            }
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipImap4Mtm,
+                                                       pEntry->OwningService());
+    } else if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipPop3Mtm,
+                                                       pEntry->OwningService());
+    }
+
+    if (pMTMOperation) {
+        if (!pMTMOperation->retrieveMessageAttachments(msgId)) {
+            User::Leave(KErrAccessDenied);
         }
-        
-        CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CleanupStack::PopAndDestroy(3);
-    }
-    
-    if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
-        TPckgBuf<TInt> parameter;
-        
-        ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());    
-
-        sel->AppendL(pEntry->EntryId());
-        
-        CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
-        CleanupStack::PushL(popSettings);
-        CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
-        TPopAccount account;
-        emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
-        emailAccounts->LoadPopSettingsL(account, *popSettings);
-        // cannot retrieve only attachment, have to retrieve entire message
-        popSettings->SetGetMailOptions(EGetPop3EmailMessages);
-        emailAccounts->SavePopSettingsL(account,*popSettings);
-        CleanupStack::PopAndDestroy(emailAccounts);
-        CleanupStack::PopAndDestroy(popSettings);
-
-        CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        CleanupStack::PopAndDestroy(3);
-        
-    }
-    
-    CleanupStack::PopAndDestroy(wait);
-    CleanupStack::PopAndDestroy(sel);    
+    } else {
+        User::Leave(KErrArgument);
+    }
+    
     CleanupStack::PopAndDestroy(pEntry);
 }
 
-bool CMTMEngine::retrieveBody(const QMessageId& id)
+bool CMTMEngine::retrieveBody(QMessageServicePrivate& privateService, const QMessageId& id)
 {
-    TRAPD(err, retrieveBodyL(id));
+    TRAPD(err, retrieveBodyL(privateService, id));
         if (err != KErrNone)
             return false;
         else
             return true;
 }
 
-void CMTMEngine::retrieveBodyL(const QMessageId& id) const
+void CMTMEngine::retrieveBodyL(QMessageServicePrivate& privateService, const QMessageId& id)
 {
-    long int messageId = SymbianHelpers::stripIdPrefix(id.toString()).toLong();
-    
-    CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
+    long int msgId = SymbianHelpers::stripIdPrefix(id.toString()).toLong();
+    
+    CMsvEntry* pEntry = ipMsvSession->GetEntryL(msgId);
     CleanupStack::PushL(pEntry);
     
-    CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
-    CleanupStack::PushL(sel);
-    
-    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
-
+    CAsynchronousMTMOperation* pMTMOperation = NULL;
     if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){    
-        TPckgBuf<TInt> parameter;
-        
-        ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
-        
-        sel->AppendL(messageId);
-        
-        CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        TImImap4GetPartialMailInfo info;
-        info.iPartialMailOptions = EBodyTextOnly;
-        TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
-
-        CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
-                                                    *sel, bodyInfo, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        if (wait->iStatus.Int() != KErrNone) { 
-            if (wait->iStatus.Int() == KErrNotFound){
-                // TODO: set messagestatus removed
-            }
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipImap4Mtm,
+                                                       pEntry->OwningService());
+    } else if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipPop3Mtm,
+                                                       pEntry->OwningService());
+    }
+
+    if (pMTMOperation) {
+        if (!pMTMOperation->retrieveMessageBody(msgId)) {
+            User::Leave(KErrAccessDenied);
         }
-        
-        CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CleanupStack::PopAndDestroy(3);
-    }
-    
-    if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
-        TPckgBuf<TInt> parameter;
-        
-        ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());    
-
-        sel->AppendL(pEntry->EntryId());
-        
-        CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
-        CleanupStack::PushL(popSettings);
-        CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
-        TPopAccount account;
-        emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
-        emailAccounts->LoadPopSettingsL(account, *popSettings);
-        // cannot retrieve only body, have to retrieve entire message
-        popSettings->SetGetMailOptions(EGetPop3EmailMessages);
-        emailAccounts->SavePopSettingsL(account,*popSettings);
-        CleanupStack::PopAndDestroy(emailAccounts);
-        CleanupStack::PopAndDestroy(popSettings);
-
-        CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        CleanupStack::PopAndDestroy(3);
-        
-    }
-    
-    CleanupStack::PopAndDestroy(wait);
-    CleanupStack::PopAndDestroy(sel);    
+    } else {
+        User::Leave(KErrArgument);
+    }
+    
     CleanupStack::PopAndDestroy(pEntry);
 }
 
-bool CMTMEngine::retrieveHeader(const QMessageId& id)
+bool CMTMEngine::retrieveHeader(QMessageServicePrivate& privateService, const QMessageId& id)
 {
-    TRAPD(err, retrieveHeaderL(id));
+    TRAPD(err, retrieveHeaderL(privateService, id));
         if (err != KErrNone)
             return false;
         else
             return true;
 }
 
-void CMTMEngine::retrieveHeaderL(const QMessageId& id) const
+void CMTMEngine::retrieveHeaderL(QMessageServicePrivate& privateService, const QMessageId& id)
 {
-    long int messageId = SymbianHelpers::stripIdPrefix(id.toString()).toLong();
-    
-    CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
+    long int msgId = SymbianHelpers::stripIdPrefix(id.toString()).toLong();
+    
+    CMsvEntry* pEntry = ipMsvSession->GetEntryL(msgId);
     CleanupStack::PushL(pEntry);
     
-    CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
-    CleanupStack::PushL(sel);
-    
-    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
-
+    CAsynchronousMTMOperation* pMTMOperation = NULL;
     if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){    
-        TPckgBuf<TInt> parameter;
-        
-        ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
-        
-        sel->AppendL(messageId);
-        
-        CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-            
-        TImImap4GetMailInfo info;
-        info.iGetMailBodyParts = EGetImap4EmailHeaders;
-        TPckg<TImImap4GetMailInfo> bodyInfo(info);
-        
-        CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
-                                                    *sel, bodyInfo, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CleanupStack::PopAndDestroy(3);
-    }
-    
-    if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
-        TPckgBuf<TInt> parameter;
-        
-        ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());    
-
-        sel->AppendL(pEntry->EntryId());
-        
-        CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opConnect);
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
-        CleanupStack::PushL(popSettings);
-        CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
-        TPopAccount account;
-        emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
-        emailAccounts->LoadPopSettingsL(account, *popSettings);
-        popSettings->SetGetMailOptions(EGetPop3EmailHeaders);
-        emailAccounts->SavePopSettingsL(account,*popSettings);
-        CleanupStack::PopAndDestroy(emailAccounts);
-        CleanupStack::PopAndDestroy(popSettings);
-
-        CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opPopulate);
-        wait->Start();
-        CActiveScheduler::Start();
-        
-        CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
-                                                    *sel, parameter, wait->iStatus);
-        CleanupStack::PushL(opDisconnect);
-        
-        wait->Start();
-        CActiveScheduler::Start();    
-        
-        CleanupStack::PopAndDestroy(3);
-        
-    }
-    
-    CleanupStack::PopAndDestroy(wait);
-    CleanupStack::PopAndDestroy(sel);    
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipImap4Mtm,
+                                                       pEntry->OwningService());
+    } else if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipPop3Mtm,
+                                                       pEntry->OwningService());
+    }
+    
+    if (pMTMOperation) {
+        if (!pMTMOperation->retrieveMessageHeader(msgId)) {
+            User::Leave(KErrAccessDenied);
+        }
+    } else {
+        User::Leave(KErrArgument);
+    }
+    
     CleanupStack::PopAndDestroy(pEntry);
 }
 
-bool CMTMEngine::exportUpdates(const QMessageAccountId &id)
+bool CMTMEngine::exportUpdates(QMessageServicePrivate& privateService, const QMessageAccountId &id)
 {
-    TRAPD(err, exportUpdatesL(id));
+    TRAPD(err, exportUpdatesL(privateService, id));
     if (err != KErrNone) {
         return false;
     } else {
@@ -1283,47 +1089,25 @@
     }
 }
 
-void CMTMEngine::exportUpdatesL(const QMessageAccountId &id) const
+void CMTMEngine::exportUpdatesL(QMessageServicePrivate& privateService, const QMessageAccountId &id)
 {
+    CAsynchronousMTMOperation* pMTMOperation = NULL;
     QMessageAccount account = this->account(id);
     CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(account.d_ptr->_service1EntryId);
     if (!pEntry) {
         User::Leave(KErrNotFound);
     }
     if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
-        TPckgBuf<TInt> parameter;
-        CMsvEntrySelection* pMsvEntrySelection = new(ELeave) CMsvEntrySelection;
-        CleanupStack::PushL(pMsvEntrySelection);
-        CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
-        
-        ipImap4Mtm->SwitchCurrentEntryL(account.d_ptr->_service1EntryId);
-        pMsvEntrySelection->AppendL(account.d_ptr->_service1EntryId);
-        
-        CMsvOperation* pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect, *pMsvEntrySelection,
-                                                                        parameter, pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
-
-        pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMFullSync, *pMsvEntrySelection,
-                                                         parameter, pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
-        
-        pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect, *pMsvEntrySelection,
-                                                         parameter, pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
-        
-        CleanupStack::PopAndDestroy(pMsvOperationWait);
-        CleanupStack::PopAndDestroy(pMsvEntrySelection);
+        pMTMOperation = createAsynchronousMTMOperation(privateService,
+                                                       ipImap4Mtm,
+                                                       account.d_ptr->_service1EntryId);
+        pMTMOperation->doFullSync();
     }
     releaseCMsvEntryAndPopFromCleanupStack(pEntry);
+    
+    if (!pMTMOperation) {
+        User::Leave(KErrArgument);
+    }
 }
 
 bool CMTMEngine::removeMessageL(const QMessageId &id, QMessageManager::RemovalOption /*option*/)
@@ -1359,26 +1143,20 @@
         ipImap4Mtm->SwitchCurrentEntryL(messageId);
         TMsvId parent = ipImap4Mtm->Entry().Entry().Parent();
         ipImap4Mtm->SwitchCurrentEntryL(parent);
-        CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
-        CMsvOperation* pMsvOperation = ipImap4Mtm->Entry().DeleteL(messageId, pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
-        CleanupStack::PopAndDestroy(pMsvOperationWait);
+        QMTMWait mtmWait;
+        CMsvOperation* pMsvOperation = ipImap4Mtm->Entry().DeleteL(messageId, mtmWait.iStatus);
+        mtmWait.start();
+        delete pMsvOperation;
     } else if (pEntry->Entry().iMtm == KUidMsgTypePOP3) {
         if (!ipPop3Mtm)
             return false;
         ipPop3Mtm->SwitchCurrentEntryL(messageId);
         TMsvId parent = ipPop3Mtm->Entry().Entry().Parent();
         ipPop3Mtm->SwitchCurrentEntryL(parent);
-        CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
-        CMsvOperation* pMsvOperation = ipPop3Mtm->Entry().DeleteL(messageId, pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
-        CleanupStack::PopAndDestroy(pMsvOperationWait);
+        QMTMWait mtmWait;
+        CMsvOperation* pMsvOperation = ipPop3Mtm->Entry().DeleteL(messageId, mtmWait.iStatus);
+        mtmWait.start();
+        delete pMsvOperation;
     } 
     
     CleanupStack::PopAndDestroy(pEntry);
@@ -1721,12 +1499,10 @@
                     applyOffsetAndLimitToMsgIds(iMessageQueries[index].ids,
                                                 iMessageQueries[index].offset,
                                                 iMessageQueries[index].limit);
-                    emit iMessageQueries[index].privateService->messagesFound(iMessageQueries[index].ids);
+                    iMessageQueries[index].privateService->messagesFound(iMessageQueries[index].ids, true, true);
                 } else {
-                    emit iMessageQueries[index].privateService->messagesCounted(iMessageQueries[index].count);
+                    iMessageQueries[index].privateService->messagesCounted(iMessageQueries[index].count);
                 }
-                iMessageQueries[index].privateService->_active = false;
-                emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
             }
         } else {
             // There was only one single filter to handle
@@ -1748,19 +1524,16 @@
                 }
                 // Handle offest & limit
                 applyOffsetAndLimitToMsgIds(ids, iMessageQueries[index].offset, iMessageQueries[index].limit);
-                emit iMessageQueries[index].privateService->messagesFound(ids);
+                iMessageQueries[index].privateService->messagesFound(ids, true, true);
             } else {
-                emit iMessageQueries[index].privateService->messagesCounted(ids.count());
+                iMessageQueries[index].privateService->messagesCounted(ids.count());
             }
-            iMessageQueries[index].privateService->_active = false;
-            emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
         }
     } else {
         iMessageQueries[index].privateService->_active = false;
         if (iMessageQueries[index].privateService->_error == QMessageManager::NoError) {
             iMessageQueries[index].privateService->_error = QMessageManager::RequestIncomplete;
         }
-        emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
     }
 
     delete iMessageQueries[index].findOperation;
@@ -2319,25 +2092,20 @@
     CleanupStack::PushL(pEntry);
     
     if (pEntry->Entry().iMtm == KUidMsgTypeSMS) {
-        if (!ipSmsMtm)
-            return message;
-        message = smsMessageL(*pEntry, messageId);
+        if (ipSmsMtm)
+            message = smsMessageL(*pEntry, messageId);
     } else if (pEntry->Entry().iMtm == KUidMsgTypeMultimedia) {
-        if (!ipMmsMtm)
-            return message;
-        message = mmsMessageL(*pEntry, messageId);
+        if (ipMmsMtm)
+            message = mmsMessageL(*pEntry, messageId);
     }  else if (pEntry->Entry().iMtm == KUidMsgTypeSMTP) {
-        if (!ipSmtpMtm)
-            return message;
-        message = emailMessageL(*pEntry, messageId);
+        if (ipSmtpMtm)
+            message = emailMessageL(*pEntry, messageId);
     } else if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
-        if (!ipImap4Mtm)
-            return message;
-        message = emailMessageL(*pEntry, messageId);
+        if (ipImap4Mtm)
+            message = emailMessageL(*pEntry, messageId);
     } else if (pEntry->Entry().iMtm == KUidMsgTypePOP3) {
-        if (!ipPop3Mtm)
-            return message;
-        message = emailMessageL(*pEntry, messageId);
+        if (ipPop3Mtm)
+            message = emailMessageL(*pEntry, messageId);
     }
 
     CleanupStack::PopAndDestroy(pEntry);
@@ -2603,7 +2371,7 @@
 
     // Update message sending state
     entry.SetSendingState(KMsvSendStateWaiting);
-    
+
     // Set SMS Service & delivery settings to the SMS header
     CSmsHeader& smsHeader = ipSmsMtm->SmsHeader();
     CSmsSettings* pSmsSettings = CSmsSettings::NewL();
@@ -2617,7 +2385,9 @@
     if (smsHeader.Message().ServiceCenterAddress().Length() == 0) {
         CSmsSettings* pSmsServiceSettings = &(ipSmsMtm->ServiceSettings());
         if (!pSmsServiceSettings->ServiceCenterCount()) {
+#ifndef Q_CC_NOKIAX86
             User::Leave(KErrNotReady);
+#endif
         } else {
             CSmsNumber* pSmsCenterNumber = CSmsNumber::NewL();
             CleanupStack::PushL(pSmsCenterNumber);
@@ -2640,14 +2410,13 @@
         // Switch current SMS MTM context to SMS message parent folder entry
         ipSmsMtm->SwitchCurrentEntryL(ipSmsMtm->Entry().Entry().Parent());
         
-        CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+        QMTMWait mtmWait;
     
         // Move SMS Message to Outbox
         CMsvOperation* pMsvOperation = ipSmsMtm->Entry().MoveL(messageId,
                                                                KMsvGlobalOutBoxIndexEntryId,
-                                                               pMsvOperationWait->iStatus);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
+                                                               mtmWait.iStatus);
+        mtmWait.start();
         delete pMsvOperation;
         
         // Send SMS Message
@@ -2662,14 +2431,11 @@
         pMsvOperation = ipSmsMtm->InvokeAsyncFunctionL(ESmsMtmCommandScheduleCopy,
                                                        *pMsvEntrySelection,
                                                        dummyParams,
-                                                       pMsvOperationWait->iStatus);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
+                                                       mtmWait.iStatus);
+        mtmWait.start();
         delete pMsvOperation;    
      
         CleanupStack::PopAndDestroy(pMsvEntrySelection);    
-    
-        CleanupStack::PopAndDestroy(pMsvOperationWait);
     } else {
         User::Leave(KErrCorrupt);
     }
@@ -2689,22 +2455,21 @@
         // => Message will be created into defined standard Folder (Default value is Drafts Folder)
         destinationFolderId =  standardFolderId(message.standardFolder());
     }
-        
-    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
-    wait->Start();
-    CMsvOperation* operation = ipMmsMtm->CreateNewEntryL(destinationFolderId, wait->iStatus);
-    CleanupStack::PushL(operation);
-    CActiveScheduler::Start();
-    if (wait->iStatus.Int() != KErrNone){ 
-    //TODO: handle error
-    }
-    TPckgBuf<TMsvId> pkg;
-    pkg.Copy( operation->ProgressL());
-    TMsvId indexEntry= pkg();
-    CleanupStack::PopAndDestroy(2); // operation and wait
-    ipMmsMtm->SwitchCurrentEntryL(indexEntry);
-    ipMmsMtm->LoadMessageL();
-            
+    
+    // Switch current MMS MTM context to folder entry    
+    ipMmsMtm->SwitchCurrentEntryL(destinationFolderId);
+
+    // Create a new MMS message entry as a child of the current context
+    // Note: CreateMessageL switches current MMS MTM context to
+    //       a new MMS message context
+    ipMmsMtm->CreateMessageL(ipMmsMtm->DefaultServiceL());    
+
+    // Get the current context (new message context)
+    CMsvEntry& newMessageContext = ipMmsMtm->Entry();
+
+    // Copy entry values from the new message context index entry
+    TMsvEntry entry = newMessageContext.Entry();
+
     // Add receivers
     QList<QMessageAddress> list(message.to());
     TPtrC16 receiver(KNullDesC);
@@ -2720,30 +2485,33 @@
     TPtrC16 sbj(reinterpret_cast<const TUint16*>(subject.utf16()));
     ipMmsMtm->SetSubjectL(sbj); 
     
-    TMsvEntry ent = ipMmsMtm->Entry().Entry();       
-    ent.SetInPreparation(EFalse); 
-    ent.SetVisible(ETrue);
+    entry.SetInPreparation(EFalse); 
+    entry.SetVisible(ETrue);
     
     switch (message.priority()) {
     case QMessage::HighPriority:
-        ent.SetPriority(EMsvHighPriority);
+        entry.SetPriority(EMsvHighPriority);
         break;
     case QMessage::NormalPriority:
-        ent.SetPriority(EMsvMediumPriority);
+        entry.SetPriority(EMsvMediumPriority);
         break;
     case QMessage::LowPriority:
-        ent.SetPriority(EMsvLowPriority);
+        entry.SetPriority(EMsvLowPriority);
         break;
     }
     if (message.status() & QMessage::Read) { 
-        ent.SetUnread(false);
-        ent.SetNew(false);
+        entry.SetUnread(false);
+        entry.SetNew(false);
     } else {
-        ent.SetUnread(true);
-        ent.SetNew(true);
-    }
-    ipMmsMtm->Entry().ChangeL(ent); 
-    // Save the changes    
+        entry.SetUnread(true);
+        entry.SetNew(true);
+    }
+    
+    // Set new message's context's index entry to the specified values.
+    // <=> Changes are set into cache only
+    newMessageContext.ChangeL(entry);
+
+    // Commit cached changes to the storage
     ipMmsMtm->SaveMessageL();
     
     CMsvStore* store = ipMmsMtm->Entry().EditStoreL();    
@@ -2865,13 +2633,13 @@
     CleanupStack::PopAndDestroy(); // store    
     
     QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
-    privateMessage->_id = QMessageId(SymbianHelpers::addIdPrefix(QString::number(indexEntry,SymbianHelpers::EngineTypeMTM)));
+    privateMessage->_id = QMessageId(SymbianHelpers::addIdPrefix(QString::number(entry.Id()),SymbianHelpers::EngineTypeMTM));
     // Save the changes
     ipMmsMtm->SaveMessageL();
     
     if (!message.receivedDate().isNull() || !message.date().isNull()) {
         // Change the date to given date
-        CMsvEntry* pEntry = ipMsvSession->GetEntryL(indexEntry);
+        CMsvEntry* pEntry = ipMsvSession->GetEntryL(entry.Id());
         CleanupStack::PushL(pEntry);
         TMsvEntry changedEntry = pEntry->Entry();
         if (!message.date().isNull()) {
@@ -3218,17 +2986,15 @@
     if (mtmUid == KUidMsgTypeSMTP) {
         ipSmtpMtm->Entry().ChangeL(msvEntry);
     } else {
-        CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+        QMTMWait mtmWait;
         CMsvOperation* pMsvOperation = NULL;
         if (mtmUid == KUidMsgTypePOP3) {
-            pMsvOperation = ipPop3Mtm->Entry().ChangeL(msvEntry, pMsvOperationWait->iStatus);
+            pMsvOperation = ipPop3Mtm->Entry().ChangeL(msvEntry, mtmWait.iStatus);
         } else {
-            pMsvOperation = ipImap4Mtm->Entry().ChangeL(msvEntry, pMsvOperationWait->iStatus);
+            pMsvOperation = ipImap4Mtm->Entry().ChangeL(msvEntry, mtmWait.iStatus);
         }
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
+        mtmWait.start();
         delete pMsvOperation;
-        CleanupStack::PopAndDestroy(pMsvOperationWait);
     }
     
     // Save the changes    
@@ -3239,8 +3005,6 @@
     
     CImEmailMessage* mailMsg = CImEmailMessage::NewLC(*entry); 
     
-    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
-    
     CImMimeHeader* mime = CImMimeHeader::NewLC(); 
     
     QByteArray filePath;
@@ -3269,9 +3033,9 @@
             QString fileName = QString(name);
             CleanupStack::PushL(attachmentInfo);  
             attachmentInfo->SetAttachmentNameL(TPtrC(reinterpret_cast<const TUint16*>(fileName.utf16())));
-            mailMsg->AttachmentManager().AddAttachmentL(attachment, attachmentInfo, waiter->iStatus);
-            waiter->Start();
-            CActiveScheduler::Start();
+            QMTMWait mtmWait;
+            mailMsg->AttachmentManager().AddAttachmentL(attachment, attachmentInfo, mtmWait.iStatus);
+            mtmWait.start();
             CleanupStack::Pop(attachmentInfo);
             CleanupStack::Pop(&attachment); // close file
         } else if (pPrivateContainer->_id == message.bodyId()) { // content is body text
@@ -3302,10 +3066,9 @@
             }
             // Insert the contents of a buffer into the document at specified position
             bodyText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
-            mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, waiter->iStatus);
-            
-            waiter->Start();
-            CActiveScheduler::Start();
+            QMTMWait mtmWait;
+            mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, mtmWait.iStatus);
+            mtmWait.start();
                     
             CleanupStack::PopAndDestroy(3); // bodyText, characterFormatLayer, paragraphFormatLayer
         }
@@ -3342,9 +3105,9 @@
         
         // Insert the contents of a buffer into the document at specified position
         bodyText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
-        mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, waiter->iStatus);
-        waiter->Start();
-        CActiveScheduler::Start();
+        QMTMWait mtmWait;
+        mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, mtmWait.iStatus);
+        mtmWait.start();
         CleanupStack::PopAndDestroy(3);
         //bodyText, characterFormatLayer, paragraphFormatLayer,
     }
@@ -3393,7 +3156,7 @@
     // Store the changes permanently
     store->CommitL();
     
-    CleanupStack::PopAndDestroy(6, entry); 
+    CleanupStack::PopAndDestroy(5, entry); 
     // mailMsg, emailEntry, store, waiter, entry, mime   
 
     if (!message.receivedDate().isNull() || !message.date().isNull()) {
@@ -3409,17 +3172,15 @@
         if (mtmUid == KUidMsgTypeSMTP) {
             ipSmtpMtm->Entry().ChangeL(changedEntry);
         } else {
-            CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+            QMTMWait mtmWait;
             CMsvOperation* pMsvOperation = NULL;
             if (mtmUid == KUidMsgTypePOP3) {
-                pMsvOperation = ipPop3Mtm->Entry().ChangeL(changedEntry, pMsvOperationWait->iStatus);
+                pMsvOperation = ipPop3Mtm->Entry().ChangeL(changedEntry, mtmWait.iStatus);
             } else {
-                pMsvOperation = ipImap4Mtm->Entry().ChangeL(changedEntry, pMsvOperationWait->iStatus);
+                pMsvOperation = ipImap4Mtm->Entry().ChangeL(changedEntry, mtmWait.iStatus);
             }
-            pMsvOperationWait->Start();
-            CActiveScheduler::Start();
+            mtmWait.start();
             delete pMsvOperation;
-            CleanupStack::PopAndDestroy(pMsvOperationWait);
         }
         CleanupStack::PopAndDestroy(pEntry);
     }
@@ -3444,14 +3205,14 @@
     }
 
     CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
-    CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+
+    QMTMWait mtmWait;
     
     CMsvOperation* pMsvOperation = NULL;
     if (!messageCreated) {
         ipMmsMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
-        pMsvOperation = ipMmsMtm->Entry().CopyL(messageId, KMsvGlobalOutBoxIndexEntryId, pMsvOperationWait->iStatus);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
+        pMsvOperation = ipMmsMtm->Entry().CopyL(messageId, KMsvGlobalOutBoxIndexEntryId, mtmWait.iStatus);
+        mtmWait.start();
         delete pMsvOperation;
         pMsvOperation = NULL;
     }
@@ -3460,16 +3221,10 @@
     CMsvEntrySelection* pMsvEntrySelection = new(ELeave) CMsvEntrySelection;
     pMsvEntrySelection->AppendL(messageId);
     ipMmsMtm->SwitchCurrentEntryL(KMsvGlobalOutBoxIndexEntryId);
-    pMsvOperation = ipMmsMtm->SendL(*pMsvEntrySelection, pMsvOperationWait->iStatus);
-    pMsvOperationWait->Start();
-    CActiveScheduler::Start();
+    pMsvOperation = ipMmsMtm->SendL(*pMsvEntrySelection, mtmWait.iStatus);
+    mtmWait.start();
+    
     delete pMsvOperation;
-   
-    while (pMsvOperationWait->iStatus == KRequestPending) {
-         CActiveScheduler::Start();
-    }
-    
-    CleanupStack::PopAndDestroy(pMsvOperationWait);
     releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);    
 }
 
@@ -3521,8 +3276,9 @@
     }
     
     QMessageAccount messageAccount = this->account(message.parentAccountId());
-    
-    CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+
+    QMTMWait mtmWait;
+    
     TMsvEmailTypeList msvEmailTypeList = 0;
     TMsvPartList msvPartList = 0;
     if (message.status() & QMessage::HasAttachments == QMessage::HasAttachments) {
@@ -3530,12 +3286,11 @@
     } else {
         msvPartList = KMsvMessagePartBody;
     }
-    CImEmailOperation* pImEmailOperation = CImEmailOperation::CreateNewL(pMsvOperationWait->iStatus, *ipMsvSession, destinationFolderId,
+    CImEmailOperation* pImEmailOperation = CImEmailOperation::CreateNewL(mtmWait.iStatus, *ipMsvSession, destinationFolderId,
                                                                          messageAccount.d_ptr->_service2EntryId, msvPartList,
                                                                          msvEmailTypeList, KUidMsgTypeSMTP);
     CleanupStack::PushL(pImEmailOperation);
-    pMsvOperationWait->Start();
-    CActiveScheduler::Start();
+    mtmWait.start();
     
     TMsvId newMessageId;
     TPckgC<TMsvId> paramPack(newMessageId);
@@ -3606,9 +3361,8 @@
             pBodyRichText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
             // Note: Email message MIME header is same as Body MIME header
             pImEmailMessage->StoreBodyTextWithMimeHeaderL(newMessageId, *pBodyRichText, *pImMimeHeader,
-                                                          pMsvOperationWait->iStatus);
-            pMsvOperationWait->Start();
-            CActiveScheduler::Start();
+                                                          mtmWait.iStatus);
+            mtmWait.start();
             
             CleanupStack::PopAndDestroy(pBodyRichText);
             CleanupStack::PopAndDestroy(pCharFormatLayer);
@@ -3651,9 +3405,10 @@
                     pBodyRichText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
             
                     // Store MIME Header and Body text to message
-                    pImEmailMessage->StoreBodyTextWithMimeHeaderL(newMessageId, *pBodyRichText, *pBodyImMimeHeader, pMsvOperationWait->iStatus);
-                    pMsvOperationWait->Start();
-                    CActiveScheduler::Start();
+                    pImEmailMessage->StoreBodyTextWithMimeHeaderL(newMessageId, *pBodyRichText,
+                                                                  *pBodyImMimeHeader,
+                                                                  mtmWait.iStatus);
+                    mtmWait.start();
                     
                     CleanupStack::PopAndDestroy(pBodyRichText);
                     CleanupStack::PopAndDestroy(pCharFormatLayer);
@@ -3690,9 +3445,10 @@
                 CleanupStack::PushL(pMsvAttachment);  
                 pMsvAttachment->SetAttachmentNameL(TPtrC(reinterpret_cast<const TUint16*>(fileName.utf16())));
                 // Note: Following call transfers ownership of attachmentFile and pMsvAttachment to AttachmentManager
-                pImEmailMessage->AttachmentManager().AddAttachmentL(attachmentFile, pMsvAttachment, pMsvOperationWait->iStatus);
-                pMsvOperationWait->Start();
-                CActiveScheduler::Start();
+                pImEmailMessage->AttachmentManager().AddAttachmentL(attachmentFile, pMsvAttachment,
+                                                                    mtmWait.iStatus);
+                mtmWait.start();
+
                 CleanupStack::Pop(pMsvAttachment); // Pop attachment from CleanupStack
                 CleanupStack::Pop(&attachmentFile); // Pop file from CleanupStack
             }        
@@ -3770,17 +3526,13 @@
         TMsvId parent = pMsvEntry->Entry().Parent();
         ipImap4Mtm->SwitchCurrentEntryL(parent);        
         CMsvOperation* pMsvOperation = ipImap4Mtm->Entry().MoveL(newMessageId, imapDestinationFolderId,
-                                                                 pMsvOperationWait->iStatus);
-        CleanupStack::PushL(pMsvOperation);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
-        CleanupStack::PopAndDestroy(pMsvOperation);
+                                                                 mtmWait.iStatus);
+        mtmWait.start();
+        delete pMsvOperation;
     }
     
     releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
 
-    CleanupStack::PopAndDestroy(pMsvOperationWait);
-    
     QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
     privateMessage->_id = QMessageId(SymbianHelpers::addIdPrefix(QString::number(newMessageId),SymbianHelpers::EngineTypeMTM));
 }
@@ -3817,28 +3569,28 @@
     }    
 
     CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
-    CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
+    
+    QMTMWait mtmWait;
     
     CMsvOperation* pMsvOperation = NULL;
     if (!messageCreated) {
         // Sending (old) message that's in message store
         // => Copy message from its original location to Outbox folder
         ipSmtpMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
-        pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId, KMsvGlobalOutBoxIndexEntryId, pMsvOperationWait->iStatus);
-        pMsvOperationWait->Start();
-        CActiveScheduler::Start();
+        pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId,
+                                                 KMsvGlobalOutBoxIndexEntryId,
+                                                 mtmWait.iStatus);
+        mtmWait.start();
         delete pMsvOperation;
         pMsvOperation = NULL;
     }    
     
     ipSmtpMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
     // Following sends Email and _moves_ Email from Outbox Folder to Sent Folder
-    pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId, messageAccount.d_ptr->_service2EntryId, pMsvOperationWait->iStatus);
-    pMsvOperationWait->Start();
-    CActiveScheduler::Start();
+    pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId, messageAccount.d_ptr->_service2EntryId, mtmWait.iStatus);
+    mtmWait.start();
     delete pMsvOperation;    
     
-    CleanupStack::PopAndDestroy(pMsvOperationWait);
     releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);   
 }
 
@@ -4554,7 +4306,7 @@
             matchingFilters.insert(it.key());
         } else {
             QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
-            if (privateMessageFilter->_field == QMessageFilterPrivate::Type) {
+            if (privateMessageFilter->_field == QMessageFilterPrivate::Type && aEvent != EMsvEntriesCreated) {
                 if (aMsgType == KUidMsgTypeSMS) {
                     message.setType(QMessage::Sms);
                 } else if (aMsgType == KUidMsgTypeMultimedia) {
@@ -4566,7 +4318,7 @@
                 } else {
                     message.setType(QMessage::NoType);
                 }
-            } else if ((privateMessageFilter->_field == QMessageFilterPrivate::StandardFolder) &&
+            } else if ((privateMessageFilter->_field == QMessageFilterPrivate::StandardFolder && aEvent != EMsvEntriesCreated) &&
                        (aMsgType == KUidMsgTypeSMS || aMsgType == KUidMsgTypeMultimedia)) {
                 if (aFolderId == KMsvGlobalInBoxIndexEntryId) {
                     QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
@@ -4771,6 +4523,24 @@
     }
 }
 
+CAsynchronousMTMOperation* CMTMEngine::createAsynchronousMTMOperation(QMessageServicePrivate& privateService,
+                                                                      CBaseMtm* mtm,
+                                                                      TMsvId serviceId)
+{
+    TInt operationId = ++iOperationIds;
+    CAsynchronousMTMOperation* op = new CAsynchronousMTMOperation((CMTMEngine&)*this,
+                                                                   privateService,
+                                                                   mtm,
+                                                                   serviceId,
+                                                                   operationId);
+    return op;
+}
+
+void CMTMEngine::deleteAsynchronousMTMOperation(CAsynchronousMTMOperation *apOperation)
+{
+    delete apOperation;
+}
+
 CMessagesFindOperation::CMessagesFindOperation(CMTMEngine& aOwner, CMsvSession* apMsvSession, int aOperationId)
     : CActive(CActive::EPriorityStandard), iOwner(aOwner), ipMsvSession(apMsvSession), iOperationId(aOperationId),
         iResultCorrectlyOrdered(false)
@@ -5657,5 +5427,305 @@
     }
 }
 
+QMTMWait::QMTMWait(TInt priority)
+    : CActive(priority)
+{
+    CActiveScheduler::Add(this);
+}
+
+QMTMWait::~QMTMWait()
+{
+    Cancel();
+}
+
+void QMTMWait::start()
+{
+    SetActive();
+    m_eventLoop.exec();
+}
+
+void QMTMWait::RunL()
+{
+    m_eventLoop.quit();
+}
+
+void QMTMWait::DoCancel()
+{
+    Cancel();
+}
+
+CAsynchronousMTMOperation::CAsynchronousMTMOperation(CMTMEngine& aParent,
+                                                     QMessageServicePrivate& aPrivateService,
+                                                     CBaseMtm* apMTM,
+                                                     TMsvId aServiceId,
+                                                     TInt aOperationId)
+    : CActive(EPriorityStandard),
+      ipParent(&aParent),
+      iOperationId(aOperationId),
+      iServiceId(aServiceId),
+      ipPrivateService(&aPrivateService),
+      ipMTM(apMTM)
+{
+    CActiveScheduler::Add(this);
+}
+
+CAsynchronousMTMOperation::~CAsynchronousMTMOperation()
+{
+    ipParent = NULL;
+    Cancel();
+}
+
+bool CAsynchronousMTMOperation::retrieveMessageHeader(TMsvId aMessageId)
+{
+    if (!isActive) {
+        isActive = true;
+        iOperation = MTMOperationRetrieveMessageHeader;
+        iOperationStep = MTMOperationStepConnect;
+        
+        iMessageId = aMessageId;
+        
+        TRAPD(err, RunL());
+        if (err == KErrNone) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CAsynchronousMTMOperation::retrieveMessageBody(TMsvId aMessageId)
+{
+    if (!isActive) {
+        isActive = true;
+        iOperation = MTMOperationRetrieveMessageBody;
+        iOperationStep = MTMOperationStepConnect;
+        
+        iMessageId = aMessageId;
+        
+        TRAPD(err, RunL());
+        if (err == KErrNone) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CAsynchronousMTMOperation::retrieveMessageAttachments(TMsvId aMessageId)
+{
+    if (!isActive) {
+        isActive = true;
+        iOperation = MTMOperationRetrieveMessageAttachments;
+        iOperationStep = MTMOperationStepConnect;
+        
+        iMessageId = aMessageId;
+        
+        TRAPD(err, RunL());
+        if (err == KErrNone) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CAsynchronousMTMOperation::doFullSync()
+{
+    if (!isActive) {
+        isActive = true;
+        iOperation = MTMOperationFullSync;
+        iOperationStep = MTMOperationStepConnect;
+        TRAPD(err, RunL());
+        if (err == KErrNone) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void CAsynchronousMTMOperation::RunL()
+{
+    if (iStatus.Int() != KErrNone && iOperationStep != MTMOperationStepDisconnect) {
+        delete ipMsvEntrySelection;
+        ipMsvEntrySelection = NULL;
+        delete ipMsvOperation;
+        ipMsvOperation = NULL;
+    
+        isActive = false;
+        ipPrivateService->setFinished(false);
+
+        if (ipParent) {
+            ipParent->deleteAsynchronousMTMOperation(this);
+        }
+        return;
+    }
+
+    ipMTM->SwitchCurrentEntryL(iServiceId);
+    
+    switch(iOperationStep) {
+    case CAsynchronousMTMOperation::MTMOperationStepConnect:
+        {
+        TPckgBuf<TInt> parameter;
+        ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+        ipMsvEntrySelection->AppendL(iServiceId);
+        
+        if (ipMTM->Type() == KUidMsgTypeIMAP4) {
+            ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMConnect,
+                                                         *ipMsvEntrySelection,
+                                                         parameter,
+                                                         iStatus);
+        } else if (ipMTM->Type() == KUidMsgTypePOP3) {
+            ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KPOP3MTMConnect,
+                                                         *ipMsvEntrySelection,
+                                                         parameter,
+                                                         iStatus);
+        }
+        iOperationStep = MTMOperationStepDoOperation;
+        SetActive();
+        }
+        break;
+    case CAsynchronousMTMOperation::MTMOperationStepDoOperation:
+        {
+        delete ipMsvEntrySelection;
+        ipMsvEntrySelection = NULL;
+        delete ipMsvOperation;
+        ipMsvOperation = NULL;
+        
+        if (iOperation == MTMOperationRetrieveMessageHeader) {
+            // Retrieve header
+            ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+            
+            if (ipMTM->Type() == KUidMsgTypeIMAP4) {
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TImImap4GetMailInfo info;
+                info.iMaxEmailSize = KMaxTInt;
+                info.iGetMailBodyParts = EGetImap4EmailHeaders;
+                TPckg<TImImap4GetMailInfo> bodyInfo(info);
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             bodyInfo,
+                                                             iStatus);
+            } else if (ipMTM->Type() == KUidMsgTypePOP3) {
+                ipMsvEntrySelection->AppendL(iServiceId);
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TPckgBuf<TInt> parameter;
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KPOP3MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             parameter,
+                                                             iStatus);
+            }
+        } else if (iOperation == MTMOperationRetrieveMessageBody) {
+            // Retrieve message body
+            ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+            
+            if (ipMTM->Type() == KUidMsgTypeIMAP4) {
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TImImap4GetPartialMailInfo info;
+                info.iMaxEmailSize = KMaxTInt;
+                info.iTotalSizeLimit = KMaxTInt;
+                info.iBodyTextSizeLimit = KMaxTInt;
+                info.iPartialMailOptions = EBodyTextOnly;
+                TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             bodyInfo,
+                                                             iStatus);
+            } else if (ipMTM->Type() == KUidMsgTypePOP3) {
+                ipMsvEntrySelection->AppendL(iServiceId);
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TPckgBuf<TInt> parameter;
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KPOP3MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             parameter,
+                                                             iStatus);
+            }
+        }  else if (iOperation == MTMOperationRetrieveMessageAttachments) {
+            // Retrieve message attachments
+            ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+            
+            if (ipMTM->Type() == KUidMsgTypeIMAP4) {
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TImImap4GetPartialMailInfo info;
+                info.iMaxEmailSize = KMaxTInt;
+                info.iTotalSizeLimit = KMaxTInt;
+                info.iAttachmentSizeLimit = KMaxTInt;
+                info.iPartialMailOptions = EAttachmentsOnly;
+                TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             bodyInfo,
+                                                             iStatus);
+            } else if (ipMTM->Type() == KUidMsgTypePOP3) {
+                ipMsvEntrySelection->AppendL(iServiceId);
+                ipMsvEntrySelection->AppendL(iMessageId);
+                TPckgBuf<TInt> parameter;
+                ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KPOP3MTMPopulate,
+                                                             *ipMsvEntrySelection,
+                                                             parameter,
+                                                             iStatus);
+            }
+        } else if (iOperation == MTMOperationFullSync) {
+            // Do full sync for IMAP Account
+            // <=> in addition to syncing messages from server to client
+            //     syncs also changes (like read statuses) from client to server
+            ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+            ipMsvEntrySelection->AppendL(iServiceId);
+            
+            TImImap4GetMailInfo imap4GetMailInfo;
+            imap4GetMailInfo.iMaxEmailSize = KMaxTInt;
+            imap4GetMailInfo.iDestinationFolder = iServiceId+1; // remote inbox
+            imap4GetMailInfo.iGetMailBodyParts = EGetImap4EmailHeaders;
+            TPckgBuf<TImImap4GetMailInfo> package(imap4GetMailInfo);
+            
+            ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMFullSync,
+                                                         *ipMsvEntrySelection,
+                                                         package,
+                                                         iStatus);
+            
+        
+        }
+        iOperationStep = MTMOperationStepDisconnect;
+        SetActive();
+        }
+        break;
+    case CAsynchronousMTMOperation::MTMOperationStepDisconnect:
+        {
+        delete ipMsvEntrySelection;
+        ipMsvEntrySelection = NULL;
+        delete ipMsvOperation;
+        ipMsvOperation = NULL;
+        
+        TPckgBuf<TInt> parameter;
+        ipMsvEntrySelection = new(ELeave) CMsvEntrySelection;
+        ipMsvEntrySelection->AppendL(iServiceId);
+        if (ipMTM->Type() == KUidMsgTypeIMAP4) {
+            ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
+                                                         *ipMsvEntrySelection,
+                                                         parameter,
+                                                         iStatus);
+        } else if (ipMTM->Type() == KUidMsgTypePOP3) {
+            ipMsvOperation = ipMTM->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
+                                                         *ipMsvEntrySelection,
+                                                         parameter,
+                                                         iStatus);
+        }
+        iOperationStep = MTMOperationStepFinished;
+        SetActive();
+        }
+        break;
+    case CAsynchronousMTMOperation::MTMOperationStepFinished:
+        delete ipMsvEntrySelection;
+        ipMsvEntrySelection = NULL;
+        delete ipMsvOperation;
+        ipMsvOperation = NULL;
+
+        isActive = false;
+        ipPrivateService->setFinished(true);
+        ipParent->deleteAsynchronousMTMOperation(this);
+        break;
+    }
+}
+
+void CAsynchronousMTMOperation::DoCancel()
+{
+    ipMsvOperation->Cancel();
+}
 
 QTM_END_NAMESPACE