ipsservices/ipssosplugin/src/ipsplgsosbaseplugin.cpp
branchRCL_3
changeset 25 3533d4323edc
parent 24 d189ee25cf9d
child 26 968773a0b6ef
--- a/ipsservices/ipssosplugin/src/ipsplgsosbaseplugin.cpp	Tue Aug 31 15:04:17 2010 +0300
+++ b/ipsservices/ipssosplugin/src/ipsplgsosbaseplugin.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -17,56 +17,28 @@
 
 #include "emailtrace.h"
 #include "ipsplgheaders.h"
-
-// <qmail> FreestyleEmailUiConstants include removed
+#include "FreestyleEmailUiConstants.h"
 
-// <qmail>
-#include "ipsplgsosbaseplugin.hrh"
-#include "ipsplgmailstoreroperation.h"
-#include "ipsplgmessagepartstoreroperation.h"
-#include "BasePlugin.h" 
-//<Qmail>
-#include "ipssosextendedsettingsmanager.h"
-#include "ipssettingkeys.h"
-//</Qmail>
-//</qmail>
-
-#define FREESTYLE_EMAIL_UI_SID 0x200255BA
+#define FREESTYLE_EMAIL_UI_SID 0x2001E277
 
 const TInt KOpGranularity = 2;
 
-// <qmail> remove unused literals
+_LIT( KMimeTextCalRequest,  "text/calendar; method=REQUEST;" );
+_LIT( KMimeTextCalResponse, "text/calendar; method=RESPONSE;" );
+_LIT( KMimeTextCalCancel,   "text/calendar; method=CANCEL;" );
+_LIT8( KMethod, "method" );
+_LIT8( KRequest, "REQUEST" );
+_LIT8( KResponse, "RESPONSE" );
+_LIT8( KCancel, "CANCEL" );
+_LIT( KLineFeed, "\r\n");
 
 #ifdef __WINS__
 _LIT( KEmulatorIMEI, "123456789012345" );
 #endif // __WINS__
 
-//<Qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::ActiveFolderChanged(
-        const TFSMailMsgId& aActiveMailboxId,
-        const TFSMailMsgId& aActiveFolderId)
-    {
-    TRAP_IGNORE( HandleActiveFolderChangeL(aActiveMailboxId,aActiveFolderId) );
-    }
-
-
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
-CEmailExtension* CIpsPlgSosBasePlugin::ExtensionL( const TUid& aInterfaceUid )
-    {
-    if(aInterfaceUid != KEmailMailboxStateExtensionUid)
-        {
-        User::Leave(KErrNotSupported);
-        }
-    
-    return iStateExtension;
-    }
-//</Qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-// <qmail> iSettingsApi removed
+//
 CIpsPlgSosBasePlugin::CIpsPlgSosBasePlugin( const TUint aFSPluginId ) :
     iFSPluginId( aFSPluginId ),
     iSession( NULL ),
@@ -78,6 +50,7 @@
     iCachedEmailMessage( NULL ),
     iMruList( NULL ),
     iSearch( NULL ),
+    iSettingsApi( NULL ),
     iEventHandler( NULL ),
     iSessionOk( ETrue ),
     iBrandingId( NULL ),
@@ -88,10 +61,31 @@
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
-// <qmail> iSettingsApi, iWait removed
+//
 CIpsPlgSosBasePlugin::~CIpsPlgSosBasePlugin()
     {
     FUNC_LOG;
+    if ( iMsvOpDeleteMessage )
+        {
+        iMsvOpDeleteMessage->Cancel();
+        }
+    
+    if ( iWaitDeleteMessage )
+        {
+        iWaitDeleteMessage->Cancel();
+        }
+    
+    delete iMsvOpDeleteMessage;
+    iMsvOpDeleteMessage = NULL;
+    delete iWaitDeleteMessage;
+    iWaitDeleteMessage = NULL;
+    delete icEntry;
+    icEntry = NULL;
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+
     iOperations.ResetAndDestroy();
     iActivitytimers.ResetAndDestroy();
     iOperations.Close();
@@ -102,12 +96,12 @@
         {
         iEventHandler->UnRegisterPropertyObserver( iSyncStateHandler );
         }
-    delete iStateExtension;
     delete iEventHandler;
     delete iCachedEntry;
     delete iCachedEmailMessage;
     delete iMsgMapper;
     delete iSearch;
+    delete iSettingsApi;
     delete iSyncStateHandler;
     delete iSession;
     delete iBrandingId;
@@ -118,14 +112,14 @@
 void CIpsPlgSosBasePlugin::BaseConstructL()
     {
     FUNC_LOG;
-    iStateExtension = CIpsStateExtension::NewL(*this);
     iEventHandler = CIpsPlgEventHandler::NewL( *this );
     iSession = CMsvSession::OpenAsyncL( *iEventHandler );
     iMsgMapper = CIpsPlgMsgMapper::NewL( *iSession, *this );
     iSmtpService = CIpsPlgSmtpService::NewL( *iSession, *this );
     iMruList = CIpsPlgMruList::NewL( );
     iSearch = CIpsPlgSearch::NewL( *iSession, *this );
-	// <qmail> iSettingsApi removed
+    iSettingsApi = CIpsSetDataApi::NewL( *iSession );
+    iSettingsApi->GetIMEIFromThePhoneL( iIMEI );
     iSyncStateHandler = CIpsPlgSyncStateHandler::NewL(
             *iSession, *this, iOperations );
     iEventHandler->RegisterPropertyObserverL( iSyncStateHandler );
@@ -139,8 +133,6 @@
         {
         iIsUnderUiProcess = EFalse;
         }
-
-#ifndef RD_101_EMAIL
     RAlwaysOnlineClientSession aosession;
     TInt err = aosession.Connect();
     if ( err == KErrNone )
@@ -151,7 +143,6 @@
                 dummyBuf ) );
         }
     aosession.Close();
-#endif    
     }
 
 // ----------------------------------------------------------------------------
@@ -189,8 +180,11 @@
             {
             DeleteAndRemoveOperation( i, aCompletionCode );
             }
-
-// <qmail> iWait removed
+        }
+    // make draft deletion synchronous so that empty drafts are not left after application close.
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
         }
     }
 
@@ -210,12 +204,8 @@
         if ( tEntry.Connected() )
             {
             status = EFSMailBoxOnline;
-            }
-        else if ( ConnOpRunning( aMailBoxId ) )
-            {
-            status = EFSMailBoxOnline;
-            }
-        else
+            }			
+		else
             {
             status = EFSMailBoxOffline;
             }
@@ -311,17 +301,7 @@
         result->SetName( tEntry.iDetails );
         result->SetSettingsUid( TUid::Uid( IPS_SET_ECOM_IMPLEMENTATION_UID ) );
 
-// <qmail>
-        CEmailAccounts* acc = CEmailAccounts::NewLC();
-        TSmtpAccount smtpAcc;
-        acc->GetSmtpAccountL( tEntry.iRelatedId , smtpAcc );
-        CImSmtpSettings* smtpSet = new (ELeave) CImSmtpSettings();
-        CleanupStack::PushL( smtpSet );
-        acc->LoadSmtpSettingsL( smtpAcc, *smtpSet );
-        address = smtpSet->EmailAddress().AllocL();
-        CleanupStack::PopAndDestroy( 2, acc );
-// </qmail>
-        
+        iSettingsApi->GetMailboxAddressL( tEntry, address );
         CleanupStack::PushL( address ); // << address
         CFSMailAddress* fsAddress = CFSMailAddress::NewLC();    // << fsAddress
         fsAddress->SetEmailAddress( *address );
@@ -348,17 +328,25 @@
         {
         User::Leave( KErrNotReady );
         }
-    
-// <qmail> RAlwaysOnlineClientSession - related code removed
+
+    // Create connection to Always Online
+    RAlwaysOnlineClientSession aosess;
+    User::LeaveIfError( aosess.Connect() );
+
     // Prepare the parameters to be forwarded to AO-server
     TPckg<TMsvId> param = aMailBoxId.Id();
 
+    // Send message to server and close it
+    TRAP_IGNORE( aosess.RelayCommandL( EServerAPIEmailAgentRemove, param ) );
+    aosess.Close();
+
     // delete MRU list from cen rep
     iMruList->ClearDataL( aMailBoxId );
 
     iSyncStateHandler->NotifyMailboxRemove( aMailBoxId.Id() );
 
