email/imum/Mtms/Src/Imap4MtmUi.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/imum/Mtms/Src/Imap4MtmUi.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,2939 @@
+/*
+* Copyright (c) 2006 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: 
+*       CImap4MtmUi - IMAP4 MTM UI
+*
+*/
+
+
+// Standard includes
+//
+#include <eikenv.h>//CEikonEnv
+#include <StringLoader.h>
+#include <avkon.mbg>
+
+//
+// Messaging includes
+//
+#include <mtmuidef.hrh>
+#include <mtclreg.h>
+#include <mtuireg.h>
+#include <eikproc.h>
+#include <MuiuMsgEditorLauncher.h>
+#include <etel.h> // KErrEtelBusyDetected
+#include <bldvariant.hrh>
+#include <etelpckt.h>
+#include <muiuflagger.h>            // CMuiuFlags
+
+#include <ErrorUI.h> // CErrorUI
+#include <mtmdef.h>
+#include <smtcmtm.h>
+#include <miuthdr.h>
+#include <MuiuMsvProgressReporterOperation.h>
+#include "PROGTYPE.H"
+#include "MsvEmailConnectionProgressProvider.h"
+
+// Specific includes
+//
+#include "impicmds.h"
+#include "ImumPanic.h"
+#include <imum.rsg>
+#include "IMAPPRGR.H"
+#include "Imap4MtmUi.h"
+#include <imapset.h>
+#include <impcmtm.h>
+#include "EmailUtils.H"
+#include "EmailFeatureUtils.h"
+#include "Imap4ConnectedOp.h"
+#include "Imap4FetchOp.h"
+#include "Imap4SizeAndFetchOp.h"
+#include "Imap4FetchAttachmentOp.h"
+#include "Imap4CopyMoveLocalOp.h"
+#include "Imap4ConnectedDeleteOp.h"
+#include "ImumDeleteMessagesLocally.h"
+#include "ImumDeleteMessagesFromServer.h"
+#include "RefreshImapFolderList.h"
+#include <Muiumsginfo.h>
+#include <Muiumsginfo.hrh>
+#include "ImumMtmLogging.h"
+#include "ImumDisconnectOperation.h"
+#include "ImumEditOperation.h"
+#include "ImumFetchAndEditOperation.h"
+#include "EmailEditorViewerUids.h"
+#include "MsvConnectionValidation.h"
+#include "IMSSettingsNoteUi.h"
+#include <ImumInternalApi.h>        // CImumInternalApi
+#include <ImumInHealthServices.h>
+#include "ImumListQueryDialog.h"
+
+#include <aknnotewrappers.h>  // CAknNoteDialog
+#include <MuiuOperationWait.h>
+// Constants
+const TInt KImumEntriesDoneReplaceIndex = 0;
+const TInt KImumTotalEntriesReplaceIndex = 1;
+const TInt KImumProgressBufferLengthSafe = CBaseMtmUi::EProgressStringMaxLen - 10; // 10 is enough to fill message numbers
+_LIT(KImpuMtmUiResourceFile, "imum.rsc");
+const TUint KForwardSlash = '/';
+const TUint KBackSlash = '\\';
+const TInt KImumDeleteMessagesLocally = 0;
+const TInt KImumMessageInfoBuffer = 32;
+const TInt KImumMessagePriorityBufferLength = 32;
+const TInt KImumApproxMailFetchSize = 1000;
+const TInt KErrDndNameNotFound = -5120;
+_LIT( KEmptySpace, " " );
+
+enum TImap4MtmUiOperations
+    {
+    EImap4MtmUiEditing=EUiProgTypeEditing
+    };
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::NewIMPUMtmUiL()
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CBaseMtmUi* NewIMPUMtmUiL(
+    CBaseMtm& aMtm,
+    CRegisteredMtmDll& aRegisteredDll )
+    {
+    return CImap4MtmUi::NewL(aMtm, aRegisteredDll);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::NewL()
+// ----------------------------------------------------------------------------
+//
+CImap4MtmUi* CImap4MtmUi::NewL(
+    CBaseMtm& aBaseMtm,
+    CRegisteredMtmDll& aRegisteredMtmDll )
+    {
+    IMUM_STATIC_CONTEXT( CImap4MtmUi::NewL, 0, mtm, KImumMtmLog );
+    IMUM_IN();
+
+    CImap4MtmUi* self=new(ELeave) CImap4MtmUi(aBaseMtm, aRegisteredMtmDll);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    IMUM_OUT();
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CImap4MtmUi()
+// ----------------------------------------------------------------------------
+//
+CImap4MtmUi::CImap4MtmUi(CBaseMtm& aBaseMtm, CRegisteredMtmDll& aRegisteredMtmDll)
+    :
+    CImumMtmBaseMtmUi( aBaseMtm, aRegisteredMtmDll )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CImap4MtmUi, 0, KImumMtmLog );
+    IMUM_IN();
+
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ConstructL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::ConstructL()
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ConstructL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CImumMtmBaseMtmUi::ConstructL();
+    iEntry = CMsvEntry::NewL(
+        Session(), KMsvRootIndexEntryId,
+        TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ) );
+    iEikonEnv->ReadResourceL( iInboxName, R_INBOX_NAME );
+
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::~CImap4MtmUi()
+// ----------------------------------------------------------------------------
+//
+CImap4MtmUi::~CImap4MtmUi()
+    {
+    IMUM_CONTEXT( CImap4MtmUi::~CImap4MtmUi, 0, KImumMtmLog );
+    IMUM_IN();
+
+    delete iEditorFilename;
+    delete iViewerFilename;
+    delete iEntry;
+
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetEditorFileNameL()
+// ----------------------------------------------------------------------------
+//
+HBufC* CImap4MtmUi::GetEditorFileNameL()
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetEditorFileNameL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if(!iEditorFilename)
+        {
+        iEditorFilename = MsvUiEditorUtilities::ResolveAppFileNameL(KUidMsgInternetMailEditor);
+        }
+    IMUM_OUT();
+    return iEditorFilename;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetViewerFileNameL()
+// ----------------------------------------------------------------------------
+//
+HBufC* CImap4MtmUi::GetViewerFileNameL()
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetViewerFileNameL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if(!iViewerFilename)
+        {
+        iViewerFilename = MsvUiEditorUtilities::ResolveAppFileNameL(KUidMsgInternetMailViewer);
+        }
+    IMUM_OUT();
+    return iViewerFilename;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CreateL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CreateL(
+    const TMsvEntry& /*aEntry*/,
+    CMsvEntry& /*aParent*/,
+    TRequestStatus& /*aStatus*/ )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CreateL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::OpenL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::OpenL( TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::OpenL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    const TMsvEntry& contextEntry=BaseMtm().Entry().Entry();
+    CheckEntryL(contextEntry);
+    if (contextEntry.iType == KUidMsvMessageEntry || contextEntry.iType == KUidMsvFolderEntry)
+        return EditL(aStatus);
+    else if (contextEntry.iType != KUidMsvServiceEntry)
+        User::Leave(KErrNotSupported);
+    //
+    // --- Trying to open a service ---
+
+    const TMsvId owningService=BaseMtm().Entry().OwningService();
+    const TInt serviceState=ServiceState(owningService);
+    if(!ServiceIsLoaded(serviceState) || ServiceIsDisconnected(serviceState))
+        {
+        CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection;
+        CleanupStack::PushL(sel);
+        sel->AppendL(contextEntry.Id());
+        //  Use the UI side connection wrapping operation
+        TBuf8<1> dummyParams;
+
+        CMsvOperation* op=InvokeAsyncFunctionL(
+            KImpiMTMConnectAndSyncCompleteAfterDisconnection,
+            *sel, aStatus, dummyParams);
+        CleanupStack::PopAndDestroy();//selection
+        IMUM_OUT();
+        return op;
+        }
+    else
+        {
+        IMUM_OUT();
+        //  Can't connect if we're not disconnected
+        return CompletedImap4OperationL(owningService, aStatus);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::OpenL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::OpenL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSelection )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::OpenL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CheckSelectionL(aSelection);
+    IMUM_OUT();
+    //
+    // --- Edit the message selection ---
+    return EditL(aStatus, aSelection);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CloseL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CloseL( TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CloseL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    const TMsvEntry& contextEntry=BaseMtm().Entry().Entry();
+    CheckEntryL(contextEntry);
+    // --- Check that current context is a service, all other entry types cannot be closed ---
+    if (contextEntry.iType!=KUidMsvServiceEntry)
+        User::Leave(KErrNotSupported);
+
+    const TMsvId owningServiceId=BaseMtm().Entry().OwningService();
+    TInt serviceState=ServiceState(owningServiceId);
+    CMsvOperation* op=NULL;
+    if ( !ServiceIsDisconnected(serviceState) && !ServiceIsDisconnecting(serviceState) )
+        {
+        //  Not disconnected or disconnecting, so try to close service
+        CMsvProgressReporterOperation* reporter =
+            CMsvProgressReporterOperation::NewL(
+                ETrue,
+                ETrue,
+                Session(),
+                aStatus,
+                EMbmAvkonQgn_note_progress );
+        CleanupStack::PushL(reporter);
+        op = CImumDisconnectOperation::NewL(*iMailboxApi, reporter->RequestStatus(), *reporter, contextEntry.Id(), KIMAP4MTMDisconnect, KUidMsgTypeIMAP4);
+        reporter->SetOperationL(op); // Takes immediate ownership
+        CleanupStack::Pop();    // reporter
+        op = reporter;
+        }
+    IMUM_OUT();
+    return op?op:CompletedImap4OperationL(owningServiceId, aStatus);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CloseL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CloseL(
+    TRequestStatus& /*aStatus*/,
+    const CMsvEntrySelection& /*aSelection*/ )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CloseL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // --- Multiple close is not supported ---
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::WithinIMAPInboxL()
+// ----------------------------------------------------------------------------
+//
+TBool CImap4MtmUi::WithinIMAPInboxL( TMsvId aEntryId )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::WithinIMAPInboxL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if (aEntryId==KMsvRootIndexEntryId)
+        return EFalse;
+    TBool withinInbox=EFalse;
+
+    CMsvEntry* myEntry=Session().GetEntryL(aEntryId);
+    CleanupStack::PushL(myEntry);
+
+    if (!(myEntry->OwningService()==KMsvLocalServiceIndexEntryId))
+        //  We're not under the local service
+        while (!withinInbox && myEntry->Entry().iType!=KUidMsvServiceEntry)
+            {
+            withinInbox = ( ( myEntry->Entry().iType==KUidMsvFolderEntry ) &&
+                ( myEntry->Entry().iDetails.CompareF(iInboxName) == 0 ) );
+            myEntry->SetEntryL(myEntry->Entry().Parent());
+            }
+
+    CleanupStack::PopAndDestroy();  //  myEntry
+    IMUM_OUT();
+    return withinInbox;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CompletedImap4OperationL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CompletedImap4OperationL(
+    TMsvId aServiceId,
+    TRequestStatus& aStatus)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CompletedImap4OperationL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TPckgBuf<TImap4UiProgress> newProgressBuf;
+    IMUM_OUT();
+    return CMsvCompletedOperation::NewL(Imap4BaseMtm()->Session(), Type(), newProgressBuf, aServiceId, aStatus, KErrNone);// KErrNone because we've reported the fact to the user
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::EditL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::EditL( TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::EditL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op=NULL;
+    const TMsvEntry& contextEntry=BaseMtm().Entry().Entry();
+    CheckEntryL(contextEntry);
+
+    switch (contextEntry.iType.iUid)
+        {
+    case KUidMsvServiceEntryValue:
+        if ( !iMailboxApi->HealthServicesL().IsMailboxHealthy(
+            contextEntry.Id() ) )
+            {
+            User::Leave( KErrNotFound );
+            }
+        op=EditImap4ServiceL( aStatus, contextEntry.iRelatedId );
+        break;
+    case KUidMsvMessageEntryValue:
+    case KUidMsvFolderEntryValue:
+        op=EditL(aStatus, *SingleEntrySelectionLC(contextEntry.Id()));
+        CleanupStack::PopAndDestroy();
+        break;
+    default:
+        User::Leave(KErrNotSupported);
+        }
+    IMUM_OUT();
+
+    return op?op:CompletedImap4OperationL(BaseMtm().Entry().OwningService(), aStatus);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::EditL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::EditL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSelection )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::EditL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op=NULL;
+
+    iEntry->SetEntryL(aSelection[0]);
+    const TMsvId owningService=iEntry->OwningService();
+
+    TMsvEmailEntry tentry=iEntry->Entry();
+
+    switch(iEntry->Entry().iType.iUid)
+        {
+    case KUidMsvServiceEntryValue:
+        BaseMtm().SwitchCurrentEntryL(tentry.Id());
+        op=EditL(aStatus);
+        break;
+    case KUidMsvMessageEntryValue:
+        {
+        if ( tentry.DisconnectedOperation() == EDisconnectedDeleteOperation )
+            {
+            // remove deleted flag
+            TInt error = MsvEmailMtmUiUtils::RemoveOfflineDeleteL(
+                BaseMtm(),
+                KIMAP4MTMUndeleteAll,
+                tentry.Id() );
+            User::LeaveIfError( error );
+            }
+
+        if(tentry.iRelatedId==KMsvNullIndexEntryId)
+            //  The entry is not a ghost - operate on it directly
+            //
+            if(tentry.BodyTextComplete())
+                {
+                op=LaunchMultipleEditorApplicationsL(aSelection, aStatus);
+                }
+            else
+                {
+                TEditorParameters editorParams;
+                editorParams.iId = aSelection[0];
+                editorParams.iFlags &= ~(EMsgLaunchEditorEmbedded | EMsgLaunchEditorThenWait);
+                editorParams.iFlags |= EMsgReadOnly;
+                const TUint preferences = Preferences();
+                if(preferences & EMtmUiFlagEditorPreferEmbedded)
+                    {
+                    editorParams.iFlags |= EMsgLaunchEditorEmbedded;
+                    }
+                if(!(preferences & EMtmUiFlagEditorNoWaitForExit))
+                    {
+                    editorParams.iFlags |= EMsgLaunchEditorThenWait;
+                    }
+
+                op = OpenMessageL(aStatus, editorParams);
+                }
+        else
+            {
+            //  The entry is a ghost entry - we need to follow the
+            //  iRelatedId back to the originator to determine what
+            //  we need to do.
+            iEntry->SetEntryL(tentry.iRelatedId);
+            tentry=iEntry->Entry();
+            if(tentry.BodyTextComplete())
+                {
+                CMsvEntrySelection* mySelection=SingleEntrySelectionLC(tentry.Id());
+                op=LaunchMultipleEditorApplicationsL(*mySelection, aStatus);
+                CleanupStack::PopAndDestroy();  //  mySelection
+                }
+            else
+                {
+                op=OfferSynchroniseL(owningService,aStatus);
+                }
+            }
+        }
+        break;
+    case KUidMsvFolderEntryValue:
+    default:
+        User::Leave(KErrNotSupported);
+        }
+    IMUM_OUT();
+    return op?op:CompletedImap4OperationL(owningService, aStatus);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ViewL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ViewL( TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ViewL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op = NULL;
+    TMsvEmailEntry context=BaseMtm().Entry().Entry();
+    if (context.iType != KUidMsvMessageEntry)
+        User::Leave(KErrNotSupported);
+
+    if(context.iRelatedId==KMsvNullIndexEntryId)
+        //  This entry is not a ghost entry - operate on it directly.
+        if(context.Complete())
+            {
+            op=LaunchEditorApplicationL(aStatus);
+            }
+        else
+            {
+            TEditorParameters editorParams;
+            editorParams.iId = context.Id();
+            editorParams.iFlags &= ~(EMsgLaunchEditorEmbedded | EMsgLaunchEditorThenWait);
+            editorParams.iFlags |= EMsgReadOnly;
+            const TUint preferences = Preferences();
+            if(preferences & EMtmUiFlagEditorPreferEmbedded)
+                {
+                editorParams.iFlags |= EMsgLaunchEditorEmbedded;
+                }
+            if(!(preferences & EMtmUiFlagEditorNoWaitForExit))
+                {
+                editorParams.iFlags |= EMsgLaunchEditorThenWait;
+                }
+            op = OpenMessageL(aStatus, editorParams);
+            }
+    else
+        {
+        //  The context is a ghost entry - follow the iRelatedId
+        //  back to the originating entry
+        BaseMtm().SwitchCurrentEntryL(context.iRelatedId);
+        if(BaseMtm().Entry().Entry().Complete())
+            op=LaunchEditorApplicationL(aStatus);
+        else
+            op=OfferSynchroniseL(BaseMtm().Entry().OwningService(),aStatus);
+        }
+    IMUM_OUT();
+
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ViewL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ViewL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSelection)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ViewL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    __ASSERT_DEBUG(aSelection.Count()>0,
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiSelectionIsEmpty));
+    BaseMtm().Entry().SetEntryL(aSelection[0]);
+    IMUM_OUT();
+    return ViewL(aStatus);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CopyToL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CopyToL(
+    const CMsvEntrySelection& /*aSelection*/,
+    TRequestStatus& /*aStatus*/)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CopyToL, 0, KImumMtmLog );
+
+    __ASSERT_DEBUG( EFalse,
+        User::Panic(KImumMtmUiPanic, EIMAP4MtmUiCopyToNotSupported ) );
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::MoveToL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::MoveToL(
+    const CMsvEntrySelection& /*aSelection*/,
+    TRequestStatus& /*aStatus*/)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::MoveToL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    __ASSERT_DEBUG( EFalse,
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiMoveToNotSupported ));
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CopyFromL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CopyFromL(
+    const CMsvEntrySelection& /*aSelection*/,
+    TMsvId /*aTargetId*/,
+    TRequestStatus& /*aStatus*/ )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CopyFromL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    __ASSERT_DEBUG( EFalse,
+        User::Panic( KImumMtmUiPanic,EIMAP4MtmUiCopyFromNotSupported ) );
+    User::Leave( KErrNotSupported );
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::MoveFromL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::MoveFromL(
+    const CMsvEntrySelection& /*aSelection*/,
+    TMsvId /*aTargetId*/,
+    TRequestStatus& /*aStatus*/)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::MoveFromL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Context should be MTM folder/service to move from
+    __ASSERT_DEBUG( EFalse,
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiMoveFromNotSupported ) );
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CancelL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::CancelL(
+    TRequestStatus& /*aStatus*/,
+    const CMsvEntrySelection& /*aSelection*/)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CancelL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Currently this function only used to suspend messages queued for sending.
+    // Can't send IMAP4 messages, so can't cancel them either.
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::QueryCapability()
+// Reporting on which commands are supported
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::QueryCapability( TUid aCapability, TInt& aResponse )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::QueryCapability, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+
+    return CBaseMtmUi::QueryCapability(aCapability, aResponse);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ServiceState()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::ServiceState( TMsvId aServiceId ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ServiceState, 0, KImumMtmLog );
+    IMUM_IN();
+
+    //  Inline functions are provided to test the returned status flags
+    //
+    TPckgBuf<TImap4CompoundProgress> myProgressBuf;
+    const TInt error=BaseMtm().Session().ServiceProgress(aServiceId, myProgressBuf);
+
+    TInt statusFlags=0;
+    if(!error)  //  NB. If error, all the flags should be returned unset
+        {
+        TImap4GenericProgress::TImap4GenericProgressState genericProgressState=myProgressBuf().iGenericProgress.iState;
+        TImap4SyncProgress::TImap4SyncProgressState syncProgressState=myProgressBuf().iSyncProgress.iState;
+
+        statusFlags|=
+            (genericProgressState==TImap4GenericProgress::EIdle &&
+            syncProgressState==TImap4SyncProgress::EIdle)?EIsIdle:0;
+
+        statusFlags|=
+            (genericProgressState==TImap4GenericProgress::EDisconnected)?EIsDisconnected:0;
+
+        statusFlags|=
+            (genericProgressState==TImap4GenericProgress::EConnecting)?EIsConnecting:0;
+
+        statusFlags|=
+            (genericProgressState==TImap4GenericProgress::EDisconnecting)?EIsDisconnecting:0;
+
+        statusFlags|=EIsLoaded; //  Must be loaded to have been able to get the progress
+        }
+    else
+        //  Service is not loaded, we can set the disconnected flag accordingly
+        statusFlags|=EIsDisconnected;
+    IMUM_OUT();
+    return statusFlags;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::IsConnected()
+// ----------------------------------------------------------------------------
+//
+TBool CImap4MtmUi::IsConnected( const TMsvId aService ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::IsConnected, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+    return(!ServiceIsDisconnected(ServiceState(aService)));
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::InvokeAsyncFunctionL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::InvokeAsyncFunctionL(
+                TInt aFunctionId,
+                const CMsvEntrySelection& aSelection,
+                TRequestStatus& aStatus,
+                TDes8& aParameter )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InvokeAsyncFunctionL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op = NULL;
+
+    //Offline checks VARIATION START
+    if( iFeatureFlags->GF( EMailFeatureOfflineMode ) &&
+        aFunctionId != KMtmUiFunctionMessageInfo )
+        {
+        TMsvId mailboxId = BaseMtm().Entry().EntryId();
+        //No need to do this if we're online...
+        TBool offline = EFalse;
+        if( !IsConnected( mailboxId ) &&
+            !iMailboxApi->MailboxUtilitiesL().HasWlanConnectionL( mailboxId ) )
+            {
+            offline = MsvEmailMtmUiUtils::DoOfflineChecksL( mailboxId );
+            }
+
+        if( offline )
+            {
+            op = CMsvCompletedOperation::NewL(
+                Session(), Type(), KNullDesC8,
+                KMsvLocalServiceIndexEntryId, aStatus, KErrCancel );
+            return op;
+            }
+        }//if
+    //VARIATION END
+
+    switch( aFunctionId )
+        {
+    case KMtmUiFunctionFetchAll:    // 'Fetch All'
+    case KMtmUiFunctionFetchNew:    // 'Fetch New'
+        {
+        // aSelection is empty.
+        TImImap4GetMailInfo getMailInfo;
+        CMsvEntrySelection* sel = new ( ELeave ) CMsvEntrySelection;
+        CleanupStack::PushL( sel );
+        InitParametersForFetchCmdL( sel, getMailInfo );
+        if( aFunctionId == KMtmUiFunctionFetchAll )
+            {
+            aFunctionId = KIMAP4MTMPopulateAllMailWhenAlreadyConnected;
+            }
+        else
+            {
+            aFunctionId = KIMAP4MTMPopulateNewMailWhenAlreadyConnected;
+            }
+        op = FetchMessagesL( aStatus, *sel, aFunctionId, getMailInfo );
+        CleanupStack::PopAndDestroy(); // sel
+        }
+        break;
+
+    case KMtmUiFunctionFetchSelected:   // 'Fetch Selected'
+        // aSelection contains the messages to populate.
+        op = PopulateMessagesL( aStatus, aSelection );
+        break;
+
+    case KImpiMTMConnect:
+    case KImpiMTMConnectAndSyncCompleteAfterConnection:
+    case KImpiMTMConnectAndSyncCompleteAfterFolderSync:
+    case KImpiMTMConnectAndSyncCompleteAfterDisconnection:
+    case KImpiMTMRefreshFolderList:
+        {
+        if( aFunctionId != KImpiMTMRefreshFolderList )
+            {
+            TImImap4GetPartialMailInfo partialGetMailInfo;
+            CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
+            CleanupStack::PushL( sel );
+
+            InitParametersForFilteredPopulateL( *sel, partialGetMailInfo );
+            if( partialGetMailInfo.iPartialMailOptions != ENoSizeLimits )
+                {
+                //if partial fetch is used, we connect this way
+                op = DoFilteredPopulateL(aStatus, *sel, aFunctionId, partialGetMailInfo );
+                CleanupStack::PopAndDestroy(); //sel
+                break;
+                }
+            else
+                {
+                CleanupStack::PopAndDestroy(); //sel
+                }
+            }//if
+
+        //  All function IDs requiring a progress reporter op
+        CMsvProgressReporterOperation* myProgressReporterOp=
+            CMsvProgressReporterOperation::NewL(
+                ETrue, ETrue, Session(),
+                aStatus, EMbmAvkonQgn_note_progress );
+
+        CleanupStack::PushL( myProgressReporterOp );
+        CMsvOperation* wrappedOp = NULL;
+
+        if( aFunctionId != KImpiMTMRefreshFolderList )
+            {
+            //  Must be some flavour of connection op
+
+            __ASSERT_DEBUG( aSelection.Count(),
+                User::Panic(KImumMtmUiPanic, EIMAP4MtmUiNoService ) );
+            if( aSelection.Count() == 0 )
+                {
+                op = CMsvCompletedOperation::NewL(
+                        Session(), Type(), KNullDesC8,
+                        KMsvLocalServiceIndexEntryId, aStatus, KErrCancel );
+                break;
+                }
+
+            iEntry->SetEntryL( aSelection[ 0 ] );
+            const TMsvId service = iEntry->OwningService();
+
+            CImapConnectionOp::TImapConnectionType connectionCase =
+                CImapConnectionOp::EWithSyncCompleteAfterDisconnection;
+            switch( aFunctionId )
+                {
+            case KImpiMTMConnect:
+                connectionCase = CImapConnectionOp::ECompleteAfterConnect;
+                break;
+            case KImpiMTMConnectAndSyncCompleteAfterConnection:
+                connectionCase = CImapConnectionOp::EWithSyncCompleteAfterConnect;
+                break;
+            case KImpiMTMConnectAndSyncCompleteAfterFolderSync:
+                connectionCase = CImapConnectionOp::EWithSyncCompleteAfterFullSync;
+                break;
+            default:
+                break;
+                }
+
+            wrappedOp = CImapConnectionOp::NewL(
+                iMailboxApi->MsvSession(), CActive::EPriorityStandard,
+                myProgressReporterOp->RequestStatus(),      // ie. complete the reporter when finished
+                service, *myProgressReporterOp, // the reporter owns the wrapped op
+                connectionCase );
+
+            myProgressReporterOp->SetOperationL( wrappedOp ); // Takes immediate ownership
+
+            TBuf<EProgressStringMaxLen> title;
+            MsvEmailMtmUiUtils::CreateConnectingToText( title,
+                Session(), BaseMtm().Entry().EntryId() );
+
+            myProgressReporterOp->SetTitleL( title );
+            }
+
+        else
+            {
+            //note text for imap folderlist update
+            HBufC* title = StringLoader::LoadLC(
+                R_IMAS_SETTINGS_DIALOG_UPDATING_FOLDERLIST, iCoeEnv );
+
+            myProgressReporterOp->SetTitleL( *title );
+            wrappedOp = CImapConnectAndRefreshFolderList::NewL(
+                *iMailboxApi, CActive::EPriorityStandard,
+                myProgressReporterOp->RequestStatus(), aSelection[ 0 ],
+                *myProgressReporterOp );
+            myProgressReporterOp->SetOperationL( wrappedOp ); //  Takes immediate ownership
+            CleanupStack::PopAndDestroy( title );
+            }
+        CleanupStack::Pop();    //  myProgressReporterOp
+        op = myProgressReporterOp;
+        }
+        break;
+    case KImpiMTMFetchAttachments:
+        {
+        __ASSERT_DEBUG( aSelection.Count(),
+            User::Panic(KImumMtmUiPanic, EIMAP4MtmUiSelectionIsEmpty ) );
+        if ( aSelection.Count() > 0 )
+            {
+            iEntry->SetEntryL( aSelection[ 0 ] );
+            const TMsvId service = iEntry->OwningService();
+            CMsvProgressReporterOperation* reporter =
+                CMsvProgressReporterOperation::NewL(
+                    Session(), aStatus, EMbmAvkonQgn_note_progress );
+            CleanupStack::PushL( reporter );
+            op = CImap4FetchAttachmentOp::NewL(
+                *iMailboxApi, reporter->RequestStatus(),
+                *reporter, service, aSelection );
+            reporter->SetOperationL( op );    //  Takes immediate ownership
+            CleanupStack::Pop();    //  reporter
+            op = reporter;
+            }
+        else
+            {
+            op = CMsvCompletedOperation::NewL(
+                Session(), Type(), KNullDesC8,
+                KMsvLocalServiceIndexEntryId, aStatus, KErrCancel );
+            }
+        }
+        break;
+
+    case KMtmUiFunctionMessageInfo:
+        IMUM_OUT();
+        return ShowMessageInfoL( aStatus, aParameter );
+
+    case KIMAP4MTMConnectAndSyncCompleteAfterFullSync:
+    default:
+        op=BaseMtm().InvokeAsyncFunctionL(
+            aFunctionId, aSelection,
+            aParameter, aStatus );
+        break;
+        }
+    IMUM_OUT();
+    return op;
+    }
+
+
+// ----------------------------------------------------------------------------
+// InitParametersForFilteredPopulateL
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::InitParametersForFilteredPopulateL(
+    CMsvEntrySelection& aSelection,
+    TImImap4GetPartialMailInfo& aPartialGetMailInfo)
+        {
+        CMsvEntrySelection* serviceChildren = BaseMtm().Entry().ChildrenL();
+        CleanupStack::PushL(serviceChildren);
+
+        aSelection.AppendL( BaseMtm().Entry().Entry().Id() );
+
+        //add inbox to selection
+
+        const TMsvId inboxId = SelectionContainsInboxL(BaseMtm().Entry(),*serviceChildren);
+        CleanupStack::PopAndDestroy();
+
+        aSelection.AppendL( inboxId );
+
+        //read settings
+        Imap4BaseMtm()->RestoreSettingsL();
+        const CImImap4Settings& settings = Imap4BaseMtm()->Imap4Settings();
+
+        aPartialGetMailInfo.iPartialMailOptions = settings.PartialMailOptions();
+        aPartialGetMailInfo.iBodyTextSizeLimit = settings.BodyTextSizeLimit();
+        aPartialGetMailInfo.iAttachmentSizeLimit = settings.AttachmentSizeLimit();
+        aPartialGetMailInfo.iTotalSizeLimit = aPartialGetMailInfo.iBodyTextSizeLimit +
+                                            aPartialGetMailInfo.iAttachmentSizeLimit;
+        }
+
+// ----------------------------------------------------------------------------
+// DoFilteredPopulateL
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::DoFilteredPopulateL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSelection,
+    TInt aFunctionId,
+    TImImap4GetPartialMailInfo& aPartialGetMailInfo)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InitParametersForFilteredPopulateL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvProgressReporterOperation* reporter =
+        CMsvProgressReporterOperation::NewL(
+            Session(), aStatus, EMbmAvkonQgn_note_progress );
+    CleanupStack::PushL(reporter);
+    const TMsvId service = BaseMtm().Entry().OwningService();
+
+    // Set func id as null, because we're only connecting, not
+    // fetching anything. ( fetching is done internally
+    // by fetchop, because we're populating )
+    CMsvOperation* fetch = CImap4FetchOp::NewL(
+        *iMailboxApi, reporter->RequestStatus(), *reporter,
+        service, aFunctionId, aPartialGetMailInfo, aSelection );
+    reporter->SetOperationL(fetch); // Takes immediate ownership
+    CleanupStack::Pop(); // reporter
+    IMUM_OUT();
+    return reporter;
+    }
+
+// ----------------------------------------------------------------------------
+// InvokeSyncFunctionL
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::InvokeSyncFunctionL(
+    TInt aFunctionId,
+    const CMsvEntrySelection& aSelection,
+    TDes8& aParameter )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InvokeSyncFunctionL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CBaseMtmUi::InvokeSyncFunctionL(aFunctionId, aSelection, aParameter);
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::PopulateMessagesSyncL()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::PopulateMessagesSyncL( const CMsvEntrySelection& aSelection )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::PopulateMessagesSyncL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvEntrySelection* sel = StripBodyTextCompleteEntriesLC(aSelection);
+    const TInt count = sel->Count();
+    CleanupStack::PopAndDestroy(); // sel
+    if(!count)
+        {
+        IMUM_OUT();
+        // Have body text.
+        return KErrNone;
+        }
+
+    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
+    waiter->iStatus = KRequestPending;
+    CMsvOperation* op = PopulateMessagesL(waiter->iStatus, aSelection);
+    CleanupStack::PushL(op);
+
+    waiter->Start();
+    CActiveScheduler::Start();
+    const TInt err = DisplayProgressSummary(op->ProgressL());
+    CleanupStack::PopAndDestroy(2); // CSI: 47 # op, waiter
+    IMUM_OUT();
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetResourceFileName()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::GetResourceFileName( TFileName& aFileName ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetResourceFileName, 0, KImumMtmLog );
+    IMUM_IN();
+
+    aFileName=KImpuMtmUiResourceFile;
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetProgress()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::GetProgress(
+    const TDesC8& aProgress,
+    TBuf<EProgressStringMaxLen>& aReturnString,
+    TInt& aTotalEntryCount,
+    TInt& aEntriesDone,
+    TInt& aCurrentEntrySize,
+    TInt& aCurrentBytesTrans ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetProgress, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if( (!aProgress.Length()) || (aProgress.Size() == sizeof(TMsvLocalOperationProgress)) )
+        return KErrNone;
+
+    TPckgC<TInt> type(0);
+    type.Set(aProgress.Left(sizeof(TInt)));
+    switch (type())
+        {
+    case KImap4UiProgressType:
+        //  IMAP specific UI buffer
+        return GetUiProgress(aProgress, aReturnString, aTotalEntryCount, aEntriesDone, aCurrentEntrySize, aCurrentBytesTrans);
+
+    case EUiProgTypeSizingMsg:
+        // Email message sizer operation progress - we don't decode this
+        // Fall-through
+    case EUiProgTypeEditing:
+        //  Email editing progress - we don't decode this
+        //  Fall-through
+    case EUiProgTypeConnecting:
+        //  Email connection progress - we don't decode this
+        return KErrNone;
+
+    case EImap4SyncProgressType:
+        return GetSyncProgress(aProgress, aReturnString, aTotalEntryCount, aEntriesDone, aCurrentEntrySize, aCurrentBytesTrans);
+        //  Fall-through
+    default:
+        break;
+        }
+
+    //  If none of the above are true, then we should be getting a TImap4CompoundProgress,
+    //  of which we should just decode the GenericProgress part (unless we are in the middle of
+    //  a sync operation)
+    __ASSERT_DEBUG(type() == EImap4GenericProgressType,
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiInvalidProgress));
+
+    TPckgBuf<TImap4CompoundProgress> paramPack;
+    paramPack.Copy(aProgress);
+    const TImap4GenericProgress& progress=paramPack().iGenericProgress;
+    TInt sliderTotal=0;
+    TInt sliderNumber=0;
+    TInt itemTotal=progress.iMsgsToDo;
+    TInt itemNumber=Min(itemTotal, progress.iMsgsDone+1);
+
+    TInt resourceId=0;
+    switch(progress.iOperation)
+        {
+        case TImap4GenericProgress::ECopyWithinService:
+        case TImap4GenericProgress::EMoveWithinService:
+            __ASSERT_DEBUG(EFalse,
+                User::Panic(KImumMtmUiPanic,EIMAP4MtmUiProgressMoveCopyWithinServiceNotSupported));
+        break;
+        case TImap4GenericProgress::ECopyToLocal:
+        case TImap4GenericProgress::EOffLineCopyToLocal:
+        case TImap4GenericProgress::EOffLineCopyFromLocal:
+        case TImap4GenericProgress::EOffLineCopyWithinService:
+            resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_COPYING) : (R_IMAP4_PROGRESS_COPYING_MULTI);
+            if(itemTotal==1)
+                {
+                sliderTotal=progress.iBytesToDo;
+                sliderNumber=progress.iBytesDone;
+                }
+            else
+                {
+                sliderTotal=progress.iMsgsToDo;
+                sliderNumber=progress.iMsgsDone;
+                }
+            break;
+
+        case TImap4GenericProgress::EPopulate:
+        case TImap4GenericProgress::EOffLinePopulate:
+            {
+            resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_FETCHING) : (R_IMAP4_PROGRESS_FETCHING_MULTI);
+            //We don't want slider to be displayed. When no progress info, wait animation is shown instead.
+            sliderTotal=0;
+			sliderNumber=0;
+            }
+            break;
+        case TImap4GenericProgress::EOffLineUndelete:
+            {
+            resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_UNDELETING) : (R_IMAP4_PROGRESS_UNDELETING_MANY);
+            }
+            break;
+        case TImap4GenericProgress::ESync:
+            {
+            TPckg<TImap4SyncProgress> syncProgress(paramPack().iSyncProgress);
+            return GetSyncProgress(syncProgress, aReturnString, aTotalEntryCount, aEntriesDone, aCurrentEntrySize, aCurrentBytesTrans);
+            }
+
+        default:
+            {
+            switch(STATIC_CAST(TInt,progress.iState))
+                {
+                case TImap4GenericProgress::EConnecting:
+                case TImap4GenericProgress::EDisconnecting:
+                case TImap4GenericProgress::EDisconnected:
+                case TImap4GenericProgress::EIdle:
+                case TImap4GenericProgress::ESelecting:
+                    //  No progress string to be returned for these,
+                    //  inc. no slider
+                    break;
+                case TImap4GenericProgress::EBusy:
+                case TImap4GenericProgress::ESyncing:
+                    sliderTotal=itemTotal;
+                    sliderNumber=progress.iMsgsDone;
+                    resourceId=R_IMAP4_PROGRESS_INBOXSYNC;
+                    break;
+                case TImap4GenericProgress::EDeleting:
+                    if( (itemTotal == 0) && (itemNumber == 0) )
+                        {
+                        // IMPS does not report counts for folder deletions, but does for messages.
+                        resourceId=R_IMAP4_PROGRESS_DELETING;
+                        }
+                    else
+                        {
+                        resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_DELETING) : (R_IMAP4_PROGRESS_DELETING_MANY);
+                        }
+                    break;
+                case TImap4GenericProgress::EFetching:
+                case TImap4GenericProgress::EPopulateNewMail:
+                case TImap4GenericProgress::EPopulateAllMail:
+                case TImap4GenericProgress::EPopulateMailSelection:
+                    {
+                    resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_FETCHING) : (R_IMAP4_PROGRESS_FETCHING_MULTI);
+                    sliderTotal=progress.iBytesToDo;
+                    sliderNumber=progress.iBytesDone;
+                    }
+                    break;
+                case TImap4GenericProgress::EAppending:
+                    __ASSERT_DEBUG(EFalse,
+                        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiProgressAppendingNotSupported));
+                    sliderTotal=progress.iBytesToDo;
+                    sliderNumber=progress.iBytesDone;
+                    break;
+                case TImap4GenericProgress::EMoveNewMail:
+                case TImap4GenericProgress::EMoving:
+                case TImap4GenericProgress::EMoveMailSelection:
+                case TImap4GenericProgress::EMoveAllMail:
+                    __ASSERT_DEBUG(EFalse,
+                        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiProgressMoveNotSupported));
+                    // drop through
+                case TImap4GenericProgress::ECopying:
+                case TImap4GenericProgress::ECopyNewMail:
+                case TImap4GenericProgress::ECopyMailSelection:
+                case TImap4GenericProgress::ECopyAllMail:
+                    resourceId = (itemTotal==1) ? (R_IMAP4_PROGRESS_COPYING) : (R_IMAP4_PROGRESS_COPYING_MULTI);
+                    sliderTotal=progress.iBytesToDo;
+                    sliderNumber=progress.iBytesDone;
+                    break;
+                case EImap4MtmUiEditing:
+                    break;
+                default:
+                    __ASSERT_DEBUG(EFalse,
+                        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiInvalidProgress));
+                    break;
+                };  // end ofinner switch case
+            };  //  end of outer switch's default
+        };  // end of outer switch
+
+
+	if ( progress.iOperation == TImap4GenericProgress::EPopulate )
+		{
+		//We don't want slider to be displayed. When no progress info, wait animation is shown instead.
+		aEntriesDone=0;
+	    aTotalEntryCount=0;
+	    aCurrentEntrySize=0;
+	    aCurrentBytesTrans=0;
+		}
+	else
+		{
+		aEntriesDone=itemNumber;
+	    aTotalEntryCount=itemTotal;
+	    aCurrentEntrySize=sliderTotal;
+	    aCurrentBytesTrans=sliderNumber;
+		}
+
+    if (resourceId!=0)
+        {
+        StringLoader::Load( aReturnString, resourceId, iCoeEnv);
+        if ( itemTotal>1 )
+            {
+            aReturnString = aReturnString.Left( KImumProgressBufferLengthSafe );
+            TBuf<EProgressStringMaxLen> tempBuffer;
+            StringLoader::Format(
+                tempBuffer,
+                aReturnString,
+                KImumEntriesDoneReplaceIndex,
+                itemNumber );
+            StringLoader::Format(
+                aReturnString,
+                tempBuffer,
+                KImumTotalEntriesReplaceIndex,
+                itemTotal );
+            }
+        }
+    else
+        {
+        aReturnString.Zero();
+        }
+    IMUM_OUT();
+
+    return progress.iErrorCode;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetSyncProgress()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::GetSyncProgress(
+    const TDesC8& aProgress,
+    TBuf<EProgressStringMaxLen>& aReturnString,
+    TInt& aTotalEntryCount,
+    TInt& aEntriesDone,
+    TInt& aCurrentEntrySize,
+    TInt& aCurrentBytesTrans ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetSyncProgress, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TPckgBuf<TImap4SyncProgress> progressPack;
+    progressPack.Copy(aProgress);
+    const TImap4SyncProgress& progress=progressPack();
+
+    TInt sliderTotal=0;
+    TInt sliderNumber=0;
+    TInt itemTotal=progress.iFoldersToDo;
+    TInt itemNumber=Min(itemTotal, progress.iFoldersDone);
+
+    TInt resourceId=0;
+
+    switch(progress.iState)
+        {
+    case TImap4SyncProgress::EIdle:
+    case TImap4SyncProgress::EConnecting:
+    case TImap4SyncProgress::EDisconnecting:
+    case TImap4SyncProgress::ESyncFolderTree:
+        //  No progress string to be returned for these states.
+        break;
+    case TImap4SyncProgress::ESyncInbox:
+        resourceId=R_IMAP4_PROGRESS_INBOXSYNC;
+        sliderTotal=progress.iMsgsToDo;
+        sliderNumber=progress.iMsgsDone;
+        break;
+    case TImap4SyncProgress::ECheckRemoteSubscription:
+    case TImap4SyncProgress::EUpdateRemoteSubscription:
+        __ASSERT_DEBUG(EFalse,
+            User::Panic(KImumMtmUiPanic,EIMAP4MtmUiSyncProgressFolder));
+        sliderTotal=0;
+        sliderNumber=0;
+        itemTotal=progress.iFoldersToDo;
+        itemNumber=progress.iFoldersDone;
+        break;
+    case TImap4SyncProgress::ESyncOther:
+    case TImap4SyncProgress::EBusy:
+    case TImap4SyncProgress::EDeleting:
+    case TImap4SyncProgress::EProcessingPendingOps:
+        resourceId=R_IMAP4_PROGRESS_INBOXSYNC;
+        sliderTotal=progress.iFoldersToDo;
+        sliderNumber=progress.iFoldersDone;
+        itemTotal=progress.iFoldersToDo;
+        itemNumber=progress.iFoldersDone;
+        break;
+    default:
+        break;
+        }
+
+    aEntriesDone=sliderNumber;
+    aTotalEntryCount=sliderTotal;
+    aCurrentEntrySize=sliderTotal;
+    aCurrentBytesTrans=sliderNumber;
+
+    if (resourceId!=0)
+        {
+        StringLoader::Load( aReturnString, resourceId, iCoeEnv);
+        }
+    else
+        {
+        aReturnString.Zero();
+        }
+    IMUM_OUT();
+
+    return progress.iErrorCode;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::GetUiProgress()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::GetUiProgress(
+    const TDesC8& aProgress,
+    TBuf<EProgressStringMaxLen>& aReturnString,
+    TInt& aTotalEntryCount,
+    TInt& aEntriesDone,
+    TInt& aCurrentEntrySize,
+    TInt& aCurrentBytesTrans ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::GetUiProgress, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TPckgBuf<TImap4UiProgress> paramPack;
+    paramPack.Copy(aProgress);
+    const TImap4UiProgress& progress=paramPack();
+
+    TInt resourceId=0;
+
+    switch(progress.iUiOperation)
+        {
+        case TImap4UiProgress::ESynchronising:
+            __ASSERT_DEBUG(EFalse,
+                User::Panic(KImumMtmUiPanic,EIMAP4MtmUiUiProgressSync));
+            break;
+        case TImap4UiProgress::ECreatingFolder:
+            __ASSERT_DEBUG(EFalse,
+                User::Panic(KImumMtmUiPanic,EIMAP4MtmUiUiProgressCreateFolder));
+            break;
+        case TImap4UiProgress::EFetchingAttachment:
+            resourceId=R_IMAP4_GETTING_ATTACHMENT;
+        default:
+            //  NB. the "default" category includes purging
+            //  attachments which should happen very quickly and
+            //  not require any progress during it's activity
+            break;
+        }
+
+    aEntriesDone=progress.iFoldersDone;
+    aTotalEntryCount=progress.iFoldersToDo;
+    aCurrentEntrySize=progress.iBytesToDo;
+    aCurrentBytesTrans=progress.iBytesDone;
+    if (resourceId==0)
+        {
+        aReturnString.Zero();
+        }
+    else
+        {
+        StringLoader::Load( aReturnString, resourceId, iCoeEnv);
+        };
+    IMUM_OUT();
+
+    return progress.iError;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DisplayProgressSummary()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::DisplayProgressSummary( const TDesC8& aProgress ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DisplayProgressSummary, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if ( ( !aProgress.Length() ) ||
+         ( aProgress.Size() == sizeof(TMsvLocalOperationProgress) ) )
+        return KErrCancel; // Probably a CMsvCompletedOperation
+
+    TPckgC<TInt> type(0);
+    type.Set( aProgress.Left( sizeof(TInt) ) );
+    switch( type() )
+        {
+    case KImap4UiProgressType:
+        IMUM_OUT();
+        return DisplayUiProgressSummary( aProgress );
+
+    case EUiProgTypeEditing:
+        // Email message editing/viewing progress, ignore errors.
+        //  Fall through...
+    case EUiProgTypeSizingMsg:
+        // Email message sizer operation progress, ignore errors.
+        IMUM_OUT();
+        return KErrNone;
+    case EUiProgTypeConnecting:
+        //  Email connection progress
+        IMUM_OUT();
+        return DisplayConnectionProgressSummary( aProgress );
+
+    case EImap4SyncProgressType:
+        IMUM_OUT();
+        return DisplaySyncProgressSummary( aProgress );
+
+    default:
+        break;
+        }
+
+    //  Should be a TImap4CompoundProgress
+    __ASSERT_DEBUG( type() == EImap4GenericProgressType,
+        User::Panic(KImumMtmUiPanic, EIMAP4MtmUiInvalidProgress ) );
+
+    TPckgBuf<TImap4CompoundProgress> paramPack;
+    paramPack.Copy( aProgress );
+    const TImap4CompoundProgress& progress = paramPack();
+    const TImap4GenericProgress& genericProgress = progress.iGenericProgress;
+    const TImap4SyncProgress& syncProgress = progress.iSyncProgress;
+
+    TBool displayErrorNote = EFalse;
+    TInt messageRID = 0;
+    TInt errorCode = KErrNone;
+    if ( genericProgress.iOperation == TImap4GenericProgress::EConnect ||
+         genericProgress.iOperation == TImap4GenericProgress::EDisconnect ||
+         genericProgress.iOperation == TImap4GenericProgress::ESync )
+        {
+        //  We take the progress from the sync progress part
+        errorCode = syncProgress.iErrorCode;
+        if ( errorCode == KErrNone )
+            {
+            // Belt and braces approach; check generic progress for errors too.
+            errorCode = genericProgress.iErrorCode;
+            }
+        if ( errorCode != KErrNone )
+            {
+            // There was an error.
+            switch ( genericProgress.iOperation )
+                {
+            case TImap4GenericProgress::EConnect:
+                //  If we are connecting, we should discount KErrCancels
+                //  Also KErrNotSupported
+                if( ( errorCode != KErrCancel ) &&
+                    ( errorCode != KErrNotSupported ) )
+                    {
+                    displayErrorNote = ETrue;
+                    }
+                break;
+            case TImap4GenericProgress::EDisconnect:
+                if ( errorCode == KErrTimedOut )
+                    {
+                    displayErrorNote = ETrue;
+                    messageRID = R_IMAP4_TIMEOUT_DIALOG_TEXT;
+                    }
+                else
+                    {
+                    displayErrorNote = ETrue;
+                    }
+                break;
+            case TImap4GenericProgress::ESync:
+                displayErrorNote = ETrue;
+                //  Fall through
+            default:
+                break;
+                };
+            }
+        }
+    else    //  We take the progress from the generic progress part
+        {
+        errorCode=genericProgress.iErrorCode;
+        if ( errorCode == KErrNone )
+            {
+            // Belt and braces approach; check sync progress for errors too.
+            errorCode=syncProgress.iErrorCode;
+            }
+        if ( errorCode != KErrNone && errorCode != KErrCancel )
+            {
+            // There was an error.
+            switch ( genericProgress.iOperation )
+                {
+            case TImap4GenericProgress::EPopulate:
+            case TImap4GenericProgress::ECopyToLocal:
+            case TImap4GenericProgress::ECopyWithinService:
+            case TImap4GenericProgress::ECopyFromLocal:
+            case TImap4GenericProgress::EMoveToLocal:
+            case TImap4GenericProgress::EMoveWithinService:
+            case TImap4GenericProgress::EMoveFromLocal:
+                displayErrorNote = ETrue;
+                break;
+            default:
+                break;
+                }
+            }
+        }
+    if ( displayErrorNote )
+        {
+        IMUM_OUT();
+        // messageRID can be 0 and then error text is received from error resolver
+        return ShowErrorDialog( errorCode, messageRID );
+        }
+    IMUM_OUT();
+    return errorCode;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DisplaySyncProgressSummary()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::DisplaySyncProgressSummary( const TDesC8& aProgress ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DisplaySyncProgressSummary, 0, KImumMtmLog );
+    IMUM_IN();
+
+    //  Sync progress is only returned by a connection operation
+    TPckgBuf<TImap4SyncProgress> paramPack;
+    paramPack.Copy( aProgress );
+    const TImap4SyncProgress& syncProgress = paramPack();
+
+    TBool displayErrorNote = EFalse;
+    TInt messageRID = 0;
+
+    if ( syncProgress.iErrorCode == KErrNone )
+        {
+        IMUM_OUT();
+        return KErrNone;
+        }
+    else
+        {
+        switch ( syncProgress.iState )
+            {
+            case TImap4SyncProgress::EConnecting:
+                if ( syncProgress.iErrorCode == KErrTimedOut )
+                    {
+                    displayErrorNote = ETrue;
+                    messageRID=R_IMAP4_TIMEOUT_DIALOG_TEXT;
+                    }
+                else if ( syncProgress.iErrorCode == KErrDndNameNotFound )
+                    {
+                    displayErrorNote = ETrue;
+                    messageRID = R_MAIL_ERR_NO_IN_SRVR;
+                    }
+                else if ( (syncProgress.iErrorCode != KErrCancel ) &&
+                         ( syncProgress.iErrorCode != KErrNotSupported ) )
+                    //  If we are connecting, we should discount KErrCancels
+                    //  Also KErrNotSupported
+                    {
+                    displayErrorNote = ETrue;
+                    }
+                break;
+            case TImap4SyncProgress::EDisconnecting:
+                displayErrorNote = ETrue;
+                if ( syncProgress.iErrorCode == KErrTimedOut )
+                    {
+                    messageRID = R_IMAP4_TIMEOUT_DIALOG_TEXT;
+                    }
+                break;
+            case TImap4SyncProgress::EIdle:
+                displayErrorNote = ETrue;
+                messageRID=R_IMAP4_TIMEOUT_DIALOG_TEXT;
+                break;
+            default:
+                //  All the rest of the sync states are related to syncing
+                displayErrorNote = ETrue;
+            break;
+            };
+        }
+    IMUM_OUT();
+
+    return ( displayErrorNote ) ?
+        ShowErrorDialog( syncProgress.iErrorCode, messageRID ) :
+        syncProgress.iErrorCode;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ShowErrorDialog()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::ShowErrorDialog(
+    TInt aErrorCode,
+    TInt aErrorMessageRID ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ShowErrorDialog, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TInt ignore = 0;
+    TInt ret = KErrNone;
+    TBuf<EProgressStringMaxLen> errorBufferText;
+    const TDesC* line = NULL;
+    if(!aErrorMessageRID)
+        {
+        if ( aErrorCode == KErrGeneral ||
+             aErrorCode == KErrEtelBusyDetected ||
+             aErrorCode == KErrAbort )
+            // general errors displayed by other components. for ex. phone app...
+            {
+            return KErrGeneral;
+            }
+
+        if ( aErrorCode == KErrCouldNotConnect )
+            {
+            aErrorCode = KErrImapConnectFail;
+            }
+        if( aErrorCode == KErrGprsServicesNotAllowed )
+            {
+            aErrorCode = KImskErrorActiveSettingIsDifferent;
+            }
+        ret = aErrorCode;
+        TRAP( ignore, iErrorResolver->ShowGlobalErrorNoteL( aErrorCode ) );
+        }
+    else if ( aErrorMessageRID == R_IMAP4_TIMEOUT_DIALOG_TEXT )
+        {
+        TBuf<EProgressStringMaxLen> tempString;
+        StringLoader::Load( tempString, aErrorMessageRID, iEikonEnv);
+        TMsvId serviceId = 0;
+        TMsvId id = BaseMtm().Entry().OwningService();
+        TMsvEntry serviceEntry;
+        if ( Session().GetEntry(
+            id,
+            serviceId,
+            serviceEntry ) == KErrNone )
+            {
+            TInt descriptionLength = EProgressStringMaxLen - tempString.Length();
+            if ( descriptionLength < 1 )
+                {
+                descriptionLength = EProgressStringMaxLen - KImumProgressBufferLengthSafe;
+                tempString = tempString.Left( KImumProgressBufferLengthSafe );
+                }
+            StringLoader::Format(
+                errorBufferText,
+                tempString,
+                -1,
+                serviceEntry.iDetails.Left(descriptionLength) );
+            }
+        else
+            {
+            StringLoader::Format( errorBufferText, tempString, -1, KEmptySpace );
+            }
+        line = &errorBufferText;
+        ret = KErrTimedOut;
+        TRAP( ignore, CIMSSettingsNoteUi::ShowNoteL(
+            *line, EIMSErrorNote, ETrue ) );
+        }
+    else
+        {
+        StringLoader::Load( errorBufferText, aErrorMessageRID, iEikonEnv);
+        line = &errorBufferText;
+        ret = KErrCancel; // some other error, just return != KErrNone
+        TRAP_IGNORE( CIMSSettingsNoteUi::ShowQueryL(
+            *line, R_EMAIL_INFORMATION_QUERY ) );
+        }
+    IMUM_OUT();
+
+    return ret;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DisplayUiProgressSummary()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::DisplayUiProgressSummary( const TDesC8& aProgress ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DisplayUiProgressSummary, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TPckgBuf<TImap4UiProgress> paramPack;
+    paramPack.Copy(aProgress);
+    const TImap4UiProgress& progress=paramPack();
+
+    if( (progress.iError != KErrNone) && (progress.iError != KErrCancel) )
+        {
+        //  Only failed creation or renaming of folders requires summary
+        // and you cannot do those so panic
+        switch(progress.iUiOperation)
+            {
+            case TImap4UiProgress::ECreatingFolder:
+            case TImap4UiProgress::ERenamingFolder:
+                __ASSERT_DEBUG(EFalse,
+                    User::Panic(KImumMtmUiPanic,EIMAP4MtmUiUiProgressSummaryCreateRenameFolder));
+                break;
+
+            case TImap4UiProgress::EDeletingMessages:
+                return ShowErrorDialog(progress.iError);
+
+            default:
+                break;
+            }
+        }
+    IMUM_OUT();
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DisplayConnectionProgressSummary()
+// ----------------------------------------------------------------------------
+//
+TInt CImap4MtmUi::DisplayConnectionProgressSummary(
+    const TDesC8& aProgress) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DisplayConnectionProgressSummary, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TPckgBuf<TMsvEmailConnectionProgress> progressBuf;
+    progressBuf.Copy(aProgress);
+    const TMsvEmailConnectionProgress& connectionProgress=progressBuf();
+    IMUM_OUT();
+
+    if(connectionProgress.iErrorCode!=KErrNone && connectionProgress.iErrorCode!=KErrCancel)
+        {
+        return ShowErrorDialog(connectionProgress.iErrorCode);
+        }
+    else
+        {
+        //  If we are connecting, we should discount KErrCancels
+        return KErrNone;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::LaunchMultipleEditorApplicationsL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::LaunchMultipleEditorApplicationsL(
+    const CMsvEntrySelection& aSelection,
+    TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::LaunchMultipleEditorApplicationsL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    BaseMtm().Entry().SetEntryL(aSelection.At(0));
+    IMUM_OUT();
+    return LaunchEditorApplicationL(aStatus);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::LaunchEditorApplicationL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::LaunchEditorApplicationL(
+    TRequestStatus& aStatus)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::LaunchEditorApplicationL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // --- Create the parameters necessary for the editor ---
+    TEditorParameters editorParams;
+    editorParams.iId=BaseMtm().Entry().EntryId();
+    editorParams.iFlags|=EMsgReadOnly;
+    IMUM_OUT();
+    return LaunchEditorApplicationL(aStatus, editorParams);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::LaunchEditorApplicationL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::LaunchEditorApplicationL(
+    TRequestStatus& aStatus,
+    const TEditorParameters& aParams)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::LaunchEditorApplicationL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Get the app name, appName not owed so must not delete it at the end
+    HBufC* appName = (aParams.iFlags & EMsgReadOnly) ? (GetViewerFileNameL()) : (GetEditorFileNameL());
+    const TUint preferences = Preferences();
+
+    TEmailEditParams editParams;
+    editParams.iPreferences = preferences;
+    editParams.iEditorFileName = *appName;
+    editParams.iEditorParams = aParams;
+
+    editParams.iEditorParams.iFlags &= ~(EMsgLaunchEditorEmbedded | EMsgLaunchEditorThenWait);
+    if(preferences & EMtmUiFlagEditorPreferEmbedded)
+        {
+        editParams.iEditorParams.iFlags |= EMsgLaunchEditorEmbedded;
+        }
+    if(!(preferences & EMtmUiFlagEditorNoWaitForExit))
+        {
+        editParams.iEditorParams.iFlags |= EMsgLaunchEditorThenWait;
+        }
+    const TBool ackReceipts = AcknowledgeReceiptsL(aParams.iId);
+    IMUM_OUT();
+    return CImumEditOperation::NewL(*iMailboxApi, aStatus, Type(), editParams, ackReceipts);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::EditImap4ServiceL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::EditImap4ServiceL(
+    TRequestStatus& aStatus,
+    TMsvId aServiceEntry )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::EditImap4ServiceL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Get SMTP client and ui dlls
+    CClientMtmRegistry* clientRegistry=CClientMtmRegistry::NewL(Session());
+    CleanupStack::PushL(clientRegistry);
+
+    CBaseMtm* smtpmtm=clientRegistry->NewMtmL(KUidMsgTypeSMTP);
+    CleanupStack::PushL(smtpmtm);
+
+    CMtmUiRegistry* mtmuireg=CMtmUiRegistry::NewL(Session());
+    CleanupStack::PushL(mtmuireg);
+
+    CBaseMtmUi* smtpUi=mtmuireg->NewMtmUiL(*smtpmtm);
+    CleanupStack::PushL(smtpUi);
+
+    smtpUi->BaseMtm().SetCurrentEntryL(Session().GetEntryL(aServiceEntry));
+
+    TRAPD(ret, STATIC_CAST(CSmtpClientMtm&,smtpUi->BaseMtm()).RestoreSettingsL());
+    if (ret==KErrNotFound)
+        STATIC_CAST(CSmtpClientMtm&,smtpUi->BaseMtm()).StoreSettingsL();
+    else
+        User::LeaveIfError(ret);
+
+    CMsvOperation* op=smtpUi->EditL(aStatus);
+    CleanupStack::PopAndDestroy(4); // CSI: 47 # smtpui, mtmuireg, smtpmtm, clientregistry
+    IMUM_OUT();
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CheckEntryL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::CheckEntryL( const TMsvEntry& aEntry ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CheckEntryL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if ((aEntry.iType!=KUidMsvMessageEntry && aEntry.iType!=KUidMsvServiceEntry && aEntry.iType!=KUidMsvFolderEntry) || aEntry.iMtm!=Type())
+        User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::CheckSelectionL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::CheckSelectionL(
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::CheckSelectionL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    __ASSERT_DEBUG(aSelection.Count(),
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiSelectionIsEmpty));
+    if ( aSelection.Count() == 0 )
+        {
+        User::Leave(KErrNotSupported);
+        }
+    iEntry->SetEntryL(aSelection[0]);
+    iEntry->SetEntryL(iEntry->Entry().Parent());
+    TMsvEntry tentry;
+    for (TInt cc=aSelection.Count(); --cc>=0;)
+        {
+        tentry=iEntry->ChildDataL(aSelection[cc]);
+        if (tentry.iType!=KUidMsvMessageEntry || tentry.iMtm!=Type())
+            {
+            User::Leave(KErrNotSupported);
+            }
+        }
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::SingleEntrySelectionLC()
+// ----------------------------------------------------------------------------
+//
+CMsvEntrySelection* CImap4MtmUi::SingleEntrySelectionLC(
+    TMsvId aId ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::SingleEntrySelectionLC, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
+    CleanupStack::PushL(selection);
+    selection->AppendL(aId);
+    IMUM_OUT();
+    return selection;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::StripInvalidEntriesLC()
+// ----------------------------------------------------------------------------
+//
+CMsvEntrySelection* CImap4MtmUi::StripInvalidEntriesLC(
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::StripInvalidEntriesLC, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvEntrySelection* entries=aSelection.CopyLC();
+    CMsvEntrySelection* contextChildren=BaseMtm().Entry().ChildrenL();
+    CleanupStack::PushL(contextChildren);
+    TInt cc=entries->Count();
+    while (cc--)
+        {
+        if (contextChildren->Find((*entries)[cc]) == KErrNotFound)
+            entries->Delete(cc);
+        }
+    CleanupStack::PopAndDestroy();
+    IMUM_OUT();
+    return entries;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::StripBodyTextCompleteEntriesLC()
+// ----------------------------------------------------------------------------
+//
+CMsvEntrySelection* CImap4MtmUi::StripBodyTextCompleteEntriesLC(
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::StripBodyTextCompleteEntriesLC, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvEntrySelection* entries=aSelection.CopyLC();
+    iEntry->SetEntryL((*entries)[0]);
+    iEntry->SetEntryL(iEntry->Entry().Parent());
+    TInt cc=entries->Count();
+    while (cc--)
+        {
+        TMsvEmailEntry emailEntry(iEntry->ChildDataL((*entries)[cc]));
+        if(emailEntry.BodyTextComplete())
+            {
+            entries->Delete(cc);
+            }
+        }
+    IMUM_OUT();
+    return entries;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::StripCompleteEntriesLC()
+// ----------------------------------------------------------------------------
+//
+CMsvEntrySelection* CImap4MtmUi::StripCompleteEntriesLC(
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::StripCompleteEntriesLC, 0, KImumMtmLog );
+    IMUM_IN();
+
+    iEntry->SetEntryL(aSelection[0]);
+    iEntry->SetEntryL(iEntry->Entry().Parent());
+    IMUM_OUT();
+    return MsvEmailMtmUiUtils::StripCompleteEntriesLC(*iEntry, aSelection);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ValidateFolderNameL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::ValidateFolderNameL(
+    const TDesC& aName,
+    TDes8& aRetProgress )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ValidateFolderNameL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    Imap4BaseMtm()->RestoreSettingsL(); //  To recover the imap settings
+    const TChar separatorChar = Imap4BaseMtm()->Imap4Settings().PathSeparator();
+
+    TImap4UiProgressBuf& retProgress = STATIC_CAST(TImap4UiProgressBuf&, aRetProgress);
+    retProgress().iError = KErrNone;
+    const TChar forwardSlash(KForwardSlash);
+    const TChar backSlash(KBackSlash);
+    if(!aName.Length())
+        {
+        retProgress().iError = KErrPathNotFound;
+        }
+    else if(aName.Length() > KImpuIMAPFolderNameLength)
+        {
+        retProgress().iError = KErrTooBig;
+        }
+    else if( ((separatorChar == forwardSlash || separatorChar == backSlash) &&
+                        ((aName.Locate(forwardSlash) >= 0) || (aName.Locate(backSlash) >= 0))) ||
+                    (aName.Locate(separatorChar) >= 0) )
+        {
+        retProgress().iSeparatorChar = separatorChar;
+        retProgress().iError = KErrBadName;
+        }
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DeleteFoldersFromL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::DeleteFoldersFromL(
+    const CMsvEntrySelection& /*aSelection*/,
+    TRequestStatus& /*aStatus*/,
+    TMsvId /*aService*/,
+    TBool /*aOnline*/)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DeleteFoldersFromL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // not supported
+    User::Leave(KErrNotSupported);
+    IMUM_OUT();
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::SelectionContainsInboxL()
+// ----------------------------------------------------------------------------
+//
+TMsvId CImap4MtmUi::SelectionContainsInboxL(
+    const CMsvEntry& aParentEntry,
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::SelectionContainsInboxL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if (aParentEntry.Entry().iType.iUid!=KUidMsvServiceEntryValue)
+        return KMsvNullIndexEntryId;
+    for (TInt cc=aSelection.Count(); --cc>=0;)
+        {
+        const TMsvEntry& tentry = aParentEntry.ChildDataL(aSelection[cc]);
+        if (tentry.iDetails.CompareF(iInboxName)==0)
+            return tentry.Id();
+        }
+    IMUM_OUT();
+    return KMsvNullIndexEntryId;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::SelectionContainsGhostEntryL()
+// ----------------------------------------------------------------------------
+//
+TBool CImap4MtmUi::SelectionContainsGhostEntryL(
+    const CMsvEntry& aParentEntry,
+    const CMsvEntrySelection& aSelection )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::SelectionContainsGhostEntryL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    if(aSelection.Count()==0)
+        {
+        return EFalse;
+        }
+
+    for(TInt cc=aSelection.Count(); --cc>=0;)
+        {
+        if(aParentEntry.ChildDataL(aSelection[cc]).iRelatedId!=KMsvNullIndexEntryId)
+            {
+            IMUM_OUT();
+            return ETrue;
+            }
+        }
+    IMUM_OUT();
+    return EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::SelectionContainsOnlyMessagesL()
+// ----------------------------------------------------------------------------
+//
+TBool CImap4MtmUi::SelectionContainsOnlyMessagesL(
+    const CMsvEntry& aParentEntry,
+    const CMsvEntrySelection& aSelection ) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::SelectionContainsOnlyMessagesL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    for(TInt cc=aSelection.Count() ; --cc>=0;)
+        {
+        if(aParentEntry.ChildDataL(aSelection[cc]).iType!=KUidMsvMessageEntry)
+            {
+            IMUM_OUT();
+            return EFalse;
+            }
+        }
+    IMUM_OUT();
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DeleteFromL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::DeleteFromL(
+    const CMsvEntrySelection& aSelection,
+    TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DeleteFromL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TBuf8<1> buf;
+    CMsvOperation* op=NULL;
+
+    // Validate selection.
+    __ASSERT_DEBUG(aSelection.Count(),
+        User::Panic(KImumMtmUiPanic,EIMAP4MtmUiSelectionIsEmpty));
+    CMsvEntrySelection* validEntries=StripInvalidEntriesLC(aSelection);
+    CMsvEntrySelection* entries=MsvEmailMtmUiUtils::StripDeletedEntriesLC(BaseMtm().Entry(), *validEntries);    // Current context is parent.
+    const TBool hasInbox = (SelectionContainsInboxL(BaseMtm().Entry(),*entries) != KMsvNullIndexEntryId);
+    if( (!entries->Count()) || (hasInbox) )
+        {
+        IMUM2(0, "Cancelling delete for reasons: %d or %d", entries->Count(), hasInbox );
+        CleanupStack::PopAndDestroy(2); // CSI: 47 # entries,validEntries
+        IMUM_OUT();
+        return CMsvCompletedOperation::NewL(Session(), Type(), buf, KMsvLocalServiceIndexEntryId, aStatus, KErrNone);
+        }
+
+    // Remove folders from the selection.
+    iEntry->SetEntryL((*entries)[0]);
+    const TMsvId parent(iEntry->Entry().Parent());
+    iEntry->SetEntryL(parent);
+    TInt numberOfItems = entries->Count();
+    while (numberOfItems--)
+        {
+        if(iEntry->ChildDataL((*entries)[numberOfItems]).iType == KUidMsvFolderEntry)
+            {
+            // remove folders from selection, we can only delete messages
+            entries->Delete(numberOfItems);
+            }
+        }
+    numberOfItems = entries->Count();
+
+    TInt chosedDelMode = KErrNotFound;
+    const TInt delMode = GetMailDeletionModeL();
+    IMUM1(0, "Selected deletion mode: %d", delMode );
+
+    TBool dlgResult = ETrue;
+
+    if ( delMode == EIMASMailDeletionAlwaysAsk )
+        {
+        IMUM0(0, "Deleting: Always Ask" );
+        CImumListQueryDialog* dlg = new (ELeave) CImumListQueryDialog( &chosedDelMode );
+        dlg->PrepareLC( R_IMUM_DELETE_LIST_QUERY );
+
+        if ( numberOfItems > 1 )
+            {
+            // change list query title
+            HBufC* manyMailsText = StringLoader::LoadLC(
+                R_IMUM_DELETE_LIST_QUERY_TITLE_MANY_MAILS, numberOfItems, iEikonEnv );
+
+            CAknPopupHeadingPane* heading = dlg->QueryHeading();
+            heading->SetTextL( *manyMailsText );
+            CleanupStack::PopAndDestroy( manyMailsText );
+            }
+
+        IMUM0(0, "Running dialog" );
+        dlgResult = dlg->RunLD();
+        }
+    else if ( numberOfItems > 1 )
+        {
+
+        HBufC* queryText = NULL;
+
+        if ( delMode == EIMASMailDeletionPhone )
+            {
+            queryText = StringLoader::LoadLC(
+                    R_IMUM_DELETE_MANY_MAILS_PHONE_QUERY, numberOfItems, iEikonEnv );
+            }
+        else
+            {
+            queryText = StringLoader::LoadLC(
+                    R_IMUM_DELETE_MANY_MAILS_SERVER_QUERY, numberOfItems, iEikonEnv );
+            }
+
+        dlgResult = CIMSSettingsNoteUi::ShowQueryL(
+               *queryText, R_EMAIL_CONFIRMATION_QUERY );
+
+        CleanupStack::PopAndDestroy( queryText );
+        }
+
+    if ( delMode == EIMASMailDeletionPhone )
+        {
+        chosedDelMode = KImumDeleteMessagesLocally;
+        }
+
+
+    if( dlgResult )
+        {
+        CMsvProgressReporterOperation* reporter =
+                CMsvProgressReporterOperation::NewL(
+                    Session(), aStatus, EMbmAvkonQgn_note_erased );
+        CleanupStack::PushL(reporter);
+
+
+        if ( chosedDelMode == KImumDeleteMessagesLocally )
+            {
+            // Show a note to make sure that user understands that header will still be seen
+            // even if mail is deleted from the phone, only showed if setting is always ask
+            if ( delMode == EIMASMailDeletionAlwaysAsk )
+                {
+                // Set info note timeout to 1 second. Otherwise progress
+                // note will come on top of info note. CAknProgressDialog
+                // lead time before displaying the dialog is hardcoded to
+                // 1 second and cannot be adjusted.
+                const TInt KTimeout = 1000000;
+                CIMSSettingsNoteUi::ShowNoteL( R_IMUM_HEADER_WILL_REMAIN_PHONE,
+                    EIMSInformationNote, EFalse, KTimeout );
+                }
+
+            CImumDeleteMessagesLocally* deleteop =
+                CImumDeleteMessagesLocally::NewL(
+                *entries,
+                *iMailboxApi,
+                reporter->iStatus );
+            reporter->SetProgressDecoder( *deleteop );
+            reporter->SetOperationL( deleteop ); // Takes immediate ownership
+            }
+        else
+            {
+            CImumDeleteMessagesFromServer* deleteop =
+                CImumDeleteMessagesFromServer::NewL(
+                *iMailboxApi,
+                reporter->iStatus,
+                *entries );
+            reporter->SetProgressDecoder( *deleteop );
+            reporter->SetOperationL( deleteop ); // Takes immediate ownership
+            }
+
+        CleanupStack::Pop(); //reporter
+        op = reporter;
+        }
+    else
+        {
+        op=CMsvCompletedOperation::NewL(
+            Session(),
+            Type(),
+            buf,
+            KMsvLocalServiceIndexEntryId,
+            aStatus,
+            KErrCancel);
+        }
+
+    CleanupStack::PopAndDestroy(2); // CSI: 47 # entries,validEntries
+
+    IMUM_OUT();
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::UnDeleteFromL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::UnDeleteFromL(
+    const CMsvEntrySelection& aSelection,
+    TRequestStatus& aStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::UnDeleteFromL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    //Un-deletes selection from current context
+
+    //  We shouldn't need to check for folders - they are always deleted
+    //  immediately on-line, so should never be in a position to be
+    //  un-deleted.
+    TBool undelete = EFalse;
+    if ( aSelection.Count() > 1 )
+        {
+        HBufC* promptText = StringLoader::LoadLC(
+            R_EMAIL_UNDELETE_MANY_MESSAGES_QUERY, aSelection.Count(), iCoeEnv );
+        undelete = CIMSSettingsNoteUi::ShowQueryL(
+            *promptText, R_EMAIL_CONFIRMATION_QUERY );
+        CleanupStack::PopAndDestroy( promptText );
+        }
+    else
+        {
+        undelete = CIMSSettingsNoteUi::ShowQueryL(
+            R_EMAIL_UNDELETE_MESSAGE_QUERY, R_EMAIL_CONFIRMATION_QUERY );
+        }
+    if ( undelete )
+        {
+        TBuf8<1> dummyParam;
+        CMsvProgressReporterOperation* reporter = CMsvProgressReporterOperation::NewL(Session(), aStatus, EMbmAvkonQgn_note_progress);
+        CleanupStack::PushL(reporter);
+        CMsvOperation* op = BaseMtm().InvokeAsyncFunctionL(KIMAP4MTMUndeleteAll,aSelection,dummyParam,reporter->RequestStatus());
+        reporter->SetOperationL(op); // Takes immediate ownership
+        CleanupStack::Pop(); // reporter
+        IMUM_OUT();
+        return reporter;
+        }
+    else
+        {
+        TBuf8<1> buf;
+        IMUM_OUT();
+        return CMsvCompletedOperation::NewL(
+            Session(),
+            Type(),
+            buf,
+            KMsvLocalServiceIndexEntryId,
+            aStatus,
+            KErrCancel);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ForwardL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ForwardL(
+    TMsvId aDestination,
+    TMsvPartList aPartList,
+    TRequestStatus& aCompletionStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ForwardL, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+
+    return ForwardOrReplyL(aPartList, aDestination, aCompletionStatus, ETrue);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ReplyL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ReplyL(
+    TMsvId aDestination,
+    TMsvPartList aPartList,
+    TRequestStatus& aCompletionStatus )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ReplyL, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+
+    return ForwardOrReplyL(aPartList, aDestination, aCompletionStatus, EFalse);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::ForwardOrReplyL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ForwardOrReplyL(
+    TMsvPartList aPartlist,
+    TMsvId aDestination,
+    TRequestStatus& aCompletionStatus,
+    TBool aForward)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ForwardOrReplyL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    //  We need to determine whether we're working with a ghost entry or not
+    TMsvId relatedId=BaseMtm().Entry().Entry().iRelatedId;
+
+    if(relatedId!=KMsvNullIndexEntryId)
+        //  We're dealing with a ghost entry - trace back to originator
+        BaseMtm().SwitchCurrentEntryL(relatedId);
+
+    TEditorParameters editorParams;
+
+    editorParams.iFlags &= ~(EMsgLaunchEditorEmbedded | EMsgLaunchEditorThenWait);
+    const TUint preferences = Preferences();
+    if(preferences & EMtmUiFlagEditorPreferEmbedded)
+        {
+        editorParams.iFlags |= EMsgLaunchEditorEmbedded;
+        }
+    if(!(preferences & EMtmUiFlagEditorNoWaitForExit))
+        {
+        editorParams.iFlags |= EMsgLaunchEditorThenWait;
+        }
+
+    if(aForward)
+        editorParams.iFlags|=EMsgForwardMessage;
+    else
+        editorParams.iFlags|=(aPartlist&KMsvMessagePartRecipient)?EMsgReplyToMessageAll:EMsgReplyToMessageSender;
+
+    editorParams.iId=BaseMtm().Entry().EntryId();
+    editorParams.iPartList = aPartlist;
+    editorParams.iDestinationFolderId = aDestination;
+
+    CMsvOperation* op=NULL;
+
+    if ( BaseMtm().Entry().Entry().Unread() )
+        {
+        // mark read before reply...
+
+        CMsvEntry* msgEntry =
+            Session().GetEntryL( BaseMtm().Entry().EntryId() );
+        CleanupStack::PushL( msgEntry );
+        TMsvEntry email = msgEntry->Entry();
+
+        // Set the unread flag
+        email.SetUnread( EFalse );
+
+        CMuiuOperationWait* wait =
+            CMuiuOperationWait::NewLC( EActivePriorityDefault );
+        CMsvOperation* op=msgEntry->ChangeL( email, wait->iStatus );
+        wait->Start();
+        CleanupStack::PopAndDestroy( wait );
+        wait = NULL;
+
+        delete op;
+        op = NULL;
+
+        CleanupStack::PopAndDestroy( msgEntry );
+        msgEntry = NULL;
+        }
+
+    if(BaseMtm().Entry().Entry().Complete())
+        op=LaunchEditorApplicationL(aCompletionStatus, editorParams);
+    else if(relatedId!=KMsvNullIndexEntryId)
+        //  We were originally dealing with ghost entry
+        op=OfferSynchroniseL(BaseMtm().Entry().OwningService(), aCompletionStatus);
+    else
+        //  We are dealing with an incomplete, non-ghost entry
+        op=OpenMessageL(aCompletionStatus, editorParams);
+    IMUM_OUT();
+
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::FetchMessagesL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::FetchMessagesL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSelection,
+    TInt aFunctionId,
+    TImImap4GetMailInfo& aGetMailInfo )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::FetchMessagesL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Fetch messages, no size checking.
+    // Used for 'Fetch All', 'Fetch New', and 'Get Mail'.
+    CMsvProgressReporterOperation* reporter =
+        CMsvProgressReporterOperation::NewL( ETrue, ETrue, Session(), aStatus,
+        EMbmAvkonQgn_note_progress );
+    CleanupStack::PushL( reporter );
+
+        HBufC* title = StringLoader::LoadLC(
+            R_IMAP4_PROGRESS_FETCHING, iCoeEnv );
+    reporter->SetTitleL( *title );
+    CleanupStack::PopAndDestroy( title );
+    title=NULL;
+
+
+    const TMsvId service = BaseMtm().Entry().OwningService();
+    CMsvOperation* fetch = CImap4FetchOp::NewL( *iMailboxApi,
+        reporter->RequestStatus(), *reporter, service, aFunctionId,
+        aGetMailInfo, aSelection );
+    reporter->SetOperationL( fetch ); // Takes immediate ownership
+    CleanupStack::Pop(); // reporter
+    IMUM_OUT();
+    return reporter;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::InitParametersForFetchCmdL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::InitParametersForFetchCmdL(
+    CMsvEntrySelection* aSelection,
+    TImImap4GetMailInfo& aGetMailInfo,
+    TBool aInsertParentFolder /* = ETrue */) const
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InitParametersForFetchCmdL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Initialise the parameters for Fetch New, Fetch All or Fetch selected.
+    // Client MTM context is folder.
+    // For populate new or populate all, we must add the parent folder to the selection.
+    if ( aInsertParentFolder && aSelection)
+        {
+        aSelection->InsertL(0, BaseMtm().Entry().EntryId());
+        }
+    aGetMailInfo.iMaxEmailSize = KMaxTInt32;
+    const TMsvId currentEntryId = BaseMtm().Entry().EntryId();
+    BaseMtm().SwitchCurrentEntryL(BaseMtm().Entry().OwningService());
+    Imap4BaseMtm()->RestoreSettingsL();
+    BaseMtm().SwitchCurrentEntryL( currentEntryId );
+
+    if ( iFeatureFlags->GF( EMailFeatureMeetingRequestSupport ) )
+        {
+        aGetMailInfo.iGetMailBodyParts = EGetImap4EmailBodyAlternativeText;
+        }
+    else
+        {
+        aGetMailInfo.iGetMailBodyParts = EGetImap4EmailBodyText;
+        }
+
+    // No destination for populate.
+    aGetMailInfo.iDestinationFolder = KMsvNullIndexEntryId;
+
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::InitParametersForGetMailCmdL()
+// ----------------------------------------------------------------------------
+//
+void CImap4MtmUi::InitParametersForGetMailCmdL(
+    CMsvEntrySelection& aSelection,
+    TImImap4GetMailInfo& aGetMailInfo)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InitParametersForGetMailCmdL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    // Initialise the parameters for Get Mail.
+    // Client MTM context is service.
+    // We must add the inbox id to the selection.
+    CMsvEntrySelection* serviceChildren = BaseMtm().Entry().ChildrenL();
+    CleanupStack::PushL(serviceChildren);
+    const TMsvId inboxId = SelectionContainsInboxL(BaseMtm().Entry(),*serviceChildren);
+    CleanupStack::PopAndDestroy(); // serviceChildren
+    aSelection.InsertL(0, inboxId);
+    Imap4BaseMtm()->RestoreSettingsL();
+    const CImImap4Settings& settings = Imap4BaseMtm()->Imap4Settings();
+    aGetMailInfo.iMaxEmailSize = (TInt32)(settings.MaxEmailSize());
+    aGetMailInfo.iGetMailBodyParts = settings.GetMailOptions();
+    aGetMailInfo.iDestinationFolder = KMsvNullIndexEntryId;     // No destination for populate.
+    IMUM_OUT();
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::OpenMessageL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::OpenMessageL(
+    TRequestStatus& aCompletionStatus,
+    const TEditorParameters& aEditorParams )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::OpenMessageL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op = DoPopulateIncompleteMessageL(aCompletionStatus, *SingleEntrySelectionLC(aEditorParams.iId), aEditorParams);
+    CleanupStack::PopAndDestroy(); // selection
+
+    IMUM_OUT();
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::PopulateMessagesL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::PopulateMessagesL(
+    TRequestStatus& aCompletionStatus,
+    const CMsvEntrySelection& aSel )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::PopulateMessagesL, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+    return DoPopulateIncompleteMessageL(
+        aCompletionStatus, aSel, TEditorParameters() );
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::DoPopulateIncompleteMessageL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::DoPopulateIncompleteMessageL(
+    TRequestStatus& aStatus,
+    const CMsvEntrySelection& aSel,
+    const TEditorParameters& aEditorParams )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::DoPopulateIncompleteMessageL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TBuf8<1> dummyParams;
+    CMsvSession& session = Session();
+
+    // this is just to make sure fetching is not even started if no disk space left.
+    if ( !MsvEmailMtmUiUtils::CheckAvailableDiskSpaceForDownloadL(
+         KImumApproxMailFetchSize, *iEikonEnv, session ) )
+        {
+        return CMsvCompletedOperation::NewL(Session(), Type(), dummyParams, KMsvLocalServiceIndexEntryId, aStatus, KErrNone);
+        }
+    // Determine how much of the message to fetch, and prompt if neccessary.
+    // Return the operation to be returned to the application.
+    // Copes with simply populating, and launching an editor after populating. If launching an editor,
+    // 'aSel' should contain only one message id.
+
+
+    // Check the whole selection for ghost entries. If such an entry exists,
+    // and we're offline, we need to synchronise.
+    CMsvEntry* msgEntry = Session().GetEntryL(aSel[0]);
+    CleanupStack::PushL(msgEntry);
+    TMsvId owningService=msgEntry->OwningService();
+    TMsvEmailEntry emailEntry(msgEntry->Entry());
+
+    TBool currentBodyComplete = emailEntry.BodyTextComplete();
+
+    const TBool offline = !IsConnected(owningService);
+    const TMsvId parentId = msgEntry->Entry().Parent();
+    msgEntry->SetEntryL(parentId);
+    if(SelectionContainsGhostEntryL(*msgEntry,aSel) && offline)
+        {
+        CleanupStack::PopAndDestroy();  //  msgEntry;
+        return OfferSynchroniseL(owningService, aStatus);
+        }
+
+    CMsvEntrySelection* entries = StripCompleteEntriesLC(aSel);
+    TInt numMsgs = entries->Count();
+    CleanupStack::PopAndDestroy();  //  entries
+    if(!numMsgs)
+        {
+        // no entries to fetch
+        CleanupStack::PopAndDestroy();  //  msgEntry;
+        return CMsvCompletedOperation::NewL(Session(), Type(), dummyParams, KMsvLocalServiceIndexEntryId, aStatus, KErrNone);
+        }
+    ////
+    //// --- Get info ---
+    ////
+    const TBool forwarding = (aEditorParams.iFlags & EMsgForwardMessage);
+    TImImap4GetMailInfo getMailInfo;
+    InitParametersForFetchCmdL(NULL, getMailInfo, EFalse);
+    enum TFetchType { EFetchCompleted, EFetchBodyText, EFetchAttachments };
+    TFetchType fetchType = EFetchBodyText;
+
+    numMsgs = aSel.Count();
+    TBool hasAttachments = EFalse;      // Do *any* of the messages have attachments?
+    TInt msgCount = 0;
+    for(; msgCount < numMsgs; msgCount++)
+        {
+        if(msgEntry->ChildDataL(aSel[msgCount]).Attachment())
+            {
+            hasAttachments = ETrue;     // Can we tell if we already have all attachments?
+            break;
+            }
+        }
+
+    if ( hasAttachments &&
+         getMailInfo.iGetMailBodyParts == EGetImap4EmailBodyTextAndAttachments )
+        {
+        fetchType = EFetchAttachments;
+        }
+
+    for(msgCount = 0; msgCount < numMsgs; msgCount++)
+        {
+        emailEntry = msgEntry->ChildDataL(aSel[msgCount]);
+        if(!emailEntry.BodyTextComplete())
+            {
+            break;
+            }
+        }
+    CleanupStack::PopAndDestroy(); //msgEntry
+
+    if(hasAttachments && forwarding)
+        {
+        // Always get attachments if forwarding.
+        fetchType = EFetchAttachments;
+        }
+
+    IMUM0(0, "Prompt for the fetching");
+
+    //Do the prompting only if opening unfetched message and offline and message body is incomplete
+    if( !currentBodyComplete && offline && aEditorParams.iFlags)
+        {
+        if ( CIMSSettingsNoteUi::ShowQueryL(
+            R_EMAIL_RETRIEVE_1_TEXT, R_EMAIL_CONFIRMATION_QUERY ) )
+            {
+            //VARIATION START
+            if ( iFeatureFlags->GF( EMailFeatureOfflineMode ) )
+                {
+                TMsvId mailboxId = BaseMtm().Entry().EntryId();
+                //No need to do this if we're online...
+                TBool offline = EFalse;
+                if( !IsConnected( mailboxId ) &&
+                    !iMailboxApi->MailboxUtilitiesL().HasWlanConnectionL( mailboxId ) )
+                    {
+                    offline = MsvEmailMtmUiUtils::DoOfflineChecksL( mailboxId );
+                    }
+                if( offline )
+                    {
+                    return CMsvCompletedOperation::NewL(Session(), Type(), KNullDesC8, KMsvLocalServiceIndexEntryId, aStatus, KErrCancel);
+                    }
+                }//if
+            //VARIATION END
+            if( hasAttachments )
+                {
+                fetchType = EFetchAttachments;
+                }
+            }
+        else
+            {
+            return CMsvCompletedOperation::NewL(Session(), Type(), dummyParams, KMsvLocalServiceIndexEntryId, aStatus, KErrCancel);
+            }
+        }
+
+    ////
+    //// --- Check there is work to do ---
+    ////
+    // We know none of the entries are complete, (since we check at the top of the fn).
+    // If just fetching body text, check we don't have the body text for all the messages.
+    if(fetchType == EFetchBodyText)
+        {
+        entries = StripBodyTextCompleteEntriesLC(aSel);
+        if(entries->Count() == 0)
+            {
+            // No messages to fetch.
+            fetchType = EFetchCompleted;
+            }
+        CleanupStack::PopAndDestroy(); // entries
+        }
+
+    if(fetchType == EFetchCompleted)
+        {
+        if(aEditorParams.iFlags)
+            {
+            IMUM_OUT();
+            // Editing, but no fetch to do.
+            return LaunchEditorApplicationL(aStatus, aEditorParams);
+            }
+        }
+
+    ////
+    //// --- Create the operation(s) ---
+    ////
+
+    // Create a progress reporting dialog.
+    CMsvProgressReporterOperation* reporter =
+        CMsvProgressReporterOperation::NewL(
+            ETrue,
+            ETrue,
+            Session(),
+            aStatus,
+            EMbmAvkonQgn_note_progress );
+    CleanupStack::PushL(reporter);
+
+    // If already connected, display the "Retrieving..." note right away.
+    if ( IsConnected( owningService ))
+    	reporter->SetTitleL( R_IMAP4_PROGRESS_FETCHING );
+    	
+    else
+    	{
+    	TBuf<EProgressStringMaxLen> title;
+    	MsvEmailMtmUiUtils::CreateConnectingToText( title,
+            *iMsvSession, owningService );
+    	reporter->SetTitleL( title );
+    	}
+
+
+    CMsvOperation* fetch = NULL;
+    getMailInfo.iDestinationFolder = parentId;
+    if(aEditorParams.iFlags)
+        {
+        // Create a fetch and edit operation.
+        HBufC* appName = (aEditorParams.iFlags & EMsgReadOnly) ? (GetViewerFileNameL()) : (GetEditorFileNameL());
+        TEmailEditParams fetchAndEditParams;
+        fetchAndEditParams.iPreferences = Preferences();
+        fetchAndEditParams.iEditorFileName = *appName;
+        fetchAndEditParams.iEditorParams = aEditorParams;
+        const TBool ackReceipts = AcknowledgeReceiptsL(aEditorParams.iId);
+        CImumFetchAndEditOperation* fetchAndEdit = CImumFetchAndEditOperation::NewL(
+            *iMailboxApi, reporter->RequestStatus(), *reporter, fetchAndEditParams, ackReceipts);
+        CleanupStack::PushL(fetchAndEdit);
+        // Create a fetch operation.
+        fetch = InvokeRemoteFetchOpL(*reporter, fetchAndEdit->RequestStatus(), aSel,
+            KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected, getMailInfo);
+        // Set up the wrapping.
+        fetchAndEdit->SetFetchOpL(fetch);
+        CleanupStack::Pop(); // fetchAndEdit
+        reporter->SetOperationL(fetchAndEdit); // Takes immediate ownership
+        }
+    else
+        {
+        // Create a fetch operation.
+        fetch = InvokeRemoteFetchOpL(*reporter, reporter->RequestStatus(), aSel,
+            KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected, getMailInfo);
+        reporter->SetOperationL(fetch); // Takes immediate ownership
+        }
+    CleanupStack::Pop(); // reporter
+
+    IMUM_OUT();
+    return reporter;
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::InvokeRemoteFetchOpL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::InvokeRemoteFetchOpL(
+    CMsvProgressReporterOperation& aReporter,
+    TRequestStatus& aCompletionStatus,
+    const CMsvEntrySelection& aSel,
+    TInt aFunctionId,
+    const TImImap4GetMailInfo& aGetMailInfo)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InvokeRemoteFetchOpL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvEntry* centry = Session().GetEntryL(aSel[0]);
+    TMsvId service = centry->OwningService();
+    delete centry;
+    IMUM_OUT();
+    return CImap4SizeAndFetchOp::NewL(*iMailboxApi,aCompletionStatus, aReporter, service, aFunctionId, aGetMailInfo, aSel);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::InvokeCopyMoveOpL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::InvokeCopyMoveOpL(
+    CMsvProgressReporterOperation& aReporter,
+    TRequestStatus& aCompletionStatus,
+    const CMsvEntrySelection& aSel,
+    TMsvId aTargetId,
+    TBool aCopy )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::InvokeCopyMoveOpL, 0, KImumMtmLog );
+    IMUM_IN();
+    IMUM_OUT();
+
+    return CImap4CopyMoveLocalOp::NewL(*iMailboxApi, aCompletionStatus, aReporter, aSel, aTargetId, aCopy);
+    }
+
+// ----------------------------------------------------------------------------
+// CImap4MtmUi::OfferSynchroniseL()
+// ----------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::OfferSynchroniseL(
+    TMsvId aService,
+    TRequestStatus& aStatus)
+    {
+    IMUM_CONTEXT( CImap4MtmUi::OfferSynchroniseL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    CMsvOperation* op=NULL;
+    TInt state=ServiceState(aService);
+    if(ServiceIsDisconnected(state) && !ServiceIsConnecting(state))
+    // no query to user, just synchronise...
+        {
+        //  User wishes to connect and sync...
+        CMsvEntrySelection* mySelection=SingleEntrySelectionLC(aService);
+        TBuf8<1> dummyParam;
+        op=InvokeAsyncFunctionL(KImpiMTMConnectAndSyncCompleteAfterDisconnection, *mySelection, aStatus, dummyParam);
+        CleanupStack::PopAndDestroy();  //  mySelection
+        }
+    else
+        op=CompletedImap4OperationL(aService, aStatus);
+    IMUM_OUT();
+    return op;
+    }
+
+// ---------------------------------------------------------------------------
+// CImap4MtmUi::ShowMessageInfoL()
+// ---------------------------------------------------------------------------
+//
+CMsvOperation* CImap4MtmUi::ShowMessageInfoL(
+    TRequestStatus& aCompletionStatus,
+    TDes8& /*aParameter*/ )
+    {
+    IMUM_CONTEXT( CImap4MtmUi::ShowMessageInfoL, 0, KImumMtmLog );
+    IMUM_IN();
+
+    TMsgInfoMessageInfoData infoData;
+    TBuf<KImumMessageInfoBuffer> dateBuf;
+    TBuf<KImumMessageInfoBuffer> timeBuf;
+    TBuf<KImumMessageInfoBuffer> sizeBuf;
+    TBuf<KImumMessagePriorityBufferLength> priorityBuf;
+    TBool readStoreFound = MsvEmailMtmUiUtils::SetMessageInfoDataLCC(
+        infoData,*Imap4BaseMtm(),*iEikonEnv,dateBuf,timeBuf,sizeBuf,priorityBuf );
+
+    TBuf<KImumMessageInfoBuffer> type;
+    iEikonEnv->ReadResourceL( type,R_IMAP_MESSAGE_INFO_MAIL_TYPE );
+    infoData.iType.Set(type);
+
+    CMsgInfoMessageInfoDialog* infoDialog = CMsgInfoMessageInfoDialog::NewL();
+    infoDialog->ExecuteLD( infoData, CMsgInfoMessageInfoDialog::EEmailViewer );
+    CleanupStack::PopAndDestroy( 2 ); // CSI: 47 # 2 because SetMessageInfoDataLCC
+    if ( readStoreFound )
+        {
+        CleanupStack::PopAndDestroy( 2 ); // CSI: 47 # 2 because store found
+        }
+    IMUM_OUT();
+
+    return CMsvCompletedOperation::NewL(
+        Session(), KUidMsvLocalServiceMtm, KNullDesC8,
+        KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
+    }
+
+// End of file
+