emailuis/emailui/src/FreestyleEmailUiMailViewerVisualiser.cpp
changeset 0 8466d47a6819
child 4 e7aa27f58ae1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/FreestyleEmailUiMailViewerVisualiser.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,5211 @@
+/*
+* Copyright (c) 2007 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 : FreestyleEmailUi  list implementation
+*
+*/
+
+
+
+// SYSTEM INCLUDES
+#include "emailtrace.h"
+#include <AknUtils.h>
+#include <freestyleemailui.mbg>
+#include <FreestyleEmailUi.rsg>
+#include <StringLoader.h>
+#include <AknBidiTextUtils.h>
+
+#ifndef FF_CMAIL_INTEGRATION
+#include <txtclipboard.h>
+#endif // FF_CMAIL_INTEGRATION
+
+//<cmail>
+#include "fstextviewer.h"
+#include "fsrichtext.h"
+///</cmail>
+#include <aknlistquerydialog.h>
+//<cmail>
+#include "fssmileydictionary.h"
+///</cmail>
+#include <commonphoneparser.h>
+#include <BrowserLauncher.h>
+//<cmail>
+#include "CFSMailMessagePart.h"
+#include "CFSMailClient.h"
+//</cmail>
+#include <apgcli.h>
+//<cmail>
+#include "CFSMailCommon.h"
+//</cmail>
+#include <featmgr.h>
+//</cmail>
+
+#include <txtfrmat.h>
+#include <aknlists.h> // CAknSinglePopupMenuStyleListBox
+#include <baclipb.h> // for clipboard copy
+//<cmail>
+#include "fstextviewerkeys.h"
+#include "fstextviewerwatermark.h"
+#include <alf/alfstatic.h>
+#include <alf/alfroster.h>
+#include <alf/alfevent.h>
+#include <alf/alfcontrolgroup.h>
+// </cmail>
+//<cmail>
+#include "AknWaitDialog.h"
+//</cmail>
+#include <finditemengine.h>
+#include <AknGlobalListQuery.h>
+#include <AknGlobalNote.h>
+
+// Meeting request
+#include <MeetingRequestUids.hrh>
+//<cmail>
+#include "cesmricalviewer.h"
+//</cmail>
+
+// for intranet application opening
+#include <AiwServiceHandler.h>
+#include <AiwMenu.h>
+
+// for opening normal browser
+#include <BrowserOverriddenSettings.h>
+#include <BrowserLauncher.h>
+
+// for bookmarks
+#include <FavouritesLimits.h>	// KBrowserBookmarks
+#include <FavouritesDb.h>
+
+// for fonts
+#include <AknFontAccess.h>
+#include <AknLayoutFont.h>
+
+// for action menu
+#include <CPbkContactEngine.h>
+#include <CPbkContactItem.h>
+#include <CPbkContactEditorDlg.h>
+#include <RPbkViewResourceFile.h>
+#include <CPbkDataSaveAppUi.h>
+#include <PbkDataSaveAppUi.hrh>
+#include <CPbkFieldsInfo.h>
+
+// <cmail>
+#include "cfsccontactactionmenu.h"
+#include "mfsccontactactionmenumodel.h"
+#include "cfsccontactactionservice.h"
+#include "cfsccontactactionmenuitem.h"
+#include "fsccontactactionmenuuids.hrh"
+#include "fsccontactactionmenudefines.h"
+// </cmail>
+
+// <cmail>
+#include "cfsccontactactionservice.h"
+#include <csxhelp/cmail.hlp.hrh>
+// </cmail>
+#include <aknnotewrappers.h>
+
+#include <SchemeHandler.h> // CSchemeHandler
+
+// <cmail>
+#include "FreestyleEmailUiConstants.h"
+//</cmail>
+// INTERNAL INCLUDES
+#include "FreestyleEmailUiAppui.h"
+#include "FreestyleEmailUiMailViewerControl.h"
+#include "FreestyleEmailUiMailListVisualiser.h"
+#include "FreestyleEmailUiFileSystemInfo.h"
+#include "FreestyleEmailUi.hrh"
+#include "FreestyleEmailCenRepHandler.h"
+#include "FreestyleEmailUiLayoutHandler.h"
+#include "FreestyleEmailUiTextureManager.h"
+#include "FreestyleEmailUiMsgDetailsVisualiser.h"
+#include "FreestyleEmailUiFolderListVisualiser.h"
+#include "FreestyleEmailUiAttachmentsListVisualiser.h"
+#include "FreestyleEmailUiShortcutBinding.h"
+#include "FreestyleEmailUiContactHandler.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "FreestyleEmailUiStatusIndicator.h"
+#include "FSEmail.pan"
+#include "FSDelayedLoader.h"
+
+#include "FreestyleEmailUiMailViewerVisualiser.h"
+#include "FreestyleEmailUiMailViewerRichText.h"
+#include "FreestyleEmailUiMailViewerConstants.h"
+
+#include <aknnavi.h>
+#include <aknnavide.h>
+#include <akntoolbar.h>
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::NewL
+// -----------------------------------------------------------------------------
+CFSEmailUiMailViewerVisualiser* CFSEmailUiMailViewerVisualiser::NewL( CAlfEnv& aEnv, CFreestyleEmailUiAppUi& aAppUi, CAlfControlGroup& aMailViewerControlGroup )
+    {
+    FUNC_LOG;
+    CFSEmailUiMailViewerVisualiser* self = CFSEmailUiMailViewerVisualiser::NewLC( aEnv, aAppUi, aMailViewerControlGroup );
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::NewLC
+// -----------------------------------------------------------------------------
+CFSEmailUiMailViewerVisualiser* CFSEmailUiMailViewerVisualiser::NewLC( CAlfEnv& aEnv, CFreestyleEmailUiAppUi& aAppUi, CAlfControlGroup& aMailViewerControlGroup )
+	{
+    FUNC_LOG;
+    CFSEmailUiMailViewerVisualiser* self = new (ELeave) CFSEmailUiMailViewerVisualiser( aEnv, aAppUi, aMailViewerControlGroup );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ConstructL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ConstructL()
+	{
+    FUNC_LOG;
+    BaseConstructL( R_FSEMAILUI_MAIL_VIEWER_VIEW );
+	iMessage = NULL;
+	iNextOrPevMessageSelected = EFalse;
+	iFirstStartCompleted = EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::DoFirstStartL()
+// Purpose of this function is to do first start only when viewer is
+// really needed to be shown. Implemented to make app start up faster.
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::DoFirstStartL()
+    {
+    FUNC_LOG;
+    iOpenMessages = new (ELeave) CStack<CFSMailMessage, ETrue>();
+    iEmbeddedMessages = new (ELeave) CStack<CFSMailMessage, EFalse>();
+    iSmDictionary = CFsSmileyDictionary::NewL();
+    iIBServiceHandler = CAiwServiceHandler::NewL();
+    iIBServiceHandler->AttachMenuL( R_FSEMAILUI_MAILVIEWER_SUBMENU_ACTIONS, R_INTRANET_AIW_INTEREST_MENU );
+    iIBServiceHandler->AttachL( R_INTRANET_AIW_INTEREST_BASE );
+
+    // Initialize browser laucher api
+    iFetchingAnimationTimer = CFSEmailUiGenericTimer::NewL( this );
+    iAsyncCallback = new (ELeave) CAsyncCallBack( CActive::EPriorityLow );
+    iDownloadProgressControlGroup = &iEnv.NewControlGroupL( KDownloadIndicatorControlGroup );
+    iDownloadProgressIndicator = CFSEmailUiStatusIndicator::NewL( iEnv, *iDownloadProgressControlGroup,
+                                                                  &iAppUi );
+
+    iViewerRichText = CFSEmailUiMailViewerRichText::NewL( iAppUi );
+
+    //here is set menu for msk
+    MenuBar()->SetContextMenuTitleResourceId( R_FSEMAILUI_MAILVIEWER_MSK_MENUBAR );
+
+    iFirstStartCompleted = ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CFSEmailUiMailViewerVisualiser
+// -----------------------------------------------------------------------------
+CFSEmailUiMailViewerVisualiser::CFSEmailUiMailViewerVisualiser( CAlfEnv& aEnv,
+    CFreestyleEmailUiAppUi& aAppUi, CAlfControlGroup& aMailViewerControlGroup )
+    : CFsEmailUiViewBase( aMailViewerControlGroup, aAppUi ),
+    iMoveToFolderOngoing( EFalse ),
+    iFetchingMessageStructure( EFalse ),
+    iFetchingPlainTextMessageBody( EFalse ),
+    iFetchingHtmlMessageBody( EFalse ),
+    iAsyncProcessComplete( ETrue ),
+    iEnv( aEnv )
+    {
+    FUNC_LOG;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::~CFSEmailUiMailViewerVisualiser
+// -----------------------------------------------------------------------------
+CFSEmailUiMailViewerVisualiser::~CFSEmailUiMailViewerVisualiser()
+	{
+    FUNC_LOG;
+        //<cmail> notewrapper is replaced by iWaitDialog
+	//delete iAsyncWaitNote;
+        //</cmail>
+	if( iIBServiceHandler )
+		{
+		iIBServiceHandler->Reset();
+		delete iIBServiceHandler;
+		}
+
+	if ( iAsyncCallback )
+	    {
+	    iAsyncCallback->Cancel();
+	    delete iAsyncCallback;
+	    }
+
+	iDownloadProgressControlGroup = NULL; // owned by AlfEnv
+	}
+
+void CFSEmailUiMailViewerVisualiser::PrepareForExit()
+    {
+    FUNC_LOG;
+    delete iSmDictionary;
+    iSmDictionary = NULL;
+    delete iNewMailTempAddress;
+    iNewMailTempAddress = NULL;
+
+    // Text viewer control need to be removed control group and deleted here,
+	// because akn physics (used by text viewer control) object's destructor
+	// ends up calling CoeEnv->AppUi, so AppUi must be alive when deleting
+	// text viewer control
+    if ( iTextViewerControl )
+        {
+        ControlGroup().Remove( iTextViewerControl );
+        }
+
+    delete iTextViewer;
+    iTextViewer = NULL;
+
+    delete iTextViewerControl;
+    iTextViewerControl = NULL;
+
+    delete iViewerRichText;
+    iViewerRichText = NULL;
+
+    if ( iFlagSelectionHanler )
+        {
+        iFlagSelectionHanler->Cancel();
+        delete iFlagSelectionHanler;
+        iFlagSelectionHanler = NULL;
+        }
+    if ( iFetchingAnimationTimer )
+        {
+        iFetchingAnimationTimer->Stop();
+        delete iFetchingAnimationTimer;
+        iFetchingAnimationTimer = NULL;
+        }
+    if ( iAppUi.DownloadInfoMediator() && iMessage )
+        {
+        iAppUi.DownloadInfoMediator()->StopObserving( this, iMessage->GetMessageId() );
+        }
+
+    delete iOpenMessages;
+    iOpenMessages = NULL;
+    delete iEmbeddedMessages;
+    iEmbeddedMessages = NULL;
+    iMessage = NULL;
+
+    delete iMailBox;
+    iMailBox = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleForegroundEventL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleForegroundEventL()
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted ) //Safety
+        {
+        // Resize the download indicator after returning from the screensaver
+        iDownloadProgressIndicator->HandleForegroundEventL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::RequestResponseL
+// for MFSEmailDownloadInformationObserver callback
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::RequestResponseL( const TFSProgress& aEvent, const TPartData& /*aPart*/ )
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted && iAppUi.CurrentActiveView() == this )
+        {
+        UpdateDownloadIndicatorL( aEvent.iProgressStatus );
+
+        // <cmail> Action menu is dismissed if it's opened on an attachment
+        // and the download has completed (to prevent canceling after completion).
+        SViewerHeadingHotSpotData currentHeaderHotSpotData;
+		CFindItemEngine::SFoundItem currentBodyHotSpotData;
+
+        THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+            currentHeaderHotSpotData, currentBodyHotSpotData );
+
+        if( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete &&
+            hotspotType == EHeaderHotspot &&
+            (currentHeaderHotSpotData.iType == ETypeAttachment ||
+            currentHeaderHotSpotData.iType == ETypeAttachments) )
+            {
+            CFSEmailUiActionMenu::Dismiss( ETrue );
+
+            // close actions menu if open
+            CEikMenuBar* menu = MenuBar();
+
+            if( menu->IsDisplayed() )
+                {
+        		menu->MenuPane()->CloseCascadeMenu();
+                }
+            }
+        // </cmail>
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::RequestResponseL
+// for MFSMailRequestObserver callback
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::RequestResponseL( TFSProgress aEvent, TInt aRequestId )
+	{
+    FUNC_LOG;
+    if ( iFirstStartCompleted ) // Safety
+        {
+        if ( aRequestId == iCurrentPlainTextBodyFetchRequestId && iFetchingPlainTextMessageBody )
+            {
+            if ( aEvent.iError != KErrNone ||
+                 aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingPlainTextMessageBody = EFalse;
+                iFetchingAnimationTimer->Stop();
+
+                // Clear the "fetching body" text from the end of the message
+                iViewerRichText->SetEmptyStatusLayoutTextL();
+                }
+            else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingPlainTextMessageBody = EFalse;
+                iFetchingAnimationTimer->Stop();
+
+                // get message again, there might be new information (in case of POP protocol)
+                TFSMailMsgId mailboxId = iMessage->GetMailBoxId();
+                TFSMailMsgId folderId = iMessage->GetFolderId();
+                TFSMailMsgId messageId = iMessage->GetMessageId();
+                UpdateMessagePtrL( mailboxId, folderId, messageId );
+
+                // Refresh viewer to show newly fetched content.
+                // Prevent screen flickering by stopping automatic screen refresh during the update
+                iEnv.SetRefreshMode( EAlfRefreshModeManual );
+                // Make sure we don't leave and forget the refresh mode as manual.
+                TRAP_IGNORE(
+                    // Try to preserve the scroll position on the same line.
+                    iAppUi.Display().Roster().Hide( ControlGroup() );
+                    TInt firstLine = iTextViewer->GetFirstDisplayedLine();
+                    RefreshL();
+                    iTextViewer->FocusLineL( firstLine, ETrue );
+                    iAppUi.Display().Roster().ShowL( ControlGroup() );
+                    );
+                iEnv.SetRefreshMode( EAlfRefreshModeAutomatic );
+                }
+            }
+
+        else if ( aRequestId == iCurrentHtmlBodyFetchRequestId && iFetchingHtmlMessageBody )
+            {
+            if ( aEvent.iError != KErrNone ||
+                 aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingHtmlMessageBody = EFalse;
+                }
+            else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingHtmlMessageBody = EFalse;
+                LaunchHtmlViewerL();
+                }
+            }
+        else if ( aRequestId == iCurrentStructureFetchRequestId && iFetchingMessageStructure )
+            {
+            if ( aEvent.iError != KErrNone ||
+                 aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingMessageStructure = EFalse;
+                }
+            else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete )
+                {
+                iAsyncProcessComplete = ETrue;
+                iFetchingMessageStructure = EFalse;
+
+                // get message again, there might be new information
+                TFSMailMsgId mailboxId = iMessage->GetMailBoxId();
+                TFSMailMsgId folderId = iMessage->GetFolderId();
+                TFSMailMsgId messageId = iMessage->GetMessageId();
+
+                UpdateMessagePtrL( mailboxId, folderId, messageId );
+                if ( iMessage )
+                    {
+                    // Stop automatic screen refresh temporarily to prevent flickering
+                    iEnv.SetRefreshMode( EAlfRefreshModeManual );
+                    // we must not leave before the update mode has been restored
+                    TRAP_IGNORE(
+                        iAppUi.Display().Roster().Hide( ControlGroup() );
+                        RefreshL( ETrue );
+                        iAppUi.Display().Roster().ShowL( ControlGroup() );
+                        );
+                    iEnv.SetRefreshMode( EAlfRefreshModeAutomatic );
+                    }
+                }
+            }
+        }
+    //<cmail>
+    if(iAsyncProcessComplete && iWaitDialog && iDialogNotDismissed)
+        iWaitDialog->ProcessFinishedL(); // deletes the dialog
+    //</cmail>
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::FolderSelectedL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::FolderSelectedL(
+	TFSMailMsgId aSelectedFolderId, TFSEmailUiCtrlBarResponse aResponse )
+	{
+    FUNC_LOG;
+
+    if ( iMoveToFolderOngoing )
+		{
+		iMoveToFolderOngoing = EFalse;
+		if ( !iMovingMeetingRequest )
+			{
+			switch ( aResponse )
+				{
+				case EFSEmailUiCtrlBarResponseSelect:
+					{
+					iMoveDestinationFolder = aSelectedFolderId;
+					iAsyncCallback->Cancel(); // cancel any outstanding callback just to be safe
+					iAsyncCallback->Set( TCallBack( MoveToFolderAndExitL, this ) );
+					iAsyncCallback->CallBack();
+					}
+					break;
+                case EFSEmailUiCtrlBarResponseCancel:
+				default:
+					break;
+				}
+			}
+		else
+		 	{
+		 	iMovingMeetingRequest = EFalse;
+			switch ( aResponse )
+				{
+				case EFSEmailUiCtrlBarResponseCancel:
+					iOpResult.iResultCode = KErrCancel;
+					break;
+				case EFSEmailUiCtrlBarResponseSelect:
+					{
+					// Do moving here, do not exit, because mrui exists itself.
+					iOpResult.iResultCode = KErrNone;
+					iMoveDestinationFolder = aSelectedFolderId;
+				    RArray<TFSMailMsgId> messageIds;
+					CleanupClosePushL( messageIds );
+					messageIds.Append( iMessage->GetMessageId() );
+					// Trap is needed because protocol might return KErrNotSupported
+					// if move away from current folder is not supprted
+					TRAPD(errMove, iAppUi.GetActiveMailbox()->MoveMessagesL( messageIds,
+			                                          iMessage->GetFolderId(), iMoveDestinationFolder ));
+	        		if ( errMove != KErrNotSupported )
+		       			{
+	        			if ( errMove == KErrNone )
+			       			{
+						    TFsEmailUiUtility::DisplayMsgsMovedNoteL( 1, iMoveDestinationFolder, ETrue );
+			       			}
+		       			else
+		       				{
+		       				User::Leave( errMove );
+		       				}
+		       			}
+					CleanupStack::PopAndDestroy( &messageIds );
+					}
+					break;
+				default:
+					break;
+				}
+		 	}
+		}
+
+	}
+
+// ---------------------------------------------------------------------------
+// From MFSEmailUiContactHandlerObserver
+// The ownership of the CLS items in the contacts array is transferred to the
+// observer, and they must be deleted by the observer.
+// ---------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::OperationCompleteL(
+    TContactHandlerCmd /*aCmd*/, const RPointerArray<CFSEmailUiClsItem>& /*aContacts*/ )
+    {
+    FUNC_LOG;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSEmailUiContactHandlerObserver
+// Handles error in contatct handler operation.
+// ---------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::OperationErrorL(
+    TContactHandlerCmd /*aCmd*/, TInt /*aError*/ )
+    {
+    FUNC_LOG;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::MoveToFolderAndExitL
+// -----------------------------------------------------------------------------
+TInt CFSEmailUiMailViewerVisualiser::MoveToFolderAndExitL( TAny* aMailViewerVisualiser )
+    {
+    FUNC_LOG;
+    CFSEmailUiMailViewerVisualiser* self =
+        static_cast<CFSEmailUiMailViewerVisualiser*>(aMailViewerVisualiser);
+
+    RArray<TFSMailMsgId> messageIds;
+	CleanupClosePushL( messageIds );
+    messageIds.Append( self->iMessage->GetMessageId() );
+
+	// Trap is needed because protocol might return KErrNotSupported
+	// if move away from current folder is not supprted
+	TRAPD(errMove, self->iAppUi.GetActiveMailbox()->MoveMessagesL( messageIds,
+                                                     self->iMessage->GetFolderId(),
+                                                     self->iMoveDestinationFolder ) );
+	if ( errMove != KErrNotSupported )
+		{
+		if ( errMove == KErrNone )
+			{
+			// move successfull, display note
+		    TFsEmailUiUtility::DisplayMsgsMovedNoteL( 1, self->iMoveDestinationFolder, ETrue );
+			}
+		else
+			{
+			// Leave with any other err code than KErrNone or KErrNotSupported.
+			User::Leave( errMove );
+			}
+		}
+	CleanupStack::PopAndDestroy( &messageIds );
+
+    // return to previous view
+    self->HandleCommandL( EAknSoftkeyBack );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenFolderListForMessageMovingL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::OpenFolderListForMessageMovingL()
+	{
+    FUNC_LOG;
+	TBool ret = EFalse;
+	// Ignore if mailbox doesn't support moving or we are viewing embedded message
+	if ( iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder ) &&
+	        !iEmbeddedMessageMode )
+	    {
+	    // Activate folder selection view and handle moving after callback gets destination
+	    iMoveToFolderOngoing = ETrue;
+	    TFolderListActivationData folderListData;
+	    folderListData.iCallback = this;
+	    CFSMailFolder* folder = iAppUi.GetMailClient()->GetFolderByUidL( iMessage->GetMailBoxId(), iMessage->GetFolderId() );
+	    folderListData.iSourceFolderType = TFSFolderType( folder->GetFolderType() );
+	    delete folder;
+	    const TPckgBuf<TFolderListActivationData> pkgOut( folderListData );
+	    iAppUi.EnterFsEmailViewL( FolderListId, KFolderListMoveMessage, pkgOut );
+	    ret = ETrue;
+	    }
+	return ret;
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ViewerControl
+// -----------------------------------------------------------------------------
+CAlfControl* CFSEmailUiMailViewerVisualiser::ViewerControl()
+	{
+    FUNC_LOG;
+	return iTextViewerControl;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::Id
+// -----------------------------------------------------------------------------
+TUid CFSEmailUiMailViewerVisualiser::Id() const
+	{
+    FUNC_LOG;
+	return MailViewerId;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ChildDoActivateL
+// -----------------------------------------------------------------------------
+// <cmail> Toolbar
+/*void CFSEmailUiMailViewerVisualiser::DoActivateL(
+    const TVwsViewId& aPrevViewId,
+    TUid aCustomMessageId,
+    const TDesC8& aCustomMessage )*/
+// </cmail> Toolbar
+void CFSEmailUiMailViewerVisualiser::ChildDoActivateL(
+    const TVwsViewId& aPrevViewId,
+    TUid aCustomMessageId,
+    const TDesC8& aCustomMessage )
+	{
+    FUNC_LOG;
+
+    // Read the activation parameters
+    TMsgViewerActivationData activationData;
+    if ( &aCustomMessage && aCustomMessage.Length() )
+        {
+        TPckgBuf<TMsgViewerActivationData> pkgBuf;
+        pkgBuf.Copy( aCustomMessage );
+        activationData = pkgBuf();
+        }
+
+    // Take ownership of the passed message pointer. No pointer should be passed
+    // in other than embedded message cases.
+    // No leaving functions may be called before this step.
+    if ( aCustomMessageId != KStartViewerWithEmbeddedMsgPtr && activationData.iEmbeddedMessage )
+        {
+        delete activationData.iEmbeddedMessage;
+        activationData.iEmbeddedMessage = NULL;
+        __ASSERT_DEBUG( EFalse, Panic(EFSEmailUiUnexpectedValue) );
+        }
+
+    CleanupStack::PushL( activationData.iEmbeddedMessage );
+
+    if ( !iFirstStartCompleted )
+        {
+        DoFirstStartL();
+        }
+    if ( aCustomMessageId == KStartViewerWithEmbeddedMsgPtr )
+        {
+        PushMessageL( activationData.iEmbeddedMessage, ETrue );
+        }
+    CleanupStack::Pop( activationData.iEmbeddedMessage ); // ownership transferred
+
+    // Clear MSK to prevent unintentional presses before viewer is fully constructed
+    ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+
+    // If returning from view launched by MRUI, just complete the ongoing async process.
+    // This will cause MRUI to be reopened and no other activation actions are needed.
+    if ( iMrObserverToInform && aCustomMessageId == KStartViewerReturnToPreviousMsg )
+        {
+        CompletePendingMrCommand();
+        }
+    // Otherwise go on with the standard view activation
+    else
+        {
+        // Cancel any pending asynchronous MR operation. There may be one at least if we
+        // have navigated from MRUI to Donwload manager and from there to another message
+        // or if external view activation happens while MRUI is open.
+        CancelPendingMrCommandL();
+
+        // Get message object unless returning to previously shown message.
+        // In KStartViewerReturnToPreviousMsg the UI assumes that iMessage is alive.
+        if ( aCustomMessageId == KStartViewerWithMsgId )
+            {
+            // Inform base view if view has been forward navigated to get correct back
+            // navigation functionality in case of external activation.
+            ViewEntered( aPrevViewId );
+            UpdateMessagePtrL( activationData.iMailBoxId, activationData.iFolderId, activationData.iMessageId );
+            }
+        else if ( aCustomMessageId == KStartViewerWithEmbeddedMsgPtr ||
+                  aCustomMessageId == KStartViewerReturnFromEmbeddedMsg )
+            {
+            if ( !iOpenMessages || iOpenMessages->IsEmpty() )
+                {
+                User::Leave( KErrNotFound );
+                }
+            UpdateMessagePtr( iOpenMessages->Head() );
+            }
+
+        // Regardless of the activation mode, we should now have a valid message pointer.
+        // Otherwise we cannot go on.
+        User::LeaveIfNull( iMessage );
+
+        iEmbeddedMessageMode = (iEmbeddedMessages->Head() != NULL);
+
+        // Update mailbox unless returning to previously open message
+        if ( aCustomMessageId != KStartViewerReturnToPreviousMsg )
+            {
+            delete iMailBox; iMailBox = NULL;
+            iMailBox = iAppUi.GetMailClient()->GetMailBoxByUidL( iMessage->GetMailBoxId() );
+
+            // Change active mailbox if necessary
+            if ( !iMessage->GetMailBoxId().IsNullId() )
+                {
+                iAppUi.SetActiveMailboxL( iMessage->GetMailBoxId(), EFalse );
+                }
+            }
+
+        // Check if MSG should be shown in the Meeting Request viewer
+        TBool msgSentToMrUi( EFalse );
+        if ( iMessage->IsFlagSet( EFSMsgFlag_CalendarMsg ) &&
+             iAppUi.MrViewerInstanceL() &&
+             !iEmbeddedMessageMode )
+            {
+            // Resolve meeting requst method
+            TESMRMeetingRequestMethod mrMethod( EESMRMeetingRequestMethodUnknown );
+            mrMethod = iAppUi.MrViewerInstanceL()->ResolveMeetingRequestMethodL( *iMessage );
+            if ( mrMethod == EESMRMeetingRequestMethodRequest ||      // Request is shown in mrui
+                 mrMethod == EESMRMeetingRequestMethodCancellation || // Cancellation is shown in mrui
+                 mrMethod == EESMRMeetingRequestMethodUnknown )       // Unknown MR needs to be to resolved in MRUI (Usually IMAP)
+                {
+                // Setting MSK empty. This blocks unwanted MSK keypresses before MrViewer is initialized.
+                ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+
+                msgSentToMrUi = ETrue;
+                ClearMailViewer(); // clear prev message to avoid it becoming visible before MRUI opens
+                iMrUiActive = ETrue;
+                // Same navi pane shown in MR viewer
+                UpdateNaviPaneL( ETrue );
+                SetMailboxNameToStatusPaneL();
+                iAppUi.MrViewerInstanceL()->ExecuteViewL( *iMessage, *this );
+                }
+            }
+
+        // MSG is not sent to MRUI, display in internal mail viewer
+        // Message is either normal email message or response to meeting request
+        if ( !msgSentToMrUi )
+            {
+            iMrUiActive = EFalse;
+
+            // Update the viewer if new message has been opened or layout has changed while we were in some other view
+            TBool changeMsg = (aCustomMessageId != KStartViewerReturnToPreviousMsg);
+            if ( changeMsg || iLayoutChangedWhileNotActive )
+                {
+                RefreshL( changeMsg );
+                }
+            else // update MSK anyway as the attachment status may have changed
+                {
+                iShowMskDownloadOption = ShowMskDownloadOptionL();
+                SetMskL();
+                }
+
+            SetMailboxNameToStatusPaneL();
+
+            // Update navipane content
+            UpdateNaviPaneL();
+            }
+
+        // Set email indicator off.. user has checked the new emails
+        TFsEmailUiUtility::ToggleEmailIconL( EFalse );
+        }
+
+    iNextOrPevMessageSelected = EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OfferToolbarEventL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OfferToolbarEventL( TInt aCommand )
+    {
+    FUNC_LOG;
+    switch (aCommand)
+        {
+        case EFsEmailUiTbCmdReply:
+            {
+            HandleCommandL(EFsEmailUiCmdActionsReply);
+            break;
+            }
+
+        case EFsEmailUiTbCmdForward:
+            {
+            HandleCommandL(EFsEmailUiCmdActionsForward);
+            break;
+            }
+        case EFsEmailUiTbCmdDelete:
+            {
+            HandleCommandL(EFsEmailUiCmdActionsDelete);
+            break;
+            }
+        case EFsEmailUiTbCmdReplyAll:
+            {
+            HandleCommandL(EFsEmailUiCmdActionsReplyAll);
+            break;
+            }
+        default:
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ToolbarResourceId
+// -----------------------------------------------------------------------------
+TInt CFSEmailUiMailViewerVisualiser::ToolbarResourceId() const
+    {
+    return R_FREESTYLE_EMAIL_UI_TOOLBAR_MESSAGE_VIEWER;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ChildDoDeactivate
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ChildDoDeactivate()
+	{
+    FUNC_LOG;
+	CancelFetchings();
+	if ( iFetchingAnimationTimer )
+	    {
+	    iFetchingAnimationTimer->Stop();
+	    }
+	if ( iDownloadProgressIndicator )
+	    {
+	    iDownloadProgressIndicator->HideIndicator();
+	    }
+
+	// Hide this view's navipane
+	HideNaviPane();
+
+	// set view itself as toolbar observer again (e.g. MRGUI could have been changed it)
+	Toolbar()->SetToolbarObserver( this );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HideNaviPane
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HideNaviPane()
+    {
+    FUNC_LOG;
+    CAknNavigationControlContainer* naviPaneContainer = NULL;
+    TRAP_IGNORE( naviPaneContainer = static_cast<CAknNavigationControlContainer*>( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ) );
+    TRAP_IGNORE( naviPaneContainer->PushDefaultL() );
+
+    CCustomStatuspaneIndicators* indicators = iAppUi.GetStatusPaneIndicatorContainer();
+    if ( indicators)
+        {
+        indicators->HideStatusPaneIndicators();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ActivateControlGroup
+// Overriden to make any running download progress bar visible after
+// control group has been swithced
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ActivateControlGroup( TInt aDelay /*= 0*/ )
+    {
+    CFsEmailUiViewBase::ActivateControlGroup( aDelay );
+    TRAP_IGNORE( UpdateDownloadIndicatorL() );
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleMrCommandL
+// Handle accept/decline/tentative/remove commands given for meeting request
+// message directly from list UI.
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleMrCommandL(
+	TInt aCommandId,
+    TFSMailMsgId aMailboxId,
+    TFSMailMsgId aFolderId,
+    TFSMailMsgId aMessageId )
+    {
+    FUNC_LOG;
+
+    // All items should be run
+    if ( !iFirstStartCompleted )
+    	{
+    	DoFirstStartL();
+        }
+
+	UpdateMessagePtrL( aMailboxId, aFolderId, aMessageId );
+
+    if ( aCommandId == EFsEmailUiCmdCalRemoveFromCalendar )
+        {
+        iAppUi.MrViewerInstanceL()->RemoveMeetingRequestFromCalendarL(
+			*iMessage, *this );
+        }
+    else
+        {
+        TESMRAttendeeStatus respondStatus;
+        if ( aCommandId == EFsEmailUiCmdCalActionsAccept )
+            {
+            respondStatus = EESMRAttendeeStatusAccept;
+            }
+        else if ( aCommandId == EFsEmailUiCmdCalActionsTentative )
+            {
+            respondStatus = EESMRAttendeeStatusTentative;
+            }
+        else // ( aCommandId == EFsEmailUiCmdCalActionsDecline )
+            {
+            respondStatus = EESMRAttendeeStatusDecline;
+            }
+        iAppUi.MrViewerInstanceL()->ResponseToMeetingRequestL(
+        	respondStatus, *iMessage, *this );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleTextViewerEventL
+// From viewer observer for CFsTextViewer callbacks
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleTextViewerEventL( TFsTextViewerEvent aEvent )
+	{
+    FUNC_LOG;
+    if ( iFirstStartCompleted ) // Safety
+        {
+        if ( aEvent == EFsTextViewerHotspotClicked )
+            {
+            // Get currently focused hotspot data
+            SViewerHeadingHotSpotData currentHeaderHotSpotData;
+            CFindItemEngine::SFoundItem currentBodyHotSpotData;
+            THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+                currentHeaderHotSpotData, currentBodyHotSpotData );
+
+            // Some header hotspots have some immediate action defined, so
+            // in case of header hotspot, try to handle the action first
+            TBool actionTaken( EFalse );
+            if ( hotspotType == EHeaderHotspot )
+                {
+                actionTaken = HandleHeaderHotspotActionL( currentHeaderHotSpotData.iType );
+                }
+
+            // If the current item is valid hotspot but it didn't have any
+            // immediate action defined, launch item specific action menu
+            if( ( hotspotType == EHeaderHotspot || hotspotType == EBodyHotspot ) &&
+                !actionTaken )
+                {
+                LaunchActionMenuL();
+                }
+            }
+        else if ( aEvent == EFsTextViewerHotspotLongTap )
+            {
+            LaunchActionMenuL();
+            }
+        else if ( aEvent == EFsTextViewerScrollDown )
+            {
+            // check if user has scroll to the bottom for start fetching rest of the message.
+            // if whole message has already been fetched, no actions are needed
+            StartFetchingRemaininBodyLinesIfAtBottomL();
+
+            // Hide action menu icon if current hotspot does not have action menu.
+            // Seems that this needs to be checked also here because "hotspot changed" events
+            // are not received reliably when scrolling down.
+            SetActionMenuIconVisbilityL();
+            }
+
+        else if ( aEvent == EFsTextViewerHotspotChanged )
+            {
+            // Hide action menu icon if current hotspot does not have action menu.
+            SetActionMenuIconVisbilityL();
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleHeaderHotspotActionL
+// Handle appropriate command for the selected header hotspot, if the currently
+// focused item has some action specified. Returns ETrue, if current item has
+// some action defined (and the action is initiated), EFalse if not.
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::HandleHeaderHotspotActionL(
+        TViewerHeadingHotspotType aHotspotType )
+    {
+    TBool actionTaken( EFalse );
+
+    switch( aHotspotType )
+        {
+        case ETypeToNMoreRecipients:
+        case ETypeCcNMoreRecipients:
+        case ETypeBccNMoreRecipients:
+            {
+            HandleCommandL( EFsEmailUiCmdViewAll );
+            actionTaken = ETrue;
+            }
+            break;
+        case ETypeAttachment:
+            {
+            HandleCommandL( EFsEmailUiCmdOpenAttachment );
+            actionTaken = ETrue;
+            }
+            break;
+        case ETypeAttachments:
+            {
+            HandleCommandL( EFsEmailUiCmdOpenAttachmentList );
+            actionTaken = ETrue;
+            }
+            break;
+        case ETypeHtml:
+            {
+            HandleCommandL( EFsEmailUiCmdActionsOpenHtmlViewer );
+            actionTaken = ETrue;
+            }
+            break;
+        }
+
+    return actionTaken;
+    }
+
+// Helper funcitons to get viewed message ID and Folder id
+TFSMailMsgId CFSEmailUiMailViewerVisualiser::ViewedMessageFolderId()
+	{
+    FUNC_LOG;
+	TFSMailMsgId ret;
+	if ( iMessage )
+		{
+		ret = iMessage->GetFolderId();
+		}
+	return ret;
+	}
+
+TFSMailMsgId CFSEmailUiMailViewerVisualiser::ViewedMessageId()
+	{
+    FUNC_LOG;
+	TFSMailMsgId ret;
+	if ( iMessage )
+		{
+		ret = iMessage->GetMessageId();
+		}
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::RefreshL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::RefreshL( TBool aFirstRefresh /*= EFalse*/ )
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted ) // Safety
+        {
+        // Show "Opening" wait note if the viewed message is a large one
+        //<cmail>
+        //TInt waitNoteId = KErrNotFound;
+        //</cmail>
+        if ( TFsEmailUiUtility::IsMessageBodyLargeL( iMessage ) )
+            {
+	        //<cmail> using normal wait note instead of using global
+	        //waitNoteId = TFsEmailUiUtility::ShowGlobalWaitNoteLC( R_FSE_WAIT_OPENING_TEXT );
+            iWaitDialogOpening = new(ELeave)CAknWaitDialog(
+                                (REINTERPRET_CAST(CEikDialog**,&iWaitDialogOpening)));
+	        HBufC* noteText = StringLoader::LoadLC( R_FSE_WAIT_OPENING_TEXT );
+            iWaitDialogOpening->SetTextL(*noteText);
+            //iWaitDialogOpening->DrawableWindow()->SetOrdinalPosition(0);
+	        CleanupStack::PopAndDestroy(noteText);
+            iWaitDialogOpening->ExecuteLD(R_FSE_WAIT_DIALOG_NO_CANCEL);
+	        //</cmail>
+            }
+
+        // Do the update
+        UpdateMailViewerL();
+        AddBackgroundPicturesL();
+
+        // scroll to Sent line after updating if requested
+        if ( aFirstRefresh )
+            {
+            iTextViewer->FocusLineL( iViewerRichText->SentTextLine(), ETrue );
+
+            iAsyncCallback->Cancel(); // just in case
+            iAsyncCallback->Set( TCallBack( DoPostRefresh, this ) );
+            iAsyncCallback->CallBack();
+            }
+
+        // Close the wait note if it was opened
+		if ( iWaitDialogOpening )//<cmail>
+            {
+		    //<cmail>
+		    //CleanupStack::PopAndDestroy( (TAny*)waitNoteId );
+            iWaitDialogOpening->ProcessFinishedL(); //it destroys the waitnote also
+		    //</cmail>
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::DoPostActivation
+// Callback function for deferred activation actions
+// -----------------------------------------------------------------------------
+TInt CFSEmailUiMailViewerVisualiser::DoPostRefresh( TAny* aSelfPtr )
+    {
+    FUNC_LOG;
+    CFSEmailUiMailViewerVisualiser* self =
+        static_cast<CFSEmailUiMailViewerVisualiser*>( aSelfPtr );
+    TRAPD( err, self->PostRefreshL() );
+    return err;
+    }
+
+void CFSEmailUiMailViewerVisualiser::PostRefreshL()
+    {
+    FUNC_LOG;
+    // Focus attahcment line if available
+    TInt attachmentTextLine = iViewerRichText->AttachmentTextLine();
+    TInt viewHtmlTextLine = iViewerRichText->ViewHtmlTextLine();
+    if ( attachmentTextLine > 0 )
+        {
+        iTextViewer->FocusLineL( attachmentTextLine, EFalse );
+        iViewerRichText->SetHotspotByIndexL( iViewerRichText->AttachmentHotSpotIndex() );
+        }
+    else if ( viewHtmlTextLine > 0 )
+        {
+        iTextViewer->FocusLineL( viewHtmlTextLine, EFalse );
+        iViewerRichText->SetHotspotByIndexL( iViewerRichText->ViewHtmlHotSpotIndex() );
+        }
+    SetActionMenuIconVisbilityL();
+
+    // Set initial value for downloaded status for one attachment case
+    iShowMskDownloadOption = ShowMskDownloadOptionL();
+    SetMskL();
+
+    // check if we know whole message, starts fetching if structure is unknown
+    // or body doesn't found
+    CheckMessageStructureL();
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CheckMessageStructureL
+// Starts fetching message structure if it is unknown.
+// If the structure is known but message body is not fetched yet, start fetching it.
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CheckMessageStructureL()
+	{
+    FUNC_LOG;
+	if ( iFirstStartCompleted && iMessage )
+		{
+		if ( !MessageStructureKnown( *iMessage ) )
+			{ // fetch structure
+			StartWaitedFetchingL( EMessageStructure );
+			}
+		else if ( StartFetchingBodyAfterOpeningL() )
+			{
+			iViewerRichText->AppendFetchingMoreTextL();
+			StartFetchingMessagePartL( *iMessage, EMessagePlainTextBodyPart );
+			iFetchingAnimationTimer->Start( KAnimationRefreshTimeIntervalInMilliseconds );
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::UpdateDownloadIndicatorL
+// Show or hide download progress indicator popup and update its contents if
+// necessary.
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::UpdateDownloadIndicatorL( TFSProgress::TFSProgressStatus aStatus
+                                                               /*= TFSProgress::EFSStatus_Waiting*/ )
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted && iMessage && iTextViewer ) // Safety
+        {
+        TFSMailMsgId messId = iMessage->GetMessageId();
+        HBufC* progressString = NULL;
+        if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsAnyAttachmentDownloads( messId ) )
+            {
+            TInt percentage = iAppUi.DownloadInfoMediator()->GetDownloadPercentageL( messId );
+            progressString = StringLoader::LoadLC( R_FSE_VIEWER_ATTACHMENTS_LIST_DOWNLOADING,
+                                                          percentage );
+            }
+        else if ( aStatus == TFSProgress::EFSStatus_RequestComplete )
+            {
+            progressString = StringLoader::LoadLC( R_FSE_VIEWER_ATTACHMENTS_LIST_DOWNLOADED_100 );
+            }
+        else if ( aStatus == TFSProgress::EFSStatus_RequestCancelled )
+            {
+            progressString = StringLoader::LoadLC( R_FSE_VIEWER_ATTACHMENTS_LIST_DOWNLOADING_CANCELLED );
+            }
+        else
+            {
+            progressString = KNullDesC().AllocLC();
+            }
+
+        if ( progressString->Length() )
+            {
+            if ( iDownloadProgressIndicator->IsVisible() )
+                {
+                // pop-up already visible, just reset the text
+                iDownloadProgressIndicator->SetContentsL( progressString );
+                }
+            else
+                {
+                // pop-up should be launched
+
+                // Create fetching status layout first to ensure there's empty space in the end of the message
+                iViewerRichText->CreateStatusLayoutL();
+
+                iDownloadProgressIndicator->ShowIndicatorL( CFSEmailUiStatusIndicator::EIndicationDownloadProgress,
+                                                            progressString,
+                                                            CFSEmailUiStatusIndicator::EIndicationNoAutomaticHiding );
+                iShowMskDownloadOption = EFalse;
+                }
+            }
+        CleanupStack::PopAndDestroy( progressString );
+
+        // Hide the progress popup after small delay if the download was completed or cancelled
+        if ( iAppUi.DownloadInfoMediator() && !iAppUi.DownloadInfoMediator()->IsAnyAttachmentDownloads( messId ) &&
+             iDownloadProgressIndicator->IsVisible() )
+            {
+            iShowMskDownloadOption = ShowMskDownloadOptionL();
+            iDownloadProgressIndicator->HideIndicator( KDownloadProgreeNoteHideDelay );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::DynInitMenuPaneL
+// For dynamically dimm/undimm menu options according to currect message and focus in the viewer
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::DynInitMenuPaneL(
+	TInt aResourceId, CEikMenuPane* aMenuPane )
+	{
+    FUNC_LOG;
+	if ( !iMessage || !iTextViewer )
+	    {
+	    User::Leave( KErrNotReady );
+	    }
+
+	if ( aResourceId == R_FSEMAILUI_MAILVIEWER_MENUPANE )
+		{
+		
+	    if ( FeatureManager::FeatureSupported( KFeatureIdFfCmailIntegration ) )
+		   {
+		   // remove help support in pf5250
+		   aMenuPane->SetItemDimmed( EFsEmailUiCmdHelp, ETrue);      
+		   }
+	    
+        // Folder independent options
+
+		// hide/show MessageReader
+		TBool hideMessageReader = iEmbeddedMessageMode || !iAppUi.MessageReaderSupportsFreestyle();
+		aMenuPane->SetItemDimmed( EFsEmailUiCmdReadEmail, hideMessageReader );
+
+		// hide/show actions sub menu
+		TBool hideActions = !ShowActionsMenuInOptionsL();
+		aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, hideActions );
+
+		// hide/show next and previous message options
+		TBool hideNext = !ShowNextMessageMenuInOptions();
+		aMenuPane->SetItemDimmed( EFsEmailUiCmdNextMessage, hideNext );
+		TBool hidePrev = !ShowPreviousMessageMenuInOptions();
+		aMenuPane->SetItemDimmed( EFsEmailUiCmdPreviousMessage, hidePrev );
+
+        // hide/show copy to clipboard
+        TBool hideCopyToClipBoard = !IsCopyToClipBoardAvailableL();
+        aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCopyToClipboard, hideCopyToClipBoard );
+
+
+		// Folder dependent options
+		TFSMailMsgId currentMessageFolderId = iMessage->GetFolderId();
+		CFSMailFolder* currentFolder = NULL;
+		if ( !iEmbeddedMessageMode )
+		    {
+            TRAP_IGNORE( currentFolder = iAppUi.GetMailClient()->GetFolderByUidL(
+                    iMessage->GetMailBoxId(), currentMessageFolderId ) );
+		    }
+		CleanupStack::PushL( currentFolder );
+		if ( !currentFolder || currentFolder->GetFolderType() == EFSOutbox )
+			{ // outbox folder or embedded message
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReply, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward2, ETrue );
+            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMoveToDrafts, !currentFolder );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsDelete, !currentFolder );
+			}
+		else
+			{ // other folders
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMoveToDrafts, ETrue );
+
+			// hide reply all if there's no multiple recipients
+			TInt numRecipients(0);
+            if ( iMessage )
+                {
+                //Get # of recipients
+                numRecipients =TFsEmailUiUtility::CountRecepients( iMessage );
+                if ( numRecipients == 1 )
+                    {
+                    //check if the malbox ownmailaddress is same as the recipients email address. If not, then assume that the
+                    //email is a distribution list and we need to inc num of Recipients so that "Reply ALL" option appears in UI.
+                    if ( iMessage->GetToRecipients().Count() )
+                        {
+                        if ( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetToRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    if ( iMessage->GetCCRecipients().Count() )
+                        {
+                        if ( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetCCRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    if( iMessage->GetBCCRecipients().Count() )
+                        {
+                        if( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetBCCRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    }
+                }
+
+			TBool hideReplyAll = ( numRecipients <= 1 );
+		    aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, hideReplyAll );
+
+            // In Sent folder, option forward is shown above options reply and reply all
+            TBool forwardAboveReply = ( currentFolder->GetFolderType() == EFSSentFolder );
+            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, !forwardAboveReply );
+            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward2, forwardAboveReply );
+			}
+		CleanupStack::PopAndDestroy( currentFolder );
+		}
+
+	if ( aResourceId == R_FSEMAILUI_MAILVIEWER_SUBMENU_MORE )
+		{
+		TFSMailMsgId currentMessageFolderId = iMessage->GetFolderId();
+        CFSMailFolder* currentFolder = NULL;
+        if ( !iEmbeddedMessageMode )
+            {
+            TRAP_IGNORE( currentFolder = iAppUi.GetMailClient()->GetFolderByUidL(
+                    iMessage->GetMailBoxId(), currentMessageFolderId ) );
+            }
+		CleanupStack::PushL( currentFolder );
+		if ( !currentFolder || currentFolder->GetFolderType() == EFSOutbox )
+			{  // outbox folder or embedded message
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsRead, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, ETrue );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsFlag, ETrue );
+// <cmail> Prevent Download Manager opening with attachments
+//			aMenuPane->SetItemDimmed( EFsEmailUiCmdDownloadManager, ETrue );
+// </cmail> Prevent Download Manager opening with attachments
+			}
+		else // other folders
+			{
+			// show read/unread according to current state
+			TBool messageIsRead = iMessage->IsFlagSet( EFSMsgFlag_Read );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsRead, messageIsRead );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, !messageIsRead );
+
+			// show/hide move message
+			TBool hideMove = !iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, hideMove );
+
+			// show/hide flag for followup
+			TBool hideFlag = !TFsEmailUiUtility::IsFollowUpSupported( *iMailBox );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsFlag, hideFlag );
+
+			// hide/show download manager option
+// <cmail> Prevent Download Manager opening with attachments
+//			TBool hideDownloadMan = !ShowDownloadManagerMenuInOptions();
+//			aMenuPane->SetItemDimmed( EFsEmailUiCmdDownloadManager, hideDownloadMan );
+// </cmail>
+			}
+		CleanupStack::PopAndDestroy( currentFolder );
+		}
+
+	if ( aResourceId == R_FSEMAILUI_MAILVIEWER_SUBMENU_ACTIONS )
+		{
+		// All menu items are hidden by default.
+		// Undimm items that should be visible in action menu.
+		SViewerHeadingHotSpotData currentHeaderHotSpotData;
+		CFindItemEngine::SFoundItem currentBodyHotSpotData;
+		THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+			currentHeaderHotSpotData, currentBodyHotSpotData );
+
+		TBool remoteLookupAvailable =
+			TFsEmailUiUtility::IsRemoteLookupSupported( *iMailBox );
+
+		if ( ( hotspotType == EHeaderHotspot && (
+			currentHeaderHotSpotData.iType == ETypeFromAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeToAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeCcAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeBccAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeEmailAddress )  )
+			||
+			( hotspotType == EBodyHotspot &&
+			  currentBodyHotSpotData.iItemType ==
+				CFindItemEngine::EFindItemSearchMailAddressBin ) )
+			{
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCall, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCreateMessage, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCreateMail, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsContactDetails, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsAddContact2, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup, !remoteLookupAvailable );
+			}
+		else if ( hotspotType == EHeaderHotspot &&
+                  currentHeaderHotSpotData.iType == ETypeAttachment )
+			{
+			TBool hideOpen = !ShowOpenAttachmentOptionL();
+   			aMenuPane->SetItemDimmed( EFsEmailUiCmdOpenAttachment, hideOpen );
+			TBool hideDownload = !ShowDownloadOptionL();
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdDownload, hideDownload );
+			TBool hideCancel = !ShowCancelDownloadOption();
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelDownload, hideCancel );
+			TBool hideSave = !ShowSaveAttachmentOptionL();
+		    aMenuPane->SetItemDimmed( EFsEmailUiCmdSave, hideSave );
+
+		    TBool hideRemove = hideOpen;
+            aMenuPane->SetItemDimmed( EFsEmailUiCmdClearFetchedAttachment, hideRemove );
+			}
+		else if ( hotspotType == EHeaderHotspot &&
+		          currentHeaderHotSpotData.iType == ETypeAttachments )
+			{
+			TBool hideOpen = !ShowOpenAttachmentOptionL();
+   			aMenuPane->SetItemDimmed( EFsEmailUiCmdOpenAttachmentList, hideOpen );
+			TBool hideDownload = !ShowDownloadOptionL();
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdDownloadAll, hideDownload );
+			TBool hideCancel = !ShowCancelDownloadOption();
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelAllDownloads, hideCancel );
+			TBool hideSave = !ShowSaveAttachmentOptionL();
+		    aMenuPane->SetItemDimmed( EFsEmailUiCmdSaveAll, hideSave );
+			}
+		else if ( hotspotType == EBodyHotspot &&
+				  currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+			{
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCall, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsAddContact, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCreateMessage, EFalse );
+			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup, !remoteLookupAvailable );
+			}
+		else if ( hotspotType == EBodyHotspot &&
+				  ( currentBodyHotSpotData.iItemType ==
+				  	CFindItemEngine::EFindItemSearchURLBin ||
+				  	currentBodyHotSpotData.iItemType ==
+				  	CFindItemEngine::EFindItemSearchScheme ) )
+			{
+			// Handle action menu for different search scheme, e.g mailto: and call:
+			TInt schemaLinkType = ResolveBodyTextSchemaUrlTypeL( currentBodyHotSpotData );
+			switch ( schemaLinkType )
+				{
+				case EFocusOnEMailInBodyText:
+					{
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCall, EFalse );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCreateMessage, EFalse );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsContactDetails, EFalse );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsAddContact2, EFalse );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup, !remoteLookupAvailable );
+					}
+					break;
+				case EFocusOnNumberWithinMessage:
+					{
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCall, EFalse );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsAddContact, EFalse );
+					// Drop out "Create message" selection for SIP addresses
+					HBufC* schemeText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+					if ( schemeText && schemeText->FindC( KVoipPrefix ) != 0 )
+						{
+						aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCreateMessage, EFalse );
+						}
+					CleanupStack::PopAndDestroy( schemeText );
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup, !remoteLookupAvailable );
+					}
+					break;
+				default:
+					{
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsOpenWeb, EFalse );
+
+					// Handle intranet browsing item by using AIW service
+					// handler's InitializeMenuPaneL-function, it will remove
+					// the IB menu item if IB is not available, or make the
+					// item visible if IB is available
+			        if ( iIBServiceHandler && iIBServiceHandler->IsAiwMenu( aResourceId ) )
+			            {
+			            TAiwGenericParam param( EGenericParamURL );
+			            CAiwGenericParamList* list = CAiwGenericParamList::NewLC();
+			            list->AppendL( param );
+			            iIBServiceHandler->InitializeMenuPaneL( *aMenuPane, aResourceId,
+			                    EFsEmailUiCmdActionsOpenInIntranetMenu, *list, ETrue );
+			            CleanupStack::PopAndDestroy( list );
+			            }
+
+					aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsAddBookmark, EFalse );
+					}
+					break;
+				}
+			}
+		}
+
+	iAppUi.ShortcutBinding().AppendShortcutHintsL( *aMenuPane,
+		CFSEmailUiShortcutBinding::EContextMailViewer );
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleCommandL
+// Handles menu selections
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleCommandL( TInt aCommand )
+    {
+    FUNC_LOG;
+	if ( !iAppUi.ViewSwitchingOngoing() )
+    	{
+	    switch ( aCommand )
+	        {
+	        case EAknSoftkeyBack:
+	        	{
+	        	// Set empty MSK when navigating back
+	        	ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+	        	// Cancel MR viewer launching if Back is pressed in the middle
+	        	// of launching process.
+	            CancelPendingMrCommandL();
+	        	NavigateBackL();
+	 			}
+	        	break;
+	        // top level options
+	        case EFsEmailUiCmdActionsMoveToDrafts:
+	        	{
+	        	TFsEmailUiUtility::MoveMessageToDraftsL(
+	        		*iAppUi.GetActiveMailbox(), *iMessage );
+	        	}
+	        	break;
+	       	case EFsEmailUiCmdCalActionsReplyAsMail:
+			case EFsEmailUiCmdActionsReply:
+				{
+				if ( !iEmbeddedMessageMode )
+				    {
+                    TEditorLaunchParams params;
+                    params.iMailboxId = iAppUi.GetActiveMailboxId();
+                    params.iMsgId = iMessage->GetMessageId();
+                    params.iActivatedExternally = EFalse;
+                    iAppUi.LaunchEditorL( KEditorCmdReply, params );
+				    }
+				}
+	            break;
+			case EFsEmailUiCmdActionsReplyAll:
+				{
+				if ( !iEmbeddedMessageMode )
+				    {
+                    TEditorLaunchParams params;
+                    params.iMailboxId = iAppUi.GetActiveMailboxId();
+                    params.iMsgId = iMessage->GetMessageId();
+                    params.iActivatedExternally = EFalse;
+                    iAppUi.LaunchEditorL( KEditorCmdReplyAll, params );
+				    }
+				}
+	            break;
+	       	case EFsEmailUiCmdCalActionsForwardAsMail:
+			case EFsEmailUiCmdActionsForward:
+			case EFsEmailUiCmdActionsForward2:
+				{
+				if ( !iEmbeddedMessageMode )
+				    {
+                    TEditorLaunchParams params;
+                    params.iMailboxId = iAppUi.GetActiveMailboxId();
+                    params.iMsgId = iMessage->GetMessageId();
+                    params.iActivatedExternally = EFalse;
+                    iAppUi.LaunchEditorL( KEditorCmdForward, params );
+				    }
+				}
+	            break;
+			case EFsEmailUiCmdActionsDelete:
+				{
+				DeleteMailL( *iMessage, ETrue );
+				}
+	            break;
+	        case EFsEmailUiCmdActionsCopyToClipboard:
+	        	{
+	        	CopyCurrentHotspotToClipBoardL();
+	        	}
+	        	break;
+	        case EFsEmailUiCmdPreviousMessage:
+	        	{
+				ShowPreviousMessageL();
+	        	}
+	        	break;
+	        case EFsEmailUiCmdNextMessage:
+	        	{
+				ShowNextMessageL();
+				}
+	        	break;
+	        case EFsEmailUiCmdHelp:
+	        	{
+	        	TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID );
+	        	}
+	        	break;
+	        case EFsEmailUiCmdExit:
+			    {
+		    	iAppUi.Exit();
+		        }
+		        break;
+	        case EFsEmailUiCmdReadEmail:
+	        	{
+	        	iAppUi.StartReadingEmailsL();
+	        	}
+	        	break;
+
+			// "actions" -sub menu options
+	        case EFsEmailUiCmdActionsCall:
+	        	{
+				CallHotSpotAddressL();
+	        	}
+				break;
+			case EFsEmailUiCmdActionsCreateMessage:
+				{
+				CreateMessageL();
+				}
+				break;
+			case EFsEmailUiCmdActionsCreateMail:
+			    {
+			    ComposeMailL();
+			    }
+			    break;
+	        case EFsEmailUiCmdActionsContactDetails:
+	        	{
+				OpenContactDetailsL();
+	        	}
+				break;
+	        case EFsEmailUiCmdActionsAddContact:
+	        case EFsEmailUiCmdActionsAddContact2:
+	        	{
+				SViewerHeadingHotSpotData currentHeaderHotSpotData;
+				CFindItemEngine::SFoundItem currentBodyHotSpotData;
+				THotspotType hotspotType =
+					iViewerRichText->FindCurrentHotSpotL(
+						currentHeaderHotSpotData, currentBodyHotSpotData );
+		     	if ( hotspotType == EHeaderHotspot )
+	        		{
+					HBufC* emailAddress =
+						iViewerRichText->GetHeaderHotspotEmailAddressLC(
+							currentHeaderHotSpotData );
+					SaveEmailAsContactL( *emailAddress );
+					CleanupStack::PopAndDestroy( emailAddress );
+					}
+	        	else if ( hotspotType == EBodyHotspot )
+	        		{
+					HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+						currentBodyHotSpotData );
+					if ( currentBodyHotSpotData.iItemType ==
+						CFindItemEngine::EFindItemSearchPhoneNumberBin )
+						{
+						SavePhoneNumberAsContactL( *hotspotText );
+						}
+					else if ( currentBodyHotSpotData.iItemType ==
+						CFindItemEngine::EFindItemSearchMailAddressBin )
+						{
+						SaveEmailAsContactL( *hotspotText );
+						}
+					else if ( currentBodyHotSpotData.iItemType ==
+							CFindItemEngine::EFindItemSearchScheme)
+						{
+						if ( hotspotText->FindC( KMailtoPrefix ) == 0 )
+							{
+							// Save email address, prefix is stripped in SaveEmailAsContactL
+							SaveEmailAsContactL( *hotspotText );
+							}
+						else if ( hotspotText->FindC( KCallPrefix ) == 0 ||
+								  hotspotText->FindC( KTelPrefix ) == 0  ||
+								  hotspotText->FindC( KSmsPrefix ) == 0 ||
+								  hotspotText->FindC( KMmsPrefix ) == 0 )
+							{
+							// Save phone nukmber, prefix is stripped in SavePhoneNumberAsContactL
+							SavePhoneNumberAsContactL( *hotspotText );
+							}
+						}
+	 	      		CleanupStack::PopAndDestroy( hotspotText );
+	        		}
+	        	}
+				break;
+	 	    case EFsEmailUiCmdActionsRemoteLookup:
+	        	{
+				SViewerHeadingHotSpotData currentHeaderHotSpotData;
+				CFindItemEngine::SFoundItem currentBodyHotSpotData;
+				THotspotType hotspotType =
+					iViewerRichText->FindCurrentHotSpotL(
+						currentHeaderHotSpotData, currentBodyHotSpotData );
+		     	if ( hotspotType == EHeaderHotspot )
+	        		{
+					HBufC* emailAddress =
+						iViewerRichText->GetHeaderHotspotEmailAddressLC(
+							currentHeaderHotSpotData );
+					LaunchRemoteLookupL( *emailAddress );
+					CleanupStack::PopAndDestroy( emailAddress );
+	      			}
+	        	else if ( hotspotType == EBodyHotspot )
+	        		{
+					HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+						currentBodyHotSpotData );
+					LaunchRemoteLookupL( *hotspotText );
+	 	      		CleanupStack::PopAndDestroy( hotspotText );
+		       		}
+	 		  	}
+				break;
+	 	    case EFsEmailUiCmdActionsOpenHtmlViewer:
+	 	        {
+	 	        LaunchHtmlViewerL();
+	 	        }
+	 	        break;
+	        case EFsEmailUiCmdActionsOpenWeb:
+	        	{
+				CFindItemEngine::SFoundItem currentBodyHotSpotData;
+				TBool bodyHotSpotFound =
+					iViewerRichText->FindCurrentBodyHotSpotL(
+						currentBodyHotSpotData );
+				OpenHotSpotUrlInBrowserL( currentBodyHotSpotData );
+	        	}
+				break;
+	        case EFsEmailUiCmdActionsOpenInIntranetMenu:
+	        	{
+				OpenLinkInIntranetL( ETrue );
+		       	}
+				break;
+	        case EFsEmailUiCmdActionsAddBookmark:
+	        	{
+				CFindItemEngine::SFoundItem currentBodyHotSpotData;
+				TBool bodyHotSpotFound =
+					iViewerRichText->FindCurrentBodyHotSpotL(
+						currentBodyHotSpotData );
+				AddToBookmarksL( currentBodyHotSpotData );
+		       	}
+				break;
+	        case EAknSoftkeyOpen:
+	        case EFsEmailUiCmdOpenAttachment:
+	            {
+	            OpenAttachmentL();
+	            }
+	            break;
+			case EFsEmailUiCmdOpenAttachmentList:
+				{
+				OpenAttachmentsViewL();
+				}
+				break;
+			case EFsEmailUiCmdDownload:
+	        case EFsEmailUiCmdDownloadAll:
+				{
+				StartDowloadingAttachmentsL();
+				}
+				break;
+	        case EFsEmailUiCmdCancelDownload:
+	        case EFsEmailUiCmdCancelAllDownloads:
+		       	{
+				CancelDowloadingAttachmentsL();
+	        	}
+				break;
+	        case EFsEmailUiCmdSave:
+	        case EFsEmailUiCmdSaveAll:
+	        	{
+				SaveAllAttachmentsL();
+	        	}
+				break;
+	        case EFsEmailUiCmdClearFetchedAttachment:
+	            {
+	            RemoveFetchedAttachmentL();
+	            }
+	            break;
+
+			// "more" -sub menu options
+	        case EFsEmailUiCmdMarkAsUnread:
+	        	{
+	        	ChangeMsgReadStatusL( EFalse, EFalse );
+	        	}
+				break;
+	        case EFsEmailUiCmdMarkAsRead:
+	        	{
+	        	ChangeMsgReadStatusL( ETrue, EFalse );
+	        	}
+				break;
+			case EFsEmailUiCmdActionsMoveMessage:
+				{
+                OpenFolderListForMessageMovingL();
+				}
+				break;
+	        case EFsEmailUiCmdActionsFlag:
+		        {
+	       		SetMessageFollowupFlagL();
+		        }
+		        break;
+			case EFsEmailUiCmdCompose:
+				{
+				iAppUi.CreateNewMailL();
+				}
+				break;
+			case EFsEmailUiCmdComposeTo:
+			    {
+			    ComposeMailL();
+			    }
+			    break;
+	       	case EFsEmailUiCmdMessageDetails:
+	       	case EFsEmailUiCmdViewAll:
+				{
+				TUid activationCmdId = KStartMsgDetailsToBeginning;
+				if ( aCommand == EFsEmailUiCmdViewAll )
+				    {
+                    SViewerHeadingHotSpotData currentHeaderHotSpotData;
+                    iViewerRichText->FindCurrentHeaderHotSpotL( currentHeaderHotSpotData );
+                    if( currentHeaderHotSpotData.iType == ETypeToNMoreRecipients )
+                        {
+                        activationCmdId = KStartMsgDetailsToTo;
+                        }
+                    else if( currentHeaderHotSpotData.iType == ETypeCcNMoreRecipients )
+                        {
+                        activationCmdId = KStartMsgDetailsToCc;
+                        }
+                    else if( currentHeaderHotSpotData.iType == ETypeBccNMoreRecipients )
+                        {
+                        activationCmdId = KStartMsgDetailsToBcc;
+                        }
+				    }
+
+                TMsgDetailsActivationData msgDetailsData;
+	  			msgDetailsData.iMailBoxId = iMessage->GetMailBoxId();
+	  			msgDetailsData.iFolderId = iMessage->GetFolderId();
+	  			msgDetailsData.iMessageId = iMessage->GetMessageId();
+				const TPckgBuf<TMsgDetailsActivationData> pkgOut( msgDetailsData );
+				iAppUi.EnterFsEmailViewL(
+					MsgDetailsViewId, activationCmdId,  pkgOut );
+				}
+				break;
+// <cmail> Prevent Download Manager opening with attachments
+//			case EFsEmailUiCmdDownloadManager:
+//				{
+//	  			iAppUi.EnterFsEmailViewL( DownloadManagerViewId );
+//				}
+//				break;
+// </cmail>
+            case EFsEmailUiCmdMarkAsReadUnreadToggle:
+                {
+                if ( iMessage && !iEmbeddedMessageMode )
+                    {
+                    if ( iMessage->IsFlagSet( EFSMsgFlag_Read ) )
+                        {
+                        HandleCommandL( EFsEmailUiCmdMarkAsUnread );
+                        }
+                    else
+                        {
+                        HandleCommandL( EFsEmailUiCmdMarkAsRead );
+                        }
+                    }
+                }
+                break;
+
+            // Moving to top or to bottom of the text. Zero seems to be
+            // treated as illegal value in FocusLineL (it is skipped),
+            // so assuming that line range is [1, total lines count].
+            // It is not documented anywhere though.
+            case EFsEmailUiCmdGoToTop:
+                {
+                // <cmail>
+                // Do nothing if focus is already in top
+                if ( iTextViewer->GetFirstDisplayedLine() > 1 )
+                	{
+                    iTextViewer->FocusLineL( 1 );
+                	}
+                }
+                // </cmail>
+                break;
+            case EFsEmailUiCmdGoToBottom:
+                {
+                iTextViewer->FocusLineL( iTextViewer->GetTotalLines() );
+                }
+                break;
+
+            // The Generic text viewer API supports setting only one key for scroll up
+            // and one key for scroll down. To have multiple scroll up/down keys,
+            // we have set artificial keys for the generic viewer and simulate those
+            // when one of the shortcut keys is pressed.
+            // Another reason to use these artificial keys is that the TextViewer identifies
+            // keys by iCodes. This doesn't fit our concept at least in product where iCode
+            // of certain keys contains the value of the character found behind Fn on that key,
+            // and the Fn mappings vary between variants.
+            // Similar mechanism is used inside AknFep with key codes EKeyF19...EKeyF24,
+            // so collisions with these must be avoided.
+	        case EFsEmailUiCmdScrollUp:
+	            {
+	            TKeyEvent simEvent = { KKeyCodeArtificialScrollUp, EStdKeyNull, 0, 0 };
+	            iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
+	            }
+	            break;
+	        case EFsEmailUiCmdScrollDown:
+	            {
+	            TKeyEvent simEvent = { KKeyCodeArtificialScrollDown, EStdKeyNull, 0, 0 };
+	            iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
+	            }
+                break;
+	        case EFsEmailUiCmdPageUp:
+                {
+                TKeyEvent simEvent = { EKeyPageUp, EStdKeyNull, 0, 0 };
+                iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
+                }
+                break;
+	        case EFsEmailUiCmdPageDown:
+                {
+                TKeyEvent simEvent = { EKeyPageDown, EStdKeyNull, 0, 0 };
+                iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
+                // Check if we reached the end of truncated message body
+                StartFetchingRemaininBodyLinesIfAtBottomL();
+                }
+                break;
+
+            default:
+	        	break;
+	        }
+        }
+    }
+
+
+void CFSEmailUiMailViewerVisualiser::ComposeMailL()
+    {
+    SViewerHeadingHotSpotData currentHeaderHotSpotData;
+    CFindItemEngine::SFoundItem currentBodyHotSpotData;
+    THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+    if ( hotspotType == EHeaderHotspot )
+       {
+       // Regular email address
+       if ( currentHeaderHotSpotData.iType == ETypeEmailAddress )
+           {
+           HBufC* emailAddress = iViewerRichText->GetHeaderHotspotEmailAddressLC( currentHeaderHotSpotData );
+           if ( emailAddress && emailAddress->Length() )
+               {
+               delete iNewMailTempAddress;
+               iNewMailTempAddress = NULL;
+               iNewMailTempAddress = CFSMailAddress::NewL();
+               iNewMailTempAddress->SetEmailAddress( *emailAddress );
+               iAppUi.LaunchEditorL( iNewMailTempAddress );
+               }
+           CleanupStack::PopAndDestroy( emailAddress );
+           }
+       // Sender addr with display name
+       else if ( currentHeaderHotSpotData.iType == ETypeFromAddressDisplayName )
+           {
+           CFSMailAddress* senderAddress = iMessage->GetSender(); // not owned
+           iAppUi.LaunchEditorL( senderAddress );
+           }
+       // To addr with display name
+       else if ( currentHeaderHotSpotData.iType == ETypeToAddressDisplayName )
+           {
+           RPointerArray<CFSMailAddress>& toArray = iMessage->GetToRecipients(); // not owned
+           CFSMailAddress* toAddress = toArray[ currentHeaderHotSpotData.iDisplayNameArrayIndex ];
+           iAppUi.LaunchEditorL( toAddress );
+           }
+       // CC addr with display name
+       else if ( currentHeaderHotSpotData.iType == ETypeCcAddressDisplayName )
+           {
+           RPointerArray<CFSMailAddress>& ccArray = iMessage->GetCCRecipients(); // not owned
+           CFSMailAddress* ccAddress = ccArray[ currentHeaderHotSpotData.iDisplayNameArrayIndex ];
+           iAppUi.LaunchEditorL( ccAddress );
+           }
+       // BCC addr with display name
+       else if ( currentHeaderHotSpotData.iType == ETypeBccAddressDisplayName )
+           {
+           RPointerArray<CFSMailAddress>& bccArray = iMessage->GetBCCRecipients(); // not owned
+           CFSMailAddress* bccAddress = bccArray[ currentHeaderHotSpotData.iDisplayNameArrayIndex ];
+           iAppUi.LaunchEditorL( bccAddress );
+           }
+       }
+    // Email address hotspot in body text clicked
+    else if ( hotspotType == EBodyHotspot && ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchMailAddressBin ||
+             currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchScheme ) )
+       {
+       WriteEmailToHotSpotAddressL( currentBodyHotSpotData );
+       }
+    }
+
+
+
+
+void CFSEmailUiMailViewerVisualiser::ProcessAsyncCommandL( TESMRIcalViewerOperationType aCommandId,
+		                								 const CFSMailMessage& aMessage,
+                										 MESMRIcalViewerObserver* aObserver )
+	{
+	FUNC_LOG;
+	if ( aObserver )
+		{
+		iMrObserverToInform = aObserver;
+		}
+	// we must cast constness away from message because of flaws in MRUI API
+	CFSMailMessage* messagePtr = const_cast<CFSMailMessage*>(&aMessage);
+	if ( messagePtr )
+		{
+        // Fill in result struct
+        iOpResult.iOpType = aCommandId;
+        iOpResult.iMessage = messagePtr;
+        iOpResult.iResultCode = KErrNotFound;
+
+        switch ( aCommandId )
+			{
+            case EESMRCmdMailMessageDetails:
+                {
+                iOpResult.iResultCode = KErrNone;
+                TMsgDetailsActivationData msgDetailsData;
+                msgDetailsData.iMailBoxId = messagePtr->GetMailBoxId();
+                msgDetailsData.iFolderId = messagePtr->GetFolderId();
+                msgDetailsData.iMessageId = messagePtr->GetMessageId();
+                const TPckgBuf<TMsgDetailsActivationData> pkgOut( msgDetailsData );
+                iAppUi.EnterFsEmailViewL( MsgDetailsViewId, KStartMsgDetailsToBeginning,  pkgOut);
+                }
+                break;
+            case EESMRCmdMailDelete:
+                {
+                if ( iMessage )
+                    {
+                    iDeletedMessageFromMrui = iMessage->GetMessageId(); //<cmail>
+                    iOpResult.iResultCode = DeleteMailL( *iMessage, EFalse, ETrue );
+                    }
+
+                // Information is returned immediately after delete has completed.
+                CompletePendingMrCommand();
+                }
+                break;
+            case EESMRCmdMailMoveMessage:
+                {
+                if ( iMessage )
+                    {
+                    if ( OpenFolderListForMessageMovingL() )
+                        {
+                        iOpResult.iResultCode = KErrNone;
+                        iMovingMeetingRequest = ETrue;
+                        }
+                    }
+                }
+                break;
+// <cmail>
+            case EESMRCmdOpenAttachment:
+                {
+                // Check that message has attachments to display
+                if ( messagePtr->IsFlagSet( EFSMsgFlag_Attachments ) )
+                    {
+                    iOpResult.iResultCode = KErrNone;
+                    OpenAttachmentL();
+                    CompletePendingMrCommand();
+                    }
+                }
+                break;
+            case EESMRCmdDownloadAttachment:
+            case EESMRCmdDownloadAllAttachments:
+                {
+                // Check that message has attachments to display
+                if ( messagePtr->IsFlagSet( EFSMsgFlag_Attachments ) )
+                    {
+                    iOpResult.iResultCode = KErrNone;
+                    StartDowloadingAttachmentsL();
+                    CompletePendingMrCommand();
+                    }
+                }
+                break;
+            case EESMRCmdSaveAttachment:
+            case EESMRCmdSaveAllAttachments:
+                {
+                // Check that message has attachments to display
+                if ( messagePtr->IsFlagSet( EFSMsgFlag_Attachments ) )
+                    {
+                    iOpResult.iResultCode = KErrNone;
+                    SaveAllAttachmentsL();
+                    CompletePendingMrCommand();
+                    }
+                }
+                break;
+// </cmail>
+            case EESMRCmdOpenAttachmentView:
+                {
+                // Check that message has attachments to display
+                if ( messagePtr->IsFlagSet( EFSMsgFlag_Attachments ) )
+                    {
+                    iOpResult.iResultCode = KErrNone;
+                    TAttachmentListActivationData params;
+                    params.iMailBoxId = messagePtr->GetMailBoxId();
+                    params.iFolderId = messagePtr->GetFolderId();
+                    params.iMessageId = messagePtr->GetMessageId();
+                    TPckgBuf<TAttachmentListActivationData> buf( params );
+                    TUid emptyCustomMessageId = { 0 };
+                    iAppUi.EnterFsEmailViewL( AttachmentMngrViewId, emptyCustomMessageId, buf );
+// <cmail>
+                    CompletePendingMrCommand();
+// </cmail>
+                    }
+                }
+                break;
+			case EESMRCmdDownloadManager:
+				{
+				// Check that there is something in dwnld manager to show
+				if ( ShowDownloadManagerMenuInOptions() )
+				    {
+				    iOpResult.iResultCode = KErrNone;
+				    iAppUi.EnterFsEmailViewL( DownloadManagerViewId );
+				    }
+				}
+				break;
+            case EESMRCmdMailComposeMessage:
+                {
+                iOpResult.iResultCode = KErrNone;
+                iAppUi.CreateNewMailL();
+                }
+                break;
+			case EESMRCmdMailReply:
+			case EESMRCmdMailReplyAll:
+			case EESMRCmdMailForwardAsMessage:
+				{
+				// Fill result codes for mrui
+				iOpResult.iResultCode = KErrNone;
+				// Fill launc params
+	    		TEditorLaunchParams params;
+	    		params.iMailboxId = iAppUi.GetActiveMailboxId();
+	    		params.iActivatedExternally = EFalse;
+	    		params.iMsgId = messagePtr->GetMessageId();
+				if ( aCommandId == EESMRCmdMailForwardAsMessage )
+					{
+		    		iAppUi.LaunchEditorL( KEditorCmdForward, params );
+					}
+				else if ( aCommandId == EESMRCmdMailReply )
+					{
+		    		iAppUi.LaunchEditorL( KEditorCmdReply, params );
+					}
+				else if ( aCommandId == EESMRCmdMailReplyAll )
+					{
+		    		iAppUi.LaunchEditorL( KEditorCmdReplyAll, params );
+					}
+				}
+				break;
+	  		case EESMRCmdMailPreviousMessage:
+	  		    {
+                iNextOrPevMessageSelected = ETrue; // prevent back navigation when operation completed received
+                ShowPreviousMessageL();
+                iOpResult.iResultCode = KErrNone;
+                CompletePendingMrCommand();
+	  		    }
+	  		    break;
+			case EESMRCmdMailNextMessage:
+				{
+				iNextOrPevMessageSelected = ETrue; // prevent back navigation when operation completed received
+				ShowNextMessageL();
+                iOpResult.iResultCode = KErrNone;
+				CompletePendingMrCommand();
+                }
+				break;
+			default:
+				break;
+			}
+		}
+
+	// Complete immediately if handling command failed. It makes no harm if following
+	// function gets called several times in some case.
+	if ( iOpResult.iResultCode < 0 )
+	    {
+	    CompletePendingMrCommand();
+	    }
+	}
+
+
+void CFSEmailUiMailViewerVisualiser::ProcessSyncCommandL(
+	TESMRIcalViewerOperationType aCommandId,
+	const CFSMailMessage& aMessage )
+	{
+    FUNC_LOG;
+	if ( &aMessage )
+		{
+		switch ( aCommandId )
+			{
+			case EESMRCmdMailMarkUnread:
+				{
+				ChangeMsgReadStatusL( EFalse, ETrue );
+				}
+				break;
+			case EESMRCmdMailMarkRead:
+				{
+				ChangeMsgReadStatusL( ETrue, ETrue );
+				}
+				break;
+			case EESMRCmdMailFlagMessage:
+				{
+		 		if ( iMessage )
+					{
+					if ( !iFlagSelectionHanler )
+						{
+						// Create when used for the first time
+						iFlagSelectionHanler =
+							CFlagSelectionGlobalNoteHandler::NewL( *this );
+						}
+					// Call to LaunchFlagListQueryDialogL will lead
+					// to FlagselectionCompleteL
+					iFlagSelectionHanler->LaunchFlagListQueryDialogL();
+					}
+				}
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+
+// ---------------------------------------------------------------------------
+// CanProcessCommand
+// Callback from meeting request UI. Determines what functionality is provided
+// to mrui by this UI
+// ---------------------------------------------------------------------------
+//
+TBool CFSEmailUiMailViewerVisualiser::CanProcessCommand(
+	TESMRIcalViewerOperationType aCommandId  ) const
+	{
+    FUNC_LOG;
+	TBool ret( EFalse );
+	TInt numRecipients(0);
+	switch ( aCommandId )
+		{
+		case EESMRCmdMailReply:
+		    ret = ETrue;
+		    break;
+		case EESMRCmdMailReplyAll:
+			//Get # of recipients
+		    if ( iMessage )
+                {
+                numRecipients=TFsEmailUiUtility::CountRecepients( iMessage );
+                if ( numRecipients == 1 )
+                    {
+                    //check if the malbox ownmailaddress is same as the recipients email address. If not, then assume that the
+                    //email is a distribution list and we need to inc num of Recipients so that "Reply ALL" option appears in UI.
+                    if ( iMessage->GetToRecipients().Count() )
+                        {
+                        if ( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetToRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    if ( iMessage->GetCCRecipients().Count() )
+                        {
+                        if ( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetCCRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    if ( iMessage->GetBCCRecipients().Count() )
+                        {
+                        if ( iMailBox->OwnMailAddress().GetEmailAddress().Compare(iMessage->GetBCCRecipients()[0]->GetEmailAddress()) )
+                            {
+                            numRecipients++;
+                            }
+                        }
+                    }
+                }
+			ret = ( iMessage && numRecipients > 1 );
+			break;
+		case EESMRCmdDownloadManager:
+			ret = ShowDownloadManagerMenuInOptions();
+			break;
+// <cmail>
+		case EESMRCmdOpenAttachment:
+    	case EESMRCmdSaveAttachment:
+    	case EESMRCmdSaveAllAttachments:
+    	case EESMRCmdDownloadAttachment:
+    	case EESMRCmdDownloadAllAttachments:
+// </cmail>
+		case EESMRCmdOpenAttachmentView:
+			ret = ETrue;
+			break;
+		case EESMRCmdMailComposeMessage:
+			ret = ETrue;
+			break;
+		case EESMRCmdMailMarkUnread:
+			{
+			ret = EFalse;
+			if ( iMessage && iMessage->IsFlagSet(EFSMsgFlag_Read) )
+				{
+				// Read, unread should be available
+				ret = ETrue;
+				}
+			}
+			break;
+		case EESMRCmdMailMarkRead:
+			{
+			ret = EFalse;
+			if ( iMessage && !iMessage->IsFlagSet(EFSMsgFlag_Read) )
+				{
+				// Read, unread should be available
+				ret = ETrue;
+				}
+			}
+			break;
+		case EESMRCmdMailMoveMessage:
+			{
+			ret = EFalse;
+			if ( iMessage )
+				{
+				// confirmed pointer exists, check whether mb has capa
+				ret = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder );
+				}
+			}
+			break;
+		case EESMRCmdMailForwardAsMessage:
+			ret = ETrue;
+			break;
+		case EESMRCmdMailFlagMessage:
+			ret = TFsEmailUiUtility::IsFollowUpSupported( *iMailBox );
+			break;
+	    case EESMRCmdMailMessageDetails:
+			ret = ETrue;
+			break;
+		case EESMRCmdMailDelete:
+			ret = ETrue;
+			break;
+   		case EESMRCmdMailPreviousMessage:
+   		    ret = ShowPreviousMessageMenuInOptions();
+   		    break;
+ 		case EESMRCmdMailNextMessage:
+ 		    ret = ShowNextMessageMenuInOptions();
+ 			break;
+		default:
+			ret = EFalse;
+			break;
+		}
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CompletePendingMrCommand()
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::CompletePendingMrCommand()
+    {
+    FUNC_LOG;
+    if ( iMrObserverToInform )
+        {
+        iMrObserverToInform->OperationCompleted( iOpResult );
+        }
+    iMrObserverToInform = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CancelPendingMrCommandL()
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::CancelPendingMrCommandL()
+    {
+    FUNC_LOG;
+    // Be sure not to call cancel if the MRUI is not active. This is because
+    // calling cancel after closing a newly fetched MR causes the MRUI to
+    // be reopened.
+    if ( iMrUiActive && iAppUi.MrViewerInstanceL() )
+        {
+        iAppUi.MrViewerInstanceL()->CancelOperation();
+        }
+    iMrUiActive = EFalse;
+    iMrObserverToInform = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OperationCompleted()
+// From MRUI observer
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::OperationCompleted( TIcalViewerOperationResult aResult )
+    {
+    FUNC_LOG;
+    if ( aResult.iOpType == EESMRViewLaunch )
+        {
+        iMrUiActive = EFalse;
+        if ( !iNextOrPevMessageSelected && iAppUi.CurrentActiveView() == this )
+            {
+            TRAP_IGNORE( NavigateBackL() );
+            }
+        if ( aResult.iAttendeeStatus == EESMRAttendeeStatusAccept ||
+             aResult.iAttendeeStatus == EESMRAttendeeStatusTentative )
+            {
+            TInt noteTextId = R_FREESTYLE_EMAIL_CONFIRM_NOTE_MEETING_ON_CALENDAR_AFTER_SYNC;
+            TRAP_IGNORE( TFsEmailUiUtility::ShowGlobalInfoNoteL( noteTextId ) );
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OperationError()
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::OperationError( TIcalViewerOperationResult aResult )
+	{
+    FUNC_LOG;
+    // Show message in standard mail viewer in case launchin MRUI fails for any
+	// other reason than viewer being cancelled by calling CancelPendingMrCommand().
+    if ( aResult.iOpType == EESMRViewLaunch )
+        {
+        iMrUiActive = EFalse;
+        if ( iAppUi.CurrentActiveView() == this && aResult.iResultCode != KErrCancel )
+            {
+            TRAP_IGNORE(
+                SetMailboxNameToStatusPaneL();
+                iAppUi.Display().Roster().Hide( ControlGroup() );
+                RefreshL( ETrue );
+                iAppUi.Display().Roster().ShowL( ControlGroup() );
+                UpdateDownloadIndicatorL();
+                );
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::SetMskL()
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::SetMskL()
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted && iTextViewer ) // Safety
+        {
+        TInt ignoreThis( 0 );
+        TBool visibleHotsSpot =
+            iTextViewer->GetVisibleFocusedHotspotLine( ignoreThis );
+        if ( visibleHotsSpot )
+            {
+            SViewerHeadingHotSpotData currentHeaderHotSpotData;
+            CFindItemEngine::SFoundItem currentBodyHotSpotData;
+            THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+                currentHeaderHotSpotData, currentBodyHotSpotData );
+
+            if ( hotspotType == EHeaderHotspot )
+                {
+                if ( currentHeaderHotSpotData.iType ==
+                        ETypeToAddressDisplayName ||
+                     currentHeaderHotSpotData.iType ==
+                        ETypeCcAddressDisplayName ||
+                     currentHeaderHotSpotData.iType ==
+                        ETypeBccAddressDisplayName ||
+                     currentHeaderHotSpotData.iType ==
+                        ETypeEmailAddress )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_COMPOSE );
+                    }
+                else if ( currentHeaderHotSpotData.iType ==
+                    ETypeFromAddressDisplayName )
+                    {
+                    if ( !iEmbeddedMessageMode )
+                        {
+                        ChangeMskCommandL( R_FSE_QTN_MSK_REPLY );
+                        }
+                    else
+                        {
+                        // Reply option is not available in the embedded mode
+                        ChangeMskCommandL( R_FSE_QTN_MSK_COMPOSE );
+                        }
+                    }
+                else if ( currentHeaderHotSpotData.iType == ETypeHtml )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_OPENHTMLVIEWER );
+                    }
+                else if ( currentHeaderHotSpotData.iType == ETypeAttachment )
+                    {
+                    if ( iShowMskDownloadOption )
+                        { // attachment not yet downloaded
+                        ChangeMskCommandL( R_FSE_QTN_MSK_DOWNLOAD );
+                        }
+                    else if ( ShowCancelDownloadOption() )
+                        { // attachment is being downloaded
+                        ChangeMskCommandL( R_FSE_QTN_MSK_OPEN_BLOCKED );
+                        }
+                    else // attachment is already downloaded
+                        {
+                        ChangeMskCommandL( R_FSE_QTN_MSK_VIEWATTACHMENT );
+                        }
+                    }
+                else if ( currentHeaderHotSpotData.iType == ETypeAttachments )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_VIEWATTACHMENTS );
+                    }
+                else if ( currentHeaderHotSpotData.iType ==
+                            ETypeToNMoreRecipients ||
+                          currentHeaderHotSpotData.iType ==
+                            ETypeCcNMoreRecipients ||
+                          currentHeaderHotSpotData.iType ==
+                            ETypeBccNMoreRecipients )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_VIEWALL );
+                    }
+                }
+             else if ( hotspotType == EBodyHotspot )
+                {
+                if ( currentBodyHotSpotData.iItemType ==
+                    CFindItemEngine::EFindItemSearchMailAddressBin )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_COMPOSE );
+                    }
+                else if ( currentBodyHotSpotData.iItemType ==
+                    CFindItemEngine::EFindItemSearchPhoneNumberBin )
+                    {
+                    ChangeMskCommandL( R_FSE_QTN_MSK_CALL );
+                    }
+                else if ( currentBodyHotSpotData.iItemType ==
+                            CFindItemEngine::EFindItemSearchURLBin ||
+                          currentBodyHotSpotData.iItemType ==
+                            CFindItemEngine::EFindItemSearchScheme )
+                    {
+                    TInt schemaLinkType = ResolveBodyTextSchemaUrlTypeL( currentBodyHotSpotData );
+                    switch ( schemaLinkType )
+                        {
+                        case EFocusOnEMailInBodyText:
+                            ChangeMskCommandL( R_FSE_QTN_MSK_COMPOSE );
+                            break;
+                        case EFocusOnNumberWithinMessage:
+                            ChangeMskCommandL( R_FSE_QTN_MSK_CALL );
+                            break;
+                        default:
+                            ChangeMskCommandL( R_FSE_QTN_MSK_OPENURL );
+                            break;
+                        }
+                    }
+                }
+             else // if hotspot is not known
+                {
+                //it will set context menu for email (reply, forward, etc.)
+                ChangeMskCommandL( R_FSE_QTN_MSK_BODY_MENU );
+                }
+            }
+        else
+            {
+	    //it will set context menu for email (reply, forward, etc.)
+            ChangeMskCommandL( R_FSE_QTN_MSK_BODY_MENU );
+            }
+        }
+    }
+
+// CFSEmailUiMailViewerVisualiser::OfferEventL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::OfferEventL(const TAlfEvent& aEvent)
+    {
+    FUNC_LOG;
+    // Consume most keys to be safe. Let only few keys to flow to
+    // text viewer because text viewer does some unexcepted actions
+    // with some keys events (at least left arrow and 0 keys)
+    TBool consumed( ETrue );
+
+    // Handle key presses if we are ready to process them
+    if ( iAsyncProcessComplete && !iAppUi.ViewSwitchingOngoing() && aEvent.IsKeyEvent() )
+        {
+        // Check keyboard shortcuts on key down event since half-QWERTY keyboard
+        // has shortcuts on keys which do not send key event at all
+        if ( aEvent.Code() == EEventKeyDown )
+            {
+            TInt shortcutCommand =
+                iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(),
+                    CFSEmailUiShortcutBinding::EContextMailViewer );
+            if ( shortcutCommand != KErrNotFound )
+                {
+                HandleCommandL( shortcutCommand );
+                }
+            }
+
+        // Update MSK label when key released to avoid constant updating
+        // on fast scrolling
+        else if ( aEvent.Code() == EEventKeyUp )
+            {
+            SetMskL();
+            }
+
+        // Handle key events
+        else if ( aEvent.Code() == EEventKey )
+            {
+            // Swap right and left controls in mirrored layout
+            TInt scanCode = aEvent.KeyEvent().iScanCode;
+            if ( AknLayoutUtils::LayoutMirrored() )
+                {
+                if ( scanCode == EStdKeyRightArrow ) scanCode = EStdKeyLeftArrow;
+                else if ( scanCode == EStdKeyLeftArrow ) scanCode = EStdKeyRightArrow;
+                }
+
+            switch ( scanCode )
+                {
+                case EStdKeyRightArrow:
+                    {
+                    // Open action menu if it is available to current hotspot item
+                    LaunchActionMenuL();
+                    break;
+                    }
+                case EStdKeyYes:
+                    {
+                    // call current header hotspot name or current body hotspot number
+                    CallHotSpotAddressL();
+                    break;
+                    }
+                case EStdKeyDownArrow:
+                case EStdKeyUpArrow:
+                case EStdKeyNull: // simulated keys events
+                    {
+                    // These keys are passed on to TextViewer
+                    consumed = EFalse;
+                    break;
+                    }
+                default:
+                    {
+                    break;
+                    }
+                }
+            }
+        }
+
+    return consumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ClearMailViewer
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ClearMailViewer()
+    {
+    FUNC_LOG;
+    iAppUi.Display().Roster().Hide( ControlGroup() );
+    if ( iTextViewer )
+        {
+        if ( iTextViewerControl )
+            {
+            ControlGroup().Remove( iTextViewerControl );
+            }
+        if ( iControl )
+            {
+            ControlGroup().Remove( iControl );
+            }
+        delete iTextViewer; iTextViewer = NULL;
+        delete iTextViewerControl; iTextViewerControl = NULL;
+        delete iControl; iControl = NULL;
+        }
+    if ( iViewerRichText )
+        {
+        iViewerRichText->Reset();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::UpdateMailViewerL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::UpdateMailViewerL()
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted ) // Safety
+        {
+        ClearMailViewer();
+
+        // Create text viewer and store control pointer
+        iTextViewer = CFsTextViewer::NewL( iEnv );
+        iTextViewerControl = iTextViewer->GetControl();
+        iTextViewer->SetObserver( this );
+
+        // Set the artificial shortcut keys used to command the viewer to scroll up/down.
+        // These are simulated when corresponding shortcut command is received from the
+        // standard shortcut binder of FsEmailUI.
+        CFsTextViewerKeys* keys = CFsTextViewerKeys::NewL();
+        keys->SetKeyPgUp( EKeyPageUp );
+        keys->SetKeyPgDown( EKeyPageDown );
+        keys->SetKeyScrollUp( KKeyCodeArtificialScrollUp );
+        keys->SetKeyScrollDown( KKeyCodeArtificialScrollDown );
+        iTextViewer->SetCustomKeys( keys );
+
+        iTextViewer->SetMirroring( AknLayoutUtils::LayoutMirrored() );
+
+        iViewerRichText->RefreshRichTextL( *iTextViewer, *iMessage, *iMailBox );
+
+        // These need to be called before setting text to the viewer.
+        iTextViewer->SetLeftMargin( iAppUi.LayoutHandler()->ViewerLeftMarginInPixels() );
+        iTextViewer->SetRightMargin( iAppUi.LayoutHandler()->ViewerRightMarginInPixels() );
+
+        SetActionButtonIconAndHighLight();
+
+        iTextViewer->SetTextL( &iViewerRichText->RichText(), iSmDictionary );
+
+        // ownerships are transfered to AlfEnviroment.
+	    //<cmail> Compared to S60 3.2.3 in S60 5.0 Alf offers the key events in
+	    // opposite order.
+        // Create control for capturing left and right navigation events
+        iControl = CFreestyleEmailUiMailViewerControl::NewL( iEnv, *this );
+        ControlGroup().AppendL( iControl );
+        ControlGroup().AppendL( iTextViewerControl );
+        //</cmail>
+
+        iLayoutChangedWhileNotActive = EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::SetActionButtonIconAndHighLight
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::SetActionButtonIconAndHighLight()
+	{
+    FUNC_LOG;
+	CFreestyleEmailUiTextureManager* textureMgr = iAppUi.FsTextureManager();
+    CFSEmailUiLayoutHandler* layoutMgr = iAppUi.LayoutHandler();
+
+    // get textures from texture manager
+	CAlfTexture& menuTexture = textureMgr->TextureByIndex( EListControlMenuIcon );
+	CAlfTexture& selectortexture = textureMgr->TextureByIndex( EViewerHighlightTexture );
+
+    iTextViewer->SetLiteLineBg( selectortexture, layoutMgr->ViewerSelectorOpacity() );
+
+	iTextViewer->SetActionButton( menuTexture, 1  );
+	iTextViewer->SetActionButtonMargin( layoutMgr->ViewerActionMenuIconMargin() );
+	TSize btnSize = layoutMgr->ViewerActionMenuIconSize();
+	iTextViewer->SetActionButtonSize( btnSize.iWidth, btnSize.iHeight );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::LaunchActionMenuL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::LaunchActionMenuL()
+	{
+    FUNC_LOG;
+	// check that current hotspot is visible
+	TInt ignoreThis; // not used here. Only return value is used not this mandatory reference parameter
+	TBool visibleHotsSpot = iTextViewer->GetVisibleFocusedHotspotLine( ignoreThis );
+	if( visibleHotsSpot )
+		{
+		// Remove items
+		CFSEmailUiActionMenu::RemoveAllL();
+
+		// check which hotspot is active.
+		SViewerHeadingHotSpotData currentHeaderHotSpotData;
+		CFindItemEngine::SFoundItem currentBodyHotSpotData;
+		THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+		TActionMenuType currentActionMenuType = ENoActionMenuFocused;
+		if( hotspotType == EHeaderHotspot && (
+			currentHeaderHotSpotData.iType == ETypeFromAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeToAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeCcAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeBccAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeEmailAddress ) )
+			{
+			currentActionMenuType = EFocusOnNameInAddressField;
+			}
+		else if( hotspotType == EHeaderHotspot && (
+			currentHeaderHotSpotData.iType == ETypeAttachment ) )
+			{
+			currentActionMenuType =	EFocusOnAttachmentName;
+			}
+		else if( hotspotType == EHeaderHotspot && (
+			currentHeaderHotSpotData.iType == ETypeAttachments ) )
+			{
+			currentActionMenuType =	EFocusOnAttachmentsText;
+			}
+		else if( hotspotType == EBodyHotspot &&
+				currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+			{
+			currentActionMenuType = EFocusOnNumberWithinMessage;
+			}
+		else if( hotspotType == EBodyHotspot && ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchURLBin ||
+			   	 currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchScheme ) )
+			{
+			TInt schemaLinkType = ResolveBodyTextSchemaUrlTypeL( currentBodyHotSpotData );
+			switch ( schemaLinkType )
+				{
+				case EFocusOnEMailInBodyText:
+					currentActionMenuType = EFocusOnEMailInBodyText;
+					break;
+				case EFocusOnNumberWithinMessage:
+					currentActionMenuType = EFocusOnNumberWithinMessage;
+					break;
+				default:
+					currentActionMenuType = EFocusOnHyperLinkWithinMessage;
+					break;
+
+				}
+			}
+		else if( hotspotType == EBodyHotspot &&
+				currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchMailAddressBin )
+			{
+			currentActionMenuType = EFocusOnEMailInBodyText;
+			}
+
+
+		if( currentActionMenuType != ENoActionMenuFocused )
+			{
+			CreateActionMenuItemsL( currentActionMenuType );
+		    TActionMenuCustomItemId menuResult = CFSEmailUiActionMenu::ExecuteL( EFscCenter );
+		    if ( menuResult != FsEActionMenuCasItemSelectedAndExecuted &&
+		    		menuResult != FsEActionMenuDismissed	)
+		    	{
+		    	HandleActionMenuCommandL( menuResult, currentActionMenuType );
+		    	}
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ResolveBodyTextSchemaUrlTypeL
+// -----------------------------------------------------------------------------
+TInt CFSEmailUiMailViewerVisualiser::ResolveBodyTextSchemaUrlTypeL( CFindItemEngine::SFoundItem aHotSpot )
+	{
+    FUNC_LOG;
+	TInt ret( EFocusOnHyperLinkWithinMessage );
+	HBufC* schemeText = iViewerRichText->GetHotspotTextLC( aHotSpot );
+	if ( schemeText->FindC( KMailtoPrefix ) == 0 )
+		{
+		ret = EFocusOnEMailInBodyText;
+		}
+	else if ( schemeText->FindC( KCallPrefix ) == 0 ||
+			  schemeText->FindC( KTelPrefix ) == 0 ||
+			  schemeText->FindC( KSmsPrefix ) == 0 ||
+			  schemeText->FindC( KMmsPrefix ) == 0 ||
+			  schemeText->FindC( KVoipPrefix ) == 0 )
+		{
+		ret = EFocusOnNumberWithinMessage;
+		}
+	else
+		{
+		ret = EFocusOnHyperLinkWithinMessage;
+		}
+	CleanupStack::PopAndDestroy( schemeText );
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::SetActionMenuIconVisbilityL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::SetActionMenuIconVisbilityL()
+    {
+    FUNC_LOG;
+    if ( iTextViewer )
+        {
+        if ( ShowActionsMenuInOptionsL() )
+            {
+            iTextViewer->ShowActionButtonForCurrentHighlightedHotspotL();
+            }
+        else
+            {
+            iTextViewer->HideActionButtonFromCurrentHighlightedHotspot();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CreateActionMenuItemsL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CreateActionMenuItemsL(
+	TActionMenuType aActionMenuType )
+	{
+    FUNC_LOG;
+	// See the ui spec for all the right action menus according to
+	// currently selected hotspot
+	RArray<TActionMenuCustomItemId> uids;
+	CleanupClosePushL( uids );
+	if ( aActionMenuType == EFocusOnNumberWithinMessage )
+		{
+		uids.Append( FsEActionMenuCall );
+		uids.Append( FsEActionMenuAddToContacts );
+		// Drop FsEActionMenuCreateMessage from sip: addresses
+		// First check which hotspot is active.
+		SViewerHeadingHotSpotData currentHeaderHotSpotData;
+		CFindItemEngine::SFoundItem currentBodyHotSpotData;
+		THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+			currentHeaderHotSpotData, currentBodyHotSpotData );
+		HBufC* schemeText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+		if ( schemeText &&  schemeText->FindC( KVoipPrefix ) != 0 )
+			{
+			uids.Append( FsEActionMenuCreateMessage );
+			}
+		CleanupStack::PopAndDestroy( schemeText );
+		if ( TFsEmailUiUtility::IsRemoteLookupSupported( *iMailBox ) )
+			{
+			uids.Append( FsEActionMenuRemoteLookup );
+			}
+		}
+	else if ( aActionMenuType == EFocusOnNameInAddressField ||
+			  aActionMenuType == EFocusOnEMailInBodyText )
+		{
+		uids.Append( FsEActionMenuCall );
+		uids.Append( FsEActionMenuCreateMessage );
+	    uids.Append( FsEActionMenuCreateEmail );
+		uids.Append( FsEActionMenuContactDetails );
+		uids.Append( FsEActionMenuAddToContacts );
+		if ( TFsEmailUiUtility::IsRemoteLookupSupported( *iMailBox ) )
+			{
+			uids.Append( FsEActionMenuRemoteLookup );
+			}
+		}
+	else if ( aActionMenuType == EFocusOnHyperLinkWithinMessage )
+		{
+		uids.Append( FsEActionMenuOpenInWeb );
+		uids.Append( FsEActionMenuOpenInIntranet );
+		uids.Append( FsEActionMenuBookmark );
+		}
+	else if ( aActionMenuType == EFocusOnAttachmentName )
+		{
+		if ( ShowOpenAttachmentOptionL() )
+		    {
+    		uids.Append( FsEActionAttachmentOpen );
+		    }
+		if ( ShowDownloadOptionL() )
+			{
+			uids.Append( FsEActionAttachmentDownload );
+			}
+		if ( ShowCancelDownloadOption() )
+			{
+			uids.Append( FsEActionAttachmentCancelDownload );
+			}
+		if ( ShowSaveAttachmentOptionL() )
+		    {
+		    uids.Append( FsEActionAttachmentSave );
+		    }
+        if ( ShowOpenAttachmentOptionL() )
+            {
+            uids.Append( FsEActionAttachmentClearFetchedContent );
+            }
+		}
+	else if ( aActionMenuType == EFocusOnAttachmentsText )
+		{
+		if ( ShowOpenAttachmentOptionL() )
+		    {
+    		uids.Append( FsEActionAttachmentViewAll );
+		    }
+		if ( ShowDownloadOptionL() )
+			{
+			uids.Append( FsEActionAttachmentDownloadAll );
+			}
+		if ( ShowCancelDownloadOption() )
+			{
+			uids.Append( FsEActionAttachmentCancelAllDownloads );
+			}
+		if ( ShowSaveAttachmentOptionL() )
+		    {
+		    uids.Append( FsEActionAttachmentSaveAll );
+		    }
+		}
+
+	TInt uidsCount = uids.Count();
+	for ( TInt i = 0; i <  uidsCount; i++ )
+		{
+		CFSEmailUiActionMenu::AddCustomItemL( uids[i] );
+		}
+	CleanupStack::PopAndDestroy( &uids );
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleActionMenuCommandL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleActionMenuCommandL(
+	TActionMenuCustomItemId aSelectedActionMenuItem,
+	TActionMenuType aActionMenuType )
+	{
+    FUNC_LOG;
+	// check which hotspot is active.
+	SViewerHeadingHotSpotData currentHeaderHotSpotData;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+		currentHeaderHotSpotData, currentBodyHotSpotData );
+
+	if ( aActionMenuType == EFocusOnNumberWithinMessage )
+		{
+		switch ( aSelectedActionMenuItem  )
+			{
+			case FsEActionMenuCall: // Call
+				{
+				CallToBodyHotSpotNumberL( currentBodyHotSpotData );
+				}
+				break;
+			case FsEActionMenuAddToContacts: // Add to Contacts
+				{
+				HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+					currentBodyHotSpotData );
+				SavePhoneNumberAsContactL( *hotspotText );
+				CleanupStack::PopAndDestroy( hotspotText );
+				}
+				break;
+			case FsEActionMenuCreateMessage: // Create message
+				{
+				CreateMessageL();
+				}
+				break;
+			case FsEActionMenuRemoteLookup: // Remote lookup
+				{
+				HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+					currentBodyHotSpotData );
+				LaunchRemoteLookupL( *hotspotText );
+				CleanupStack::PopAndDestroy( hotspotText );
+				}
+				break;
+			}
+		}
+	else if ( aActionMenuType == EFocusOnNameInAddressField )
+		{
+		switch( aSelectedActionMenuItem )
+			{
+			case FsEActionMenuCall: // Call
+				{
+				CallHotSpotAddressL();
+				}
+				break;
+			case FsEActionMenuCreateMessage: // Create message
+				{
+				CreateMessageL();
+				}
+				break;
+            case FsEActionMenuCreateEmail: // Create message
+                {
+                ComposeMailL();
+                }
+                break;
+			case FsEActionMenuContactDetails: // Contact details
+				{
+				OpenContactDetailsL();
+				}
+				break;
+			case FsEActionMenuAddToContacts: // Add to Contacts
+				{
+				HBufC* emailAddress =
+					iViewerRichText->GetHeaderHotspotEmailAddressLC(
+						currentHeaderHotSpotData );
+				SaveEmailAsContactL( *emailAddress );
+				CleanupStack::PopAndDestroy( emailAddress );
+				}
+				break;
+			case FsEActionMenuRemoteLookup: // Remote lookup
+				{
+				HBufC* emailAddress =
+					iViewerRichText->GetHeaderHotspotEmailAddressLC(
+						currentHeaderHotSpotData );
+				LaunchRemoteLookupL( *emailAddress );
+				CleanupStack::PopAndDestroy( emailAddress );
+				}
+				break;
+			}
+		}
+	else if ( aActionMenuType == EFocusOnHyperLinkWithinMessage )
+		{
+		switch ( aSelectedActionMenuItem )
+			{
+			case FsEActionMenuOpenInWeb: // Open in web
+				{
+				OpenHotSpotUrlInBrowserL( currentBodyHotSpotData );
+				}
+				break;
+			case FsEActionMenuOpenInIntranet: // Open in intranet
+				{
+				OpenLinkInIntranetL( EFalse );
+				}
+				break;
+			case FsEActionMenuBookmark: // Bookmark
+				{
+				AddToBookmarksL( currentBodyHotSpotData );
+				}
+				break;
+			}
+		}
+	else if ( aActionMenuType == EFocusOnAttachmentName ||
+              aActionMenuType == EFocusOnAttachmentsText )
+		{
+		switch ( aSelectedActionMenuItem )
+			{
+			case FsEActionAttachmentOpen: // Open single attachment
+			    {
+			    OpenAttachmentL();
+                }
+                break;
+			case FsEActionAttachmentViewAll: // Open attachments list
+			    {
+			    OpenAttachmentsViewL();
+			    }
+				break;
+			case FsEActionAttachmentDownload: // Dowload one
+			case FsEActionAttachmentDownloadAll : /// all attachments
+				{
+				StartDowloadingAttachmentsL();
+				}
+				break;
+			case FsEActionAttachmentCancelDownload: // Cancel one / all downloads
+			case FsEActionAttachmentCancelAllDownloads:
+				{
+				CancelDowloadingAttachmentsL();
+				}
+				break;
+			case FsEActionAttachmentSave: // Save one / all attachments
+			case FsEActionAttachmentSaveAll:
+				{
+				SaveAllAttachmentsL();
+				}
+				break;
+			case FsEActionAttachmentClearFetchedContent:
+			    {
+			    RemoveFetchedAttachmentL();
+			    }
+			    break;
+			}
+		}
+	else if ( aActionMenuType == EFocusOnEMailInBodyText )
+		{
+		switch ( aSelectedActionMenuItem )
+			{
+			case FsEActionMenuCall: // Call
+				{
+				CallHotSpotAddressL();
+				}
+				break;
+			case FsEActionMenuCreateMessage: // Create message
+				{
+				CreateMessageL();
+				}
+				break;
+            case FsEActionMenuCreateEmail: // Create message
+                {
+                ComposeMailL();
+                }
+                break;
+			case FsEActionMenuContactDetails: // Contact details
+				{
+				OpenContactDetailsL();
+				}
+				break;
+			case FsEActionMenuAddToContacts: // Add to Contacts
+				{
+				HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+					currentBodyHotSpotData );
+				if ( currentBodyHotSpotData.iItemType ==
+					CFindItemEngine::EFindItemSearchPhoneNumberBin )
+					{
+					SavePhoneNumberAsContactL( *hotspotText );
+					}
+				else if ( currentBodyHotSpotData.iItemType ==
+					CFindItemEngine::EFindItemSearchMailAddressBin )
+					{
+					SaveEmailAsContactL( *hotspotText );
+					}
+				else if ( currentBodyHotSpotData.iItemType ==
+					CFindItemEngine::EFindItemSearchScheme )
+					{
+					if ( hotspotText->FindC( KMailtoPrefix ) == 0 )
+						{
+						// Save email as contact, address mailto: strip is done in SaveEmailAsContactL
+						SaveEmailAsContactL( *hotspotText );
+						}
+					}
+				CleanupStack::PopAndDestroy( hotspotText );
+				}
+				break;
+			case FsEActionMenuRemoteLookup: // Remote lookup
+				{
+				HBufC* hotspotText = iViewerRichText->GetHotspotTextLC(
+					currentBodyHotSpotData );
+				LaunchRemoteLookupL( *hotspotText );
+				CleanupStack::PopAndDestroy( hotspotText );
+				}
+				break;
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenContactDetailsL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OpenContactDetailsL()
+	{
+    FUNC_LOG;
+	SViewerHeadingHotSpotData currentHeaderHotSpotData;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+	HBufC* emailAddress = NULL;
+	if ( hotspotType == EHeaderHotspot )
+		{
+		emailAddress = iViewerRichText->GetHeaderHotspotEmailAddressLC( currentHeaderHotSpotData );
+		}
+	else if ( hotspotType == EBodyHotspot )
+		{
+		emailAddress = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+		// Delete "mailto:" prefix if found
+		if ( emailAddress->FindC( KMailtoPrefix ) == 0 )
+			{
+			emailAddress->Des().Delete( 0, KMailtoPrefix().Length() );
+			}
+		}
+	else
+		{
+		return;
+		}
+
+	CFsDelayedLoader::InstanceL()->GetContactHandlerL()->ShowContactDetailsL(
+			*emailAddress, EContactUpdateEmail, NULL );
+
+	CleanupStack::PopAndDestroy( emailAddress );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::LaunchHtmlViewerL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::LaunchHtmlViewerL()
+	{
+    FUNC_LOG;
+	if ( MessagePartFullyFetchedL( EMessageHtmlBodyPart ) )
+		{
+		THtmlViewerActivationData htmlData;
+		htmlData.iActivationDataType = THtmlViewerActivationData::EMailMessage;
+		htmlData.iMailBoxId = iMessage->GetMailBoxId();
+        htmlData.iFolderId = iMessage->GetFolderId();
+        htmlData.iMessageId = iMessage->GetMessageId();
+        htmlData.iEmbeddedMessageMode = iEmbeddedMessageMode;
+		TPckgBuf<THtmlViewerActivationData> pckgData( htmlData );
+
+		iAppUi.EnterFsEmailViewL( HtmlViewerId, KHtmlViewerOpenNew, pckgData );
+		}
+	else
+		{
+		StartWaitedFetchingL( EMessageHtmlBodyPart );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::LaunchRemoteLookupL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::LaunchRemoteLookupL( const TDesC& aDes ) const
+	{
+    FUNC_LOG;
+	// this method assumes that remote lookup is available with current plugin.
+	HBufC* textData = HBufC::NewLC( aDes.Length() );
+	textData->Des().Append( aDes );
+	if ( textData->FindC( KMailtoPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KMailtoPrefix().Length() );
+		}
+	else if ( textData->FindC( KCallPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KCallPrefix().Length() );
+		}
+	else if ( textData->FindC( KTelPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KTelPrefix().Length() );
+		}
+	else if ( textData->FindC( KSmsPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KSmsPrefix().Length() );
+		}
+	else if ( textData->FindC( KMmsPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KMmsPrefix().Length() );
+		}
+	else if ( textData->FindC( KVoipPrefix ) == 0 )
+		{
+		textData->Des().Delete( 0, KVoipPrefix().Length() );
+		}
+
+	CFsDelayedLoader::InstanceL()->GetContactHandlerL()->LaunchRemoteLookupWithQueryL( *iMailBox, *textData );
+	CleanupStack::PopAndDestroy( textData );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::AddToBookmarksL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::AddToBookmarksL(
+				const CFindItemEngine::SFoundItem& aBodyHotspotData ) const
+	{
+    FUNC_LOG;
+	HBufC* hotspotText =
+		iViewerRichText->GetHotspotTextLC( aBodyHotspotData );
+
+	RFavouritesSession fSession;
+	User::LeaveIfError( fSession.Connect() );
+	CleanupClosePushL( fSession );
+
+	RFavouritesDb favoris;
+	User::LeaveIfError( favoris.Open( fSession, KBrowserBookmarks ) );
+	CleanupClosePushL( favoris );
+
+	CFavouritesItem *favorisItem = CFavouritesItem::NewLC();
+	favorisItem->SetType( CFavouritesItem::EItem );
+	favorisItem->SetUrlL( *hotspotText );
+    // Should be less than KFavouritesMaxName ( 50 )
+	if ( hotspotText->Length() > KFavouritesMaxName )
+		{
+		favorisItem->SetNameL( hotspotText->Left( KFavouritesMaxName ) );
+		}
+	else
+		{
+     	favorisItem->SetNameL( *hotspotText );
+		}
+
+	favorisItem->SetParentFolder( KFavouritesRootUid );
+
+	TInt error = favoris.Add( *favorisItem, ETrue );
+
+	CleanupStack::PopAndDestroy( favorisItem );
+	CleanupStack::PopAndDestroy( &favoris );
+	CleanupStack::PopAndDestroy( &fSession );
+
+	CleanupStack::PopAndDestroy( hotspotText );
+
+	if ( error == KErrNone )
+		{
+		TFsEmailUiUtility::ShowInfoNoteL(
+			R_FREESTYLE_EMAIL_UI_VIEWER_BOOKMARK_ADDED, ETrue );
+		}
+	else // Error in bookmark creation, show could not complete message
+		{
+		TFsEmailUiUtility::ShowErrorNoteL(
+			R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE, ETrue );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CallHotSpotAddressL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CallHotSpotAddressL()
+	{
+    FUNC_LOG;
+	SViewerHeadingHotSpotData currentHeaderHotSpotData;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+   if( hotspotType == EHeaderHotspot &&  currentHeaderHotSpotData.iType == ETypeFromAddressDisplayName )
+        {
+        HBufC* emailAddress = iViewerRichText->GetHeaderHotspotEmailAddressLC( currentHeaderHotSpotData );
+           CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( *emailAddress,
+                    iAppUi.GetActiveMailbox(), this, ETrue /*use call sender text*/);
+           CleanupStack::PopAndDestroy( emailAddress );
+        }
+   else if( ( hotspotType == EHeaderHotspot &&
+			( currentHeaderHotSpotData.iType == ETypeToAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeCcAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeBccAddressDisplayName ||
+			currentHeaderHotSpotData.iType == ETypeEmailAddress )
+			)
+		)
+		{
+		HBufC* emailAddress = iViewerRichText->GetHeaderHotspotEmailAddressLC( currentHeaderHotSpotData );
+		CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( *emailAddress,
+				 iAppUi.GetActiveMailbox(), this, EFalse /*use call sender text*/);
+		CleanupStack::PopAndDestroy( emailAddress );
+		}
+	else if( hotspotType == EBodyHotspot &&
+				currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchMailAddressBin	)
+		{
+		HBufC* emailAddress = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+		CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( *emailAddress,
+				 iAppUi.GetActiveMailbox(), this, EFalse );
+		CleanupStack::PopAndDestroy( emailAddress );
+		}
+	else if( hotspotType == EBodyHotspot &&
+				currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+		{
+		CallToBodyHotSpotNumberL( currentBodyHotSpotData );
+		}
+	else if ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchScheme )
+		{
+		// Get scheme text and make sure there is "mailto:" text or "call:" text
+		HBufC* schemeText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+		if ( schemeText &&  schemeText->FindC( KMailtoPrefix ) == 0 )
+			{
+			schemeText->Des().Delete( 0, KMailtoPrefix().Length() );
+			CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( *schemeText,
+				 iAppUi.GetActiveMailbox(), this, EFalse);
+			}
+		else if ( schemeText->FindC( KCallPrefix ) == 0 ||
+				  schemeText->FindC( KTelPrefix ) == 0 ||
+				  schemeText->FindC( KSmsPrefix ) == 0 ||
+				  schemeText->FindC( KMmsPrefix ) == 0 ||
+				  schemeText->FindC( KVoipPrefix ) == 0 )
+			{
+			CallToBodyHotSpotNumberL( currentBodyHotSpotData );
+			}
+		CleanupStack::PopAndDestroy( schemeText );
+		}
+
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CreateMessageL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CreateMessageL() const
+	{
+    FUNC_LOG;
+	SViewerHeadingHotSpotData currentHeaderHotSpotData;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+	if( hotspotType == EHeaderHotspot )
+		{
+		HBufC* emailAddress = iViewerRichText->GetHeaderHotspotEmailAddressLC( currentHeaderHotSpotData );
+		CFSEmailUiContactHandler* cntHandlerInstance = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
+		cntHandlerInstance->FindAndCreateMsgToContactByEmailL( *emailAddress, iAppUi.GetActiveMailbox() );
+		CleanupStack::PopAndDestroy( emailAddress );
+		}
+	else if( hotspotType == EBodyHotspot )
+		{
+		// Sending based on email address, goes to contact handler
+		if ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchMailAddressBin )
+			{
+			HBufC* emailAddress = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+			CFSEmailUiContactHandler* cntHandlerInstance = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
+			cntHandlerInstance->FindAndCreateMsgToContactByEmailL( *emailAddress, iAppUi.GetActiveMailbox() );
+			CleanupStack::PopAndDestroy( emailAddress );
+			}
+		// Sending based on found number, goes to utility class
+		else if ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+			{
+			HBufC* hotspotText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+			TFsEmailUiUtility::ShowCreateMessageQueryL( *hotspotText );
+			CleanupStack::PopAndDestroy( hotspotText );
+			}
+		else if ( currentBodyHotSpotData.iItemType == CFindItemEngine::EFindItemSearchScheme )
+			{
+			// Get scheme text and make sure there is "mailto:" text or "call:" text
+			HBufC* schemeText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+			if ( schemeText && ( schemeText->FindC( KMailtoPrefix ) == 0 ||
+				 schemeText->FindC( KVoipPrefix ) == 0) )
+				{
+				schemeText->Des().Delete( 0, KMailtoPrefix().Length() );
+				CFSEmailUiContactHandler* cntHandlerInstance = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
+				cntHandlerInstance->FindAndCreateMsgToContactByEmailL( *schemeText, iAppUi.GetActiveMailbox() );
+				}
+			else if ( schemeText && schemeText->FindC( KCallPrefix ) == 0 )
+				{
+				schemeText->Des().Delete( 0, KCallPrefix().Length() );
+				TFsEmailUiUtility::ShowCreateMessageQueryL( *schemeText );
+				}
+			else if ( schemeText && schemeText->FindC( KTelPrefix ) == 0 )
+				{
+				schemeText->Des().Delete( 0, KTelPrefix().Length() );
+				TFsEmailUiUtility::ShowCreateMessageQueryL( *schemeText );
+				}
+			else if ( schemeText && schemeText->FindC( KSmsPrefix ) == 0 )
+				{
+				schemeText->Des().Delete( 0, KSmsPrefix().Length() );
+				TFsEmailUiUtility::ShowCreateMessageQueryL( *schemeText );
+				}
+			else if ( schemeText && schemeText->FindC( KMmsPrefix ) == 0 )
+				{
+				schemeText->Des().Delete( 0, KMmsPrefix().Length() );
+				TFsEmailUiUtility::ShowCreateMessageQueryL( *schemeText );
+				}
+			CleanupStack::PopAndDestroy( schemeText );
+			}
+		}
+	}
+
+TBool CFSEmailUiMailViewerVisualiser::IsCopyToClipBoardAvailableL() const
+    {
+    FUNC_LOG;
+    TBool available = EFalse;
+    TInt ignoreThis( 0 );
+    TBool visibleHotsSpot =
+        iTextViewer->GetVisibleFocusedHotspotLine( ignoreThis );
+
+    // Copy to clipboard is hidden if there's no visible hotspot focus
+    if ( visibleHotsSpot )
+        {
+        // Check the type of focused hotspot
+        SViewerHeadingHotSpotData currentHeaderHotSpotData;
+        CFindItemEngine::SFoundItem currentBodyHotSpotData;
+        THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL(
+            currentHeaderHotSpotData, currentBodyHotSpotData );
+
+        if ( hotspotType == EBodyHotspot )
+            {
+            // copying is available for all body hotspots
+            available = ETrue;
+            }
+        else if ( hotspotType == EHeaderHotspot )
+            {
+            // in header, copying is available for email addresses
+            switch ( currentHeaderHotSpotData.iType )
+                {
+                case ETypeFromAddressDisplayName:
+                case ETypeToAddressDisplayName:
+                case ETypeCcAddressDisplayName:
+                case ETypeBccAddressDisplayName:
+                case ETypeEmailAddress:
+                    available = ETrue;
+                    break;
+                default:
+                    available = EFalse;
+                    break;
+                }
+            }
+        else // hotspotType == ENoHotspot
+            {
+            available = EFalse;
+            }
+        }
+
+    return available;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CopyCurrentHotspotToClipBoardL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CopyCurrentHotspotToClipBoardL() const
+	{
+    FUNC_LOG;
+    TInt ignoreThis( 0 );
+    TBool visibleHotsSpot =
+        iTextViewer->GetVisibleFocusedHotspotLine( ignoreThis );
+
+    // Copy to clipboard is disabled if there's no visible hotspot focus
+    if ( visibleHotsSpot )
+        {
+        HBufC* clipBoardText = NULL;
+        SViewerHeadingHotSpotData currentHeaderHotSpotData;
+        CFindItemEngine::SFoundItem currentBodyHotSpotData;
+        THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+        if ( hotspotType == EHeaderHotspot )
+            {
+            switch ( currentHeaderHotSpotData.iType )
+                {
+                case ETypeFromAddressDisplayName:
+                case ETypeToAddressDisplayName:
+                case ETypeCcAddressDisplayName:
+                case ETypeBccAddressDisplayName:
+                    {
+                    // Get email address attachned to display name, cropped display name has no use
+                    clipBoardText = iViewerRichText->GetEmailAddressLC( currentHeaderHotSpotData );
+                    }
+                    break;
+                case ETypeEmailAddress:
+                    {
+                    clipBoardText = iViewerRichText->GetHotspotTextLC( currentHeaderHotSpotData );
+                    }
+                    break;
+                }
+            }
+        else if ( hotspotType == EBodyHotspot )
+            {
+            clipBoardText = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+            }
+
+        if ( clipBoardText )
+            {
+            CClipboard* cb = CClipboard::NewForWritingLC( CCoeEnv::Static()->FsSession() );
+            cb->StreamDictionary().At( KClipboardUidTypePlainText );
+            CPlainText* plainText = CPlainText::NewL();
+            CleanupStack::PushL( plainText );
+            plainText->InsertL( 0 , *clipBoardText );
+            plainText->CopyToStoreL( cb->Store(), cb->StreamDictionary(), 0, plainText->DocumentLength() );
+            CleanupStack::PopAndDestroy( plainText );
+            cb->CommitL();
+            CleanupStack::PopAndDestroy( cb );
+            CleanupStack::PopAndDestroy( clipBoardText );
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowOpenAttachmentOptionL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowOpenAttachmentOptionL()
+    {
+    FUNC_LOG;
+    TInt ret = EFalse;
+
+	RPointerArray<CFSMailMessagePart> attachments;
+	CleanupResetAndDestroyClosePushL( attachments );
+	iMessage->AttachmentListL( attachments );
+
+    // The Open option is always available when focus on the multiple
+    // attachments item.
+    if ( attachments.Count() > 1 )
+        {
+        ret = ETrue;
+        }
+    // When focus on single attachment item, the Open is shown only when the
+    // attachment is fully downloaded
+    else if ( attachments.Count() == 1 )
+        {
+        TPartData partData = MailData();
+        partData.iMessagePartId = attachments[0]->GetPartId();
+        if ( iAppUi.DownloadInfoMediator() && !iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) &&
+             !iAppUi.DownloadInfoMediator()->IsDownloading( partData.iMessagePartId ) )
+            {
+            ret = ETrue;
+            }
+        }
+    else
+        {
+        ret = EFalse;
+        }
+
+    CleanupStack::PopAndDestroy( &attachments );
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowSaveAttachmentOptionL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowSaveAttachmentOptionL()
+    {
+    FUNC_LOG;
+    // Save (all) is displayed if there are no ongoing downloads.
+    TBool saveAvailable = !ShowCancelDownloadOption();
+
+    // When viewing an embedded message object, saving needs to be disabled
+    // in case there are any attachments of message type. This is due to
+    // limitations in the Activesync plugin.
+    if ( saveAvailable && iEmbeddedMessageMode )
+        {
+        RPointerArray<CFSMailMessagePart> attachments;
+        CleanupResetAndDestroyClosePushL( attachments );
+        iMessage->AttachmentListL( attachments );
+
+        for ( TInt i = 0 ; i < attachments.Count() && saveAvailable ; ++i )
+            {
+            const TDesC& attName = attachments[i]->AttachmentNameL();
+            const TDesC& attMime = attachments[i]->GetContentType();
+            TFileType attType = TFsEmailUiUtility::GetFileType( attName, attMime );
+            if ( attType == EMessageType )
+                {
+                saveAvailable = EFalse;
+                }
+            }
+
+        CleanupStack::PopAndDestroy( &attachments );
+        }
+    return saveAvailable;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowDownloadOptionL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowDownloadOptionL()
+	{
+    FUNC_LOG;
+	TBool retVal = EFalse;
+
+	TPartData partData = MailData();
+
+	RPointerArray<CFSMailMessagePart> attachments;
+	CleanupResetAndDestroyClosePushL( attachments );
+	iMessage->AttachmentListL( attachments );
+	TInt attachmentsCount = attachments.Count();
+	for ( TInt i = 0; i < attachmentsCount; i++ )
+		{
+		partData.iMessagePartId = attachments[i]->GetPartId();
+		if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) )
+			{
+	    	retVal = ETrue;
+	    	break;
+			}
+		}
+	CleanupStack::PopAndDestroy( &attachments );
+	return retVal;
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowDownloadOptionL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowMskDownloadOptionL()
+    {
+    FUNC_LOG;
+    // Check status only if download status might have changed
+    TBool ret( EFalse );
+    if ( iMessage && iMessage->IsFlagSet(EFSMsgFlag_Attachments) )
+        {
+        TPartData partData = MailData();
+        RPointerArray<CFSMailMessagePart> attachments;
+        CleanupResetAndDestroyClosePushL( attachments );
+        iMessage->AttachmentListL( attachments );
+        // Safety, this function should not be called for any other amount than 1
+        if ( attachments.Count() == 1 )
+            {
+            partData.iMessagePartId = attachments[0]->GetPartId();
+            if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) )
+                {
+                ret = ETrue;
+                }
+            }
+        CleanupStack::PopAndDestroy( &attachments );
+        }
+    return ret;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowCancelDownloadOption
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowCancelDownloadOption()
+	{
+    FUNC_LOG;
+	TBool ret( EFalse );
+	if ( iMessage && iAppUi.DownloadInfoMediator() )
+		{
+		ret = iAppUi.DownloadInfoMediator()->IsAnyAttachmentDownloads(
+		        iMessage->GetMessageId() );
+		}
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenAttachmentL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OpenAttachmentL()
+	{
+    FUNC_LOG;
+	if ( !iMessage )
+	    {
+	    User::Leave( KErrNotReady );
+	    }
+
+	RPointerArray<CFSMailMessagePart> attachments;
+	CleanupResetAndDestroyClosePushL( attachments );
+	iMessage->AttachmentListL( attachments );
+
+	// start downloading if not yet downloaded.
+	if ( ShowDownloadOptionL() )
+		{
+		StartDowloadingAttachmentsL();
+		}
+	else if ( ShowCancelDownloadOption() ) // show download ongoing info
+		{
+		TFsEmailUiUtility::ShowInfoNoteL(
+			R_FSE_VIEWER_NOTE_ATTACHMENT_DOWNLOADING_PROGRESS );
+		}
+	else // open if attachment is already downloaded
+		{
+		TInt attachmentsCount = attachments.Count();
+		if ( attachmentsCount )
+			{
+			// <cmail>
+			TFsEmailUiUtility::OpenAttachmentL( *attachments[attachmentsCount-1] );
+			// </cmail>
+			}
+		}
+
+	CleanupStack::PopAndDestroy( &attachments );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenAttachmentsViewL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OpenAttachmentsViewL()
+	{
+    FUNC_LOG;
+	// give pointer to current for attachments list view
+	TAttachmentListActivationData params;
+	params.iMailBoxId = iMessage->GetMailBoxId();
+	params.iFolderId = iMessage->GetFolderId();
+	params.iMessageId = iMessage->GetMessageId();
+	params.iEmbeddedMsgMode = iEmbeddedMessageMode;
+	// use package buffer to pass the params
+	TPckgBuf<TAttachmentListActivationData> buf( params );
+	TUid emptyCustomMessageId = { 0 };
+	iAppUi.EnterFsEmailViewL(
+		AttachmentMngrViewId, emptyCustomMessageId, buf );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartDowloadingAttachmentsL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::StartDowloadingAttachmentsL()
+	{
+    FUNC_LOG;
+	TPartData partData = MailData();
+
+	RPointerArray<CFSMailMessagePart> attachments;
+	CleanupResetAndDestroyClosePushL( attachments );
+	iMessage->AttachmentListL( attachments );
+	TInt attachmentsCount = attachments.Count();
+	for( TInt i = 0; i < attachmentsCount; i++)
+		{
+		if ( attachments[i]->FetchLoadState() == EFSNone ||
+	    	 attachments[i]->FetchLoadState() == EFSPartial )
+			{
+			partData.iMessagePartId = attachments[i]->GetPartId();
+			if ( iAppUi.DownloadInfoMediator() )
+				{
+				iAppUi.DownloadInfoMediator()->DownloadL( partData );
+				}
+			}
+		}
+	CleanupStack::PopAndDestroy( &attachments );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CancelDowloadingAttachmentsL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CancelDowloadingAttachmentsL()
+	{
+    FUNC_LOG;
+	RPointerArray<CFSMailMessagePart> attachments;
+	CleanupResetAndDestroyClosePushL( attachments );
+	iMessage->AttachmentListL( attachments );
+	TInt attachmentsCount = attachments.Count();
+
+	// ask confirmation for cancel
+	TInt promptTextId = R_FSE_VIEWER_CANCEL_DOWNLOAD_QUERY;
+	if ( attachmentsCount > 1 )
+		{
+		promptTextId = R_FSE_VIEWER_CANCEL_DOWNLOADS_QUERY;
+		}
+
+	if ( TFsEmailUiUtility::ShowConfirmationQueryL(promptTextId) && iAppUi.DownloadInfoMediator() )
+		{
+		for ( TInt i = 0 ; i < attachmentsCount ; i++ )
+			{
+			TFSPartFetchState fetchState = attachments[i]->FetchLoadState();
+			if ( fetchState == EFSPartial || fetchState == EFSNone )
+				{
+		    	iAppUi.DownloadInfoMediator()->CancelDownloadL( attachments[i]->GetPartId() );
+				}
+			}
+		}
+	CleanupStack::PopAndDestroy( &attachments );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::SaveAllAttachmentsL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::SaveAllAttachmentsL()
+	{
+    FUNC_LOG;
+	TFileName fileName;
+  	if ( TFsEmailUiUtility::ShowSaveFolderDialogL( fileName ) )
+		{
+		// start downloading attachemts which are not downloaded.
+		// Save all attachment which all already downloaded
+		TPartData partData = MailData();
+
+		RPointerArray<CFSMailMessagePart> attachments;
+		CleanupResetAndDestroyClosePushL( attachments );
+		iMessage->AttachmentListL( attachments );
+		TInt attachmentsCount = attachments.Count();
+
+        // <cmail> remove the MRUI part of the message so we
+	    // don't save unnecessary .ics file
+        CFSMailMessagePart* calendarPart = iMessage->FindBodyPartL( KFSMailContentTypeTextCalendar );
+        CleanupStack::PushL( calendarPart );
+        // </cmail>
+
+		TInt savedCount( 0 );
+		for ( TInt i = 0; i < attachmentsCount; i++ )
+			{
+			partData.iMessagePartId = attachments[i]->GetPartId();
+			if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) )
+				{ // start download and let mediator do the saving
+				iAppUi.DownloadInfoMediator()->DownloadAndSaveL( partData, fileName );
+				}
+			else // save immediately.
+				{
+				// <cmail>
+                if( (calendarPart && partData.iMessagePartId != calendarPart->GetPartId() ||
+                    !calendarPart) && TFsEmailUiUtility::OkToSaveFileL( fileName, *attachments[i] ) )
+                    {
+		    		attachments[i]->CopyContentFileL( fileName );
+		    		savedCount++;
+                    }
+				// </cmail>
+				}
+			}
+        if ( savedCount )
+            {
+            TFsEmailUiUtility::ShowFilesSavedToFolderNoteL( savedCount );
+            }
+        // <cmail>
+        CleanupStack::PopAndDestroy( calendarPart );
+        // </cmail>
+		CleanupStack::PopAndDestroy( &attachments );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::RemoveFetchedAttachmentL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::RemoveFetchedAttachmentL()
+    {
+    FUNC_LOG;
+    TInt reallyClear =
+        TFsEmailUiUtility::ShowConfirmationQueryL( R_FSE_VIEWER_CLEAR_FETCHED_QUERY );
+    if ( reallyClear )
+        {
+        RPointerArray<CFSMailMessagePart> attachments;
+        CleanupResetAndDestroyClosePushL( attachments );
+        iMessage->AttachmentListL( attachments );
+        TInt attachmentsCount = attachments.Count();
+        for ( TInt i = 0; i < attachmentsCount; i++ )
+            {
+            attachments[i]->RemoveContentL();
+            }
+        CleanupStack::PopAndDestroy( &attachments );
+        iShowMskDownloadOption = ShowMskDownloadOptionL();
+        SetMskL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::MailData
+// -----------------------------------------------------------------------------
+TPartData CFSEmailUiMailViewerVisualiser::MailData()
+	{
+    FUNC_LOG;
+	TPartData newPartData;
+	newPartData.iMailBoxId = iMessage->GetMailBoxId();
+	newPartData.iFolderId = iMessage->GetFolderId();
+	newPartData.iMessageId = iMessage->GetMessageId();
+	return newPartData;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartFetchingBodyAfterOpeningL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::StartFetchingBodyAfterOpeningL() const
+	{
+    FUNC_LOG;
+	TBool retVal = EFalse;
+	CFSMailMessagePart* textPart = iMessage->PlainTextBodyPartL();
+	if ( textPart )
+		{
+		TFSPartFetchState currentPlainTextFetchState = textPart->FetchLoadState();
+		if ( currentPlainTextFetchState == EFSNone )
+			{
+			retVal = ETrue;
+			}
+		}
+	delete textPart;
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::MessagePartFullyFetchedL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::MessagePartFullyFetchedL( TFetchedContentType aFetchedContentType ) const
+	{
+    FUNC_LOG;
+	TBool retVal = ETrue;
+	if( aFetchedContentType == EMessagePlainTextBodyPart )
+		{
+		CFSMailMessagePart* textPart = iMessage->PlainTextBodyPartL();
+		if( textPart )
+			{
+			TFSPartFetchState currentPlainTextFetchState = textPart->FetchLoadState();
+			if( currentPlainTextFetchState != EFSFull )
+				{
+				retVal = EFalse;
+				}
+			}
+		delete textPart;
+		}
+	else if( aFetchedContentType == EMessageHtmlBodyPart )
+		{
+		CFSMailMessagePart* htmlPart = iMessage->HtmlBodyPartL();
+		if( htmlPart )
+			{
+			TFSPartFetchState currentHtmlTextFetchState = htmlPart->FetchLoadState();
+			if( currentHtmlTextFetchState != EFSFull )
+				{
+				retVal = EFalse;
+				}
+			}
+		delete htmlPart;
+		}
+	else if( aFetchedContentType == EMessageStructure )
+		{
+		retVal = MessageStructureKnown( *iMessage );
+		}
+	else
+		{
+		User::Leave( KErrNotSupported );
+		}
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartFetchingMessagePartL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::StartFetchingMessagePartL( CFSMailMessage& aMessagePtr,
+											TFetchedContentType aFetchedContentType )
+	{
+    FUNC_LOG;
+	if( aFetchedContentType == EMessagePlainTextBodyPart )
+		{
+		CFSMailMessagePart* textPart = aMessagePtr.PlainTextBodyPartL();
+		CleanupStack::PushL( textPart );
+		TFSMailMsgId textPartId = textPart->GetPartId();
+		iFetchingPlainTextMessageBody = ETrue;
+		iCurrentPlainTextBodyFetchRequestId = textPart->FetchMessagePartL( textPartId, *this, 0 );
+		CleanupStack::PopAndDestroy( textPart );
+		}
+	else if( aFetchedContentType == EMessageHtmlBodyPart )
+		{
+		CFSMailMessagePart* htmlPart = aMessagePtr.HtmlBodyPartL();
+		CleanupStack::PushL( htmlPart );
+		TFSMailMsgId htmlPartId = htmlPart->GetPartId();
+		iFetchingHtmlMessageBody = ETrue;
+		iCurrentHtmlBodyFetchRequestId = htmlPart->FetchMessagePartL( htmlPartId, *this, 0 );
+		CleanupStack::PopAndDestroy( htmlPart );
+		}
+	else if( aFetchedContentType == EMessageStructure )
+		{
+		StartFetchingMessageStructureL( aMessagePtr );
+		}
+	else
+		{
+		User::Leave( KErrNotSupported );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CancelFetchings
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CancelFetchings()
+	{
+    FUNC_LOG;
+	if( iFetchingPlainTextMessageBody )
+		{
+		TRAP_IGNORE( iAppUi.GetMailClient()->CancelL( iCurrentPlainTextBodyFetchRequestId ) );
+		iFetchingPlainTextMessageBody = EFalse;
+		}
+	if( iFetchingHtmlMessageBody )
+		{
+		TRAP_IGNORE( iAppUi.GetMailClient()->CancelL( iCurrentHtmlBodyFetchRequestId ) );
+		iFetchingHtmlMessageBody = EFalse;
+		}
+	if( iFetchingMessageStructure )
+		{
+		TRAP_IGNORE( iAppUi.GetMailClient()->CancelL( iCurrentStructureFetchRequestId ) );
+		iFetchingMessageStructure = EFalse;
+		}
+	iAsyncProcessComplete = ETrue;
+	//<cmail>
+    if(iWaitDialog && iDialogNotDismissed)
+	    TRAP_IGNORE(iWaitDialog->ProcessFinishedL()); // deletes the dialog
+	//</cmail>
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::MessageStructureKnownL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::MessageStructureKnown( CFSMailMessage& aMsg ) const
+	{
+    FUNC_LOG;
+	return TFsEmailUiUtility::IsMessageStructureKnown( aMsg );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartFetchingMessageStructureL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::StartFetchingMessageStructureL( CFSMailMessage& aMsg )
+	{
+    FUNC_LOG;
+	TFSMailMsgId currentMailboxId = aMsg.GetMailBoxId();
+	TFSMailMsgId currentMessageFolderId = aMsg.GetFolderId();
+	CFSMailFolder* currentFolder  = iAppUi.GetMailClient()->GetFolderByUidL( currentMailboxId, currentMessageFolderId );
+	CleanupStack::PushL( currentFolder );
+	RArray<TFSMailMsgId> messageIds;
+	CleanupClosePushL( messageIds );
+	messageIds.Append( aMsg.GetMessageId() );
+	iFetchingMessageStructure = ETrue;
+	iCurrentStructureFetchRequestId = currentFolder->FetchMessagesL( messageIds, EFSMsgDataStructure, *this );
+	CleanupStack::PopAndDestroy( &messageIds );
+	CleanupStack::PopAndDestroy( currentFolder );
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartWaitedFetchingL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::StartWaitedFetchingL( TFetchedContentType aFetchedContentType )
+	{
+    FUNC_LOG;
+    iAsyncProcessComplete = EFalse;
+    iFetchingAlready = EFalse;
+    iStartAsyncFetchType = aFetchedContentType;
+    //<cmail> in cmail we are using different wait dialog, since this wrapper dialog gives
+    // problems in red key exit, when its active
+    //delete iAsyncWaitNote; iAsyncWaitNote = NULL;
+    //iAsyncWaitNote = CAknWaitNoteWrapper::NewL();
+    // surpress start delay to prevent situation where wait note gets visible
+    // only after the structure has been fetched
+    //iAsyncWaitNote->ExecuteL( R_FSE_FETCHING_WAIT_DIALOG, *this, ETrue );
+    //</cmail>
+
+    //<cmail>
+    iWaitDialog = new(ELeave)CAknWaitDialog(
+                   (REINTERPRET_CAST(CEikDialog**,&iWaitDialog)), ETrue);
+    iWaitDialog->SetCallback(this);
+    iDialogNotDismissed = ETrue;
+    iWaitDialog->ExecuteLD(R_FSE_FETCHING_WAIT_DIALOG);
+		StartFetchingMessagePartL( *iMessage, iStartAsyncFetchType );
+ 		iFetchingAlready = ETrue;
+    //</cmail>
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StartFetchingRemaininBodyLinesIfAtBottomL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::StartFetchingRemaininBodyLinesIfAtBottomL()
+    {
+    FUNC_LOG;
+    TInt totalLines = iTextViewer->GetTotalLines();
+    TInt currentLastDisplayedLine = iTextViewer->GetLastDisplayedLine();
+
+    if ( totalLines == currentLastDisplayedLine )
+        {
+        // check if there is something to be fetched
+        if ( !MessagePartFullyFetchedL( EMessagePlainTextBodyPart ) && !iFetchingPlainTextMessageBody )
+            {
+            iViewerRichText->AppendFetchingMoreTextL();
+            // ensure the status layout in the bottom of the screen is visible
+            iTextViewer->FocusLineL( iTextViewer->GetTotalLines() );
+            // start fetching
+            StartFetchingMessagePartL( *iMessage, EMessagePlainTextBodyPart );
+            iFetchingAnimationTimer->Start( KAnimationRefreshTimeIntervalInMilliseconds );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::TimerEventL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::TimerEventL( CFSEmailUiGenericTimer* aTriggeredTimer )
+	{
+    FUNC_LOG;
+	if ( aTriggeredTimer == iFetchingAnimationTimer )
+	    {
+    	iViewerRichText->AppendFetchingMoreTextL();
+    	iFetchingAnimationTimer->Start( KAnimationRefreshTimeIntervalInMilliseconds );
+	    }
+	}
+
+// MAknBackgroundProcess methods
+//
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::StepL
+// -----------------------------------------------------------------------------
+//<cmail>
+/*
+void CFSEmailUiMailViewerVisualiser::StepL()
+	{
+    FUNC_LOG;
+	if( !iFetchingAlready )
+		{
+		StartFetchingMessagePartL( *iMessage, iStartAsyncFetchType );
+ 		iFetchingAlready = ETrue;
+ 		}
+ 	}*/
+//</cmail>
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::IsProcessDone
+// -----------------------------------------------------------------------------
+//<cmail>
+/*
+TBool CFSEmailUiMailViewerVisualiser::IsProcessDone() const
+    {
+    FUNC_LOG;
+    return iAsyncProcessComplete;
+	}*/
+//</cmail>
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ProcessFinished
+// -----------------------------------------------------------------------------
+//<cmail>
+//void CFSEmailUiMailViewerVisualiser::ProcessFinished() {/* nothing here */ }
+//</cmail>
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::DialogDismissedL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::DialogDismissedL( TInt aButtonId )
+	{
+    FUNC_LOG;
+    iDialogNotDismissed = EFalse;
+	if( aButtonId == EAknSoftkeyCancel )
+		{
+		CancelFetchings();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CycleError
+// -----------------------------------------------------------------------------
+//<cmail>
+//TInt CFSEmailUiMailViewerVisualiser::CycleError( TInt /*aError*/ )
+/*
+    {
+    FUNC_LOG;
+    iAsyncProcessComplete = ETrue;
+    CancelFetchings();
+    return KErrNone;
+    }*/
+//</cmail>
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::AddBackgroundPicturesL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::AddBackgroundPicturesL()
+	{
+	CAlfTexture& headerTexture = iAppUi.FsTextureManager()->TextureByIndex( EViewerTextureHeaderBackGround );
+	CAlfTexture& backgroundTexture = iAppUi.FsTextureManager()->TextureByIndex( EBackgroundTextureMailList );
+
+	// add header texture
+	// -1 is here for to bottom space icon
+	// // <cmail> S60 Skin support
+	//	iTextViewer->SetPartBgImageL( 0, iViewerRichText->HeaderLengthInCharacters()-2, headerTexture );
+	// </cmail>
+
+	// add bg texture
+	//<cmail> S60 skin support
+	//iTextViewer->SetBackgroundImageL( backgroundTexture );
+    //</cmail>
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::SetMessageFollowupFlagL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::SetMessageFollowupFlagL()
+	{
+    FUNC_LOG;
+ 	if ( iMessage &&
+ 	     iTextViewer &&
+ 	     iViewerRichText &&
+ 	     TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) &&
+ 	     !iEmbeddedMessageMode )
+		{
+		TFollowUpNewState newState = TFsEmailUiUtility::SetMessageFollowupFlagL( *iMessage );
+
+		switch ( newState )
+			{
+			case EFollowUp:
+				{
+				iViewerRichText->UpdateIconL( CFSEmailUiMailViewerRichText::EViewerIconFollowUp );
+				}
+				break;
+			case EFollowUpComplete:
+				{
+				iViewerRichText->UpdateIconL( CFSEmailUiMailViewerRichText::EViewerIconFollowUpComplete );
+				}
+				break;
+			case EFollowUpClear:
+				{
+				iViewerRichText->UpdateIconL( CFSEmailUiMailViewerRichText::EViewerIconFollowUpNone );
+				}
+				break;
+			case EFollowUpNoChanges:
+			default:
+				{
+				// do nothing.
+				}
+				break;
+			}
+
+		if ( newState != EFollowUpNoChanges )
+		    {
+		    // Update icon in viewer
+	        TInt iconLine = iViewerRichText->FollowupIconLine();
+            iTextViewer->ReloadPicturesL( iconLine );
+            // Notify appui of changed mail item
+            SendEventToAppUiL( TFSEventMailChanged );
+		    }
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::DeleteMailL
+// -----------------------------------------------------------------------------
+TInt CFSEmailUiMailViewerVisualiser::DeleteMailL( CFSMailMessage& aMessagePtr, TBool aReturnPreviousView, TBool aDisableNote )
+	{
+    FUNC_LOG;
+	TInt ret( KErrCancel );
+
+	if ( iEmbeddedMessageMode )
+	    {
+	    // embedded messages can't be deleted
+	    ret = KErrNotSupported;
+	    }
+	else
+	    {
+        TInt okToDelete( ETrue );
+        if ( !aDisableNote )
+            {
+            if(iAppUi.GetCRHandler()->WarnBeforeDelete())
+                {
+                okToDelete = TFsEmailUiUtility::ShowConfirmationQueryL( R_FREESTYLE_EMAIL_UI_DELETE_MESSAGE_CONFIRMATION );
+                }
+            }
+        if ( okToDelete )
+            {
+            CFSMailMessage* confirmedMsgPtr = NULL;
+            TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(),
+                                                                                     aMessagePtr.GetFolderId(),
+                                                                                     aMessagePtr.GetMessageId() ,
+                                                                                     EFSMsgDataEnvelope ) );
+            if ( confirmedMsgPtr )
+                {
+                CleanupStack::PushL( confirmedMsgPtr );
+                RArray<TFSMailMsgId> msgIds;
+                CleanupClosePushL( msgIds );
+                msgIds.Append( confirmedMsgPtr->GetMessageId() );
+                TFSMailMsgId mailBox = iAppUi.GetActiveMailbox()->GetId();
+                iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, confirmedMsgPtr->GetFolderId(), msgIds );
+                // Notify appui of deleted mail item
+                SendEventToAppUiL( TFSEventMailDeleted );
+                CleanupStack::PopAndDestroy( &msgIds );
+                CleanupStack::PopAndDestroy( confirmedMsgPtr );
+                }
+
+            // return to previous view
+            if ( aReturnPreviousView )
+                {
+                // return only if we are in mail viewer
+                if ( iAppUi.CurrentActiveView()->Id() == MailViewerId )
+                	{
+                	HandleCommandL( EAknSoftkeyBack );
+                	}
+                }
+            }
+        if ( okToDelete )
+            {
+            ret = KErrNone;
+            }
+	    }
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowActionsMenuInOptionsL
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowActionsMenuInOptionsL() const
+	{
+    FUNC_LOG;
+	TBool retVal = ETrue;
+
+	SViewerHeadingHotSpotData currentHeaderHotSpotData;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	THotspotType hotspotType = iViewerRichText->FindCurrentHotSpotL( currentHeaderHotSpotData, currentBodyHotSpotData );
+
+	if( hotspotType == ENoHotspot || ( hotspotType == EHeaderHotspot && (
+		currentHeaderHotSpotData.iType == ETypeToNMoreRecipients ||
+		currentHeaderHotSpotData.iType == ETypeCcNMoreRecipients ||
+		currentHeaderHotSpotData.iType == ETypeBccNMoreRecipients ||
+		currentHeaderHotSpotData.iType == ETypeHtml ) ) )
+		{
+		retVal = EFalse;
+		}
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowDownloadManagerMenuInOptions
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowDownloadManagerMenuInOptions() const
+	{
+    FUNC_LOG;
+	TBool ret(EFalse);
+/* <cmail> Download Manager blocked
+	if ( iAppUi.DownloadInfoMediator() )
+		{
+		ret = iAppUi.DownloadInfoMediator()->IsAnyAttachmentDownloads();
+		}
+</cmail> */
+	return ret;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowNextMessageMenuInOptions
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowNextMessageMenuInOptions() const
+	{
+    FUNC_LOG;
+	TBool available = EFalse;
+	// Next/previous message options are inavailable in the embedded mode
+	if ( iMessage && !iEmbeddedMessageMode )
+	    {
+        TFSMailMsgId currentMsgId = iMessage->GetMessageId();
+        TFSMailMsgId nextMsgId;
+        TFSMailMsgId nextMsgFolderId;
+        available = iAppUi.IsNextMsgAvailable( currentMsgId, nextMsgId, nextMsgFolderId );
+	    }
+	return available;
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowPreviousMessageMenuInOptions
+// -----------------------------------------------------------------------------
+TBool CFSEmailUiMailViewerVisualiser::ShowPreviousMessageMenuInOptions() const
+	{
+    FUNC_LOG;
+    TBool available = EFalse;
+    // Next/previous message options are inavailable in the embedded mode
+    if ( iMessage && !iEmbeddedMessageMode )
+        {
+        TFSMailMsgId currentMsgId = iMessage->GetMessageId();
+        TFSMailMsgId prevMsgId;
+        TFSMailMsgId prevMsgFolderId;
+        available = iAppUi.IsPreviousMsgAvailable( currentMsgId, prevMsgId, prevMsgFolderId );
+        }
+    return available;
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowNextMessageL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ShowNextMessageL()
+	{
+    FUNC_LOG;
+	if ( iMessage && !iEmbeddedMessageMode )
+		{
+		TFSMailMsgId currentMsgId = iMessage->GetMessageId();
+		TFSMailMsgId nextMsgId;
+		TFSMailMsgId nextMsgFolderId;
+		if ( iAppUi.IsNextMsgAvailable( currentMsgId, nextMsgId, nextMsgFolderId ) )
+			{
+			// Stop timer and cancel fetchings before showing next message
+			iFetchingAnimationTimer->Stop();
+			CancelFetchings();
+
+			// Change empty msk when moving to next
+			ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+
+			iAppUi.MoveToNextMsgL( currentMsgId, nextMsgId );
+			// Next message is displayed in this view through doactivate, because view is re-activate by mail list
+			}
+		}
+	}
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ShowPreviousMessageL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ShowPreviousMessageL()
+	{
+    FUNC_LOG;
+	if ( iMessage && !iEmbeddedMessageMode )
+		{
+		TFSMailMsgId currentMsgId = iMessage->GetMessageId();
+		TFSMailMsgId prevMsgId;
+		TFSMailMsgId prevMsgFolderId;
+		if ( iAppUi.IsPreviousMsgAvailable( currentMsgId, prevMsgId, prevMsgFolderId ) )
+			{
+			// Stop timer and cancel fetchings before showing prev message
+			iFetchingAnimationTimer->Stop();
+			CancelFetchings();
+
+		    // Change empty msk when moving to previous
+		    ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+
+			iAppUi.MoveToPreviousMsgL( currentMsgId, prevMsgId );
+			// Previous message is displayed in this view through doactivate, because view is re-activate by mail list
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::UpdateMessagePtrL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::UpdateMessagePtrL( TFSMailMsgId aNewMailboxId,
+                                                        TFSMailMsgId aNewFolderId,
+                                                        TFSMailMsgId aNewMessageId )
+    {
+    FUNC_LOG;
+    TBool messageChanged = ETrue;
+
+    if ( iMessage )
+        {
+        // Check is the message going to be changed or are we just updating the
+        // same message object which has been previously shown.
+        messageChanged = ( iMessage->GetMessageId() != aNewMessageId );
+
+        // stop observing downloads from the previous message in case the message was changed
+        if ( iAppUi.DownloadInfoMediator() && messageChanged )
+            {
+            iAppUi.DownloadInfoMediator()->StopObserving( this, iMessage->GetMessageId() );
+            }
+        delete iMessage;
+        iMessage = NULL;
+        PopMessage();
+        }
+
+    iMessage = iAppUi.GetMailClient()->GetMessageByUidL( aNewMailboxId,
+                                                         aNewFolderId,
+                                                         aNewMessageId,
+                                                         EFSMsgDataEnvelope  );
+    if ( iMessage )
+        {
+
+        UpdateMessagePtr( iMessage );
+        // Update the open messages stack.
+        EraseMessageStack(); // takes care of deallocating any previous messages
+        PushMessageL( iMessage, EFalse ); // this is non-embedded message
+        // Opened to viewer -> set message as read
+        if ( !iMessage->IsFlagSet( EFSMsgFlag_Read ) )
+            {
+            iMessage->SetFlag( EFSMsgFlag_Read );
+            iMessage->SaveMessageL(); // Save read status
+            // Notify appui of changed mail item, it seems that protocols don't do this
+            SendEventToAppUiL( TFSEventMailChanged );
+            }
+        // Start observing attachment downloads from the new message
+        if ( iAppUi.DownloadInfoMediator() && messageChanged )
+            {
+            iAppUi.DownloadInfoMediator()->AddObserver( this, iMessage->GetMessageId() );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::UpdateMessagePtr
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::UpdateMessagePtr( CFSMailMessage* aNewMessagePtr )
+    {
+    ASSERT( aNewMessagePtr );
+
+    TBool messageChanged = ETrue;
+
+    // Stop observing any previous message and update iMessage pointer
+    if ( iMessage )
+        {
+        // Check is the message going to be changed or are we just updating the
+        // same message object which has been previously shown.
+        messageChanged = ( iMessage->GetMessageId() != aNewMessagePtr->GetMessageId() );
+
+        // stop observing downloads from the previous message in case the message was changed
+        if ( iAppUi.DownloadInfoMediator() && messageChanged )
+            {
+            iAppUi.DownloadInfoMediator()->StopObserving( this, iMessage->GetMessageId() );
+            }
+        }
+    iMessage = aNewMessagePtr;
+
+    // Start observing attachment downloads from the new message
+    if ( iAppUi.DownloadInfoMediator() && messageChanged )
+        {
+        iAppUi.DownloadInfoMediator()->AddObserver( this, iMessage->GetMessageId() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::PushMessageL
+// Message stack handling. Ownership of message is transferred when succesful.
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::PushMessageL( CFSMailMessage* aMessage, TBool aIsEmbedded )
+    {
+    if ( !iOpenMessages || !iEmbeddedMessages )
+        {
+        User::Leave( KErrNotReady );
+        }
+
+    // We must ensure that push is done succesfully either to both stacks or to neither one.
+    if ( aIsEmbedded )
+        {
+        iEmbeddedMessages->PushL( aMessage );
+        }
+    else
+        {
+        iEmbeddedMessages->PushL( NULL );
+        }
+    TRAPD( err, iOpenMessages->PushL( aMessage ) );
+    if ( err )
+        {
+        iEmbeddedMessages->Pop();
+        User::Leave( err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::PopMessage
+// Message stack handling. Ownership of message is returned.
+// -----------------------------------------------------------------------------
+//
+CFSMailMessage* CFSEmailUiMailViewerVisualiser::PopMessage()
+    {
+    ASSERT( iOpenMessages && iEmbeddedMessages );
+    ASSERT( iOpenMessages->Count() == iEmbeddedMessages->Count() );
+
+    CFSMailMessage* msg = NULL;
+    if ( !iOpenMessages->IsEmpty() )
+        {
+        msg = iOpenMessages->Pop();
+        }
+    if ( !iEmbeddedMessages->IsEmpty() )
+        {
+        iEmbeddedMessages->Pop();
+        }
+    return msg;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::EraseMessageStack
+// Message stack handling. All messages in stack are deallocated
+// -----------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::EraseMessageStack()
+    {
+    ASSERT( iOpenMessages && iEmbeddedMessages );
+    ASSERT( iOpenMessages->Count() == iEmbeddedMessages->Count() );
+
+    iOpenMessages->ResetAndDestroy();
+    iEmbeddedMessages->Reset();
+    }
+// CFSEmailUiMailViewerVisualiser::NavigateBackL
+// Overriden from base class
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::NavigateBackL()
+    {
+    FUNC_LOG;
+    // clean up current message
+    if ( iMessage && iAppUi.DownloadInfoMediator() )
+        {
+        iAppUi.DownloadInfoMediator()->StopObserving( this, iMessage->GetMessageId() );
+        }
+    delete iMessage;
+    iMessage = NULL;
+    PopMessage();
+    // Return to previous message in the stack if there is still some left
+    if ( !iOpenMessages->IsEmpty() )
+        {
+        iAppUi.EnterFsEmailViewL( MailViewerId, KStartViewerReturnFromEmbeddedMsg, KNullDesC8 );
+        }
+    // In usual case we use the base view implementation
+    else
+        {
+        CFsEmailUiViewBase::NavigateBackL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleDynamicVariantSwitchL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleDynamicVariantSwitchL( CFsEmailUiViewBase::TDynamicSwitchType /*aType*/ )
+	{
+    FUNC_LOG;
+	// Set scroll offset to match screen height
+	if ( iFirstStartCompleted && iTextViewer && iMessage )
+	    {
+	    // <cmail>
+	    TInt firstLine = iTextViewer->GetFirstDisplayedLine();        // get first line number
+	    TInt firstChar = iTextViewer->GetFirstCharInLine(firstLine);  // get first char offset
+	    // </cmail>
+
+	    iAppUi.Display().Roster().Hide( ControlGroup() );
+	    RefreshL();
+
+	    // <cmail>
+	    TInt newLine = iTextViewer->GetLineNumber(firstChar);   // get the new line number for this offset
+	    if(newLine<0) newLine = firstLine;                       // in case of error go to the prev. line number
+	    iTextViewer->FocusLineL(newLine,ETrue);                  // focus on the found line number
+	    // </cmail>
+	    // <cmail>
+	    SetActionMenuIconVisbilityL();
+            // </cmail>
+            iAppUi.Display().Roster().ShowL( ControlGroup() );
+	    iDownloadProgressIndicator->NotifyLayoutChange();
+	    }
+ 	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::HandleDynamicVariantSwitchOnBackgroundL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::HandleDynamicVariantSwitchOnBackgroundL( CFsEmailUiViewBase::TDynamicSwitchType /*aType*/ )
+    {
+    FUNC_LOG;
+    iLayoutChangedWhileNotActive = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenLinkInIntranetL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OpenLinkInIntranetL( TBool aMenuSelection )
+	{
+    FUNC_LOG;
+	CFindItemEngine::SFoundItem currentBodyHotSpotData;
+	TBool bodyHotSpotFound = iViewerRichText->FindCurrentBodyHotSpotL( currentBodyHotSpotData );
+	if ( bodyHotSpotFound )
+		{
+ 		HBufC* intranetUrl = iViewerRichText->GetHotspotTextLC( currentBodyHotSpotData );
+ 		TInt len = intranetUrl->Length();
+ 		HBufC8* eightBitUrl = HBufC8::NewLC( len );
+		eightBitUrl->Des().Copy( *intranetUrl );
+
+		TAiwGenericParam param( EGenericParamURL, TAiwVariant(*eightBitUrl) );
+        CAiwGenericParamList& paramList = iIBServiceHandler->InParamListL();
+        paramList.AppendL( param );
+        if ( aMenuSelection )
+            {
+            iIBServiceHandler->ExecuteMenuCmdL( EFsEmailUiCmdActionsOpenInIntranetMenu,
+                paramList, iIBServiceHandler->OutParamListL() );
+            }
+        else
+            {
+            iIBServiceHandler->ExecuteServiceCmdL( KAiwCmdView,
+                paramList, iIBServiceHandler->OutParamListL() );
+            }
+		CleanupStack::PopAndDestroy( eightBitUrl );
+		CleanupStack::PopAndDestroy( intranetUrl );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::ChangeMsgReadStatusL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::ChangeMsgReadStatusL(
+	TBool aRead, TBool aCmdFromMrui )
+	{
+    FUNC_LOG;
+	if ( iMessage && !iEmbeddedMessageMode )
+		{
+		if ( aRead )
+ 			{
+			// Send flags, local and server
+ 			iMessage->SetFlag( EFSMsgFlag_Read );
+			}
+		else
+			{
+			// Send flags, local and server
+ 			iMessage->ResetFlag( EFSMsgFlag_Read );
+			}
+		iMessage->SaveMessageL(); // Save read status
+		SendEventToAppUiL( TFSEventMailChanged );
+
+		if ( !aCmdFromMrui && iViewerRichText && iTextViewer )
+			{
+			iViewerRichText->UpdateIconL(
+				CFSEmailUiMailViewerRichText::EViewerEmailStatus );
+			TInt iconLine = iViewerRichText->EmailStatusIconLine();
+	        iTextViewer->ReloadPicturesL( iconLine );
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::OpenHotSpotUrlInBrowserL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::OpenHotSpotUrlInBrowserL(  CFindItemEngine::SFoundItem& aHotSpot  )
+	{
+    FUNC_LOG;
+	if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchURLBin ||
+		 aHotSpot.iItemType == CFindItemEngine::EFindItemSearchScheme ) // Scheme is needed also
+		{
+		// use browser launcher API here
+		HBufC* urlToOpen = iViewerRichText->GetHotspotTextLC( aHotSpot );
+		// Check if the address is rtsp url and send it media player
+		if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchScheme &&
+			 urlToOpen->FindC( KRtspUrlPrefix ) == 0 )
+			{
+			RApaLsSession appArcSession;
+			User::LeaveIfError( appArcSession.Connect() );
+			TThreadId id;
+			appArcSession.StartDocument( urlToOpen->Des(), KUidMediaPlayer , id );
+			appArcSession.Close();
+			}
+		else
+			{
+			// Check wheter the url text has some prefix (http, https, ftp, etc.).
+			// If no prefix found, try with the default prefix http.
+			TInt urlPos = urlToOpen->Find( KUrlPrefixIdentifier );
+			if ( urlPos == KErrNotFound )
+			    {
+			    HBufC* newBuf = urlToOpen->ReAllocL( urlToOpen->Length() + KHttpUrlPrefix().Length() );
+		        CleanupStack::Pop( urlToOpen );
+		        urlToOpen = newBuf;
+	            CleanupStack::PushL( urlToOpen );
+	            TPtr urlToOpenPtr = urlToOpen->Des();
+	            urlToOpenPtr.Insert( 0, KHttpUrlPrefix );
+			    }
+
+			// Use scheme handler to launch the browser as a stand alone application
+	        CSchemeHandler* handler = CSchemeHandler::NewL( *urlToOpen );
+	        CleanupStack::PushL( handler );
+	        handler->HandleUrlStandaloneL();
+	        CleanupStack::PopAndDestroy( handler );
+			}
+
+		CleanupStack::PopAndDestroy( urlToOpen );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::CallToBodyHotSpotNumberL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::CallToBodyHotSpotNumberL( CFindItemEngine::SFoundItem& aHotSpot )
+	{
+    FUNC_LOG;
+
+	if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+		{
+		HBufC* phoneNumber = iViewerRichText->GetHotspotTextLC( aHotSpot );
+		TInt answer = TFsEmailUiUtility::ShowConfirmationQueryL(
+		        R_FREESTYLE_EMAIL_UI_VIEWER_CALL_HOTSPOT, *phoneNumber );
+		if ( answer )
+			{
+	        TPtr numberPtr = phoneNumber->Des();
+		    CommonPhoneParser::ParsePhoneNumber( numberPtr,
+		                          CommonPhoneParser::EPhoneClientNumber);
+
+		    CFsDelayedLoader::InstanceL()->GetContactHandlerL()->MakeAiwCallL( NULL, *phoneNumber );
+			}
+        CleanupStack::PopAndDestroy( phoneNumber );
+		}
+	else if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchScheme )
+		{
+		TBool voipCall( EFalse );
+		HBufC* schemeText = iViewerRichText->GetHotspotTextLC( aHotSpot );
+		// Strip scheme prefix text if found
+		if ( schemeText && schemeText->FindC( KCallPrefix ) == 0 )
+			{
+			schemeText->Des().Delete( 0, KCallPrefix().Length() );
+			}
+		else if ( schemeText && schemeText->FindC( KTelPrefix ) == 0 )
+			{
+			schemeText->Des().Delete( 0, KTelPrefix().Length() );
+			}
+		else if ( schemeText && schemeText->FindC( KSmsPrefix ) == 0 )
+			{
+			schemeText->Des().Delete( 0, KSmsPrefix().Length() );
+			}
+		else if ( schemeText && schemeText->FindC( KMmsPrefix ) == 0 )
+			{
+			schemeText->Des().Delete( 0, KMmsPrefix().Length() );
+			}
+		else if ( schemeText && schemeText->FindC( KVoipPrefix ) == 0 )
+			{
+			voipCall = ETrue;
+			schemeText->Des().Delete( 0, KVoipPrefix().Length() );
+			}
+
+		TInt answer = TFsEmailUiUtility::ShowConfirmationQueryL(
+		        R_FREESTYLE_EMAIL_UI_VIEWER_CALL_HOTSPOT, *schemeText );
+		if ( answer )
+			{
+			if ( !voipCall )
+				{
+				// use common phone parser for other than voip numbers
+		        TPtr numberPtr = schemeText->Des();
+			    CommonPhoneParser::ParsePhoneNumber( numberPtr,
+		                         CommonPhoneParser::EPhoneClientNumber );
+				}
+		    CFsDelayedLoader::InstanceL()->GetContactHandlerL()->MakeAiwCallL( NULL, *schemeText, voipCall );
+			}
+		CleanupStack::PopAndDestroy( schemeText );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CFSEmailUiMailViewerVisualiser::WriteEmailToHotSpotAddressL
+// -----------------------------------------------------------------------------
+void CFSEmailUiMailViewerVisualiser::WriteEmailToHotSpotAddressL( CFindItemEngine::SFoundItem& aHotSpot )
+	{
+    FUNC_LOG;
+	if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchMailAddressBin )
+		{
+		delete iNewMailTempAddress; iNewMailTempAddress = NULL;
+		iNewMailTempAddress = CFSMailAddress::NewL();
+		HBufC* mailAddress = iViewerRichText->GetHotspotTextLC( aHotSpot );
+		iNewMailTempAddress->SetEmailAddress( *mailAddress );
+ 		CleanupStack::PopAndDestroy( mailAddress );
+		iAppUi.LaunchEditorL( iNewMailTempAddress );
+		}
+	else if ( aHotSpot.iItemType == CFindItemEngine::EFindItemSearchScheme )
+		{
+		HBufC* schemeText = iViewerRichText->GetHotspotTextLC( aHotSpot );
+		if ( schemeText && schemeText->FindC( KMailtoPrefix ) == 0)
+			{
+			schemeText->Des().Delete( 0, KMailtoPrefix().Length() );
+			delete iNewMailTempAddress; iNewMailTempAddress = NULL;
+			iNewMailTempAddress = CFSMailAddress::NewL();
+			iNewMailTempAddress->SetEmailAddress( *schemeText );
+			iAppUi.LaunchEditorL( iNewMailTempAddress );
+			}
+		CleanupStack::PopAndDestroy( schemeText );
+		}
+	}
+
+void CFSEmailUiMailViewerVisualiser::SaveEmailAsContactL(
+	const TDesC& aEmailAddress )
+	{
+    FUNC_LOG;
+	TAddToContactsType type;
+	// Query to "update existing" or "Create new"
+	// --> EFALSE = user chose "cancel"
+	if ( CFsDelayedLoader::InstanceL()->GetContactHandlerL()->
+		AddtoContactsQueryL( type ) )
+		{
+		// Create buffer and strip scheme data such as mailto: and call:
+		HBufC* textData = aEmailAddress.AllocLC();
+		if ( textData->FindC( KMailtoPrefix ) == 0 )
+			{
+			textData->Des().Delete( 0, KMailtoPrefix().Length() );
+			}
+		CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddToContactL(
+				*textData, EContactUpdateEmail, type, this );
+		CleanupStack::PopAndDestroy( textData );
+		}
+	}
+
+void CFSEmailUiMailViewerVisualiser::SavePhoneNumberAsContactL(
+	const TDesC& aPhoneNumber )
+	{
+    FUNC_LOG;
+	TAddToContactsType type;
+	// Query to "update existing" or "Create new"
+	// --> EFALSE = user chose "cancel"
+	if ( CFsDelayedLoader::InstanceL()->GetContactHandlerL()->
+		AddtoContactsQueryL( type ) )
+		{
+		// Create buffer and strip scheme data such as mailto: and call:
+		HBufC* textData = aPhoneNumber.AllocLC();
+		// Strip scheme prefix text if found
+		if ( textData && textData->FindC( KCallPrefix ) == 0 )
+			{
+			textData->Des().Delete( 0, KCallPrefix().Length() );
+			}
+		else if ( textData && textData->FindC( KTelPrefix ) == 0 )
+			{
+			textData->Des().Delete( 0, KTelPrefix().Length() );
+			}
+		else if ( textData && textData->FindC( KSmsPrefix ) == 0 )
+			{
+			textData->Des().Delete( 0, KSmsPrefix().Length() );
+			}
+		else if ( textData && textData->FindC( KMmsPrefix ) == 0 )
+			{
+			textData->Des().Delete( 0, KMmsPrefix().Length() );
+			}
+		CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddToContactL(
+			*textData, EContactUpdateNumber, type, this );
+		CleanupStack::PopAndDestroy( textData );
+		}
+	}
+
+
+void CFSEmailUiMailViewerVisualiser::FlagselectionCompleteL( TInt aSelection )
+	{
+    FUNC_LOG;
+	// Set message follow up flag
+	if ( iMessage && aSelection != KErrNotFound )
+		{
+		switch ( aSelection )
+			{
+			case EFollowUp:
+				{
+				iMessage->SetFlag( EFSMsgFlag_FollowUp );
+				iMessage->ResetFlag( EFSMsgFlag_FollowUpComplete );
+				iMessage->SaveMessageL();
+				}
+				break;
+			case EFollowUpComplete:
+				{
+				iMessage->SetFlag( EFSMsgFlag_FollowUpComplete );
+				iMessage->ResetFlag( EFSMsgFlag_FollowUp );
+				iMessage->SaveMessageL();
+				}
+				break;
+			case EFollowUpClear:
+				{
+				iMessage->ResetFlag( EFSMsgFlag_FollowUp | EFSMsgFlag_FollowUpComplete );
+				iMessage->SaveMessageL();
+				}
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+
+void CFSEmailUiMailViewerVisualiser::SetMailboxNameToStatusPaneL()
+	{
+    FUNC_LOG;
+	iAppUi.SetActiveMailboxNameToStatusPaneL();
+	}
+
+void CFSEmailUiMailViewerVisualiser::GetParentLayoutsL( RPointerArray<CAlfVisual>& aLayoutArray ) const
+    {
+    if ( iTextViewer )
+        {
+        aLayoutArray.AppendL( iTextViewer->RootLayout() );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::UpdateNaviPaneL( TBool aForESMR )
+    {
+    FUNC_LOG;
+    // Get navigation decorator for mail viewer
+    CAknNavigationDecorator* naviDecorator = iAppUi.NaviDecoratorL( MailViewerId );
+    if ( naviDecorator )
+        {
+        // Check if there's next and previous message available, and set
+        // the navipane arrows accordingly
+        TFSMailMsgId currentMsgId = iMessage->GetMessageId();
+        TFSMailMsgId tmpMsgId;
+        TFSMailMsgId tmpMsgFolderId;
+        if ( iAppUi.IsNextMsgAvailable( currentMsgId, tmpMsgId, tmpMsgFolderId ) )
+            {
+            naviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, EFalse );
+            }
+        else
+            {
+            naviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, ETrue );
+            }
+        if ( iAppUi.IsPreviousMsgAvailable( currentMsgId, tmpMsgId, tmpMsgFolderId ) )
+            {
+            naviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, EFalse );
+            }
+        else
+            {
+            naviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, ETrue );
+            }
+
+        // Set this view's navipane to the top of the navipane control stack
+        CAknNavigationControlContainer* naviPaneContainer =
+            static_cast<CAknNavigationControlContainer*>(
+            StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) );
+        naviPaneContainer->PushL( *naviDecorator );
+        naviDecorator->SetNaviDecoratorObserver( aForESMR ? NULL : this );
+        }
+
+    // Set priority and follow-up flags
+    CCustomStatuspaneIndicators* indicators = iAppUi.GetStatusPaneIndicatorContainer();
+    if ( indicators)
+        {
+        indicators->ShowStatusPaneIndicators();
+
+        if ( iMessage->IsFlagSet( EFSMsgFlag_Low ) )
+            {
+            indicators->SetPriorityFlag( EMsgPriorityLow );
+            }
+        else if ( iMessage->IsFlagSet( EFSMsgFlag_Important ) )
+            {
+            indicators->SetPriorityFlag( EMsgPriorityHigh );
+            }
+        else
+            {
+            indicators->SetPriorityFlag( EMsgPriorityNormal );
+            }
+
+        CCustomStatuspaneIndicators::TFollowUpFlagType flagType = CCustomStatuspaneIndicators::EFollowUpNone;
+        if (iMessage->IsFlagSet(EFSMsgFlag_FollowUp))
+            {
+            flagType = CCustomStatuspaneIndicators::EFollowUp;
+            }
+        if (iMessage->IsFlagSet(EFSMsgFlag_FollowUpComplete))
+            {
+            flagType = CCustomStatuspaneIndicators::EFollowUpComplete;
+            }
+        indicators->SetFollowUpFlag( flagType );
+        
+        indicators->DrawNow();
+        }
+
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::HandleNaviDecoratorEventL( TInt aEventID )
+    {
+    FUNC_LOG;
+    CAknNavigationDecorator* naviDecorator = iAppUi.NaviDecoratorL( MailViewerId );
+    if ( naviDecorator )
+        {
+        naviDecorator->SetNaviDecoratorObserver( NULL );
+        }
+    if( aEventID == MAknNaviDecoratorObserver::EAknNaviDecoratorEventRightTabArrow )
+        {
+        ShowNextMessageL();
+        }
+    else
+        {
+        ShowPreviousMessageL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// HandleMailBoxEventL
+// Mailbox event handler, responds to events sent by the plugin.
+// ---------------------------------------------------------------------------
+//
+void CFSEmailUiMailViewerVisualiser::HandleMailBoxEventL( TFSMailEvent aEvent,
+    TFSMailMsgId aMailbox, TAny* aParam1, TAny* /*aParam2*/, TAny* /*aParam3*/ )
+    {
+    FUNC_LOG;
+    if ( iFirstStartCompleted && iMessage && aMailbox.Id() == iAppUi.GetActiveMailboxId().Id() &&
+    	 aEvent == TFSEventMailDeleted && aParam1 ) // Safety, in list events that only concern active mailbox are handled
+        {
+        TFSMailMsgId curMsgId = iMessage->GetMessageId();
+		RArray<TFSMailMsgId>* removedEntries = static_cast<RArray<TFSMailMsgId>*>(aParam1);
+		for ( TInt i=0 ; i < removedEntries->Count() ; i++ )
+			{
+		    //<cmail>
+			if ( (curMsgId == (*removedEntries)[i]) &&
+					(iDeletedMessageFromMrui != curMsgId) )
+				{
+				//</cmail>
+	        	ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
+	        	NavigateBackL();
+				break;
+				}
+			}
+        }
+    }
+
+void CFSEmailUiMailViewerVisualiser::SendEventToAppUiL( TFSMailEvent aEventType )
+    {
+    RArray<TFSMailMsgId> msgIdArray;
+    CleanupClosePushL( msgIdArray );
+    msgIdArray.AppendL( iMessage->GetMessageId() );
+    TFSMailMsgId folderId = iMessage->GetFolderId();
+    iAppUi.EventL( aEventType,
+                   iAppUi.GetActiveMailboxId(),
+                   &msgIdArray, &folderId, NULL );
+    CleanupStack::PopAndDestroy( &msgIdArray );
+    }
+
+//////////////////////////////////////////////////////////////////////////////////////
+// CLASS IMPLEMENTATION CHANGE TO FLAG DIALOG GLOBAL NOTE
+///////////////////////////////////////////////////////////////////////////////////
+CFlagSelectionGlobalNoteHandler* CFlagSelectionGlobalNoteHandler::NewL( CFSEmailUiMailViewerVisualiser& aViewerVisualiser )
+    {
+    FUNC_LOG;
+    CFlagSelectionGlobalNoteHandler* self =
+       	 new (ELeave) CFlagSelectionGlobalNoteHandler( aViewerVisualiser );
+    return self;
+    }
+
+
+CFlagSelectionGlobalNoteHandler::~CFlagSelectionGlobalNoteHandler()
+	{
+    FUNC_LOG;
+	delete iPrompt;
+	delete iGlobalFlagQuery;
+	}
+
+void CFlagSelectionGlobalNoteHandler::Cancel()
+	{
+    FUNC_LOG;
+	}
+
+void CFlagSelectionGlobalNoteHandler::LaunchFlagListQueryDialogL()
+	{
+    FUNC_LOG;
+	iSelection = 0;
+	if ( !iPrompt )
+		{
+	    iPrompt = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_VIEWER_FLAG_DIALOG_HEADER );
+		}
+ 	if ( !iGlobalFlagQuery )
+	 	{
+	    iGlobalFlagQuery = CAknGlobalListQuery::NewL();
+		iGlobalFlagQuery->SetHeadingL( *iPrompt ); // Set query heading.
+ 		}
+
+	CDesCArrayFlat* array = new (ELeave) CDesCArrayFlat( 3 );
+	CleanupStack::PushL( array );
+	// Add follow up text
+	HBufC* followUp = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_FLAG_FOLLOW_UP );
+    array->AppendL( *followUp );
+	CleanupStack::PopAndDestroy( followUp );
+
+	// Add flag complete text
+	HBufC* completeFlag = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_FLAG_COMPLETE );
+    array->AppendL( *completeFlag );
+	CleanupStack::PopAndDestroy( completeFlag );
+
+	// Add clear flag text
+	HBufC* clearFlag = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_FLAG_CLEAR );
+    array->AppendL( *clearFlag );
+	CleanupStack::PopAndDestroy( clearFlag );
+
+    // Show query
+    iGlobalFlagQuery->ShowListQueryL( array, iStatus, iSelection );
+	CleanupStack::PopAndDestroy( array );
+
+	// Set active
+    SetActive();
+	}
+
+void CFlagSelectionGlobalNoteHandler::RunL()
+	{
+    FUNC_LOG;
+    TInt status = iStatus.Int();
+	iViewerVisualiser.FlagselectionCompleteL( status );
+	}
+
+void CFlagSelectionGlobalNoteHandler::DoCancel()
+	{
+    FUNC_LOG;
+	}
+
+TInt CFlagSelectionGlobalNoteHandler::RunError( TInt /*aError*/ )
+	{
+    FUNC_LOG;
+	TInt err( KErrNone );
+	return err;
+	}
+
+CFlagSelectionGlobalNoteHandler::CFlagSelectionGlobalNoteHandler(  CFSEmailUiMailViewerVisualiser& aViewerVisualiser )
+    : CActive ( EPriorityHigh ),
+    iViewerVisualiser( aViewerVisualiser )
+    {
+    FUNC_LOG;
+    CActiveScheduler::Add( this );
+    iSelection = 0;
+    }
+