-// <qmail> CancelAllOnlineOperations function call removed
+    CancelAllOnlineOperations( aMailBoxId );
+
     iSession->GetEntry( aMailBoxId.Id(), service, tEntry );
     if ( tEntry.Connected() )
         {
@@ -380,7 +368,7 @@
         }
     else
         {
-// <qmail> iSettingsApi removed
+        iSettingsApi->RemoveAccountL( tEntry, *iSession );
         TFSProgress progress = { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone };
         progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
         progress.iError = KErrNone;
@@ -400,12 +388,32 @@
         {
         User::Leave( KErrNotReady );
         }
-    CMsvEntry* mboxEntry = iSession->GetEntryL( aMailBoxId.Id() );
-    CleanupStack::PushL( mboxEntry );
-
-// <qmail> iSettingsApi removed, iBrandingId removed
-    CleanupStack::PopAndDestroy( mboxEntry );
-
+    
+    TMsvEntry tEntry;
+    TMsvId serviceId;
+    TInt status = iSession->GetEntry( aMailBoxId.Id(), serviceId, tEntry );
+ 
+    if ( status == KErrNone )
+        {
+        HBufC* address( NULL );
+        iSettingsApi->GetMailboxAddressL( tEntry, address );
+        CleanupStack::PushL( address );
+        TPtrC ptr = address->Des();
+        TInt index = ptr.Locate('@') + 1;
+        if( index > 0 && ptr.Length() > 0 )
+            {
+            if( iBrandingId )
+                {
+                delete iBrandingId;
+                iBrandingId = NULL;
+                }
+            ptr.Set( ptr.Right( ptr.Length() - index ) );        
+            iBrandingId = HBufC::NewL( ptr.Length() );
+            iBrandingId->Des().Copy( ptr );
+            }
+        CleanupStack::PopAndDestroy( address );
+        }    
+    
     return *iBrandingId;
     }
 
@@ -419,7 +427,6 @@
     const TFSMailMsgId& aDestinationFolderId )
 	{
     FUNC_LOG;
-	// Pop3 has no implementation for this virtual
 	if( aDestinationFolderId.Id() == KMsvDraftEntryId  )
 	    {
 	    MoveMessagesToDraftL(
@@ -518,13 +525,16 @@
         }
     if( sel->Count() )
         {
-        // <qmail> remove activeschedulerwait
-        TMsvLocalOperationProgress progress;
+        CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC();
         if( !aSourceFolderId.IsNullId() )
             {
             CMsvEntry* cEntry = iSession->GetEntryL( aSourceFolderId.Id() );
             CleanupStack::PushL( cEntry );
-            cEntry->MoveL( *sel, aDestinationFolderId.Id(), progress );
+            cEntry->MoveL(
+                *sel,
+                           aDestinationFolderId.Id(),//KMsvDraftEntryIdValue
+                           wait->iStatus );
+
             CleanupStack::PopAndDestroy( cEntry );
             }
         else
@@ -533,10 +543,13 @@
             // because it's equal to destination.
             TMsvId parent = msgEntry->Entry().Parent();
             msgEntry->SetEntryL( parent );
-            msgEntry->CopyL( *sel, aDestinationFolderId.Id(), progress );
+            msgEntry->CopyL(
+                *sel,
+                             aDestinationFolderId.Id(),//KMsvDraftEntryIdValue
+                             wait->iStatus );
             }
-        User::LeaveIfError( progress.iError );
-        // </qmail>
+        wait->Start();
+        CleanupStack::PopAndDestroy( wait ); // wait
         }
     CleanupStack::PopAndDestroy( 2, sel ); // msgEntry, sel
     }
@@ -605,9 +618,9 @@
         User::Leave( KErrNotReady );
         }
     iSession->GetEntry( aMailBoxId.Id(), service, tEntry );
-// <qmail>
-    TInt state(0);
-// </qmail>
+
+    TInt state = iSettingsApi->GetLastSyncStatusL( tEntry );
+
     switch( state )
         {
         case ESyncFinishedSuccessfully:
@@ -642,24 +655,24 @@
             iOperations[i]->BaseOperation();
         if ( baseOp && baseOp->FSMailboxId() == aMailBoxId &&
                ( baseOp->IpsOpType() == EIpsOpTypePop3SyncOp
+                || baseOp->IpsOpType() == EIpsOpTypePop3PopulateOp		   
                 || baseOp->IpsOpType() == EIpsOpTypeImap4SyncOp
                 || baseOp->IpsOpType() == EIpsOpTypeImap4PopulateOp ) )
             {
             DeleteAndRemoveOperation( i, KErrCancel );
             }
         }
-    
-#ifndef RD_101_EMAIL    
+/** <should be commented out until AO Manager API enhancements are back ported>
     RAlwaysOnlineClientSession aosession;
     err = aosession.Connect();
     if ( err == KErrNone )
         {
         TPckgBuf<TMsvId> buf(aMailBoxId.Id());
-        TRAP( err, aosession.RelayCommandL( 
+        TRAP( err, aosession.RelayCommandL(
                 EServerAPIEmailCancelAllAndDoNotDisconnect, buf ) );
         }
     aosession.Close();
-#endif    
+    */
 
     return err;
     }
@@ -825,185 +838,68 @@
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
  CFSMailMessage* CIpsPlgSosBasePlugin::CreateMessageToSendL(
-    const TFSMailMsgId& /*aMailBoxId*/ )
+    const TFSMailMsgId& aMailBoxId )
 	{
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-    return NULL; // prevents compiler warning
+    FUNC_LOG;
+    CFSMailMessage* msg = iSmtpService->CreateNewSmtpMessageL( aMailBoxId );
+	return msg;
 	}
 
-// <qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::CreateMessageToSendL( const TFSMailMsgId& aMailBoxId,
-                                    MFSMailRequestObserver& aOperationObserver,
-                                    const TInt aRequestId )
-    {
-    FUNC_LOG;
-    // asynchronous message creation is started here to enable canceling of the operation
-    TMsvPartList partList( KMsvMessagePartBody );
-    
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC(*this);
-
-    //<qmail> removed mboxEntry from parameters + changed iSmtpService to pointer 
-    
-    CIpsPlgCreateMessageOperation* op = CIpsPlgCreateMessageOperation::NewL( 
-        *iSmtpService, 
-        *iSession,
-        watcher->iStatus,
-        partList, 
-        aMailBoxId, 
-        aOperationObserver, 
-        aRequestId );
-    //</qmail>
-    watcher->SetOperation( op );
-
-    iOperations.AppendL( watcher ); 
-    CleanupStack::Pop( watcher );    
-    }
-// </qmail> 
- 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 CFSMailMessage* CIpsPlgSosBasePlugin::CreateForwardMessageL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aOriginalMessageId*/,
-    const TDesC& /*aHeaderDescriptor*/ )
-    {
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-    return NULL; // prevents compiler warning
-    }
-
-// <qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::CreateForwardMessageL( 
     const TFSMailMsgId& aMailBoxId,
     const TFSMailMsgId& aOriginalMessageId,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId,
-    const TDesC& /*aHeaderDescriptor*/ )
+    const TDesC& aHeaderDescriptor )
     {
     FUNC_LOG;
-    // asynchronous message creation is started here to enable canceling of the operation
-    
-    // 1. part of function checs that body text and all
-    // attachments are fetched
-    TMsvEntry orgMsg;
-    TMsvId service;
-    User::LeaveIfError( iSession->GetEntry( 
-            aOriginalMessageId.Id(), service, orgMsg ) );
-    
-    if ( orgMsg.Id() ==  KMsvNullIndexEntryIdValue )
-        {
-        User::Leave(KErrNotFound);
-        }
-    
-    if ( ( orgMsg.Parent() == KMsvSentEntryIdValue ) && 
-         ( orgMsg.iMtm == KSenduiMtmSmtpUid ) )
-        {
-        iSmtpService->ChangeServiceIdL( orgMsg );
-        }
+    CFSMailMessage* msg = iSmtpService->CreateForwardSmtpMessageL(
+        aMailBoxId, aOriginalMessageId );
     
-    TMsvPartList partList( KMsvMessagePartBody | KMsvMessagePartAttachments );
-    
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC(*this);
-    
-    //<qmail> changed iSmtpService to pointer
-    CIpsPlgCreateForwardMessageOperation* op = CIpsPlgCreateForwardMessageOperation::NewL( 
-        *iSmtpService, 
-        *iSession,
-        watcher->iStatus,
-        partList, 
-        aMailBoxId, 
-        orgMsg.Id(), 
-        aOperationObserver, 
-        aRequestId );
-    //</qmail>
-    watcher->SetOperation( op );
-
-    iOperations.AppendL( watcher ); 
-    CleanupStack::Pop( watcher );
+    if ( aHeaderDescriptor != KNullDesC )
+        {
+        // Ignoring trap as it is better to provide something in case of the
+        // below fix method fails than nothing.
+        TRAP_IGNORE( FixReplyForwardHeaderL( 
+                        msg, 
+                        aMailBoxId, 
+                        aOriginalMessageId, 
+                        aHeaderDescriptor ) );
+        }
+  
+    return msg;
     }
