ipsservices/ipssosplugin/src/ipsplgsosbaseplugin.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
child 18 578830873419
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosplugin/src/ipsplgsosbaseplugin.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,2318 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This file implements classes CIpsPlgSosBasePlugin, Plugin.
+ *
+*/
+
+
+
+#include "emailtrace.h"
+#include "ipsplgheaders.h"
+
+#define FREESTYLE_EMAIL_UI_SID 0x2001E277
+
+const TInt KOpGranularity = 2;
+
+_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" );
+
+#ifdef __WINS__
+_LIT( KEmulatorIMEI, "123456789012345" );
+#endif // __WINS__
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+CIpsPlgSosBasePlugin::CIpsPlgSosBasePlugin( const TUint aFSPluginId ) :
+    iFSPluginId( aFSPluginId ),
+    iSession( NULL ),
+    iMsgMapper( NULL ),
+    iOperations( KOpGranularity ),
+    iActivitytimers( KOpGranularity ),
+    iSmtpService( NULL ),
+    iCachedEntry( NULL ),
+    iCachedEmailMessage( NULL ),
+    iMruList( NULL ),
+    iSearch( NULL ),
+    iSettingsApi( NULL ),
+    iEventHandler( NULL ),
+    iSessionOk( ETrue ),
+    iBrandingId( NULL ),
+    iIsUnderUiProcess( EFalse )
+    {
+    FUNC_LOG;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+CIpsPlgSosBasePlugin::~CIpsPlgSosBasePlugin()
+    {
+    FUNC_LOG;
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+
+    iOperations.ResetAndDestroy();
+    iActivitytimers.ResetAndDestroy();
+    iOperations.Close();
+    iActivitytimers.Close();
+    delete iSmtpService;
+    delete iMruList;
+    if ( iEventHandler )
+        {
+        iEventHandler->UnRegisterPropertyObserver( iSyncStateHandler );
+        }
+    delete iEventHandler;
+    delete iCachedEntry;
+    delete iCachedEmailMessage;
+    delete iMsgMapper;
+    delete iSearch;
+    delete iSettingsApi;
+    delete iSyncStateHandler;
+    delete iSession;
+    delete iBrandingId;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::BaseConstructL()
+    {
+    FUNC_LOG;
+    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 );
+    iSettingsApi = CIpsSetDataApi::NewL( *iSession );
+    iSettingsApi->GetIMEIFromThePhoneL( iIMEI );
+    iSyncStateHandler = CIpsPlgSyncStateHandler::NewL(
+            *iSession, *this, iOperations );
+    iEventHandler->RegisterPropertyObserverL( iSyncStateHandler );
+
+    RProcess process;
+    if ( process.SecureId() == FREESTYLE_EMAIL_UI_SID )
+        {
+        iIsUnderUiProcess = ETrue;
+        }
+    else
+        {
+        iIsUnderUiProcess = EFalse;
+        }
+    RAlwaysOnlineClientSession aosession;
+    TInt err = aosession.Connect();
+    if ( err == KErrNone )
+        {
+        TBuf8<1> dummyBuf;
+        TRAP( err, aosession.RelayCommandL(
+                EServerAPIEmailDisableAOEmailPlugin,
+                dummyBuf ) );
+        }
+    aosession.Close();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::CompleteConstructL()
+    {
+    FUNC_LOG;
+    iSessionOk = ETrue;
+    iEventHandler->CompleteConstructL( iSession );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SessionTerminated()
+    {
+    FUNC_LOG;
+    iSessionOk = EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::OpCompleted(
+	CIpsPlgSingleOpWatcher& aOpWatcher,
+	TInt aCompletionCode )
+    {
+    FUNC_LOG;
+    // Get valid operation count in each, some operations could have been
+    // deleted in array
+    TInt opId = aOpWatcher.Operation().Id();
+    for ( TInt i = iOperations.Count()-1; i >= 0; i-- )
+        {
+        CMsvOperation& oper = iOperations[i]->Operation();
+
+        if ( oper.Id() == opId )
+            {
+            DeleteAndRemoveOperation( i, aCompletionCode );
+            }
+        }
+    // make draft deletion synchronous so that empty drafts are not left after application close.
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+ TFSMailBoxStatus CIpsPlgSosBasePlugin::GetMailBoxStatus(
+    const TFSMailMsgId&  aMailBoxId  )
+    {
+    FUNC_LOG;
+    TMsvEntry tEntry;
+    TMsvId service;
+    TFSMailBoxStatus status;
+    if( iSessionOk )
+        {
+        iSession->GetEntry( aMailBoxId.Id(), service, tEntry );
+
+        if ( tEntry.Connected() )
+            {
+            status = EFSMailBoxOnline;
+            }
+        else if ( ConnOpRunning( aMailBoxId ) )
+            {
+            status = EFSMailBoxOnline;
+            }
+        else
+            {
+            status = EFSMailBoxOffline;
+            }
+        }
+    else
+        {
+        status = EFSMailBoxOffline;
+        }
+    return status;
+    }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgSosBasePlugin::SpecifiedSendingMailbox
+// Returns 'null' ID, because the method is not relevant with IPS protocols
+// ----------------------------------------------------------------------------
+ TFSMailMsgId CIpsPlgSosBasePlugin::SpecifiedSendingMailbox()
+     {
+    FUNC_LOG;
+     return TFSMailMsgId();
+     }
+
+ // ----------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::ListMailBoxesL( RArray<TFSMailMsgId>& aMailboxes )
+	{
+    FUNC_LOG;
+
+	if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+	CMsvEntry* cEntry = iSession->GetEntryL( KMsvRootIndexEntryId );
+    CleanupStack::PushL( cEntry );
+
+    CMsvEntrySelection* childEntries = cEntry->ChildrenWithMtmL( MtmId() );
+    CleanupStack::PushL( childEntries );
+
+    TInt count( childEntries->Count() );
+    for ( TInt i(0); i < count; i++)
+        {
+      	TFSMailMsgId mailboxId;
+    	TMsvEntry tEntry;
+    	TMsvId serviceId;
+    	TDriveUnit driveUnit = EDriveC;
+
+        iSession->GetEntry( childEntries->At(i), serviceId, tEntry );
+
+        if( iIMEI.Compare( tEntry.iDescription ) == 0 )
+            {
+            mailboxId.SetPluginId( TUid::Uid( PluginId() ) );
+            mailboxId.SetId( childEntries->At(i) );
+            aMailboxes.AppendL( mailboxId );
+            }
+        else
+            {
+            TRAPD( err, driveUnit = iSession->CurrentDriveL() );
+            if ( err == KErrNone && driveUnit == EDriveC )
+                {
+                // When memory card restored to another phone mailbox
+                // should be visible
+                mailboxId.SetPluginId( TUid::Uid( PluginId() ) );
+                mailboxId.SetId( childEntries->At(i) );
+                StoreIMEIToMailboxL( mailboxId.Id() );
+                aMailboxes.AppendL( mailboxId );
+                }
+            }
+        }
+    CleanupStack::PopAndDestroy( 2, cEntry ); // childEntries
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailBox* CIpsPlgSosBasePlugin::GetMailBoxByUidL(
+    const TFSMailMsgId& aMailBoxId)
+	{
+    FUNC_LOG;
+    CFSMailBox* result( NULL );
+    TMsvEntry tEntry;
+    TMsvId    serviceId;
+    TInt      status;
+    HBufC*    address( NULL );
+
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+    status = iSession->GetEntry( aMailBoxId.Id(), serviceId, tEntry );
+
+    if ( status == KErrNone )
+        {
+        result = CFSMailBox::NewL( aMailBoxId );
+        CleanupStack::PushL( result );   // << result
+        result->SetName( tEntry.iDetails );
+        result->SetSettingsUid( TUid::Uid( IPS_SET_ECOM_IMPLEMENTATION_UID ) );
+
+        iSettingsApi->GetMailboxAddressL( tEntry, address );
+        CleanupStack::PushL( address ); // << address
+        CFSMailAddress* fsAddress = CFSMailAddress::NewLC();    // << fsAddress
+        fsAddress->SetEmailAddress( *address );
+        result->SetOwnMailAddressL( fsAddress );
+        CleanupStack::Pop( fsAddress ); // >> fsAddress
+        CleanupStack::PopAndDestroy( address ); // >>> address
+        CleanupStack::Pop( result );    // >> result
+        }
+
+    return result;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DeleteMailBoxByUidL(
+    const TFSMailMsgId& aMailBoxId,
+    MFSMailRequestObserver& aOperationObserver,
+    const TInt aRequestId )
+    {
+    FUNC_LOG;
+    TMsvEntry tEntry;
+    TMsvId service;
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+
+    // 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() );
+
+    CancelAllOnlineOperations( aMailBoxId );
+
+    iSession->GetEntry( aMailBoxId.Id(), service, tEntry );
+    if ( tEntry.Connected() )
+        {
+        DisconnectL( aMailBoxId, aOperationObserver, aRequestId, ETrue );
+
+        // remove activity timer from array here but leave the actual delete
+        // to the disconnect operation. This is because the disconnect op
+        // sometimes tries to use the timer after it was deleted here.
+        TInt timerCount = iActivitytimers.Count();
+        for ( TInt j = 0; j < timerCount; j++ )
+            {
+            if ( iActivitytimers[j]->FSMailboxId() == aMailBoxId )
+                {
+                iActivitytimers.Remove( j );
+                timerCount--;
+                j--;
+                }
+            }
+        }
+    else
+        {
+        iSettingsApi->RemoveAccountL( tEntry, *iSession );
+        TFSProgress progress = { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone };
+        progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+        progress.iError = KErrNone;
+        TInt requestId = aRequestId;
+        aOperationObserver.RequestResponseL( progress, requestId );
+
+        DeleteActivityTimer( aMailBoxId  );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TDesC& CIpsPlgSosBasePlugin::GetBrandingIdL( const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+    CMsvEntry* mboxEntry = iSession->GetEntryL( aMailBoxId.Id() );
+    CleanupStack::PushL( mboxEntry );
+
+    TDesC& address = iSettingsApi->GetServerAddressL( *mboxEntry );
+    delete iBrandingId;
+    iBrandingId = NULL;
+    iBrandingId = address.AllocL();
+    CleanupStack::PopAndDestroy( mboxEntry );
+
+    return *iBrandingId;
+    }
+
+// ----------------------------------------------------------------------------
+// Pop3 has no implementation for this virtual
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::MoveMessagesL(
+    const TFSMailMsgId& aMailBoxId,
+    const RArray<TFSMailMsgId>& aMessageIds,
+    const TFSMailMsgId& aSourceFolderId,
+    const TFSMailMsgId& aDestinationFolderId )
+	{
+    FUNC_LOG;
+	if( aDestinationFolderId.Id() == KMsvDraftEntryId  )
+	    {
+	    MoveMessagesToDraftL(
+	        aMailBoxId,
+	        aMessageIds,
+	        aSourceFolderId,
+	        aDestinationFolderId );
+	    }
+	}
+
+// ----------------------------------------------------------------------------
+// asynchronic version from move messages function, pop3 plugin not implent
+// this virtual fucntion.
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::MoveMessagesL(
+    const TFSMailMsgId& aMailBoxId,
+    const RArray<TFSMailMsgId>& aMessageIds,
+    const TFSMailMsgId& aSourceFolderId,
+    const TFSMailMsgId& aDestinationFolderId,
+    MFSMailRequestObserver& aOperationObserver,
+    TInt aRequestId )
+    {
+    FUNC_LOG;
+    TInt ret = KErrNotSupported;
+    if( aDestinationFolderId.Id() == KMsvDraftEntryId  )
+        {
+        MoveMessagesToDraftL(
+            aMailBoxId,
+            aMessageIds,
+            aSourceFolderId,
+            aDestinationFolderId );
+        ret = KErrNone;
+        }
+    ret = KErrNotSupported;
+    TFSProgress progress = { 
+            TFSProgress::EFSStatus_RequestComplete, 0, 0, ret };
+    aOperationObserver.RequestResponseL(
+            progress, aRequestId );
+    return ret;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::MoveMessagesToDraftL(
+    const TFSMailMsgId& /*aMailBoxId*/,
+    const RArray<TFSMailMsgId>& aMessageIds,
+    const TFSMailMsgId& aSourceFolderId,
+    const TFSMailMsgId& aDestinationFolderId )
+    {
+    FUNC_LOG;
+
+    TInt count( aMessageIds.Count() );
+    if ( !count )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+
+    TMsvId msgService;
+    TMsvEntry tEntry;
+
+    CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
+    CleanupStack::PushL(sel);
+
+    CMsvEntry* msgEntry = iSession->GetEntryL( aMessageIds[0].Id() );
+    CleanupStack::PushL( msgEntry );
+
+	for( TInt i(0); i < count; i++ )
+        {
+        iSession->GetEntry( aMessageIds[i].Id(), msgService, tEntry );
+
+        if( aSourceFolderId.Id() == KMsvGlobalOutBoxIndexEntryIdValue )
+            {
+            if( tEntry.SendingState() != KMsvSendStateSending )
+                {
+                // Set all states in outbox to suspended
+                tEntry.SetSendingState( KMsvSendStateSuspended );
+                msgEntry->ChangeL( tEntry );
+                sel->AppendL( tEntry.Id() );
+                }
+            else
+                {
+                // Not possible to move when sending, what to do???
+                // Probably some note back to UI, but we leave..
+                User::Leave( KErrNotSupported );
+                }
+            }
+        else
+            {
+            sel->AppendL( tEntry.Id() );
+            }
+        }
+    if( sel->Count() )
+        {
+        CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC();
+        if( !aSourceFolderId.IsNullId() )
+            {
+            CMsvEntry* cEntry = iSession->GetEntryL( aSourceFolderId.Id() );
+            CleanupStack::PushL( cEntry );
+            cEntry->MoveL(
+                *sel,
+                           aDestinationFolderId.Id(),//KMsvDraftEntryIdValue
+                           wait->iStatus );
+
+            CleanupStack::PopAndDestroy( cEntry );
+            }
+        else
+            {
+            // Message is in editing state, we can't use parent as entry
+            // because it's equal to destination.
+            TMsvId parent = msgEntry->Entry().Parent();
+            msgEntry->SetEntryL( parent );
+            msgEntry->CopyL(
+                *sel,
+                             aDestinationFolderId.Id(),//KMsvDraftEntryIdValue
+                             wait->iStatus );
+            }
+        wait->Start();
+        CleanupStack::PopAndDestroy( wait ); // wait
+        }
+    CleanupStack::PopAndDestroy( 2, sel ); // msgEntry, sel
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::CopyMessagesL(
+    const TFSMailMsgId& /*aMailBoxId*/,
+    const RArray<TFSMailMsgId>& /*aMessageIds*/,
+    RArray<TFSMailMsgId>& /*aNewMessages*/,
+    const TFSMailMsgId& /*aSourceFolderId*/,
+    const TFSMailMsgId& /*aDestinationFolderId*/ )
+	{
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+MDesCArray* CIpsPlgSosBasePlugin::GetMrusL(
+                const TFSMailMsgId& aMailBoxId)
+    {
+    return iMruList->GetMruListL( aMailBoxId );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SetMrusL(
+    const TFSMailMsgId& aMailBoxId,
+    MDesCArray*  aNewMruList )
+    {
+    iMruList->SetMruListL( aMailBoxId, aNewMruList );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::GoOnlineL( const TFSMailMsgId& aMailBoxId )
+    {
+    if ( !ConnOpRunning( aMailBoxId) )
+        {
+        // append mailbox id go online mailbox array
+        RefreshNowL( aMailBoxId, *this, 0 );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::GoOfflineL( const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    CancelAllOnlineOperations( aMailBoxId );
+    // use 0 for request id
+    DisconnectL( aMailBoxId, *this, 0 );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+const TFSProgress CIpsPlgSosBasePlugin::GetLastSyncStatusL(
+    const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    TMsvEntry tEntry;
+    TMsvId service;
+    TFSProgress progress = { TFSProgress::EFSStatus_Status, 0, 0, KErrNone };
+
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+    iSession->GetEntry( aMailBoxId.Id(), service, tEntry );
+
+    TInt state = iSettingsApi->GetLastSyncStatusL( tEntry );
+
+    switch( state )
+        {
+        case ESyncFinishedSuccessfully:
+            progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+            break;
+        case ESyncCancelled:
+            progress.iProgressStatus = TFSProgress::EFSStatus_RequestCancelled;
+            break;
+        case ESyncError:
+            progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+            progress.iError = KErrGeneral;
+            break;
+        default:
+            progress.iProgressStatus = TFSProgress::EFSStatus_Status;
+            progress.iError = state; // probably some symbian error code
+            break;
+        }
+    return progress;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::CancelSyncL( const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    TInt err = KErrNone;
+
+    // found correct operation
+    for ( TInt i = iOperations.Count()-1; i >= 0; i-- )
+        {
+        const CIpsPlgBaseOperation* baseOp =
+            iOperations[i]->BaseOperation();
+        if ( baseOp && baseOp->FSMailboxId() == aMailBoxId &&
+               ( baseOp->IpsOpType() == EIpsOpTypePop3SyncOp
+                || baseOp->IpsOpType() == EIpsOpTypeImap4SyncOp
+                || baseOp->IpsOpType() == EIpsOpTypeImap4PopulateOp ) )
+            {
+            DeleteAndRemoveOperation( i, KErrCancel );
+            }
+        }
+/** <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(
+                EServerAPIEmailCancelAllAndDoNotDisconnect, buf ) );
+        }
+    aosession.Close();
+    */
+
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+CFSMailFolder* CIpsPlgSosBasePlugin::GetFolderByUidL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& aFolderId )
+    {
+    FUNC_LOG;
+    CFSMailFolder* result( NULL);
+    if( !iSessionOk )
+        {
+        User::Leave( KErrNotReady );
+        }
+
+    CMsvEntry* folderEntry = iSession->GetEntryL( aFolderId.Id() );
+    CleanupStack::PushL( folderEntry ); // << folderEntry
+
+    if ( folderEntry )
+        {
+        result = CFSMailFolder::NewLC( aFolderId ); // << result
+        result->SetMailBoxId( aMailBoxId );
+
+        CMsvEntrySelection* msgChilds = folderEntry->ChildrenWithTypeL(
+                KUidMsvMessageEntry );
+        CleanupStack::PushL( msgChilds );
+        TInt msgCount( msgChilds->Count() );
+        result->SetMessageCount( msgCount );
+        TInt unreadCount( 0 );
+        TMsvId serviceId;
+        for ( TInt i(0); i < msgCount; i++ )
+            {
+            TMsvEmailEntry emlEntry;
+            TMsvId dummy;
+            TBool isRead = ETrue;
+            if ( iSession->GetEntry(
+                    msgChilds->At(i), dummy, emlEntry ) == KErrNone )
+                {
+                if ( ( PluginId() == KIpsPlgImap4PluginUid.iUid ||
+                       PluginId() == KIpsPlgPop3PluginUid.iUid ) &&
+                        emlEntry.Unread() )
+                    {
+                    isRead = EFalse;
+                    }
+                }
+            if ( !isRead && !emlEntry.LocallyDeleted() )
+                {
+                unreadCount++;
+                }
+            }
+
+        CleanupStack::PopAndDestroy( msgChilds );
+        result->SetUnreadCount( unreadCount );
+        result->SetFolderName( folderEntry->Entry().iDetails );
+        result->SetFolderType( GetFolderType( folderEntry, aFolderId ) );
+        TMsvEntry parentEntry;
+        TInt status = iSession->GetEntry( folderEntry->Entry().Parent( ), serviceId,
+                parentEntry );
+        TUint parent( 0 );
+		if( status == KErrNone )
+			{
+			if( parentEntry.iType == KUidMsvFolderEntry )
+				{
+				parent = static_cast<TUint>( folderEntry->Entry().Parent() );
+				}
+			else
+				{
+                parent = 0;
+				}
+			}
+
+        TFSMailMsgId parentId( PluginId(), parent );
+        result->SetParentFolderId( parentId );
+
+        // Set subfolder count here for ListFolderL
+        CMsvEntrySelection* fldChildren =
+    		folderEntry->ChildrenWithTypeL( KUidMsvFolderEntry );
+    	CleanupStack::PushL( fldChildren );    // << children
+        result->SetSubFolderCount( fldChildren->Count() );
+        CleanupStack::PopAndDestroy( fldChildren );    // >>> children
+
+        // Set blocklist for FW
+        BlockCopyMoveFromFoldersL( folderEntry, aFolderId, *result );
+
+        CleanupStack::Pop( result );    // >> result
+        }
+	CleanupStack::PopAndDestroy( folderEntry ); // >>> folderEntry
+
+    return result;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailFolder* CIpsPlgSosBasePlugin::CreateFolderL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aFolderId */,
+    const TDesC& /* aFolderName */,
+    const TBool /* aSync */)
+	{
+	return NULL;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DeleteFolderByUidL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aFolderId */)
+	{
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+MFSMailIterator* CIpsPlgSosBasePlugin::ListMessagesL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& aFolderId,
+    const TFSMailDetails aDetails,
+    const RArray<TFSMailSortCriteria>& aSorting )
+    {
+    FUNC_LOG;
+    CIpsPlgMsgIterator* iterator = CIpsPlgMsgIterator::NewL(
+        *this, *iSession, aMailBoxId, aFolderId, aDetails, aSorting );
+
+    return iterator;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+CFSMailMessage* CIpsPlgSosBasePlugin::GetMessageByUidL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailDetails aDetails)
+	{
+    FUNC_LOG;
+	CFSMailMessage* result( NULL );
+	TMsvId serviceId;
+	TMsvEntry tEntry;
+	TInt status( KErrNone );
+
+	if( !iSessionOk )
+	    {
+	    User::Leave( KErrNotReady );
+	    }
+
+	status = iSession->GetEntry( aMessageId.Id(), serviceId, tEntry);
+
+	const TMsvEmailEntry& emlEntry(tEntry);
+	// do not give deleted marked messages
+	if ( status == KErrNone &&
+	    EDisconnectedDeleteOperation != emlEntry.DisconnectedOperation()
+	    && !emlEntry.DeletedIMAP4Flag() )
+	    {
+        result = iMsgMapper->GetMailMessageL( aMailBoxId, tEntry, aDetails );
+	    }
+
+	return result;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+ CFSMailMessage* CIpsPlgSosBasePlugin::CreateMessageToSendL(
+    const TFSMailMsgId& aMailBoxId )
+	{
+    FUNC_LOG;
+    CFSMailMessage* msg = iSmtpService->CreateNewSmtpMessageL( aMailBoxId );
+	return msg;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessage* CIpsPlgSosBasePlugin::CreateForwardMessageL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& aOriginalMessageId,
+    const TDesC& /* aHeaderDescriptor */)
+    {
+    FUNC_LOG;
+    CFSMailMessage* msg = iSmtpService->CreateForwardSmtpMessageL(
+        aMailBoxId, aOriginalMessageId );
+    return msg;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessage* CIpsPlgSosBasePlugin::CreateReplyMessageL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& aOriginalMessageId,
+    const TBool aReplyToAll,
+    const TDesC& /* aHeaderDescriptor */ )
+    {
+    FUNC_LOG;
+    CFSMailMessage* msg = iSmtpService->CreateReplySmtpMessageL(
+        aMailBoxId, aOriginalMessageId, aReplyToAll );
+    return msg;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::StoreMessageL(
+    const TFSMailMsgId& aMailBoxId,
+    CFSMailMessage& aMessage )
+ 	{
+    FUNC_LOG;
+    TInt status( KErrNone);
+    TFSMailMsgId msgId( aMessage.GetMessageId( ));
+    TMsvEntry tEntry;
+    TMsvId serviceId;
+    TBool incoming( EFalse);
+
+    // Check whether this is IMAP4 or POP3 (incoming) message
+    if ( !msgId.IsNullId() )
+        {
+        status = iSession->GetEntry( msgId.Id( ), serviceId, tEntry );
+
+        if ( status == KErrNone )
+            {
+            incoming = ( tEntry.iMtm == KSenduiMtmImap4Uid ) ||
+                ( tEntry.iMtm == KSenduiMtmPop3Uid );
+            }
+        }
+
+    if ( incoming )
+        {
+        // 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 );
+            iOperations.AppendL( opW );
+            CleanupStack::Pop( opW );
+            }
+        else
+            {
+            CleanupStack::PopAndDestroy( opW );
+            }*/
+        }
+    else
+        {
+        iSmtpService->StoreMessageL( aMailBoxId, aMessage );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgSosBasePlugin::GetMessagesL()
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::GetMessagesL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& aFolderId,
+    const RArray<TFSMailMsgId>& aMessageIds,
+    RPointerArray<CFSMailMessage>& aMessageList,
+    const TFSMailDetails aDetails )
+	{
+    FUNC_LOG;
+    TInt i;
+    CFSMailMessage* msg;
+
+	for (i = 0; i < aMessageIds.Count(); i++ )
+        {
+        msg = GetMessageByUidL(
+            aMailBoxId, aFolderId, aMessageIds[i], aDetails );
+        CleanupStack::PushL( msg );
+        aMessageList.AppendL( msg );
+        CleanupStack::Pop( msg );
+        }
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::ChildPartsL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aParentId,
+    RPointerArray<CFSMailMessagePart>& aParts)
+	{
+    FUNC_LOG;
+    iMsgMapper->GetChildPartsL( aMailBoxId, aMessageId, aParentId, aParts );
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessagePart* CIpsPlgSosBasePlugin::NewChildPartL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aParentPartId,
+    const TFSMailMsgId& /* aInsertBefore */,
+    const TDesC& aContentType )
+	{
+    FUNC_LOG;
+    CFSMailMessagePart* result;
+    result = iMsgMapper->NewChildPartL( aMailBoxId, aMessageId, aParentPartId,
+        aContentType );
+    return result;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessagePart* CIpsPlgSosBasePlugin::NewChildPartFromFileL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& /* aParentPartId */,
+    const TDesC& aContentType,
+    const TDesC& aFilePath )
+    {
+    FUNC_LOG;
+    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();
+
+    // Initialize CMsvAttachment instance for the attachment creation
+    CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
+    CleanupStack::PushL( info );
+
+    info->SetAttachmentNameL( aFilePath );
+    info->SetSize( fileSize );
+
+    // Create/acquire Symbian message entry objects
+    GetMessageEntryL( aMessageId.Id(), cEntry, message );
+
+    // Operation waiter needed to implement synchronous operation
+    // on the top of async API
+    CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+    CleanupStack::PushL( waiter );
+
+    // Start attachment creation
+    message->AttachmentManager().AddAttachmentL(
+        aFilePath, info, waiter->iStatus );
+
+    waiter->Start();
+    CleanupStack::PopAndDestroy( waiter );
+    CleanupStack::Pop( info ); // attachment manager takes ownership
+
+    // 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 );
+
+    // 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;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessagePart* CIpsPlgSosBasePlugin::NewChildPartFromFileL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& /* aParentPartId */,
+    const TDesC& aContentType,
+    RFile& aFile )
+    {
+    FUNC_LOG;
+
+    // Initialize helper variables
+    CFSMailMessagePart* result ( NULL );
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+    TInt fileSize( 0 );
+    TBuf<KMaxFileName> fileName;
+
+    // Create/acquire Symbian message entry objects
+    CleanCachedMessageEntries();
+    GetMessageEntryL( aMessageId.Id(), cEntry, message );
+
+    // 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 );
+
+    // Operation waiter needed to implement synchronous operation
+    // on the top of async API
+    CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+    CleanupStack::PushL( waiter );
+    message->AttachmentManager().AddAttachmentL( aFile, info, waiter->iStatus );
+    waiter->Start();
+    CleanupStack::PopAndDestroy( waiter );
+    CleanupStack::Pop( info ); // attachment manager takes ownership
+
+    // 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;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CFSMailMessagePart* CIpsPlgSosBasePlugin::CopyMessageAsChildPartL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    const TFSMailMsgId& /* aParentPartId */,
+    const TFSMailMsgId& /* aInsertBefore */,
+    const CFSMailMessage& /* aMessage */)
+	{
+	return NULL;
+	}
+
+// ----------------------------------------------------------------------------
+// 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)
+	{
+    FUNC_LOG;
+    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
+        GetMessageEntryL( aMessageId.Id(), cEntry, message );
+
+        MMsvAttachmentManager& attachmentMgr( message->AttachmentManager() );
+
+        CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL();
+        CleanupStack::PushL( waiter );
+
+        attachmentMgr.RemoveAttachmentL(
+            (TMsvAttachmentId) aPartId.Id(), waiter->iStatus );
+
+        waiter->Start();
+        CleanupStack::PopAndDestroy( waiter );
+        }
+    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.
+// ----------------------------------------------------------------------------
+//
+CFSMailMessagePart* CIpsPlgSosBasePlugin::MessagePartL(
+    const TFSMailMsgId& aMailBoxId,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aMessagePartId)
+	{
+    FUNC_LOG;
+    CFSMailMessagePart* result( NULL );
+    result = iMsgMapper->GetMessagePartL( aMessagePartId.Id(), aMailBoxId,
+        aMessageId );
+    return result;
+	}
+
+// ----------------------------------------------------------------------------
+// The implementation bypass CImEmailMessage and its email's attachment
+// manager. Instead, it calls Symbian framework classes directly by
+// accessing the attachment entry.
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::GetMessagePartFileL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    const TFSMailMsgId& aMessagePartId,
+    RFile& aFileHandle)
+	{
+    FUNC_LOG;
+    TInt status( KErrNone );
+    CMsvEntry* cEntry = iSession->GetEntryL( aMessagePartId.Id() );
+    CleanupStack::PushL( cEntry );
+    CMsvStore* store = NULL;
+    TBool hasStore = cEntry->HasStoreL();
+    if ( hasStore )
+        {
+        store = cEntry->ReadStoreL();
+        }
+
+    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() )
+        {
+        aFileHandle = attachmentMgr.GetAttachmentFileL( 0 );
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    CleanupStack::PopAndDestroy( store );
+    CleanupStack::PopAndDestroy( cEntry );
+	return status;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::CopyMessagePartFileL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aMessagePartId,
+    const TDesC& aFilePath)
+	{
+    FUNC_LOG;
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+
+    CFileMan* fileMgr = CFileMan::NewL( iSession->FileSession() );
+    CleanupStack::PushL( fileMgr );
+
+    // We trust that the message ID really refers to a message
+    GetMessageEntryL( aMessageId.Id(), cEntry, message );
+
+    // Without this e.g. alternative body iCal parts are not found
+    message->GetAttachmentsListL( aMessageId.Id(),
+        CImEmailMessage::EAllAttachments,
+        CImEmailMessage::EThisMessageAndEmbeddedMessages );
+    MMsvAttachmentManager& attachmentMgr( message->AttachmentManager() );
+    // It is assumed that the attachment ID is same as the corresponding
+    // entry ID
+    RFile attachmentFile = attachmentMgr.GetAttachmentFileL(
+        (TMsvAttachmentId) aMessagePartId.Id() );
+
+    // Overwrites the target file if such exists
+    // There is no other way to report errors than leave
+    User::LeaveIfError( fileMgr->Copy( attachmentFile, aFilePath ) );
+
+    attachmentFile.Close();
+    CleanupStack::PopAndDestroy( fileMgr );
+	}
+
+// ----------------------------------------------------------------------------
+// The method supports only reading of the plain text body currently.
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::GetContentToBufferL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aMessagePartId,
+    TDes& aBuffer,
+    const TUint aStartOffset)
+	{
+    FUNC_LOG;
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+
+    // We trust that the message ID really refers to a message
+    GetMessageEntryL( aMessageId.Id(), cEntry, message );
+    if ( message )
+        {
+    message->GetBodyTextEntryIdL(
+        cEntry->Entry().Id(), CImEmailMessage::EThisMessageOnly );
+
+    if ( message->Selection().Count() > 0 )
+        {
+        // Check whether the body text is requested
+        if ( message->Selection()[0] == aMessagePartId.Id() )
+            {
+            CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL();
+            CleanupStack::PushL(globalParaLayer);
+            CCharFormatLayer* globalCharLayer = CCharFormatLayer::NewL();
+            CleanupStack::PushL(globalCharLayer);
+
+            CRichText* bodyText = CRichText::NewL(
+                globalParaLayer, globalCharLayer);
+            CleanupStack::PushL( bodyText );
+
+            message->GetBodyTextL(
+                aMessageId.Id(), CImEmailMessage::EThisMessageOnly,
+                *bodyText, *globalParaLayer, *globalCharLayer );
+
+            bodyText->Extract( aBuffer, aStartOffset, aBuffer.MaxLength() );
+
+            CleanupStack::PopAndDestroy(bodyText);
+            CleanupStack::PopAndDestroy(globalCharLayer);
+            CleanupStack::PopAndDestroy(globalParaLayer);
+            }
+        }
+	}
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SetContentL(
+    const TDesC& aBuffer,
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& aMessageId,
+    const TFSMailMsgId& aMessagePartId )
+	{
+    FUNC_LOG;
+    CMsvEntry* cEntry( NULL );
+    CImEmailMessage* message( NULL );
+
+    // We trust that the message ID really refers to a message
+    GetMessageEntryL( aMessageId.Id(), cEntry, message );
+	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 );
+	    		}
+	    	}
+	    }
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::RemovePartContentL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    const RArray<TFSMailMsgId>& aPartIds )
+    {
+    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 );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SetPartContentFromFileL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    const TFSMailMsgId& /* aMessagePartId */,
+    const TDesC& /* aFilePath */)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::StoreMessagePartL(
+    const TFSMailMsgId& /* aMailBoxId */,
+    const TFSMailMsgId& /* aParentFolderId */,
+    const TFSMailMsgId& /* aMessageId */,
+    CFSMailMessagePart& /* aMessagePart */)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::UnregisterRequestObserver( TInt /* aRequestId */)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SendL(TFSMailMsgId aMessageId )
+ 	{
+    FUNC_LOG;
+ 	CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
+ 	CleanupStack::PushL(watcher);
+    CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewLC(
+        *iSession, CActive::EPriorityStandard, watcher->iStatus, ETrue );
+    watcher->SetOperation(op);
+    CleanupStack::Pop( op ); // op added as member of watcher
+    op->StartSendL( aMessageId.Id() );
+    iOperations.AppendL(watcher);
+    CleanupStack::Pop( watcher );
+ 	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SendMessageL( CFSMailMessage& aMessage )
+    {
+    FUNC_LOG;
+    // is EFSMsgFlag_CalendarMsg enabled,
+    // then move send to back ground process
+    if ( aMessage.GetFlags() & EFSMsgFlag_CalendarMsg )
+        {
+        iEventHandler->SetNewPropertyEvent(
+                aMessage.GetMessageId().Id(),
+                KIPSSosSmtpEmptyOutboxNow, KErrNone );
+        }
+    else
+        {
+        SendL( aMessage.GetMessageId() );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TFSProgress CIpsPlgSosBasePlugin::StatusL( TInt aRequestId )
+	{
+    FUNC_LOG;
+	TFSProgress status;
+	status.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+	for ( TInt i = 0; i < iOperations.Count(); i++ )
+        {
+        const CIpsPlgBaseOperation* op = iOperations[i]->BaseOperation();
+        if ( op && op->FSRequestId() == aRequestId )
+            {
+            status = op->GetFSProgressL();
+            }
+        }
+	return status;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::CancelL(TInt aRequestId)
+	{
+    FUNC_LOG;
+	const TInt count = iOperations.Count();
+    for ( TInt i = count-1; i >= 0; i-- )
+        {
+        const CIpsPlgBaseOperation* oper = iOperations[i]->BaseOperation();
+        // all Fs operations are derived from ips base operation
+        if ( oper && oper->FSRequestId() == aRequestId )
+            {
+            DeleteAndRemoveOperation( i, KErrCancel );
+            break;
+            }
+        }
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SearchL(
+    const TFSMailMsgId& aMailBoxId,
+    const RArray<TFSMailMsgId>& aFolderIds,
+    const RPointerArray<TDesC>& aSearchStrings,
+    const TFSMailSortCriteria& aSortCriteria,
+    MFSMailBoxSearchObserver& aSearchObserver )
+    {
+    FUNC_LOG;
+	iSearch->SearchL(
+	    aMailBoxId,
+	    aFolderIds,
+	    aSearchStrings,
+	    aSortCriteria,
+	    aSearchObserver );
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::CancelSearch( const TFSMailMsgId& /* aMailBoxId */ )
+	{
+    FUNC_LOG;
+	iSearch->Cancel();
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::ClearSearchResultCache(
+    const TFSMailMsgId& /* aMailBoxId */ )
+	{
+    FUNC_LOG;
+	iSearch->ClearCache();
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::AddObserverL(MFSMailEventObserver& aObserver)
+	{
+    FUNC_LOG;
+	iEventHandler->AddPluginObserverL( &aObserver );
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::RemoveObserver(MFSMailEventObserver& aObserver)
+	{
+	//don't delete. we don't own this.
+	iEventHandler->RemovePluginObserver( &aObserver );
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DeleteMessagesByUidL(
+    const TFSMailMsgId& /*aMailBoxId*/,
+    const TFSMailMsgId& /*aFolderId*/,
+	const RArray<TFSMailMsgId>& aMessages )
+    {
+    FUNC_LOG;
+    CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection;
+    CleanupStack::PushL(sel);
+
+    TInt count = aMessages.Count();
+    TMsvEntry tEntry;
+    TMsvId service;
+
+    TMsvEntry parentEntry;
+
+    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 )
+            {
+            iSession->GetEntry( tEntry.Parent( ), service, parentEntry );
+
+            CMsvEntry *cEntry = CMsvEntry::NewL(
+                        *iSession, tEntry.Id(), TMsvSelectionOrdering() );
+            CleanupStack::PushL( cEntry );
+            CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( );
+            // 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 );
+            CMsvOperation* msvOp = cEntry->ChangeL( tEntry, wait->iStatus );
+            CleanupStack::PushL(msvOp);
+            wait->Start();
+            sel->AppendL( tEntry.Id() );
+            CleanupStack::PopAndDestroy( 3, cEntry );
+            }
+        }
+
+    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL( *this );
+    CleanupStack::PushL( watcher );
+    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 );
+        }
+
+    CleanupStack::PopAndDestroy( sel );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SubscribeMailboxEventsL(
+    const TFSMailMsgId& aMailboxId,
+    MFSMailEventObserver& aObserver)
+    {
+    FUNC_LOG;
+    TUint32 key = iSettingsApi->CreateCenRepKeyL(   // faulty CS warning
+        aMailboxId.Id(),
+        MtmId(),
+        CIpsSetDataStorer::EIpsSetDataLastModifiedH );
+
+    iEventHandler->SubscribeMailboxEventsL( aMailboxId, aObserver, key );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::UnsubscribeMailboxEvents(
+    const TFSMailMsgId& aMailboxId,
+    MFSMailEventObserver& aObserver)
+    {
+    FUNC_LOG;
+    iEventHandler->UnsubscribeMailboxEvents( aMailboxId, aObserver );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TSSMailSyncState CIpsPlgSosBasePlugin::CurrentSyncState(
+    const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    return iSyncStateHandler->GetCurrentSyncState( aMailBoxId );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::WizardDataAvailableL( )
+    {
+    FUNC_LOG;
+    TInt error = KErrNone;
+    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;
+        }
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::GetConnectionId(
+        TFSMailMsgId /*aMailBoxId*/,
+        TUint32& /*aConnectionId*/ )
+    {
+    return KErrNotSupported;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::IsConnectionAllowedWhenRoaming(
+             TFSMailMsgId /*aMailBoxId*/,
+             TBool& /*aConnectionAllowed*/ )
+    {
+    return KErrNotSupported;
+    }
+
+// ----------------------------------------------------------------------------
+// The method is not relevant for the Symbian based implementation
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::AuthenticateL(
+    MFSMailRequestObserver& /* aOperationObserver */,
+    TInt /* aRequestId */)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// method sets authentication popup data
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SetCredentialsL( const TFSMailMsgId& aMailBoxId,
+	const TDesC& /*aUsername*/, const TDesC& aPassword )
+	{
+    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 );
+	}
+
+// ----------------------------------------------------------------------------
+// CIpsPlgSosBasePlugin::GetMessageEntryL( )
+// Checks whether the requested message is already cached. If not, the cached
+// objects are deleted and new objects are created.
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::GetMessageEntryL(
+    TMsvId aId,
+    CMsvEntry*& aMessageEntry,
+    CImEmailMessage*& aImEmailMessage )
+    {
+    FUNC_LOG;
+    if ( !iCachedEntry || ( aId != iCachedEntry->Entry().Id() ) ||
+            iCachedEmailMessage->IsActive() )
+        {
+        CleanCachedMessageEntries();
+
+        iCachedEntry = iSession->GetEntryL( aId );
+        if ( iCachedEntry->Entry().iType == KUidMsvMessageEntry )
+            {
+            iCachedEmailMessage = CImEmailMessage::NewL( *iCachedEntry );
+            }
+        }
+    aMessageEntry = iCachedEntry;
+    aImEmailMessage = iCachedEmailMessage;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::CleanCachedMessageEntries()
+    {
+    FUNC_LOG;
+    delete iCachedEmailMessage;
+    iCachedEmailMessage = NULL;
+    delete iCachedEntry;
+    iCachedEntry = NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TFSFolderType CIpsPlgSosBasePlugin::GetFolderType(
+    CMsvEntry* aEntry,
+    TFSMailMsgId aFolderId )
+	{
+    FUNC_LOG;
+    TFSFolderType folderType( EFSOther );
+
+	if( ( aEntry->Entry().iDetails.CompareF( KIpsPlgInbox ) == 0 ) &&
+		( aEntry->Entry().iType == KUidMsvFolderEntry ) )
+        {
+        folderType = EFSInbox;
+        }
+	else if( ( aEntry->Entry().iMtm == KSenduiMtmPop3Uid ) &&
+	         ( aEntry->Entry().iType == KUidMsvServiceEntry ) &&
+	         ( aEntry->Entry().iServiceId == aFolderId.Id() ) )
+	    {
+	    folderType = EFSInbox;
+        }
+    else if( aFolderId.Id() == KMsvGlobalOutBoxIndexEntryId )
+        {
+        folderType = EFSOutbox;
+        }
+    else if( aFolderId.Id() == KMsvDraftEntryId )
+        {
+        folderType = EFSDraftsFolder;
+        }
+    else if( aFolderId.Id() == KMsvSentEntryId )
+        {
+        folderType = EFSSentFolder;
+        }
+    else if( aFolderId.Id() == KMsvDeletedEntryFolderEntryId )
+        {
+        folderType = EFSDeleted;
+        }
+    else if( aFolderId.Id() == KMsvUnknownServiceIndexEntryId )
+        {
+        folderType = EFSOther;
+        }
+    return folderType;
+	}
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsPlgTimerOperation& CIpsPlgSosBasePlugin::ActivityTimerL(
+    const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    CIpsPlgTimerOperation* timer=NULL;
+    for ( TInt i = 0; i < iActivitytimers.Count(); i++ )
+        {
+        if ( iActivitytimers[i]->FSMailboxId().Id() == aMailBoxId.Id() )
+            {
+            timer = iActivitytimers[i];
+            }
+        }
+
+    if ( !timer )
+        {
+        // No timer for mailbox found create new
+        timer = CIpsPlgTimerOperation::NewL( aMailBoxId, *this );
+        CleanupStack::PushL( timer );
+        User::LeaveIfError( iActivitytimers.Append( timer ) );
+        CleanupStack::Pop( timer );
+        }
+    return *timer;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsPlgSyncStateHandler& CIpsPlgSosBasePlugin::GetSyncStateHandler()
+    {
+    return *iSyncStateHandler;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::CancelAllOnlineOperations(
+    const TFSMailMsgId& aMailboxId )
+    {
+    FUNC_LOG;
+    // cancel all ongoing operations
+    for ( TInt i = iOperations.Count()-1; i >= 0; i-- )
+        {
+        const CIpsPlgBaseOperation* baseOp = iOperations[i]->BaseOperation();
+        if ( baseOp && baseOp->FSMailboxId() == aMailboxId )
+            {
+            delete iOperations[i];
+            iOperations.Remove(i);
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DeleteAndRemoveOperation(
+        const TInt aOpArrayIndex, TInt aCompleteCode )
+    {
+    FUNC_LOG;
+    CIpsPlgSingleOpWatcher* opWatcher = iOperations[aOpArrayIndex];
+
+    // The operations matches, handle it in protocol plugin...if needed.
+    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 ) )
+        {
+        service = op->Service();
+        }
+    iOperations.Remove( aOpArrayIndex );
+    delete opWatcher;
+    opWatcher = NULL;
+    // need to remove operation first because after signaling
+    // sync complete mailbox status is asked immediatelly
+    // and function checks connects ops also (see GetMailBoxStatus)
+    if ( service != KErrNotFound )
+        {
+        iEventHandler->SetNewPropertyEvent(
+                service, KIpsSosEmailSyncCompleted, aCompleteCode );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DisconnectL(
+    const TFSMailMsgId& aMailBoxId,
+    MFSMailRequestObserver& aObserver,
+    const TInt aRequestId,
+    TBool aRemoveAccountAlso )
+    {
+    FUNC_LOG;
+    TMsvId service = aMailBoxId.Id();
+    TMsvEntry tEntry;
+    TMsvId serv;
+    iSession->GetEntry( service, serv, tEntry );
+
+    if ( tEntry.Connected() )
+        {
+        CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
+        CleanupStack::PushL( watcher );
+
+        TBuf8<1> dummyParams;
+        dummyParams.Zero();
+        CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection;
+        CleanupStack::PushL(sel);
+
+        sel->AppendL( service );
+
+        CIpsPlgBaseOperation* op = CIpsPlgDisconnectOp::NewL( *iSession,
+            watcher->iStatus, service, ActivityTimerL( aMailBoxId ),
+            aMailBoxId, aObserver, aRequestId,
+            aRemoveAccountAlso );
+
+        watcher->SetOperation( op );
+        CleanupStack::PopAndDestroy( sel );
+        iOperations.AppendL( watcher );
+        CleanupStack::Pop( watcher );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::HandleTimerFiredL( const TFSMailMsgId& aMailboxId )
+    {
+    FUNC_LOG;
+    for ( TInt i = 0; i < iActivitytimers.Count(); i++ )
+        {
+        // do not disconnect automatically mailboxes that are set to
+        // "connected"
+        if ( iActivitytimers[i]->FSMailboxId().Id() == aMailboxId.Id() )
+            {
+            // 0 for request id
+            DisconnectL( iActivitytimers[i]->FSMailboxId(), *this, 0 );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::RequestResponseL(
+    TFSProgress /*aEvent*/,
+    TInt /*aRequestId*/ )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::EmptyOutboxL( const TFSMailMsgId& aMailBoxId )
+    {
+    FUNC_LOG;
+    CIpsPlgSingleOpWatcher* watcher = CIpsPlgSingleOpWatcher::NewL(*this);
+ 	CleanupStack::PushL(watcher);
+    CIpsPlgSmtpOperation* op = CIpsPlgSmtpOperation::NewLC(
+        *iSession, CActive::EPriorityStandard, watcher->iStatus, ETrue );
+    watcher->SetOperation(op);
+    op->EmptyOutboxFromPendingMessagesL( aMailBoxId.Id() );
+    iOperations.AppendL(watcher);
+    CleanupStack::Pop( 2, watcher );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::CanConnectL( const TFSMailMsgId& /*aMailboxId*/,
+    TInt& /*aReason*/ )
+    {
+    FUNC_LOG;
+#ifdef __WINS__
+    return ETrue;
+#endif
+    TBool ret=ETrue;
+    //check offline mode. If set, we can't connect.
+    ret = !OfflineModeSetL();
+    if( ret )
+        {
+        ret = RoamingCheckL();
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::IsUnderUiProcess()
+    {
+    return iIsUnderUiProcess;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::OfflineModeSetL()
+    {
+    FUNC_LOG;
+    return !LocalFeatureL( KCRUidCoreApplicationUIs,
+        KCoreAppUIsNetworkConnectionAllowed, 1 );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::LocalFeatureL(
+    const TUid& aCenRepUid,
+    const TUint32 aKeyId,
+    const TUint32 aFlag )
+    {
+    FUNC_LOG;
+    // Create the connection to Central Repository
+    CRepository* cenrep = CRepository::NewLC( aCenRepUid );
+
+    // Fetch the value from the
+    TInt flags(0);
+    if ( cenrep )
+        {
+        cenrep->Get( aKeyId, flags );
+        }
+
+    // Remove the connection
+    CleanupStack::PopAndDestroy( cenrep );
+    cenrep = NULL;
+
+    // Return the result as a boolean value
+    return ( flags & aFlag ) == aFlag;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::RoamingCheckL()
+    {
+    FUNC_LOG;
+    //first check our registration status
+    TInt regStatus = RegistrationStatusL();
+
+    if ( regStatus == ENetworkRegistrationHomeNetwork )
+        {
+        return ETrue;
+        }
+    else if ( regStatus == ENetworkRegistrationRoaming )
+        {
+        //we're roaming. by default no auto connect when roaming.
+        return EFalse;
+        }
+    else
+        {
+        //other reg status states indicate that we cannot connect
+        //in any case.
+        //any different handling needed here?
+        return EFalse;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TInt CIpsPlgSosBasePlugin::RegistrationStatusL()
+    {
+    FUNC_LOG;
+    TRequestStatus status;
+    TInt registrationStatus( 0 );
+
+    //check network status
+    iConMon.ConnectL();
+
+    iConMon.GetIntAttribute(
+        EBearerIdGSM, 0, KNetworkRegistration,
+        registrationStatus, status );
+
+    User::WaitForRequest( status ); // faulty CS warning
+
+    iConMon.Close();
+
+    return registrationStatus;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSosBasePlugin::BlockCopyMoveFromFoldersL(
+    CMsvEntry* aFolderEntry,
+    TFSMailMsgId aFolderId,
+    CFSMailFolder& aFSMailFolder )
+    {
+    FUNC_LOG;
+    // Currently IPS plugin can connect automatically when doing the actual
+    // move/copy operation, so no need to block offline moves separately
+    RArray<TFSFolderType> blockFolders;
+    CleanupClosePushL( blockFolders );
+
+    // Move/Copy operations only between remote folders (+ IMAP Inbox) and
+    // Outbox -> Drafts, block others.
+    blockFolders.Reset();
+
+    if( ( GetFolderType( aFolderEntry, aFolderId ) != EFSOther ) &&
+        ( GetFolderType( aFolderEntry, aFolderId ) != EFSInbox ) )
+        {
+        blockFolders.Append( EFSInbox );
+        blockFolders.Append( EFSOther );
+        }
+
+    if( GetFolderType( aFolderEntry, aFolderId ) != EFSDraftsFolder )
+        {
+        blockFolders.Append( EFSOutbox );
+        }
+    blockFolders.Append( EFSSentFolder );
+    blockFolders.Append( EFSDraftsFolder );
+    blockFolders.Append( EFSDeleted );
+
+    // Block move/copy to this folder from blocklist, same blocklist
+    // applies to both online and offline moves/copies
+    aFSMailFolder.BlockCopyFromL( blockFolders, EFSMailBoxOnline );
+    aFSMailFolder.BlockMoveFromL( blockFolders, EFSMailBoxOnline );
+    aFSMailFolder.BlockCopyFromL( blockFolders, EFSMailBoxOffline );
+    aFSMailFolder.BlockMoveFromL( blockFolders, EFSMailBoxOffline );
+
+    CleanupStack::PopAndDestroy( &blockFolders );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::StoreIMEIToMailboxL( const TMsvId aMailboxId )
+    {
+    FUNC_LOG;
+    CMsvEntry* centry = iSession->GetEntryL( aMailboxId );
+    CleanupStack::PushL( centry );
+
+    TMsvEntry tentry = centry->Entry();
+    tentry.iDescription.Set( iIMEI );
+    centry->ChangeL( tentry );
+
+    CleanupStack::PopAndDestroy( centry );
+    centry = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TBool CIpsPlgSosBasePlugin::ConnOpRunning( const TFSMailMsgId& aMailBoxId  )
+    {
+    FUNC_LOG;
+    return iSyncStateHandler->ConnOpRunning( aMailBoxId );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::SetMailboxName(
+        const TFSMailMsgId& aMailboxId,
+        const TDesC& aMailboxName )
+    {
+    FUNC_LOG;
+    TMsvEntry tEntry;
+    TMsvId service;
+    iSession->GetEntry( aMailboxId.Id(), service, tEntry );
+    TRAP_IGNORE( iSettingsApi->SetMailboxNameL( tEntry, aMailboxName ) );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TUid CIpsPlgSosBasePlugin::MtmId() const
+    {
+    FUNC_LOG;
+    TUid ret = KSenduiMtmImap4Uid;
+    if ( iFSPluginId == KIpsPlgPop3PluginUidValue )
+        {
+        ret = KSenduiMtmPop3Uid;
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+TUint CIpsPlgSosBasePlugin::PluginId() const
+    {
+    return iFSPluginId;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void CIpsPlgSosBasePlugin::DeleteActivityTimer( const TFSMailMsgId& aMailboxId  )
+    {
+    FUNC_LOG;
+    TInt timerCount = iActivitytimers.Count();
+    for ( TInt j = 0; j < timerCount; j++ )
+        {
+        if ( iActivitytimers[j]->FSMailboxId() == aMailboxId )
+            {
+            delete iActivitytimers[j];
+            iActivitytimers[j] = NULL;
+            iActivitytimers.Remove( j );
+            timerCount--;
+            j--;
+            }
+        }
+    }
+