-// </qmail> 
 
 // ----------------------------------------------------------------------------
-// ---------------------------------------------------------------------------- 	
-CFSMailMessage* CIpsPlgSosBasePlugin::CreateReplyMessageL( 
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aOriginalMessageId*/,
-    const TBool /*aReplyToAll*/,
-    const TDesC& /*aHeaderDescriptor*/ )
-    {
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-    return NULL; // prevents compiler warning
-    }
-
-// <qmail>
 // ----------------------------------------------------------------------------
-// ---------------------------------------------------------------------------- 	
-void CIpsPlgSosBasePlugin::CreateReplyMessageL( 
+CFSMailMessage* CIpsPlgSosBasePlugin::CreateReplyMessageL(
     const TFSMailMsgId& aMailBoxId,
     const TFSMailMsgId& aOriginalMessageId,
     const TBool aReplyToAll,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId,
-    const TDesC& /* aHeaderDescriptor */ )
+    const TDesC& aHeaderDescriptor )
     {
     FUNC_LOG;
-    // asynchronous message creation is started here to enable canceling of the operation
-    
-    // find orginal message header and check that body is fetched
-    TMsvEntry orgMsg;
-    TMsvId service;
-    User::LeaveIfError( 
-        iSession->GetEntry( aOriginalMessageId.Id(), service, orgMsg ) );
-    
-    if ( orgMsg.Id() ==  KMsvNullIndexEntryIdValue )
+    CFSMailMessage* msg = iSmtpService->CreateReplySmtpMessageL(
+        aMailBoxId, aOriginalMessageId, aReplyToAll );
+
+    if ( aHeaderDescriptor != KNullDesC )
         {
-        User::Leave(KErrNotFound);
-        }
-    
-    if ( ( orgMsg.Parent() == KMsvSentEntryIdValue ) && 
-         ( orgMsg.iMtm == KSenduiMtmSmtpUid ) )
-        {
-        iSmtpService->ChangeServiceIdL( orgMsg );
+        // Ignoring trap as it is better to provide something in case of the
+        // below fix method fails than nothing.
+        TRAP_IGNORE( FixReplyForwardHeaderL( 
+                                msg, 
+                                aMailBoxId, 
+                                aOriginalMessageId, 
+                                aHeaderDescriptor ) );
         }
-    
-    // partList flags control e.g. what kind of recipient set is created
-    TMsvPartList partList = KMsvMessagePartBody | KMsvMessagePartDescription
-    | KMsvMessagePartOriginator;        
-    if( aReplyToAll )
-        {
-        partList |= KMsvMessagePartRecipient;
-        }
-    
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC(*this);
-    
-    //<qmail> changed iSmtpService to pointer
-    CIpsPlgCreateReplyMessageOperation* op = CIpsPlgCreateReplyMessageOperation::NewL( 
-        *iSmtpService, 
-        *iSession,
-        watcher->iStatus,
-        partList, 
-        aMailBoxId, 
-        orgMsg.Id(), 
-        aOperationObserver, 
-        aRequestId );
-    //</qmail>
-    watcher->SetOperation( op );
 
-    iOperations.AppendL( watcher ); 
-    CleanupStack::Pop( watcher );
+    return msg;
     }
-// </qmail>
 
 // ----------------------------------------------------------------------------
-// ---------------------------------------------------------------------------- 	
-//	
-void CIpsPlgSosBasePlugin::StoreMessageL( 
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::StoreMessageL(
     const TFSMailMsgId& aMailBoxId,
     CFSMailMessage& aMessage )
  	{
@@ -1028,12 +924,14 @@
 
     if ( incoming )
         {
-		// <qmail> Cmail change to synchronous call (UpdateMessageFlagsL) ignored,
-        // <qmail> because it causes emulator & HW to freeze on 10.1
-        CIpsPlgSingleOpWatcher* opW = CIpsPlgSingleOpWatcher::NewLC( *this );
-        CMsvOperation* op = iMsgMapper->UpdateMessageFlagsAsyncL( 
+        // It`s commented because when it`s used heavile cause -16 error
+        // For example when user want to mark as read/unread many messages
+        // Synchronous method solves this issue
+        iMsgMapper->UpdateMessageFlagsL(msgId.Id(), aMessage);
+        /*CIpsPlgSingleOpWatcher* opW = CIpsPlgSingleOpWatcher::NewLC( *this );
+        CMsvOperation* op = iMsgMapper->UpdateMessageFlagsAsyncL(
                 msgId.Id(), aMessage, opW->iStatus );
-        
+
         if ( op )
             {
             opW->SetOperation( op );
@@ -1043,7 +941,7 @@
         else
             {
             CleanupStack::PopAndDestroy( opW );
-            }
+            }*/
         }
     else
         {
@@ -1051,37 +949,6 @@
         }
     }
 
-// <qmail>
-/**
- *
- * @param aMailBoxId Mailbox id.
- * @param aOperationObserver Operation observer.
- * @param aRequestId The request id.
- */
-void CIpsPlgSosBasePlugin::StoreMessagesL(
-    const TFSMailMsgId& /*aMailBox*/,
-    RPointerArray<CFSMailMessage> &messages,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId )
-    
-    {
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
-    CleanupStack::PushL(watcher);
-    CIpsPlgMailStorerOperation* op = 
-            CIpsPlgMailStorerOperation::NewLC(
-                    *iSession,
-                    watcher->iStatus,
-                    *this, 
-                    messages, 
-                    aOperationObserver, 
-                    aRequestId );
-    
-    watcher->SetOperation(op);
-    iOperations.AppendL(watcher);
-    CleanupStack::Pop( 2, watcher );
-    }
-// </qmail>
-
 // ----------------------------------------------------------------------------
 // CIpsPlgSosBasePlugin::GetMessagesL()
 // ----------------------------------------------------------------------------
@@ -1140,64 +1007,275 @@
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 CFSMailMessagePart* CIpsPlgSosBasePlugin::NewChildPartFromFileL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aParentFolderId*/,
-    const TFSMailMsgId& /*aMessageId*/,
-    const TFSMailMsgId& /*aParentPartId*/,
-    const TDesC& /*aContentType*/,
-    const TDesC& /*aFilePath*/ )
-    {
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-    return NULL; // prevents compiler warning
-    }
-
-// <qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------  
-void CIpsPlgSosBasePlugin::NewChildPartFromFileL(
     const TFSMailMsgId& aMailBoxId,
     const TFSMailMsgId& /* aParentFolderId */,
     const TFSMailMsgId& aMessageId,
     const TFSMailMsgId& /* aParentPartId */,
     const TDesC& aContentType,
-    const TDesC& aFilePath,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId )
+    const TDesC& aFilePath )
     {
     FUNC_LOG;
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC(*this);
-    
-    CIpsPlgNewChildPartFromFileOperation* op = CIpsPlgNewChildPartFromFileOperation::NewL(
-        *iSession, 
-        watcher->iStatus,
-        aMailBoxId,
-        aMessageId,
-        aContentType,
-        aFilePath,
-        aOperationObserver, 
-        aRequestId,
-        iMsgMapper);
-    watcher->SetOperation( op );
+    CFSMailMessagePart* result ( NULL );
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+    RFile file;
+    TInt fileSize( 0 );
+    TBool parentToMultipartAlternative( EFalse );
+
+    // Read attachment size
+    User::LeaveIfError( file.Open( iSession->FileSession(), aFilePath, EFileShareReadersOnly ) );
+
+    //in rare case that file has disappeared while sending
+    //we just won't get the size for it
+    file.Size( fileSize );
+    file.Close();
+
+  // Take ownership of message entry objects since thanks to
+    // "clever" use of active scheduler waits we can re-enter 
+    // this function leading to crashes if somebody clears the cache
+    // while this iteration still needs them
+    TakeMessageEntryLC( aMessageId.Id(), cEntry, message );
+	
+    // Operation waiter needed to implement synchronous operation
+    // on the top of async API
+    CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+    CleanupStack::PushL( waiter );
+
+    // Initialize CMsvAttachment instance for the attachment creation
+    CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
+    CleanupStack::PushL( info );
+    info->SetAttachmentNameL( aFilePath );
+    info->SetSize( fileSize );
+
+    // Start attachment creation
+    message->AttachmentManager().AddAttachmentL(
+        aFilePath, info, waiter->iStatus );
+    CleanupStack::Pop( info ); // attachment manager takes ownership
+
+    waiter->Start();
+    CleanupStack::PopAndDestroy( waiter );
+    	
+    // Return message entry objects back to cache
+    CleanupStack::Pop( 2 ); // cEntry, message
+    ReturnMessageEntry( cEntry, message );
+
+    // Dig out the entry ID of the new attachment (unbelievable that
+    // there seems to be no better way to do this)
+    message->GetAttachmentsListL( cEntry->Entry().Id( ),
+        CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly );
+    TKeyArrayFix key( 0, ECmpTInt32 );
+    CMsvEntrySelection* attachmentIds = message->Selection().CopyLC();
+    attachmentIds->Sort( key );
+    if ( !attachmentIds->Count() )
+        {
+        User::Leave( KErrGeneral );
+        }
+    TMsvId newAttachmentId = (*attachmentIds)[ attachmentIds->Count()-1 ];
+    CleanupStack::PopAndDestroy( attachmentIds );
+
+    CMsvEntry* cAtta = iSession->GetEntryL( newAttachmentId );
+    CleanupStack::PushL( cAtta );
 
-    iOperations.AppendL( watcher ); 
-    CleanupStack::Pop( watcher );
+    // Set filename to iDetails
+    TMsvEntry tEntry = cAtta->Entry();
+    tEntry.iDetails.Set( aFilePath );
+    cAtta->ChangeL( tEntry );
+
+    if( cAtta->HasStoreL() )
+        {
+        CMsvStore* store = cAtta->EditStoreL();
+        CleanupStack::PushL( store );
+        CImMimeHeader* mimeHeader = CImMimeHeader::NewLC();
+
+        if( store->IsPresentL( KUidMsgFileMimeHeader ) )
+            {
+            mimeHeader->RestoreL( *store );
+            CDesC8Array& array = mimeHeader->ContentTypeParams();
+            array.AppendL( KMethod );
+            parentToMultipartAlternative = ETrue;
+
+            if( aContentType.Find( KMimeTextCalRequest ) != KErrNotFound )
+                {
+                array.AppendL( KRequest );
+                }
+            else if( aContentType.Find( KMimeTextCalResponse ) != KErrNotFound )
+                {
+                array.AppendL( KResponse );
+                }
+            else if( aContentType.Find( KMimeTextCalCancel ) != KErrNotFound )
+                {
+                array.AppendL( KCancel );
+                }
+            else
+                {
+                parentToMultipartAlternative = EFalse;
+                }
+            mimeHeader->StoreWithoutCommitL( *store );
+            store->CommitL();
+            }
+
+        CleanupStack::PopAndDestroy( 2, store );
+        }
+
+    if( parentToMultipartAlternative &&
+        aFilePath.Find( _L(".ics")) != KErrNotFound )
+        {
+        TMsvEntry tAttaEntry = cAtta->Entry();
+        TMsvId id = tAttaEntry.Parent();
+        CMsvEntry* cParent = iSession->GetEntryL( id );
+        CleanupStack::PushL( cParent );
+
+        TMsvEmailEntry tEntry = cParent->Entry();
+        tEntry.SetMessageFolderType( EFolderTypeAlternative );
+        cParent->ChangeL( tEntry );
+
+        CleanupStack::PopAndDestroy( cParent );
+        }
+    CleanupStack::PopAndDestroy( cAtta );
+
+    // Delete the message entries to get all the changes to disk and
+    // possible store locks released
+    CleanCachedMessageEntries();
+
+    // Create the FS message part object
+    result = iMsgMapper->GetMessagePartL( newAttachmentId, aMailBoxId,
+        aMessageId );
+
+    return result;
     }
-// </qmail> 
 
 // ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------  
+// ----------------------------------------------------------------------------
 CFSMailMessagePart* CIpsPlgSosBasePlugin::NewChildPartFromFileL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aParentFolderId*/,
-    const TFSMailMsgId& /*aMessageId*/,
-    const TFSMailMsgId& /*aParentPartId*/,
-    const TDesC& /*aContentType*/,
-    RFile& /*aFile*/ )
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& /* aParentPartId */,
+    const TDesC& aContentType,
+    RFile& aFile )
     {
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-    return NULL; // prevents compiler warning
+    FUNC_LOG;
+
+    // Initialize helper variables
+    CFSMailMessagePart* result ( NULL );
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+    TInt fileSize( 0 );
+    TBuf<KMaxFileName> fileName;
+
+ // Take ownership of message entry objects since thanks to
+    // "clever" use of active scheduler waits we can re-enter 
+    // this function leading to crashes if somebody clears the cache
+    // while this iteration still needs them
+    TakeMessageEntryLC( aMessageId.Id(), cEntry, message );
+
+    // Operation waiter needed to implement synchronous operation
+    // on the top of async API
+    CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+    CleanupStack::PushL( waiter );
+
+    // Initialize CMsvAttachment instance for the attachment creation
+    CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
+    CleanupStack::PushL( info );
+
+    // Read attachment size
+    User::LeaveIfError( aFile.Size( fileSize ) );
+    info->SetSize( fileSize );
+
+    // Read attachment filename
+    User::LeaveIfError( aFile.FullName( fileName ) );
+    info->SetAttachmentNameL( fileName );
+
+    message->AttachmentManager().AddAttachmentL( aFile, info, waiter->iStatus );
+    CleanupStack::Pop( info ); // attachment manager takes ownership
+    
+    waiter->Start();
+    CleanupStack::PopAndDestroy( waiter );
+
+ 	// Return message entry objects back to cache
+ 	CleanupStack::Pop( 2 ); // cEntry, message
+ 	ReturnMessageEntry( cEntry, message );
+
+    // Dig out the entry ID of the new attachment
+    message->GetAttachmentsListL( cEntry->Entry().Id( ),
+        CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly );
+    TKeyArrayFix key( 0, ECmpTInt32 );
+    CMsvEntrySelection* attachmentIds = message->Selection().CopyLC();
+    attachmentIds->Sort( key );
+    if ( !attachmentIds->Count() )
+        {
+        User::Leave( KErrGeneral );
+        }
+    TMsvId newAttachmentId = (*attachmentIds)[ attachmentIds->Count()-1 ];
+    CleanupStack::PopAndDestroy( attachmentIds );
+
+    // Meeting request related handling
+    TBool parentToMultipartAlternative( EFalse );
+    CMsvEntry* cAtta = iSession->GetEntryL( newAttachmentId );
+    CleanupStack::PushL( cAtta );
+
+    // Set filename to iDetails
+    TMsvEntry tEntry = cAtta->Entry();
+    tEntry.iDetails.Set( fileName );
+    cAtta->ChangeL( tEntry );
+
+    if( cAtta->HasStoreL() )
+        {
+        CMsvStore* store = cAtta->EditStoreL();
+        CleanupStack::PushL( store );
+        CImMimeHeader* mimeHeader = CImMimeHeader::NewLC();
+
+        if( store->IsPresentL( KUidMsgFileMimeHeader ) )
+            {
+            mimeHeader->RestoreL( *store );
+            CDesC8Array& array = mimeHeader->ContentTypeParams();
+            array.AppendL( KMethod );
+            parentToMultipartAlternative = ETrue;
+
+            if( aContentType.Find( KMimeTextCalRequest ) != KErrNotFound )
+                {
+                array.AppendL( KRequest );
+                }
+            else if( aContentType.Find( KMimeTextCalResponse ) != KErrNotFound )
+                {
+                array.AppendL( KResponse );
+                }
+            else if( aContentType.Find( KMimeTextCalCancel ) != KErrNotFound )
+                {
+                array.AppendL( KCancel );
+                }
+            else
+                {
+                parentToMultipartAlternative = EFalse;
+                }
+            mimeHeader->StoreWithoutCommitL( *store );
+            store->CommitL();
+            }
+        CleanupStack::PopAndDestroy( 2, store );
+        }
+    if( parentToMultipartAlternative && fileName.Find( _L(".ics")) != KErrNotFound )
+        {
+        TMsvEntry tAttaEntry = cAtta->Entry();
+        TMsvId id = tAttaEntry.Parent();
+        CMsvEntry* cParent = iSession->GetEntryL( id );
+        CleanupStack::PushL( cParent );
+
+        TMsvEmailEntry tEntry = cParent->Entry();
+        tEntry.SetMessageFolderType( EFolderTypeAlternative );
+        cParent->ChangeL( tEntry );
+
+        CleanupStack::PopAndDestroy( cParent );
+        }
+    CleanupStack::PopAndDestroy( cAtta );
+
+    // Delete the message entries to get all the changes to disk and
+    // possible store locks released
+    CleanCachedMessageEntries();
+
+    // Create the FS message part object and return it
+    result = iMsgMapper->GetMessagePartL( newAttachmentId, aMailBoxId,
+        aMessageId );
+    return result;
     }
 
 // ----------------------------------------------------------------------------
@@ -1219,48 +1297,56 @@
 // ----------------------------------------------------------------------------
 //
 void CIpsPlgSosBasePlugin::RemoveChildPartL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aParentFolderId*/,
-    const TFSMailMsgId& /*aMessageId*/,
-    const TFSMailMsgId& /*aParentPartId*/,
-    const TFSMailMsgId& /*aPartId*/)
-	{
-    // <qmail> not used any more
-    User::Leave(KErrFSMailPluginNotSupported);
-	}
-
-// <qmail>
-// ----------------------------------------------------------------------------
-// Supports currently deletion of attachments and multipart structures 
-// which are represented as folders in Symbian store)
-// ----------------------------------------------------------------------------  
-//
-void CIpsPlgSosBasePlugin::RemoveChildPartL(
     const TFSMailMsgId& /* aMailBoxId */,
     const TFSMailMsgId& /* aParentFolderId */,
     const TFSMailMsgId& aMessageId,
     const TFSMailMsgId& /* aParentPartId */,
-    const TFSMailMsgId& aPartId,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId )
-    {
+    const TFSMailMsgId& aPartId)
+	{
     FUNC_LOG;
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC(*this);
-    
-    CIpsPlgRemoveChildPartOperation* op = CIpsPlgRemoveChildPartOperation::NewL(
-        *iSession, 
-        watcher->iStatus,
-        aMessageId,
-        aPartId,
-        aOperationObserver, 
-        aRequestId);
-    watcher->SetOperation( op );
+    TInt status( KErrNone );
+    CMsvEntry* cEntry( NULL );
+    TMsvEntry tEntry;
+    TMsvId serviceId;
+    status = iSession->GetEntry( aPartId.Id(), serviceId, tEntry );
+
+    if ( ( status == KErrNone ) &&
+         ( tEntry.iType == KUidMsvAttachmentEntry ) )
+        {
+        CImEmailMessage* message( NULL );
+  
+        // We trust that the message ID really refers to a message
+        
+        // Take ownership of message entry objects since thanks to
+        // "clever" use of active scheduler waits we can re-enter 
+        // this function leading to crashes if somebody clears the cache
+        // while this iteration still needs them
+        TakeMessageEntryLC( aMessageId.Id(), cEntry, message );
+
+        MMsvAttachmentManager& attachmentMgr( message->AttachmentManager() );
 
-    iOperations.AppendL( watcher ); 
-    CleanupStack::Pop( watcher );
+        CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+        CleanupStack::PushL( waiter );
+
+        attachmentMgr.RemoveAttachmentL(
+            (TMsvAttachmentId) aPartId.Id(), waiter->iStatus );
 
-    }
-// </qmail>
+        waiter->Start();
+        CleanupStack::PopAndDestroy( waiter );
+        	
+        // Return message entry objects to cache
+        CleanupStack::Pop( 2 ); // cEntry, message
+        ReturnMessageEntry( cEntry, message );
+        }
+    else if ( ( status == KErrNone ) &&
+              ( tEntry.iType == KUidMsvFolderEntry ) )
+        {
+        cEntry = iSession->GetEntryL( tEntry.Parent() );
+        CleanupStack::PushL( cEntry );
+        cEntry->DeleteL( tEntry.Id() );
+        CleanupStack::PopAndDestroy( cEntry );
+        }
+	}
 
 // ----------------------------------------------------------------------------
 // The implementation supoorts the atachment and body parts at the moment.
@@ -1283,9 +1369,8 @@
 // The implementation bypass CImEmailMessage and its email's attachment
 // manager. Instead, it calls Symbian framework classes directly by
 // accessing the attachment entry.
-// Qmail change: returns file handle for read/write
-// ----------------------------------------------------------------------------  
-TInt CIpsPlgSosBasePlugin::GetMessagePartFileL(  
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::GetMessagePartFileL(
     const TFSMailMsgId& /* aMailBoxId */,
     const TFSMailMsgId& /* aParentFolderId */,
     const TFSMailMsgId& /* aMessageId */,
@@ -1300,12 +1385,7 @@
     TBool hasStore = cEntry->HasStoreL();
     if ( hasStore )
         {
-//<qmail>
-        // We need to open store for edit to support multipart/alternative
-        // structure: we must have a possibility to modify text/html message part
-        //store = cEntry->ReadStoreL();
-        store = cEntry->EditStoreL();
-//</qmail>
+        store = cEntry->ReadStoreL();
         }
 
     if ( !store || !hasStore )
@@ -1318,12 +1398,7 @@
     // It is assumed that the attachment file is always in the index 0
     if ( attachmentMgr.AttachmentCount() )
         {
-//<qmail>
-        // We need to open store for edit to support multipart/alternative
-        // structure: we must have a possibility to modify text/html message part
-        //aFileHandle = attachmentMgr.GetAttachmentFileL( 0 );
-        aFileHandle = attachmentMgr.GetAttachmentFileForWriteL( 0 );
-//</qmail>
+        aFileHandle = attachmentMgr.GetAttachmentFileL( 0 );
         }
     else
         {
@@ -1345,7 +1420,6 @@
     const TDesC& aFilePath)
 	{
     FUNC_LOG;
-    //<qmail>
     CMsvEntry* cEntry = iSession->GetEntryL( aMessagePartId.Id() );
     CleanupStack::PushL( cEntry );
     CMsvStore* store = NULL;
@@ -1378,7 +1452,6 @@
         }
     CleanupStack::PopAndDestroy( store );
     CleanupStack::PopAndDestroy( cEntry );
-    //</qmail>
 	}
 
 // ----------------------------------------------------------------------------
@@ -1437,51 +1510,112 @@
     const TDesC& aBuffer,
     const TFSMailMsgId& /* aMailBoxId */,
     const TFSMailMsgId& /* aParentFolderId */,
-    const TFSMailMsgId& /* aMessageId */,
+    const TFSMailMsgId& aMessageId,
     const TFSMailMsgId& aMessagePartId )
 	{
     FUNC_LOG;
-    
-//<qmail> Rewritten in Qmail: CIpsPlgOperationWait is no longer used 
-    // Notice that SetContentL sets only the content of text/plain message part:
-    // text/html part can be modified directly using GetMessagePartFileL
-	CMsvEntry* cEntry( NULL );
-    CMsvStore* store = NULL;
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+
+    // Take ownership of message entry objects since thanks to
+    // "clever" use of active scheduler waits we can re-enter 
+    // this function leading to crashes if somebody clears the cache
+    // while this iteration still needs them
+    TakeMessageEntryLC( aMessageId.Id(), cEntry, message );
     
-    // following code should fill text/plain content
-    cEntry = iSession->GetEntryL( aMessagePartId.Id() );
-    CleanupStack::PushL( cEntry );
-    TBool hasStore = cEntry->HasStoreL();
-    if ( hasStore ) {
-        store = cEntry->EditStoreL();
-        CleanupStack::PushL(store);
-        CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL();
-        CleanupStack::PushL(globalParaLayer);
-        CCharFormatLayer* globalCharLayer = CCharFormatLayer::NewL();
-        CleanupStack::PushL(globalCharLayer);
-        CRichText* text = CRichText::NewL( globalParaLayer, globalCharLayer );
-        CleanupStack::PushL( text );
-        // insert text
-        text->InsertL(0, aBuffer );
-        store->StoreBodyTextL(*text);
-        store->CommitL();
-        CleanupStack::PopAndDestroy( 4, store );
-    }
-    CleanupStack::PopAndDestroy(cEntry);
-//</qmail>
+	if ( message )
+	    {
+
+	    message->GetBodyTextEntryIdL(
+	    		cEntry->Entry().Id(), CImEmailMessage::EThisMessageOnly );
+	    if ( message->Selection().Count() > 0 )
+	    	{
+	    	TMsvId dummy;
+	    	TMsvEmailEntry newEmailMsg;
+	    	iSession->GetEntry( aMessageId.Id(), dummy, newEmailMsg );
+	    	TMsvId parent = newEmailMsg.Parent();
+
+	    	if ( message->Selection()[0] == aMessagePartId.Id() ||
+	    		 newEmailMsg.ICalendar() )
+	    		{
+	    		CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( );
+	    		CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL();
+	    		CleanupStack::PushL(globalParaLayer);
+	    		CCharFormatLayer* globalCharLayer = CCharFormatLayer::NewL();
+	    		CleanupStack::PushL(globalCharLayer);
+	    		CRichText* text = CRichText::NewL( globalParaLayer, globalCharLayer );
+	    		CleanupStack::PushL( text );
+	    		// insert text
+	    		text->InsertL(0, aBuffer );
+	    		// synchronously
+	    		message->StoreBodyTextL(
+	    				cEntry->Entry().Id(), *text ,wait->iStatus );
+	    		wait->Start();
+	    		CleanupStack::PopAndDestroy( 4, wait );
+	    		}
+	    	}
+	    }
+	
+	// Return message entry objects to cache
+	CleanupStack::Pop( 2 ); // cEntry, message
+	ReturnMessageEntry( cEntry, message );
 	}
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 void CIpsPlgSosBasePlugin::RemovePartContentL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aParentFolderId*/,
-    const TFSMailMsgId& /*aMessageId*/,
-    const RArray<TFSMailMsgId>& /*aPartIds*/ )
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    const RArray<TFSMailMsgId>& aPartIds )
     {
-    // <qmail>
-    User::Leave( KErrFSMailPluginNotSupported );
-    // </qmail>
+    TInt count( aPartIds.Count() );
+
+    for( TInt i(0); i < count; i++ )
+        {
+        CMsvEntry* cEntry = iSession->GetEntryL( aPartIds[i].Id() );
+        CleanupStack::PushL( cEntry );
+        CMsvStore* store = NULL;
+        TBool hasStore = cEntry->HasStoreL();
+        if ( hasStore )
+            {
+            store = cEntry->EditStoreL();
+            }
+
+        if ( !store || !hasStore )
+            {
+            User::Leave( KErrNotFound );
+            }
+        CleanupStack::PushL( store );
+        MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+
+        // It is assumed that the attachment file is always in the index 0
+        if ( attachmentMgr.AttachmentCount() )
+            {
+            // delete attachment file
+            CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewLC();
+            attachmentMgr.RemoveAttachmentL( 0, waiter->iStatus );
+            waiter->Start();
+            CleanupStack::PopAndDestroy( waiter );
+            store->CommitL();
+
+            // clear complete flag
+            TMsvEntry tEntry( cEntry->Entry() );
+            tEntry.SetComplete( EFalse );
+
+            waiter = CIpsPlgOperationWait::NewLC();
+            CMsvOperation* ops = cEntry->ChangeL( tEntry, waiter->iStatus );
+            CleanupStack::PushL( ops );
+            waiter->Start();
+            CleanupStack::PopAndDestroy( 2, waiter );
+            }
+        else
+            {
+            User::Leave( KErrNotFound );
+            }
+        CleanupStack::PopAndDestroy( store );
+        CleanupStack::PopAndDestroy( cEntry );
+        }
     }
 
 // ----------------------------------------------------------------------------
@@ -1505,29 +1639,8 @@
     {
     }
 
-//<qmail>
 // ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------     
-void CIpsPlgSosBasePlugin::StoreMessagePartsL(
-    RPointerArray<CFSMailMessagePart>&  aMessageParts,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId )
-    {
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
-    CleanupStack::PushL(watcher);
-    CIpsPlgMessagePartStorerOperation* op =
-            CIpsPlgMessagePartStorerOperation::NewLC(*iSession,
-                    watcher->iStatus, *this, aMessageParts,
-                    aOperationObserver, aRequestId);
-    
-    watcher->SetOperation(op);
-    iOperations.AppendL(watcher);
-    CleanupStack::Pop( 2, watcher );    
-    }
-//<//qmail>
-
 // ----------------------------------------------------------------------------
-// ---------------------------------------------------------------------------- 	
 void CIpsPlgSosBasePlugin::UnregisterRequestObserver( TInt /* aRequestId */)
     {
     }
@@ -1539,10 +1652,8 @@
     FUNC_LOG;
  	CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
  	CleanupStack::PushL(watcher);
-// <qmail>
     CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewLC(
-        *iSession, watcher->iStatus );
-// </qmail>
+        *iSession, CActive::EPriorityStandard, watcher->iStatus, ETrue );
     op->SetEventHandler(iEventHandler);
     watcher->SetOperation(op);
     CleanupStack::Pop( op ); // op added as member of watcher
@@ -1551,54 +1662,24 @@
     CleanupStack::Pop( watcher );
  	}
 
-   
+// ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
-// ---------------------------------------------------------------------------- 	
-void CIpsPlgSosBasePlugin::SendMessageL( CFSMailMessage& /*aMessage*/ )
+void CIpsPlgSosBasePlugin::SendMessageL( CFSMailMessage& aMessage )
     {
     FUNC_LOG;
-    // <qmail>
-    User::Leave( KErrFSMailPluginNotSupported );
-    // </qmail>
-    }
-
-// <qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::SendMessageL(
-        CFSMailMessage& aMessage,
-        MFSMailRequestObserver& aOperationObserver,
-        const TInt aRequestId )
-    {
-    FUNC_LOG;
-    // <qmail> Not activated yet
     // is EFSMsgFlag_CalendarMsg enabled,
     // then move send to back ground process
-    //if ( aMessage.GetFlags() & EFSMsgFlag_CalendarMsg )
-    //    {
-    //    iEventHandler->SetNewPropertyEvent(
-    //            aMessage.GetMessageId().Id(),
-    //            KIPSSosSmtpEmptyOutboxNow, KErrNone );
-    //    }
-    //else
-    //    {
-        CIpsPlgSingleOpWatcher* watcher =
-            CIpsPlgSingleOpWatcher::NewLC(*this);
-
-        // <qmail> priority parameter has been removed
-        CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewL(
-            *iSession,
-            watcher->iStatus,
-            &aOperationObserver,
-            aRequestId );
-        watcher->SetOperation(op); // ownership is transferred
-        op->StartSendL( aMessage.GetMessageId().Id() );
-        iOperations.AppendL(watcher);
-        CleanupStack::Pop( watcher );
-    //    }
-    // </qmail>
+    if ( aMessage.GetFlags() & EFSMsgFlag_CalendarMsg )
+        {
+        iEventHandler->SetNewPropertyEvent(
+                aMessage.GetMessageId().Id(),
+                KIPSSosSmtpEmptyOutboxNow, KErrNone );
+        }
+    else
+        {
+        SendL( aMessage.GetMessageId() );
+        }
     }
-// </qmail>
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
@@ -1693,7 +1774,7 @@
 void CIpsPlgSosBasePlugin::DeleteMessagesByUidL(
     const TFSMailMsgId& /*aMailBoxId*/,
     const TFSMailMsgId& /*aFolderId*/,
-	const RArray<TFSMailMsgId>& aMessages )
+    const RArray<TFSMailMsgId>& aMessages )
     {
     FUNC_LOG;
     CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection;
@@ -1702,72 +1783,98 @@
     TInt count = aMessages.Count();
     TMsvEntry tEntry;
     TMsvId service;
+
+    TMsvEntry parentEntry;
     
-    for(TInt i=0; i<count; i++)
+    // simulation of canceling deletion operation
+    if ( !count ) 
+        {
+        if ( iMsvOpDeleteMessage )
+            {
+            iMsvOpDeleteMessage->Cancel();
+            }
+        
+        if ( iWaitDeleteMessage )
+            {
+            iWaitDeleteMessage->Cancel();
+            }
+        
+        delete iMsvOpDeleteMessage;
+        iMsvOpDeleteMessage = NULL;
+        delete iWaitDeleteMessage;
+        iWaitDeleteMessage = NULL;
+        delete icEntry;
+        icEntry = NULL;
+        }
+    else
         {
-        iSession->GetEntry( aMessages[i].Id(), service, tEntry );
-        //make sure that only messages get deleted.
-        if( tEntry.iType == KUidMsvMessageEntry )
-            {            
-			// <qmail>    
-            sel->AppendL( tEntry.Id() );
-			// </qmail>    
+        for( TInt i = 0; i < count; i++ )
+            {
+            iSession->GetEntry( aMessages[i].Id(), service, tEntry );
+            
+            //make sure that only messages get deleted.
+            if( tEntry.iType == KUidMsvMessageEntry )
+                {
+                if(iMsvOpDeleteMessage)
+                    {
+                    iMsvOpDeleteMessage->Cancel();
+                    delete iMsvOpDeleteMessage;
+                    iMsvOpDeleteMessage = NULL;
+                    }
+                
+                if ( iWaitDeleteMessage )
+                    {
+                    iWaitDeleteMessage->Cancel();
+                    delete iWaitDeleteMessage;
+                    iWaitDeleteMessage = NULL;
+                    }
+
+                delete icEntry;
+                icEntry = NULL;
+            
+                iSession->GetEntry( tEntry.Parent( ), service, parentEntry );
+
+                icEntry = CMsvEntry::NewL( 
+                        *iSession, tEntry.Id(), TMsvSelectionOrdering() );
+                
+                
+                // priority slightly increased not to pause the function longer than needed
+                iWaitDeleteMessage = CIpsPlgOperationWait::NewL( CActive::EPriorityStandard+1 );
+                // Sets bit 32 of iMtmData1, used when msg deleted in Offline
+                // and status hasn't updated to server (client entry still exists)
+                tEntry.SetLocallyDeleted( ETrue );
+                
+                iMsvOpDeleteMessage = icEntry->ChangeL( tEntry, 
+                        iWaitDeleteMessage->iStatus );
+                        
+                iWaitDeleteMessage->Start();
+                
+                sel->AppendL( tEntry.Id() );
+                }
+            }
+
+        CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewLC( *this );
+
+        CMsvOperation* op = CIpsPlgDeleteRemote::NewL( *iSession, 
+                watcher->iStatus, *sel );
+        watcher->SetOperation( op );
+
+        // make draft deletion synchronous so that empty drafts are not left after application close
+        if ( parentEntry.Id() == KMsvDraftEntryIdValue && count == 1 )
+            {
+            iWait.Start();
+            CleanupStack::PopAndDestroy( watcher );
+            }
+        else
+            {
+            iOperations.AppendL( watcher );
+            CleanupStack::Pop( watcher );
             }
         }
-        
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL( *this );
-    CleanupStack::PushL( watcher );
-    //<qmail>
-    CMsvOperation* op = CIpsPlgDeleteOperation::NewL( *iSession,
-        watcher->iStatus, sel );
-    //</qmail>
-    watcher->SetOperation( op );
-    iOperations.AppendL( watcher );
-    CleanupStack::Pop( watcher );
-    //<qmail>
-    CleanupStack::Pop( sel );
-    //</qmail>
+    
+    CleanupStack::PopAndDestroy( sel );
     }
 
-// <qmail>
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::DeleteMessagesByUidL(
-    const TFSMailMsgId& /*aMailBoxId*/,
-    const TFSMailMsgId& /*aFolderId*/,
-	const RArray<TFSMailMsgId>& aMessages,
-    MFSMailRequestObserver& aOperationObserver,
-    const TInt aRequestId)
-    {
-    FUNC_LOG;
-    CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection;
-    CleanupStack::PushL(sel);
-
-    TInt count = aMessages.Count();
-    TMsvEntry tEntry;
-    TMsvId service;
-    
-    for(TInt i=0; i<count; i++)
-        {
-        iSession->GetEntry( aMessages[i].Id(), service, tEntry );
-        //make sure that only messages get deleted.
-        if( tEntry.iType == KUidMsvMessageEntry )
-            {            
-            sel->AppendL( tEntry.Id() );
-            }
-        }
-        
-    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL( *this );
-    CleanupStack::PushL( watcher );
-    CMsvOperation* op = CIpsPlgDeleteOperation::NewL( *iSession,
-        watcher->iStatus, sel, aOperationObserver, aRequestId );
-    watcher->SetOperation( op );
-    iOperations.AppendL( watcher );
-    CleanupStack::Pop( watcher );
-    CleanupStack::Pop( sel );
-    }
-// </qmail>
-
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 void CIpsPlgSosBasePlugin::SubscribeMailboxEventsL(
@@ -1775,9 +1882,10 @@
     MFSMailEventObserver& aObserver)
     {
     FUNC_LOG;
-// <qmail>
-    TUint32 key(0);
-// </qmail>
+    TUint32 key = iSettingsApi->CreateCenRepKeyL(   // faulty CS warning
+        aMailboxId.Id(),
+        MtmId(),
+        CIpsSetDataStorer::EIpsSetDataLastModifiedH );
 
     iEventHandler->SubscribeMailboxEventsL( aMailboxId, aObserver, key );
     }
@@ -1807,15 +1915,13 @@
     {
     FUNC_LOG;
     TInt error = KErrNone;
-// <qmail> iSettingsApi not available in Qmail
-    /*error = iSettingsApi->HandleMailboxCreation( MtmId(), *iSession );
+    error = iSettingsApi->HandleMailboxCreation( MtmId(), *iSession );
     if ( error == KErrNotSupported )
         {
         // this means that wizard data is not meaned for this plugin (instance)
         // just return KErrNone at the moment
         return KErrNone;
-        }*/
-// </qmail>
+        }
     return error;
     }
 
@@ -1849,35 +1955,45 @@
 // ----------------------------------------------------------------------------
 // method sets authentication popup data
 // ----------------------------------------------------------------------------
-//
-void CIpsPlgSosBasePlugin::SetCredentialsL( const TFSMailMsgId& /*aMailBoxId*/,
-	const TDesC& /*aUsername*/, const TDesC& /*aPassword*/ )
+void CIpsPlgSosBasePlugin::SetCredentialsL( const TFSMailMsgId& aMailBoxId,
+	const TDesC& /*aUsername*/, const TDesC& aPassword )
 	{
-// <qmail> not used; should be removed
-//    FUNC_LOG;
-//	TBool cancelled = EFalse;
-//	
-//	if ( aPassword.Length() > 0 )
-//	    {
-//    	//Set new password and signal (possible) ongoing connect operation
-//    	//CIpsSetDataApi* api = CIpsSetDataApi::NewL( *iSession );
-//        //CleanupStack::PushL( api );
-//        
-//        //CMsvEntry* cEntry = iSession->GetEntryL( aMailBoxId.Id() );
-//        //CleanupStack::PushL( cEntry );
-//        
-//        //api->SetNewPasswordL( *cEntry, aPassword );
-//        
-//        //CleanupStack::PopAndDestroy( 2, api );//cEntry, api
-//        
-//        //now signal through eventhandler that credientials have been set       
-//	    }
-//	else
-//	    {
-//	    cancelled = ETrue;
-//	    }
-//	iEventHandler->SignalCredientialsSetL( aMailBoxId.Id(), cancelled );
-// </qmail>
+    FUNC_LOG;
+	TBool cancelled = EFalse;
+
+	if ( aPassword.Length() > 0 )
+	    {
+    	//Set new password and signal (possible) ongoing connect operation
+    	CIpsSetDataApi* api = CIpsSetDataApi::NewL( *iSession );
+        CleanupStack::PushL( api );
+
+        CMsvEntry* cEntry = iSession->GetEntryL( aMailBoxId.Id() );
+        CleanupStack::PushL( cEntry );
+
+        RProcess process;
+        // only email server can set outgoing password
+        if ( process.SecureId() == FREESTYLE_FSSERVER_SID )
+            {
+            if ( !iEventHandler->IncomingPass() )
+                {
+                CMsvEntry* cTmp = iSession->GetEntryL( cEntry->Entry().iRelatedId );
+                CleanupStack::PopAndDestroy( 1, cEntry );
+                CleanupStack::PushL( cTmp );
+                cEntry = cTmp;
+                }
+            }
+
+		api->SetNewPasswordL( *cEntry, aPassword );
+
+        CleanupStack::PopAndDestroy( 2, api );//cEntry, api
+
+        //now signal through eventhandler that credientials have been set
+	    }
+	else
+	    {
+	    cancelled = ETrue;
+	    }
+	iEventHandler->SignalCredientialsSetL( aMailBoxId.Id(), cancelled );
 	}
 
 // ----------------------------------------------------------------------------
@@ -2073,18 +2189,18 @@
     {
     FUNC_LOG;
     CIpsPlgSingleOpWatcher* opWatcher = iOperations[aOpArrayIndex];
-    
-// <qmail> removed; does nothing
+
     // The operations matches, handle it in protocol plugin...if needed.
-    //TRAP_IGNORE( HandleOpCompletedL( *opWatcher, aCompleteCode ) );
-// </qmail>
+    TRAP_IGNORE( HandleOpCompletedL( *opWatcher, aCompleteCode ) );
+
     const CIpsPlgBaseOperation* op = opWatcher->BaseOperation();
     TMsvId service = KErrNotFound;
     TUint pluginId = PluginId();
     if ( op && (
             op->IpsOpType() == EIpsOpTypeImap4SyncOp  ||
              op->IpsOpType() == EIpsOpTypePop3SyncOp ||
-             op->IpsOpType() == EIpsOpTypeImap4PopulateOp ) )
+             op->IpsOpType() == EIpsOpTypeImap4PopulateOp ||
+             op->IpsOpType() == EIpsOpTypePop3PopulateOp ) )
         {
         service = op->Service();
         }
@@ -2137,14 +2253,37 @@
                             textBodyPart->FetchedContentSize() );
                     TPtr bPtr( body->Des() );
                     origMsgTextBodyPart->GetContentToBufferL( bPtr, 0 );
-                    HBufC* content = HBufC::NewLC(
-                            hPtr.Length() + bPtr.Length() );
-                    TPtr cPtr( content->Des() );                        
+                    TInt contentLength = hPtr.Length() + bPtr.Length() + 
+                            KLineFeed().Length();
+                    HBufC* signatureText = NULL;
+                    // if signature resolving leaves, ignore it, i.e., 
+                    // continue without signature adding
+                    TRAP_IGNORE( signatureText = 
+                            ResolveSignatureTextL( aMailBoxId ) );
+                    if ( signatureText ) 
+                        {
+                        CleanupStack::PushL( signatureText );
+                        contentLength += signatureText->Length() +
+                                KLineFeed().Length();
+                        }
+                    HBufC* content = HBufC::NewLC( contentLength );
+                    TPtr cPtr( content->Des() );
+                    if ( signatureText )
+                        {
+                        cPtr.Append( *signatureText );
+                        // extra empty line between signature and original txt
+                        cPtr.Append( KLineFeed );
+                        }
+                    cPtr.Append( KLineFeed );
                     cPtr.Append( hPtr );
                     cPtr.Append( bPtr );
                     textBodyPart->SetContent( cPtr );
                     textBodyPart->SaveL();
                     CleanupStack::PopAndDestroy( content );
+                    if ( signatureText )
+                        {
+                        CleanupStack::PopAndDestroy( signatureText );
+                        }
                     CleanupStack::PopAndDestroy( body );
                     CleanupStack::PopAndDestroy( origMsgTextBodyPart );
                     }
@@ -2156,17 +2295,38 @@
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
+HBufC* CIpsPlgSosBasePlugin::ResolveSignatureTextL( 
+        const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    HBufC* signatureText = NULL;
+        
+    if ( iSettingsApi && iSession )
+        {
+        TMsvEntry entry;
+        TMsvId serv;
+        iSession->GetEntry( aMailBoxId.Id(), serv, entry );
+        signatureText = iSettingsApi->SignatureTextL( entry );
+        }
+
+    return signatureText;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
 void CIpsPlgSosBasePlugin::DisconnectL(
     const TFSMailMsgId& aMailBoxId,
     MFSMailRequestObserver& aObserver,
     const TInt aRequestId,
-    TBool /*aRemoveAccountAlso*/ )
+    TBool aRemoveAccountAlso )
     {
     FUNC_LOG;
     TMsvId service = aMailBoxId.Id();
     TMsvEntry tEntry;
     TMsvId serv;
     iSession->GetEntry( service, serv, tEntry );
+    
+    CancelSyncL( aMailBoxId );
 
     if ( tEntry.Connected() )
         {
@@ -2180,14 +2340,10 @@
 
         sel->AppendL( service );
 
-        CIpsPlgBaseOperation* op = CIpsPlgDisconnectOp::NewL(
-            *iSession,
-            watcher->iStatus, 
-            service, 
-            ActivityTimerL( aMailBoxId ),
-            aMailBoxId, 
-            &aObserver, 
-            aRequestId );
+        CIpsPlgBaseOperation* op = CIpsPlgDisconnectOp::NewL( *iSession,
+            watcher->iStatus, service, ActivityTimerL( aMailBoxId ),
+            aMailBoxId, aObserver, aRequestId,
+            aRemoveAccountAlso );
 
         watcher->SetOperation( op );
         CleanupStack::PopAndDestroy( sel );
@@ -2228,9 +2384,8 @@
     FUNC_LOG;
     CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
  	CleanupStack::PushL(watcher);
-// <qmail>
-    CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewLC( *iSession, watcher->iStatus );
-// </qmail>
+    CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewLC(
+        *iSession, CActive::EPriorityStandard, watcher->iStatus, ETrue );
     op->SetEventHandler(iEventHandler);
     watcher->SetOperation(op);
     op->EmptyOutboxFromPendingMessagesL( aMailBoxId.Id() );
@@ -2416,15 +2571,15 @@
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
-void CIpsPlgSosBasePlugin::SetMailboxName( 
-        const TFSMailMsgId& aMailboxId, 
-        const TDesC& /*aMailboxName*/ )
+void CIpsPlgSosBasePlugin::SetMailboxName(
+        const TFSMailMsgId& aMailboxId,
+        const TDesC& aMailboxName )
     {
     FUNC_LOG;
     TMsvEntry tEntry;
     TMsvId service;
     iSession->GetEntry( aMailboxId.Id(), service, tEntry );
-// <qmail> iSettingsApi removed
+    TRAP_IGNORE( iSettingsApi->SetMailboxNameL( tEntry, aMailboxName ) );
     }
 
 // ---------------------------------------------------------------------------
@@ -2465,71 +2620,24 @@
             }
         }
     }
-
-// <qmail> new function
 // ---------------------------------------------------------------------------
-// ---------------------------------------------------------------------------
-TBool CIpsPlgSosBasePlugin::HasOperations( const TFSMailMsgId& aMailboxId )
-    {
-    FUNC_LOG;
-    TBool ret( EFalse );
-    for ( TInt i = 0; i < iOperations.Count(); i++ )
-        {
-        if( iOperations[i]->BaseOperation() && 
-            iOperations[i]->BaseOperation()->FSMailboxId() == aMailboxId )
-            {
-            ret = ETrue;
-            }
-        }
-    return ret;
-    }
-//</Qmail>
-//<Qmail>
-// ---------------------------------------------------------------------------
-// CIpsPlgImap4Plugin::HandleActiveFolderChangeL
+// finds and returns extension
 // ---------------------------------------------------------------------------
 //
-void CIpsPlgSosBasePlugin::HandleActiveFolderChangeL(
-        const TFSMailMsgId& aActiveMailboxId,
-        const TFSMailMsgId& aActiveFolderId)
+CEmailExtension* CIpsPlgSosBasePlugin::ExtensionL( const TUid& aInterfaceUid )
     {
-    TMsvId service;
-    TMsvEntry folder;
-    iSession->GetEntry( aActiveFolderId.Id(), service, folder );
+    FUNC_LOG;
     
+    // search for settings extension
+    CEmailExtension* extension = CExtendableEmail::ExtensionL( aInterfaceUid );
     
-    //currently, no actions unless this is inbox
-    //also, if id is '0', it means inbox before first sync...it doesn't really exist yet
-    if( folder.iDetails.CompareF( KIpsPlgInbox ) == 0 || folder.Id() == 0 || 
-            ( folder.iMtm == KSenduiMtmPop3Uid ) &&
-            ( folder.iType == KUidMsvServiceEntry ) &&
-            ( folder.iServiceId == aActiveFolderId.Id() ) )
+    // if not found create settings extension
+    if ( extension == NULL && aInterfaceUid == KEmailSettingExtensionUid)
         {
-        //folder is inbox
-        if ( iSyncStateHandler->GetMailboxIpsState( aActiveMailboxId.Id() )
-                    == KIpsSosEmailSyncStarted )
-            {
-            //we won't do anything if sync is already started
-            return;
-            }
-        
-        //check are we in polling mode
-        NmIpsSosExtendedSettingsManager* eMgr= 
-                new NmIpsSosExtendedSettingsManager(aActiveMailboxId.Id());
-        
-        QVariant value;
-        bool ok = eMgr->readSetting(IpsServices::ReceptionActiveProfile, value);
-        delete eMgr;
-        
-        if ( ok )
-            {
-            TInt profile = value.toInt();
-            if ( profile != IpsServices::EmailSyncProfileManualFetch )
-                {
-                // let's sync
-                GoOnlineL(aActiveMailboxId);
-                }
-            }        
-        }        
+        extension = new (ELeave) CEmailSettingsExtensionImpl(iSession);
+        CleanupStack::PushL( extension );
+        iExtensions.AddL( extension );
+        CleanupStack::Pop(); 
+        }
+    return extension;
     }
-// </qmail>