/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: This file implements classes CFSEmailUiMailListVisualiser, CMailListUpdater, CMsgMovedNoteTimer, CDateChangeTimer.
*
*/


// SYSTEM INCLUDES
#include "emailtrace.h"
#include <freestyleemailui.mbg>
#include <AknUtils.h>
#include <gulicon.h>
#include <StringLoader.h>
#include <FreestyleEmailUi.rsg>
#include <featmgr.h>
#include "cfsmailclient.h"
#include "cfsmailbox.h"
#include "cfsmailfolder.h"
#include "fscontrolbar.h"
#include "fscontrolbuttoninterface.h"
#include "fstreelist.h"
#include "fstreevisualizerbase.h"
#include "fstreeplainonelinenodedata.h"
#include "fstreeplainonelinenodevisualizer.h"
#include "fstreeplaintwolineitemdata.h"
#include "fstreeplaintwolineitemvisualizer.h"
#include "cfsmailcommon.h"
#include "ceuiemaillisttouchmanager.h"
#include "FSEmailBuildFlags.h"
#include "cfsccontactactionmenu.h"
#include "mfsccontactactionmenumodel.h"

#include <hlplch.h>
#include <AknIconArray.h>
#include <alf/alfdecklayout.h>
#include <alf/alfcontrolgroup.h>
#include <alf/alfframebrush.h>
#include <alf/alfevent.h>
#include <alf/alfstatic.h>

#include <aknnotewrappers.h>
#include <msvapi.h>
#include <akntitle.h>
#include "esmailsettingspluginuids.hrh"
#include "esmailsettingsplugin.h"
#include "mfsmailbrandmanager.h"
#include <AknWaitDialog.h>
#include <aknlayoutscalable_apps.cdl.h>
#include <layoutmetadata.cdl.h>
#include <csxhelp/cmail.hlp.hrh>
// Meeting request
#include <MeetingRequestUids.hrh>
#include "cesmricalviewer.h"
#include <aknstyluspopupmenu.h>
#include <akntoolbar.h>

// INTERNAL INCLUDES
#include "FreestyleEmailUiUtilities.h"
#include "FreestyleEmailUiLiterals.h"
#include "FreestyleEmailUiLayoutHandler.h"
#include "FreestyleEmailUiMailListModel.h"
#include "FreestyleEmailUiMailListVisualiser.h"
#include "FreestyleEmailUiFileSystemInfo.h"
#include "FreestyleEmailUiAppui.h"
#include "FreestyleEmailUi.hrh"
#include "FreestyleEmailUiTextureManager.h"
#include "FreestyleEmailUiMailListControl.h"
#include "FreestyleEmailUiMailViewerVisualiser.h"
#include "FreestyleEmailUiStatusIndicator.h"
#include "freestyleemailcenrephandler.h"
#include "FreestyleEmailUiFolderListVisualiser.h"
#include "FreestyleEmailUiShortcutBinding.h"
#include "FreestyleEmailUiMsgDetailsVisualiser.h"
#include "FreestyleEmailDownloadInformationMediator.h"
#include "FreestyleEmailUiContactHandler.h"
#include "FreestyleEmailUiLauncherGridVisualiser.h"
#include "FreestyleEmailUiHtmlViewerView.h"
#include "FSDelayedLoader.h"
#include "FSEmail.pan"
#include "fsemailstatuspaneindicatorhandler.h"
#include "ipsplgcommon.h"

// CONST VALUES
const TInt KControlBarTransitionTime = 250;
const TInt KMaxPreviewPaneLength = 60;
const TInt KMsgUpdaterTimerDelay = 2500000; // Time to update list, 2,5sec
static const TInt KMsgDeletionWaitNoteAmount = 5;
_LIT( KMissingPreviewDataMarker, "..." );

static const TInt KMaxItemsFethed = 1000;
static const TInt KCMsgBlock = 15;
static const TInt KCMsgMaxBlock = 120;

// ---------------------------------------------------------------------------
// Generic method for deleting a pointer and setting it NULL.
// ---------------------------------------------------------------------------
//
template <class T> void SafeDelete(T*& ptr)
    {
    delete ptr;
    ptr = NULL;
    }

// TDeleteTask
// Task class for deleting mail
// ---------------------------------------------------------------------------
// Class definition
// ---------------------------------------------------------------------------
template <class T> struct TDeleteTask
    {
    
public:
    
    typedef void ( T::*TDeleteMethod )( const RFsTreeItemIdList& aEntries );
    
public:    
    
    TDeleteTask(T& aObject, TDeleteMethod aMethod);    
    ~TDeleteTask();
    void ExecuteL();
    RFsTreeItemIdList& Entries();
    void Reset();
    
private:

    T& iObject;
    TDeleteMethod iMethod;    
    RFsTreeItemIdList iEntries;
    
    };

// ---------------------------------------------------------------------------
// TDeleteTask<T>::TDeleteTask
// ---------------------------------------------------------------------------
//
template <class T> TDeleteTask<T>::TDeleteTask( T& aObject, TDeleteMethod aMethod )
    : iObject(aObject), iMethod(aMethod)
    {    
    }

// ---------------------------------------------------------------------------
// TDeleteTask<T>::~TDeleteTask
// ---------------------------------------------------------------------------
//
template <class T> TDeleteTask<T>::~TDeleteTask()
    {
    iEntries.Close();
    }

// ---------------------------------------------------------------------------
// TDeleteTask<T>::ExecuteL
// ---------------------------------------------------------------------------
//
template <class T> void TDeleteTask<T>::ExecuteL()
    {
    (iObject.*iMethod)(iEntries);
    Reset();
    }

// ---------------------------------------------------------------------------
// TDeleteTask<T>::Entries
// ---------------------------------------------------------------------------
//
template <class T> RFsTreeItemIdList& TDeleteTask<T>::Entries()
    {
    return iEntries;
    }

// ---------------------------------------------------------------------------
// TDeleteTask<T>::Reset
// ---------------------------------------------------------------------------
//
template <class T> void TDeleteTask<T>::Reset()
    {
    iEntries.Reset();
    }
// CMailListModelUpdater

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CMailListModelUpdater::CMailListModelUpdater() : CActive(EPriorityStandard)
    {
    CActiveScheduler::Add(this);
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CMailListModelUpdater::~CMailListModelUpdater()
    {
    iObserver = NULL;
    Cancel();
    iSorting.Close();
    }

// ---------------------------------------------------------------------------
// Returns arrays for sorting parameters. Updater owns the arrays because
// it has to stay alive as long as the iterator is being used.
// ---------------------------------------------------------------------------
//
RArray<TFSMailSortCriteria>& CMailListModelUpdater::Sorting()
    {
    iSorting.Reset();
    return iSorting;
    }

// ---------------------------------------------------------------------------
// Update the mail list model from given iterator. Update progress will be
// informed to the observer.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::UpdateModelL(MObserver& aObserver, MFSMailIterator* aIterator)
    {
    Cancel();
    iObserver = &aObserver;
    iIterator = aIterator;
    Signal(EInitialize);
    }

// ---------------------------------------------------------------------------
// Internal method. Sets new state and signals itself.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::Signal(TState aState, TInt aError)
    {
    iState = aState;
    iStatus = KRequestPending;
    SetActive();
    TRequestStatus* status = &iStatus;
    User::RequestComplete(status, aError);
    }

// ---------------------------------------------------------------------------
// Initialization state. Reset update and call UpdateBeginL() for the observer.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::InitializeL()
    {
    iBlockSize = KCMsgBlock;
    iParentId = KFsTreeRootID;
    iId = TFSMailMsgId();
    iItemsFetched = 0;
    iObserver->UpdateBeginL();
    Signal(EFetch);
    }

// ---------------------------------------------------------------------------
// Fetch state. Fetch next messages and if there is more messages signal
// fetch state again OR proceed to finalizing state.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::FetchL()
    {
    RPointerArray<CFSMailMessage> messages(iBlockSize);
    CleanupClosePushL(messages);
    const TBool moreMessages(iIterator->NextL(iId, iBlockSize, messages));
    iBlockSize = Min(KCMsgMaxBlock, iBlockSize * 2);
    if (messages.Count() > 0)
        {
        iItemsFetched += messages.Count();
        iId = messages[messages.Count() - 1]->GetMessageId();
        iObserver->UpdateProgressL(iParentId, messages);
        }
    CleanupStack::PopAndDestroy(); // messages.Close()
    if (moreMessages && iItemsFetched < KMaxItemsFethed)
        {
        Signal(EFetch);
        }
    else
        {
        Signal(EFinalize);
        }
    }

// ---------------------------------------------------------------------------
// Finalizing state. Notify observer that model update has been done and
// free the resources.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::FinalizeL()
    {
    iObserver->UpdateCompleteL();
    Reset();
    }

// ---------------------------------------------------------------------------
// If the state is anything but EIdle, returns ETrue.
// ---------------------------------------------------------------------------
//
TBool CMailListModelUpdater::IsUpdating() const
    {
    return iState > EIdle;
    }

// ---------------------------------------------------------------------------
// Reset the state to EIdle and free resources.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::Reset()
    {
    iSorting.Reset();
    SafeDelete(iIterator);
    iState = EIdle;
    }

// ---------------------------------------------------------------------------
// Active objects RunL()
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::RunL()
    {
    const TInt error(iStatus.Int());
    if (!error)
        {
        switch (iState)
            {
            case EInitialize:
                InitializeL();
                break;
            case EFetch:
                FetchL();
                break;
            case EFinalize:
            default:
                FinalizeL();
                break;
            }
        }
    else
        {
        iObserver->UpdateErrorL(error);
        }
    }

// ---------------------------------------------------------------------------
// Update has been cancelled. Inform the observer and free resources.
// ---------------------------------------------------------------------------
//
void CMailListModelUpdater::DoCancel()
    {
    if (iObserver)
        {
        iObserver->UpdateCancelled(IsUpdating());
        }
    Reset();
    }

// ---------------------------------------------------------------------------
// Static constructor.
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListVisualiser* CFSEmailUiMailListVisualiser::NewL(CAlfEnv& aEnv,
																 CFreestyleEmailUiAppUi* aAppUi,
																 CAlfControlGroup& aMailListControlGroup )
    {
    FUNC_LOG;
    CFSEmailUiMailListVisualiser* self = CFSEmailUiMailListVisualiser::NewLC(aEnv, aAppUi, aMailListControlGroup );
    CleanupStack::Pop(self);
    return self;
    }

// ---------------------------------------------------------------------------
// Static constructor.
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListVisualiser* CFSEmailUiMailListVisualiser::NewLC(CAlfEnv& aEnv,
																  CFreestyleEmailUiAppUi* aAppUi,
																  CAlfControlGroup& aMailListControlGroup)
    {
    FUNC_LOG;
    CFSEmailUiMailListVisualiser* self =
        new (ELeave) CFSEmailUiMailListVisualiser( aEnv, aAppUi, aMailListControlGroup );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// ---------------------------------------------------------------------------
// Second phase constructor.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ConstructL()
	{
    FUNC_LOG;

	BaseConstructL( R_FSEMAILUI_MAIL_LIST_VIEW );

	iMailListModelUpdater = new (ELeave) CMailListModelUpdater();

	// Don't construct this anywhere else than here.
	// Don't delete this until in the destructor to avoid NULL checks.
    iModel = CFSEmailUiMailListModel::NewL( &iAppUi );

	// Set list as initial focused control
	iFocusedControl = EMailListComponent;
	iThisViewActive = EFalse;
	iSkinChanged = EFalse;

	iFirstStartCompleted = EFalse;

	iAsyncCallback = new (ELeave) CAsyncCallBack( CActive::EPriorityStandard );
	iAsyncRedrawer = new (ELeave) CAsyncCallBack( CActive::EPriorityLow );
	iLastFocus = EFalse;
    iDeleteTask = new (ELeave) TDeleteTask<CFSEmailUiMailListVisualiser> (*this, HandleDeleteTaskL);

	iTouchFeedBack = MTouchFeedback::Instance();
 	}

// CFSEmailUiMailListVisualiser::DoFirstStartL()
// Purpose of this function is to do first start things only when list is
// really needed to be shown. Implemented to make app startuo faster.
void CFSEmailUiMailListVisualiser::DoFirstStartL()
    {
    FUNC_LOG;
    // Create mail list updater timer
    iMailListUpdater = CMailListUpdater::NewL( this );

    // Set initial sort criteria
    iCurrentSortCriteria.iField = EFSMailSortByDate;
    iCurrentSortCriteria.iOrder = EFSMailDescending;

    // Create screen control and anchor layout
    iMailListControl = CFreestyleEmailUiMailListControl::NewL( iEnv, this );
    iScreenAnchorLayout = CAlfAnchorLayout::AddNewL( *iMailListControl );
    iScreenAnchorLayout->SetFlags(EAlfVisualFlagAutomaticLocaleMirroringEnabled);

    //<cmail>
    iTouchManager = CEUiEmailListTouchManager::NewL(*this);
    //</cmail>

    // Create control bar control and append to control group and anchor layout
    iControlBarControl = CFsControlBar::NewL( iEnv );
    iControlBarControl->AddObserverL( *this );
    //<cmail>
    iControlBarControl->AddObserverL( *iTouchManager );
    //</cmail>

    CreateControlBarLayoutL();
    SetMailListLayoutAnchors();

    iControlBarControl->SetSelectorTransitionTimeL( KControlBarTransitionTime );
    iControlBarControl->ClearBackgroundColor();
    iControlBarLayout = CAlfDeckLayout::AddNewL( *iControlBarControl, iScreenAnchorLayout );
    iControlBarVisual = iControlBarControl->Visual();

    // Create list and append to control group and anchor layout

    iListLayout = CAlfDeckLayout::AddNewL( *iMailListControl, iScreenAnchorLayout );
    iMailTreeListVisualizer = CFsTreeVisualizerBase::NewL(iMailListControl, *iListLayout);
    iMailTreeListVisualizer->SetFlipState( iKeyboardFlipOpen );
    iMailTreeListVisualizer->SetFocusVisibility( iFocusVisible );
    iMailList = CFsTreeList::NewL(*iMailTreeListVisualizer, iEnv );

    // Set mark type and icon
    iMailList->SetMarkTypeL( CFsTreeList::EFsTreeListMultiMarkable );
    iMailList->SetIndentationL(0);

    //<cmail> Compared to S60 3.2.3 in S60 5.0 Alf offers the key events in
    // opposite order.
    ControlGroup().AppendL( iMailListControl );
    ControlGroup().AppendL( iControlBarControl );
    ControlGroup().AppendL( iMailList->TreeControl() );
    //</cmail>

    iTreeItemArray.Reset();

    // Set empty text
    HBufC* emptyText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_EMPTY_MSG_LIST_TEXT );
    iMailTreeListVisualizer->SetEmptyListTextL( *emptyText );
    CleanupStack::PopAndDestroy( emptyText );

    TRgb normalColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor();
    iMailTreeListVisualizer->RootNodeVisualizer()->SetNormalStateTextColor( normalColor );

    // Set page up and page down keys
    iMailTreeListVisualizer->AddCustomPageUpKey( EStdKeyPageUp );
    iMailTreeListVisualizer->AddCustomPageDownKey( EStdKeyPageDown );

    // Set selector brushes
    CAlfBrush* listSelectorBrush = iAppUi.FsTextureManager()->ListSelectorBrushL(); // not owned
    iMailTreeListVisualizer->SetSelectorPropertiesL( listSelectorBrush, 1.0, CFsTreeVisualizerBase::EFsSelectorMoveSmoothly );

    CAlfBrush* cbSelectorBrush = iAppUi.FsTextureManager()->NewCtrlBarSelectorBrushLC();
    iControlBarControl->SetSelectorImageL( cbSelectorBrush );
    CleanupStack::Pop( cbSelectorBrush ); // ownership transferred to control bar

    iNewEmailText = StringLoader::LoadL( R_COMMAND_AREA_NEW_EMAIL );

    // Set menu, mark and background icons
    iMailTreeListVisualizer->SetMarkIcon( iAppUi.FsTextureManager()->TextureByIndex( EListControlMarkIcon ) );
    iMailTreeListVisualizer->SetMenuIcon( iAppUi.FsTextureManager()->TextureByIndex( EListControlMenuIcon ) );
    //<cmail> s60 skin support
    //iMailTreeListVisualizer->SetBackgroundTextureL( iAppUi.FsTextureManager()->TextureByIndex( EBackgroundTextureMailList ) );
    //</cmail>
    iMailList->AddObserverL( *this );
    //<cmail>
    iMailList->AddObserverL( *iTouchManager );
    //</cmail>
    // Initializing the default stylus long tap popup menu
    if( !iStylusPopUpMenu )
        {
        TPoint point( 0, 0 );
        iStylusPopUpMenu = CAknStylusPopUpMenu::NewL( this , point );
		TResourceReader reader;
		iCoeEnv->CreateResourceReaderLC( reader,
				R_STYLUS_POPUP_MENU_MESSAGE_LIST_VIEW );
		iStylusPopUpMenu->ConstructFromResourceL( reader );
		CleanupStack::PopAndDestroy(); // reader
        }

    iAppUi.LayoutHandler()->SetListMarqueeBehaviour( iMailList );

    iDateChangeTimer = CDateChangeTimer::NewL( *this );
    iDateChangeTimer->Start();

    UpdateMailListSettingsL();

    iMailList->SetIndentationL(0);
    iMailList->SetLoopingType( EFsTreeListLoopingDisabled );
    iMailTreeListVisualizer->SetItemExpansionDelay( iAppUi.LayoutHandler()->ListItemExpansionDelay() );
    iMailList->SetScrollTime( iAppUi.LayoutHandler()->ListScrollingTime(), 0.5 );

    iFirstStartCompleted = ETrue;
    }


// ---------------------------------------------------------------------------
// Constructor.
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListVisualiser::CFSEmailUiMailListVisualiser( CAlfEnv& aEnv,
    CFreestyleEmailUiAppUi* aAppUi, CAlfControlGroup& aMailListControlGroup )
    : CFsEmailUiViewBase( aMailListControlGroup, *aAppUi ),
    iEnv( aEnv ),
    iListMarkItemsState( ETrue ), //Initlly list has no markings
    iMoveToFolderOngoing( EFalse ),
    iConsumeStdKeyYes_KeyUp( EFalse ), // use to prevent Call application execution if call for contact processed
    iMailOpened(EFalse)
	{
    FUNC_LOG;
	}

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListVisualiser::~CFSEmailUiMailListVisualiser()
    {
    FUNC_LOG;
    if (iExtension)
        {
        iAppUi.GetMailClient()->ReleaseExtension(iExtension);
        }
    SafeDelete(iMailListModelUpdater);
    SafeDelete(iMailFolder);
    delete iTouchManager;
    delete iStylusPopUpMenu;
    delete iMailList;
    delete iNewEmailText;

	// Don't construct this anywhere else than in constructor.
	// Don't delete anywhere else thatn here to avoid NULL checks.
    delete iModel;
    
    delete iDeleteTask;
    }

void CFSEmailUiMailListVisualiser::PrepareForExit()
    {
    FUNC_LOG;
    iMailListModelUpdater->Cancel();
    if ( iMsgNoteTimer )
        {
        iMsgNoteTimer->Cancel();
        SafeDelete(iMsgNoteTimer);
        }
    if ( iDateChangeTimer )
        {
        iDateChangeTimer->Cancel();
        SafeDelete(iDateChangeTimer);
        }
    if ( iMailListUpdater )
        {
        iMailListUpdater->Stop();
        SafeDelete(iMailListUpdater);
        }
    if ( iAsyncRedrawer )
        {
        iAsyncRedrawer->Cancel();
        SafeDelete(iAsyncRedrawer);
        }
    if ( iAsyncCallback )
        {
        iAsyncCallback->Cancel();
        SafeDelete(iAsyncCallback);
        }
    if ( iMailList )
        {
        iMailList->RemoveObserver( *this );
        }
    if ( iControlBarControl )
        {
        iControlBarControl->RemoveObserver( *this );
        }
    SafeDelete(iMailFolder);
    iTreeItemArray.Reset();
	// Reset, not delete to avoid NULL checks.
    iModel->Reset();
    // Resources freed, new start required
    iFirstStartCompleted = EFalse;
    }

// ---------------------------------------------------------------------------
// Returns reference to mail list.
// ---------------------------------------------------------------------------
//
CFsTreeList& CFSEmailUiMailListVisualiser::GetMailList()
	{
    FUNC_LOG;
	return *iMailList;
	}

// ---------------------------------------------------------------------------
// @see CMailListModelUpdater::MObserver::UpdateErrorL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateErrorL(TInt aError)
    {
    FUNC_LOG;
    User::Leave(aError);
    }

// ---------------------------------------------------------------------------
// @see CMailListModelUpdater::MObserver::UpdateBeginL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateBeginL()
    {
    FUNC_LOG;
    iModel->Reset();
    iTreeItemArray.Reset();
    }

// ---------------------------------------------------------------------------
// @see CMailListModelUpdater::MObserver::UpdateProgressL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateProgressL(TFsTreeItemId& aParentId, RPointerArray<CFSMailMessage>& aMessages)
    {
    FUNC_LOG;
    const TInt itemsInModel(iModel->Count());
    CreateModelItemsL(aMessages);
    RefreshListItemsL(aParentId, itemsInModel, iModel->Count());
    }

// ---------------------------------------------------------------------------
// @see CMailListModelUpdater::MObserver::UpdateCompleteL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateCompleteL()
    {
    FUNC_LOG;
    if ( !iModel->Count() )
        {
        iFocusedControl = EControlBarComponent;
        }
    else
        {
        iFocusedControl = EMailListComponent;
        if (iMailList->FocusedItem() == KFsTreeNoneID)
            {
            iMailList->SetFocusedItemL( iTreeItemArray[0].iListItemId );
            }
        }
    SetListAndCtrlBarFocusL();
    iAppUi.StartMonitoringL();
    TIMESTAMP( "Locally stored messages fetched for message list" );
    }

// ---------------------------------------------------------------------------
// @see CMailListModelUpdater::MObserver::UpdateCancelled
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateCancelled(const TBool aForceRefresh)
    {
    FUNC_LOG;
    iForceRefresh = aForceRefresh;
    }

// ---------------------------------------------------------------------------
// Asynchronous mail list model update.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateMailListModelAsyncL()
    {
    FUNC_LOG;
    if ( iMailFolder )
        {
        TFSMailDetails details( EFSMsgDataEnvelope );
        RArray<TFSMailSortCriteria>& sorting(iMailListModelUpdater->Sorting());
        sorting.AppendL( iCurrentSortCriteria );
        if ( iCurrentSortCriteria.iField != EFSMailSortByDate )
            {
            // Add date+descending as secondary sort criteria if primary field is something else than date
            TFSMailSortCriteria secondarySortCriteria;
            secondarySortCriteria.iField = EFSMailSortByDate;
            secondarySortCriteria.iOrder = EFSMailDescending;
            sorting.AppendL( secondarySortCriteria );
            }
        // List all or maximum number of messages
        iMailListModelUpdater->UpdateModelL(*this, iMailFolder->ListMessagesL(details, sorting));
        }
    else
        {
        UpdateCompleteL();
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateMailListModelL()
    {
    FUNC_LOG;
    // Make sure asynchronous update is not going on
    iMailListModelUpdater->Cancel();
    // Reset model with each update
	iModel->Reset();
	if ( iMailFolder )
		{
		// Update folder if provided, otherwise use current folder
		RPointerArray<CFSMailMessage> folderMessages( KCMsgBlock );
		CleanupClosePushL( folderMessages );

		RPointerArray<CFSMailMessage> tempFolderMessages( KCMsgBlock );
        CleanupClosePushL( tempFolderMessages );

	 	TFSMailDetails details( EFSMsgDataEnvelope );
	    RArray<TFSMailSortCriteria> sorting;
		CleanupClosePushL( sorting );
	    sorting.Append( iCurrentSortCriteria );
	    if ( iCurrentSortCriteria.iField != EFSMailSortByDate )
	    	{
            // Add date+descending as secondary sort criteria if primary field is something else than date
            TFSMailSortCriteria secondarySortCriteria;
            secondarySortCriteria.iField = EFSMailSortByDate;
            secondarySortCriteria.iOrder = EFSMailDescending;
            sorting.Append( secondarySortCriteria );
	    	}

	    // List all or maximum number of messages
	    MFSMailIterator* iterator = iMailFolder->ListMessagesL( details, sorting );
		CleanupDeletePushL( iterator ); // standard CleanupStack::PushL does not work with non-C-class pointer

		// Use iterator to get messages in peaces of KCMsgBlock to avoid OOM in FSStore
		TFSMailMsgId dummy;
        TBool moreMessagesToFollow = iterator->NextL( dummy, KCMsgBlock, folderMessages  );
        for ( TInt i = KCMsgBlock; i < KMaxItemsFethed && moreMessagesToFollow ; i += KCMsgBlock )
            {
            tempFolderMessages.Reset();
            moreMessagesToFollow = iterator->NextL( folderMessages[i-1]->GetMessageId(), KCMsgBlock, tempFolderMessages  );
            for ( TInt a=0 ; a<tempFolderMessages.Count() ; a++)
                {
                folderMessages.Append(tempFolderMessages[a]);
                }
            }

		CleanupStack::PopAndDestroy( iterator );
		CleanupStack::PopAndDestroy( &sorting );

		// Update mail list model based on sorting criteria
		CreateModelItemsL( folderMessages );

		CleanupStack::PopAndDestroy( &tempFolderMessages );
		CleanupStack::PopAndDestroy( &folderMessages );
		}
    }


// ---------------------------------------------------------------------------
// CreateModelItemsL
// This function creates model items for the given messages and appends them
// to the model. Also title divider items are created when necessary.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::CreateModelItemsL( RPointerArray<CFSMailMessage>& aMessages )
	{
    FUNC_LOG;
	// New Items
	CFSEmailUiMailListModelItem* newItem(NULL);

	// Draw first separator if there are messages.
	if ( aMessages.Count() && iNodesInUse == EListControlSeparatorEnabled )
		{
		if (iModel->Count())
		    {
		    CFSMailMessage* nextMessage = aMessages[0];
		    CFSEmailUiMailListModelItem* previousMessage(static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(iModel->Count() - 1)));
            TBool needANewDivider =
                !MessagesBelongUnderSameSeparatorL( previousMessage->MessagePtr(), *nextMessage );
            if ( needANewDivider )
                {
                newItem = CreateSeparatorModelItemLC( *nextMessage );
                iModel->AppendL( newItem );
                CleanupStack::Pop( newItem );
                }
            }
		else
		    {
	    newItem = CreateSeparatorModelItemLC( *aMessages[0] );
	    iModel->AppendL( newItem );
		CleanupStack::Pop( newItem );
		}
		}

	// Start appending items
    for (int i = 0; i < aMessages.Count(); i++)
	    {
	    CFSMailMessage* curMessage = aMessages[i];
	    if ( curMessage )
	        {
	        newItem = CFSEmailUiMailListModelItem::NewL( curMessage, ETypeMailItem );
	        CleanupStack::PushL( newItem );
	        iModel->AppendL( newItem );
	        CleanupStack::Pop( newItem );

	        // Append new separator if needed
	        if ( i != aMessages.Count()-1 && iNodesInUse == EListControlSeparatorEnabled )
	            {
	            CFSMailMessage* nextMessage = aMessages[i+1];   // This msg is next in the list

	            if ( nextMessage )
	                {
	                TBool needANewDivider =
	                    !MessagesBelongUnderSameSeparatorL( *curMessage, *nextMessage );
	                if ( needANewDivider )
	                    {
	                    newItem = CreateSeparatorModelItemLC( *nextMessage );
	                    iModel->AppendL( newItem );
	                    CleanupStack::Pop( newItem );
	                    }
	                }
	            }
	        }
	    }
	}

// ---------------------------------------------------------------------------
// CreateSeparatorModelItemLC
// Create separator model item for the given message. Separator text depends
// on active sorting mode.
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListModelItem* CFSEmailUiMailListVisualiser::CreateSeparatorModelItemLC( CFSMailMessage& aMessage ) const
    {
    FUNC_LOG;
    CFSEmailUiMailListModelItem* separator =
        CFSEmailUiMailListModelItem::NewL( &aMessage, ETypeSeparator );
    CleanupStack::PushL( separator );

    HBufC* separatorText = NULL;

    switch ( iCurrentSortCriteria.iField )
        {
        case EFSMailSortByFlagStatus:
            {
            if ( aMessage.IsFlagSet( EFSMsgFlag_FollowUp ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_FOLLOW_UP );
                }
            else if ( aMessage.IsFlagSet( EFSMsgFlag_FollowUpComplete ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_FLAG_COMPLETE );
                }
            else
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_NO_FLAG );
                }
            }
            break;
        case EFSMailSortByPriority:
            {
            if ( aMessage.IsFlagSet( EFSMsgFlag_Important ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_HIGH );
                }
            else if ( aMessage.IsFlagSet( EFSMsgFlag_Low ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_LOW );
                }
            else
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_NORMAL );
                }
            }
            break;
        case EFSMailSortByRecipient:
        case EFSMailSortBySender:
            {
            TInt folderType(EFSInbox);
            if( iMailFolder )
                {
                folderType = iMailFolder->GetFolderType();
                }
            TBool useRecipient = ( folderType == EFSSentFolder ||
                                   folderType == EFSDraftsFolder ||
                                   folderType == EFSOutbox );

            CFSMailAddress* fromAddress(0);
            // Check address based on whether we are using recipient or sender sort
            if ( useRecipient )
                {
                RPointerArray<CFSMailAddress>& toArray = aMessage.GetToRecipients();
                if ( toArray.Count() )
                    {
                    fromAddress = toArray[0];
                    }
                }
            else
                {
                fromAddress = aMessage.GetSender();
                }
            TDesC* diplayName(0);
            if ( fromAddress )
                {
                diplayName = &fromAddress->GetDisplayName();
                }

            if ( fromAddress && diplayName && diplayName->Length() != 0 )
                {
                separatorText = diplayName->AllocLC();
                }
            else if ( fromAddress && fromAddress->GetEmailAddress().Length() != 0 )
                {
                separatorText = fromAddress->GetEmailAddress().AllocLC();
                }
            else
                {
                if ( useRecipient )
                    {
                    separatorText = KNullDesC().AllocLC();
                    }
                else
                    {
                    separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE );
                    }
                }
			// Get rid of possible unwanted characters in display name
           	if ( separatorText )
           		{
	           	TFsEmailUiUtility::StripDisplayName( *separatorText );
           		}
            }
            break;
        case EFSMailSortByAttachment:
            {
            if ( aMessage.IsFlagSet( EFSMsgFlag_Attachments ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_ATTACHMENTS );
                }
            else
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_NO_ATTACHMENTS );
                }
            }
            break;
        case EFSMailSortByUnread:
            {
            if ( aMessage.IsFlagSet( EFSMsgFlag_Read ) )
                {
                separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_READ_MSGS );
                }
            else
                {
                separatorText = StringLoader::LoadLC(R_FREESTYLE_EMAIL_UI_SEPARATOR_UNREAD_MSGS);
                }
            }
            break;
        case EFSMailSortBySubject:
            {
            separatorText = TFsEmailUiUtility::CreateSubjectWithoutLocalisedPrefixLC( &aMessage );
            }
            break;
        case EFSMailSortByDate:
            {
            TBool eventToday = EFalse;
            TBool eventYesterday = EFalse;
            HBufC* weekDay = TFsEmailUiUtility::WeekDayTextFromMsgLC( &aMessage, ETrue, EFalse, eventToday, eventYesterday );
            if ( eventToday || eventYesterday )
                {
                separatorText = weekDay;
                }
            else
                {
                HBufC* dateTextFromMsg = TFsEmailUiUtility::DateTextFromMsgLC( &aMessage );
                separatorText = HBufC::NewL( weekDay->Length() +
                                             KSpace().Length() +
                                             dateTextFromMsg->Length() );
                separatorText->Des().Append( *weekDay );
                separatorText->Des().Append( KSpace );
                separatorText->Des().Append( *dateTextFromMsg );
                CleanupStack::PopAndDestroy( dateTextFromMsg );
                CleanupStack::PopAndDestroy( weekDay );
                CleanupStack::PushL( separatorText );
                }
            }
            break;
        default:
            {
            separatorText = KNullDesC().AllocLC();
            }
            break;
        }

    separator->SetSeparatorTextL( *separatorText );
    CleanupStack::PopAndDestroy( separatorText );

    return separator;
    }

// ---------------------------------------------------------------------------
// MessagesBelongUnderSameSeparatorL
// Checks if the given messages belong under the same title divider. This
// depends on the currect sorting mode.
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::MessagesBelongUnderSameSeparatorL(
                                            const CFSMailMessage& aMessage1,
                                            const CFSMailMessage& aMessage2 ) const
    {
    FUNC_LOG;
    return CFSEmailUiMailListModel::MessagesBelongUnderSameSeparatorL( aMessage1,
                                                                       aMessage2,
                                                                       iCurrentSortCriteria.iField );
    }

// ---------------------------------------------------------------------------
// InsertNewMessagesL
// Gets new message items from the framework using the given IDs and inserts
// them in the correct place within the mail list. Both model and tree list
// are updated during this function.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::InsertNewMessagesL( const RArray<TFSMailMsgId>& aMessages )
    {
    FUNC_LOG;
    iModel->SetSortCriteria( iCurrentSortCriteria );

    // Do complete refresh in case the list is not currently correctly ordered
    // (alternatively, we could first reorder the existing items and then insert
    // the new ones)
    if ( iListOrderMayBeOutOfDate )
        {
        if ( iMailListUpdater )
            {
            if ( iMailListUpdater->IsActive() )
                {
                iMailListUpdater->Stop();
                }
            iMailListUpdater->StartL();
            }
        }
    // Otherwise, just add the new items to correct places.
    else
        {
        // Set extended status before inserting messages
        SetMailListItemsExtendedL();
        TInt count(0);
        count = aMessages.Count();
        for ( TInt i = 0 ; i < count ; ++i )
            {
            // Make sure we don't add duplicate items.
            TInt existingIdx = ItemIndexFromMessageId( aMessages[i] );
            if ( existingIdx < 0 )
                {
                CFSMailMessage* msgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(),
                                                                                    iMailFolder->GetFolderId(),
                                                                                    aMessages[i] ,
                                                                                   EFSMsgDataEnvelope );
                if (msgPtr == NULL)
                    {
                    User::Leave(KErrNotFound);
                    }
                CleanupStack::PushL( msgPtr );
                //first item - show scrollbar
                //last item - updete scrollbar
                TBool allowRefresh = ( i == 0 || i == count - 1 );
                InsertNewMessageL( msgPtr, allowRefresh );
                CleanupStack::Pop( msgPtr ); // ownership transferred to model
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// InsertNewMessageL
// Creates a single new message item to the model and tree list from the given
// message pointer. Ownership of the message is transferred. Also new
// separator item is created if necessary.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::InsertNewMessageL( CFSMailMessage* aNewMessage, const TBool aAllowRefresh )
    {
    FUNC_LOG;
    // Use simple heuristic rule: if the first item is highlighted before the new
    // item is added, the highlight is forced to remain on the (possibly new) first
    // item. Otherwise the highligh stays on the same item as before.
    TBool firstItemWasFocused =
        ( iTreeItemArray.Count() && iTreeItemArray[0].iListItemId == iMailList->FocusedItem() );

    CFSEmailUiMailListModelItem* newItem =
        CFSEmailUiMailListModelItem::NewLC( aNewMessage, ETypeMailItem );
    TInt idx = KErrNotFound;
    TFsTreeItemId parentId = KFsTreeRootID;
    TInt childIdx = KErrNotFound;
    TInt moveViewPortPosition = 0;

    if ( !iNodesInUse )
        {
        // Simple case: nodes are not in use. Just insert to correct place under root node.
        idx = iModel->GetInsertionPointL( *newItem );
        childIdx = idx;
        }
    else
        {
        // More complicated case: nodes are in use.
        TInt parentIdx = KErrNotFound;
        idx = iModel->GetInsertionPointL( *newItem, childIdx, parentIdx );

        CFSEmailUiMailListModelItem* parentNode = NULL;
        if ( parentIdx < 0 )
            {
            // Suitable parent node for the new item was not found and has to be created.
            parentNode = CreateSeparatorModelItemLC( *aNewMessage );
            iModel->InsertL( parentNode, idx );
            CleanupStack::Pop( parentNode );
            idx++; // The originally found index was used for the new node and the new item will reside in the next index

            // To insert the node item to the tree list, we need to figure out the index of the
            // new node under the root node. If the new item is not the last item in the list,
            // then the insertion location currently contains the node in front of which the new
            // node is inserted.
            if ( idx == iModel->Count() )
                {
                InsertNodeItemL( idx-1, KErrNotFound, aAllowRefresh ); // append
                }
            else
                {
                CFSEmailUiMailListModelItem* nextNode =
                    static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(idx) );
                TFsTreeItemId nextNodeId = nextNode->CorrespondingListId();
                TInt nodeIdxUnderRoot = iMailList->ChildIndex( KFsTreeRootID, nextNodeId );
                InsertNodeItemL( idx-1, nodeIdxUnderRoot, aAllowRefresh );
                }
            moveViewPortPosition += iAppUi.LayoutHandler()->OneLineListItemHeight();
            }
        else
            {
            // Suitable parent node exists and was found
            parentNode = static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(parentIdx) );
            }
        parentId = parentNode->CorrespondingListId();
        }

    // Insert the model item
    iModel->InsertL( newItem, idx );
    CleanupStack::Pop( newItem );

    // Insert the tree list item
    TPoint viewPortCenterPos = iMailTreeListVisualizer->ViewPosition();
    TPoint viewPortTopPos = iMailTreeListVisualizer->ViewPortTopPosition();
    TInt itemPos = iMailTreeListVisualizer->GetItemWorldPosition( idx );
    TBool refresh = viewPortTopPos.iY != 0 && itemPos < viewPortCenterPos.iY;

    if( refresh )
    	{
		InsertListItemL( idx, parentId, childIdx, EFalse );
		// viewPort update needed
		moveViewPortPosition += iAppUi.LayoutHandler()->TwoLineListItemHeight(); // add mail item height
		viewPortCenterPos.iY += moveViewPortPosition;
		iMailTreeListVisualizer->ViewPositionChanged( viewPortCenterPos, EFalse, 1 );
    	}
    else
    	{
    	InsertListItemL( idx, parentId, childIdx, aAllowRefresh );
    	}

    // Move focus after insertion if necessary
    if ( firstItemWasFocused )
        {
        TFsTreeItemId firstItemId = iMailList->Child( KFsTreeRootID, 0 );
        TFsTreeItemId focusedId = iMailList->FocusedItem();

        if ( firstItemId != focusedId )
            {
            // Set the first item as focused and set
            // list/ctrl bar focus according iFocusedControl
            // <cmail>
            //iMailList->SetFocusedItemL( firstItemId );
            iMailTreeListVisualizer->SetFocusedItemL( firstItemId, EFalse );
            // </cmail>
            SetListAndCtrlBarFocusL();
            }
        }
    }

// ---------------------------------------------------------------------------
// HighlightedIndex
// This function return highlighted inxed
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::HighlightedIndex() const
    {
    FUNC_LOG;
    TFsTreeItemId focusedId = static_cast<TFsTreeItemId>( iMailList->FocusedItem() );
    // Map id to the index in model
    TInt ret( KErrNotFound );
    if ( focusedId != KFsTreeNoneID )
        {
        for ( TInt i=0; i<iTreeItemArray.Count();i++ )
            {
            if ( focusedId == iTreeItemArray[i].iListItemId )
                {
                ret = i;
                break;
                }
            }
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// HighlightedIndex
// Use this function to set highlighted inxed
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetHighlightedIndexL( TInt aWantedIndex )
	{
    FUNC_LOG;
	if ( aWantedIndex >= 0 )
		{
		iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[aWantedIndex].iListItemId );
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::NewEmailsInModelL() const
	{
    FUNC_LOG;
    // <cmail>
	TInt newCount(0);
	for ( TInt i=0; i<iModel->Count();i++)
		{
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(i));
		if ( item->ModelItemType() == ETypeMailItem )
			{
			if ( !item->MessagePtr().IsFlagSet(EFSMsgFlag_Read) )
				{
				newCount++;
				}
			}
		}
	return newCount;
    // </cmail>
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::EmailsInModelL() const
	{
    FUNC_LOG;
    // <cmail>
	TInt ret(0);
	for ( TInt i=0; i<iModel->Count(); i++ )
		{
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(i));
		if ( item && item->ModelItemType() == ETypeMailItem )
			{
			ret++;
			}
		}
	return ret;
	// </cmail>
	}


// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TUid CFSEmailUiMailListVisualiser::Id() const
	{
    FUNC_LOG;
	return MailListId;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ChildDoActivateL(const TVwsViewId& aPrevViewId,
                     TUid aCustomMessageId,
                     const TDesC8& aCustomMessage)
	{
    FUNC_LOG;
    TIMESTAMP( "Opening message list view" );
    iShowReplyAll = EFalse;

	if ( !iFirstStartCompleted )
	    {
	    DoFirstStartL();
	    }
    // set when editor was called so reset is needed i.e. here (Called by DoActivate)
   	iMailOpened = EFalse; 

    // Make sure that pending popup is not displayd
	if ( iAppUi.FolderList().IsPopupShown() )
        {
        iAppUi.FolderList().HidePopupL();
        }
    DisableMailList( EFalse );

	// inform baseView if view entered with forward navigation
	TBool forwardNavigation = EFalse;
	if ( aCustomMessageId != KStartListReturnToPreviousFolder &&
	     aCustomMessageId != TUid::Uid(KMailSettingsReturnFromPluginSettings) )
	    {
	    ViewEntered( aPrevViewId );
	    forwardNavigation = ETrue;
	    }

	if( iAppUi.CurrentFixedToolbar() )
	    {
        iAppUi.CurrentFixedToolbar()->SetToolbarVisibility( EFalse );
	    }

    // Set control bar and list layout size always in activation
    TRect clientRect = iAppUi.ClientRect();
    iScreenAnchorLayout->SetSize( clientRect.Size() );
    SetMailListLayoutAnchors();
    ScaleControlBarL();
    SetListAndCtrlBarFocusL();

	// Update mail list settings and date formats, is done every time
	// the user might have changed these in settings, so the list needs to refresh
	// Store previous modes
	TInt prevListMode = iListMode;
	TInt prevNodesmode = iNodesInUse;
	TAknUiZoom prevZoomLevel = iCurrentZoomLevel;
	STimeDateFormats prevDateFormats = MailListTimeDateSettings();

	// Get new settings and list drawing modes
    CAknEnv::Static()->GetCurrentGlobalUiZoom( iCurrentZoomLevel );
	UpdateMailListSettingsL();
	UpdateMailListTimeDateSettings();

	// Check for changed settings, in that case a complete list refresh is needed
	TBool refreshNeeded(EFalse);
	if ( aCustomMessageId == KStartListWithFolderIdFromHomeScreen
	     || iSkinChanged
	     || iDateChanged
	     || iListMode != prevListMode
		 || iNodesInUse != prevNodesmode
		 || iCurrentZoomLevel != prevZoomLevel
		 || prevDateFormats.iDateFormat != iDateFormats.iDateFormat
		 || prevDateFormats.iTimeFormat != iDateFormats.iTimeFormat
		 || prevDateFormats.iAmPmPosition != iDateFormats.iAmPmPosition
		 || prevDateFormats.iDateSeparator.GetNumericValue() != iDateFormats.iDateSeparator.GetNumericValue()
		 || prevDateFormats.iTimeSeparator.GetNumericValue() != iDateFormats.iTimeSeparator.GetNumericValue() )
		{
		refreshNeeded = ETrue;
		iSkinChanged = EFalse;
		iDateChanged = EFalse;
		}

	// Store previously used mailbox and folder IDs
	TFSMailMsgId prevMailBoxId = iAppUi.GetActiveMailboxId();
	TFSMailMsgId prevFolderId = FolderId();

    CFSMailClient* mailClient = iAppUi.GetMailClient();
    User::LeaveIfNull( mailClient ); // we can't go on if no mail client is available

	// FIGURE OUT WHICH FOLDER TO ACTIVATE
    TMailListActivationData activationData;

    // Opening folder given in custom message
    if ( aCustomMessage.Length() )
        {
        TPckgBuf<TMailListActivationData> viewData;
        viewData.Copy( aCustomMessage );
        activationData = viewData();
        }

    // Returning to previous folder
    if ( aCustomMessageId == KStartListReturnToPreviousFolder ||
         aCustomMessageId == TUid::Uid(KMailSettingsReturnFromPluginSettings) )
        {
        activationData.iMailBoxId = prevMailBoxId;
        activationData.iFolderId = prevFolderId;
        }

    // Proper mailbox ID is not given in custom message. Try using MSV session.
    if ( activationData.iMailBoxId.IsNullId() )
        {
        CMsvSession* msvSession = iAppUi.GetMsvSession();
        CFSMailBox* mailBox = NULL;

        if ( msvSession )
            {
            // MSV id is passed to us in aCustomMessageId when activation happens by email key
            if ( aCustomMessageId != TUid::Null() )
                {
                // <cmail>
                TInt error = KErrNone;
                TRAP( error, mailBox = TFsEmailUiUtility::GetMailboxForMtmIdL( *mailClient, *msvSession, aCustomMessageId.iUid ) );
                // </cmail>
                if ( mailBox )
                    {
                    activationData.iMailBoxId = mailBox->GetId();
                    delete mailBox;
                    mailBox = NULL;
                    }
                }

            // Try to get MCE default mailbox if we still haven't got any other box
            if ( activationData.iMailBoxId.IsNullId() )
                {
                // <cmail>
                TInt error = KErrNone;
                TRAP( error, mailBox = TFsEmailUiUtility::GetMceDefaultMailboxL( *mailClient, *msvSession ) );
                // </cmail>
                if ( mailBox )
                    {
                    activationData.iMailBoxId = mailBox->GetId();
                    delete mailBox;
                    mailBox = NULL;
                    }
                }
            }

        }

    // If still no mailbox then use first from the list of the framework
    if ( activationData.iMailBoxId.IsNullId() )
        {
        TFSMailMsgId id;
        RPointerArray<CFSMailBox> mailboxes;
        CleanupResetAndDestroyClosePushL( mailboxes );
        mailClient->ListMailBoxes( id, mailboxes );
        if ( mailboxes.Count() > 0 )
            {
            activationData.iMailBoxId = mailboxes[0]->GetId();
            }
        CleanupStack::PopAndDestroy( &mailboxes );
        }


    // Check if we got any mailbox
    if ( activationData.iMailBoxId.IsNullId() )
        {
        // could not get mailbox so leave
        User::Leave( KErrGeneral );
        }
    else
        {
        // Set the active mailbox of AppUi. Do this also when mailbox hasn't actually
        // changed to do the autoconnect when necessary and to verify that the previously
        // active mailbox is still valid.
        // Leave is caused if mailbox is no longer available, and BaseView will take care
        // of the error handling.
        iAppUi.SetActiveMailboxL( activationData.iMailBoxId, forwardNavigation );

        // we got mailbox but no folder has been given => use Inbox
        if ( activationData.iFolderId.IsNullId() ||
             activationData.iFolderId.Id() == 0 )
            {
            activationData.iFolderId = iAppUi.GetActiveBoxInboxId();
            }
        }

    // NOW WE HAVE A VALID MAILBOX AND FOLDER ID.
    // Tries to create an extension for the Ozone plugin
    CreateExtensionL();

    // CHECK IF MODEL NEEDS TO BE UPDATED
    if ( activationData.iMailBoxId != prevMailBoxId ||
         activationData.iFolderId != prevFolderId ||
         activationData.iRequestRefresh ||
         iForceRefresh )
         {
         iForceRefresh = EFalse;
         // Set initial sort criteria when folder is changed
         iCurrentSortCriteria.iField = EFSMailSortByDate;
         iCurrentSortCriteria.iOrder = EFSMailDescending;
         SetSortButtonTextAndIconL();

         SafeDelete(iMailFolder);
         TRAP_IGNORE( iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL(
                 activationData.iMailBoxId, activationData.iFolderId ) );
         if ( !iMailFolder )
             {
             if ( forwardNavigation )
                 {
                 iAppUi.StartMonitoringL();
                 }
             // Safety, try to revert back to standard folder inbox
             TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox );
             iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( activationData.iMailBoxId, inboxId );
             }
         HBufC* newFolderName = CreateFolderNameLC( iMailFolder );
         iFolderListButton->SetTextL( *newFolderName );
         CleanupStack::PopAndDestroy( newFolderName );
         iMailList->SetFocusedItemL( KFsTreeNoneID );
         refreshNeeded = ETrue;
         }

    // Set mailbox name to status pane
    SetMailboxNameToStatusPaneL();

    // Set branded watermark and mailbox icon
    SetBrandedListWatermarkL();
    SetBrandedMailBoxIconL();

    // Check sync icon timer and sync status
    ConnectionIconHandling();

    // REBUILD TREE LIST IF NECESSARY
    if ( refreshNeeded )
        {
        // Try to maintain previously active item if possible.
        // This is of course not possible if folder has changed.
        TFSMailMsgId focused = MsgIdFromListId( iMailList->FocusedItem() );

        // Clear any previous items from the screen and then make the view visible
        iMailList->BeginUpdate();
        iMailList->RemoveAllL();
        iTreeItemArray.Reset();
        iModel->Reset();
        iMailList->EndUpdateL();
        iMailList->ShowListL();

        // If coming from wizard use synchronous list updating
        if (activationData.iReturnAfterWizard)
            {
            UpdateMailListModelL();
            }
        else
            {
            UpdateMailListModelAsyncL();
            }
        }
    // THE CORRECT FOLDER IS ALREADY OPEN. CHECK IF SOME PARTIAL UPDATE IS NEEDED.
    else
        {
        iMailList->ShowListL();
        if (forwardNavigation)
            {
            iAppUi.StartMonitoringL();
            }
        SetListAndCtrlBarFocusL(); // ShowListL() makes list focused and this may need to be reverted
        UnmarkAllItemsL();
        if ( aCustomMessageId == TUid::Uid(KMailSettingsReturnFromPluginSettings) )
            {
            // Better to refresh launcher grid view because mailbox branding might be changed.
            iAppUi.LauncherGrid().SetRefreshNeeded();
            }
        // Check the validity of focused message, it may be deleted or
        // reply/forward, read/unread status might have changed in editor or viewer
        UpdateItemAtIndexL( HighlightedIndex() );
        SetMskL();
        }

    iCurrentClientRect = clientRect;
	iThisViewActive = ETrue;
	//emailindicator handling, we dont care if something goes wrong in the mailindicator update. User can still open the mailbox
	TRAP_IGNORE(TFsEmailStatusPaneIndicatorHandler::StatusPaneMailIndicatorHandlingL( activationData.iMailBoxId.Id()));
	    
    //Update mailbox widget index status in homescreen
    TFsEmailUiUtility::ToggleEmailIconL(EFalse, activationData.iMailBoxId );

	iShiftDepressed = EFalse; // clear state just in case

	// Inform MR observer if needed, special MR case, returning from attachment list
	iAppUi.MailViewer().CompletePendingMrCommand();

	// Make sure that correct component is set to focused.
	if ( iFocusedControl == EMailListComponent )
	    {
	    SetTreeListFocusedL();
	    }
	else
	    {
	    SetControlBarFocusedL();
	    iControlBarControl->MakeSelectorVisible( iAppUi.IsFocusShown() );
	    }
	UpdateButtonTextsL();
	FocusVisibilityChange( iAppUi.IsFocusShown() );
	iAppUi.ShowTitlePaneConnectionStatus();
	TIMESTAMP( "Message list view opened" );
	}

// ---------------------------------------------------------------------------
// Sets status bar layout
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetStatusBarLayout()
	{
    TInt res = R_AVKON_STATUS_PANE_LAYOUT_USUAL_FLAT;
    if( Layout_Meta_Data::IsLandscapeOrientation() )
        {
        // landscape must use different layout
		res = R_AVKON_STATUS_PANE_LAYOUT_USUAL_EXT;
        }

	if ( StatusPane()->CurrentLayoutResId() != res )
		{
		TRAP_IGNORE(
			StatusPane()->SwitchLayoutL( res ));
		}
	}


// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ChildDoDeactivate()
	{
    FUNC_LOG;
    if (iMailListModelUpdater)
        {
        iMailListModelUpdater->Cancel();
        }
	if ( !iAppUi.AppUiExitOngoing() )
  	    {
  	    TRAP_IGNORE( {
            iMailList->HideListL();
            iMailList->SetFocusedL( EFalse );
  	        } );
  	    iMailTreeListVisualizer->NotifyControlVisibilityChange( EFalse );
  	    }
	iThisViewActive = EFalse;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
CFSEmailUiMailListModel* CFSEmailUiMailListVisualiser::Model()
	{
    FUNC_LOG;
	return iModel;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TFSMailMsgId CFSEmailUiMailListVisualiser::FolderId()
	{
    FUNC_LOG;
	TFSMailMsgId folderId; // constructs null ID
	if ( iMailFolder )
	    {
	    folderId = iMailFolder->GetFolderId();
	    }
	return folderId;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
	{
    FUNC_LOG;
	CompletePendingRefresh();

	// Get the list of items which will be targetted by the actions menu commands
	RFsTreeItemIdList targetEntries;
	CleanupClosePushL( targetEntries );
	GetActionsTargetEntriesL( targetEntries );

	TBool supportsMoving = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder );
	TBool supportsFlag = TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() );

	TInt currentFolderType = KErrNotFound;
	if ( iMailFolder )
	    {
	    currentFolderType = iMailFolder->GetFolderType();
	    }

    // MAIN MENU ***************************************************************************
	if ( aResourceId == R_FSEMAILUI_MAILLIST_MENUPANE )
	    {
            // Sync/cancel sync
	    CFSMailBox* activeMailbox = iAppUi.GetActiveMailbox();
	    TBool supportsSync = activeMailbox->HasCapability( EFSMBoxCapaSupportsSync );
        TFSMailBoxStatus onlineStatus = activeMailbox->GetMailBoxStatus();
         if ( onlineStatus == EFSMailBoxOnline && 
		      KIpsPlgImap4PluginUid == activeMailbox->GetId().PluginId() )
        	{
            aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, ETrue );
        	}

            // flag to hide or show SyncButton
            TBool hideSync = GetLatestSyncState();
            if(activeMailbox->CurrentSyncState()==StartingSync) hideSync=EFalse;

            // hide or show options: Sync/cancel sync
        if ( !supportsSync )
        {
				// POP3 behaviour
				if( onlineStatus == EFSMailBoxOnline || iMailListModelUpdater->IsUpdating() )
				  {
					aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelSync, EFalse );
					aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, ETrue );
				  }
				else
					{
					aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelSync, ETrue );
					aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, EFalse );
					}
        }
      else if ( hideSync || iMailListModelUpdater->IsUpdating() )
        {
        aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, ETrue );
        }
      else
        {
        aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelSync, ETrue );
        }

		// Saves a focus visibility.
		iLastFocus = EFalse;
		if( iFocusedControl == EMailListComponent && IsFocusShown() )
		    {
		    iLastFocus = ETrue;
		    }
	    if (FeatureManager::FeatureSupported( KFeatureIdFfCmailIntegration ))
		   {
		   // remove help support in pf5250
		   aMenuPane->SetItemDimmed( EFsEmailUiCmdHelp, ETrue);
		   }

	    // Checks if a device has a keyboard or not.
		if( !iLastFocus )
    	    {
            // Hide all the normal email message specific actions
            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReply, ETrue );
            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue );
            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, ETrue );
            aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, ETrue);

            TInt markedCount = CountMarkedItemsL();
            // Hide mark/unmark all when not applicable
            if ( markedCount == EmailsInModelL() ) // Hide mark all
		       {
		       aMenuPane->SetItemDimmed( EFsEmailUiCmdSubMenuMark, ETrue );
		       }
            if ( markedCount == 0 ) // Hide unmark all
		       {
		       aMenuPane->SetItemDimmed( EFsEmailUiCmdSubMenuUnmark, ETrue );
		       }

            }
        else
    	    {
    		CFSMailMessage* targetMessage = NULL;
            if ( targetEntries.Count() == 1 )
                {
                targetMessage = &MsgPtrFromListIdL( targetEntries[0] );
                }

            // Hide the irrelevant reply / reply all / forward commands
            TInt numRecipients(0);
            if ( targetMessage )
                {
                //Get # of recipients
                numRecipients = TFsEmailUiUtility::CountRecipientsSmart( iAppUi, targetMessage );
                }
            // All reply/forward options are hidden when multiple marked messages or folder is outbox or drafts
            if ( targetEntries.Count() != 1 ||
                 currentFolderType == EFSOutbox ||
                 currentFolderType == EFSDraftsFolder )
                {
                aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReply, ETrue );
                aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue );
                aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, ETrue );
                }

            // Reply all is hidden also when the single target message has multiple recipients
            else if ( !targetMessage || numRecipients <= 1 )
                {
                aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue );
                }

            aMenuPane->SetItemDimmed( EFsEmailUiCmdSubMenuUnmark, ETrue);
            }

	    // EMPTY LIST, MOST OPTIONS ARE HIDDEN
	    if ( !iModel->Count() || !iMailFolder )
	        {
	        aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, ETrue );
	        aMenuPane->SetItemDimmed( EFsEmailUiCmdSubMenuMark, ETrue );
	        aMenuPane->SetItemDimmed( EFsEmailUiCmdSubMenuUnmark, ETrue );
	        aMenuPane->SetItemDimmed( EFsEmailUiCmdSearch, ETrue );
	        }

	    // FOLDER SPECIFIC COMMAND HIDING
	    // "Clear deleted folder" command is available only in Deleted folder
	    if ( currentFolderType != EFSDeleted || !iModel->Count() )
	        {
	        aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsEmptyDeleted, ETrue );
	        }
		}
    // MAIN MENU ***************************************************************************


	// ACTIONS SUBMENU *********************************************************************
	if ( aResourceId == R_FSEMAILUI_MAILLIST_SUBMENU_MAIL_ACTIONS  )
		{
        // COMMON PART OF ACTIONS SUBMENU
		aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsRead, !IsMarkAsReadAvailableL() );
        aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, !IsMarkAsUnreadAvailableL() );

		if ( !supportsMoving || !iMailFolder ) // Hide move from actions if not supported
			{
			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, ETrue );
			}
		else
			{
			// Moving supported, show/hide moving options depending on the current folder
			// Check for outbox case
			if ( currentFolderType == EFSOutbox )
				{
				// moving from outbox is not allowed otherwise
				aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, ETrue );
				}
			// Handle rest of the folders
			else
				{
				aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, EFalse );
				}
			}

		TInt markedCount = CountMarkedItemsL();

	    // Hide expand/collapse all when not applicable
		if ( iNodesInUse == EListControlSeparatorDisabled || !iModel->Count() )
			{
			aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsCollapseAll, ETrue);
			aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsExpandAll, ETrue);
			}
		else
			{
			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, AllNodesCollapsed() );
			aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, AllNodesExpanded() );
			}

		// Hide followup flagging if not applicable
		if ( !supportsFlag || !targetEntries.Count() )
		    {
		    aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsFlag, ETrue);
		    }

	    // Some commands are hidden in the outbox and drafts folders
        if ( currentFolderType == EFSOutbox ||
             currentFolderType == EFSDraftsFolder )
            {
            aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsFlag, ETrue );
            }
		}
    // ACTIONS SUBMENU *********************************************************************


	// MARK SUBMENU ************************************************************************
	// Mark submenu show only when focus is visible
	if ( aResourceId == R_FSEMAILUI_MAILLIST_SUBMENU_MARK)
		{
	    // Checks if a device has a keyboard or not.
		if( !iLastFocus )
       	    {
            aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkMark, ETrue );
            aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkMarkAll, ETrue );
	        }
         else
       	    {
            aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkSubAll, ETrue );
	        }
		}

    // MARK SUBMENU ************************************************************************


	// UNMARK SUBMENU ************************************************************************
	// Unmark submenu show only when focus is not visible
	if ( aResourceId == R_FSEMAILUI_MAILLIST_SUBMENU_UNMARK)
		{
		// Nothing to do yet
		}
    // UNMARK SUBMENU ************************************************************************


	CleanupStack::PopAndDestroy( &targetEntries );

	// Add shortcut hints
	iAppUi.ShortcutBinding().AppendShortcutHintsL( *aMenuPane,
	                             CFSEmailUiShortcutBinding::EContextMailList );
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::MarkAllItemsL()
	{
    FUNC_LOG;
	if ( iTreeItemArray.Count() )
		{
		for ( TInt i=0;i<iTreeItemArray.Count(); i++ )
			{
			if ( !iMailList->IsNode(iTreeItemArray[i].iListItemId ) )
				{
		       	iMailList->MarkItemL( iTreeItemArray[i].iListItemId, ETrue );
				}
			}
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UnmarkAllItemsL()
	{
    FUNC_LOG;
	for ( TInt i=0 ; i<iTreeItemArray.Count() ; i++ )
	    {
	    if ( !iMailList->IsNode(iTreeItemArray[i].iListItemId) )
	        {
	        iMailList->MarkItemL( iTreeItemArray[i].iListItemId, EFalse );
	        }
	    }
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::CountMarkedItemsL()
    {
    FUNC_LOG;
    RFsTreeItemIdList markedEntries;
    CleanupClosePushL( markedEntries );
    iMailList->GetMarkedItemsL( markedEntries );
    TInt count = markedEntries.Count();
    CleanupStack::PopAndDestroy( &markedEntries );
    return count;
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::GetMarkedMessagesL( RArray<TFSMailMsgId>& aMessageIDs ) const
    {
    FUNC_LOG;
    aMessageIDs.Reset();

	RFsTreeItemIdList markedEntries;
	CleanupClosePushL( markedEntries );
	iMailList->GetMarkedItemsL( markedEntries );

	for ( TInt i=0 ; i<markedEntries.Count() ; ++i )
	    {
	    // This could be optimized if we could be certain that the order of the
	    // marked entries is the same as the order in the message list. This is
	    // probably true, but the interface does not guarantee that. Now the
	    // time counsumption is Theta(n*m) while Theta(n+m) could be possible
	    TFSMailMsgId messageId = MsgIdFromListId( markedEntries[i] );
	    if ( !messageId.IsNullId() )
	        {
	        aMessageIDs.Append( messageId );
	        }
	    }

	CleanupStack::PopAndDestroy( &markedEntries );
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::MarkMessagesIfFoundL( const RArray<TFSMailMsgId>& aMessageIDs )
    {
    FUNC_LOG;
    for ( TInt i=0 ; i<aMessageIDs.Count() ; ++i )
        {
        // Same performance tweaking possibility is here that is commented in GetMarkedMessagesL().
        TInt index = ItemIndexFromMessageId( aMessageIDs[i] );
        if ( index >= 0 )
            {
            iMailList->MarkItemL( iTreeItemArray[index].iListItemId, ETrue );
            }
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::RefreshL( TFSMailMsgId* aFocusToMessage )
	{
    FUNC_LOG;
	iMailList->RemoveAllL();
	iTreeItemArray.Reset();

    // when we get refresh mail list updates should be fully enabled
    iMailOpened = EFalse;

	RefreshListItemsL();

	if ( !iModel->Count() )
		{
		iFocusedControl = EControlBarComponent;
		// If focus is not visible, hide selector
		iControlBarControl->MakeSelectorVisible( IsFocusShown() );
		}
	else
	    {
        // Try to keep the previous list item if focused message ptr is given,
	    // and it's not NULL id
        if ( aFocusToMessage && !aFocusToMessage->IsNullId() )
            {
            TInt idx = ItemIndexFromMessageId( *aFocusToMessage );
            if ( idx >= 0 )
                {
                TFsTreeItemId itemId = iTreeItemArray[idx].iListItemId;
                iMailList->SetFocusedItemL( itemId );
                // If contorl bar is focused, we need to hide
                // focus then.
                if( iFocusedControl == EControlBarComponent )
                    {
                    iMailTreeListVisualizer->UpdateItemL( itemId );
                    }
                }
            }
	    }

    SetListAndCtrlBarFocusL();
    SetMskL();

    iListOrderMayBeOutOfDate = EFalse;
	}

void CFSEmailUiMailListVisualiser::RefreshOrderL()
    {
    FUNC_LOG;
    if ( iTreeItemArray.Count() )
        {
        TInt itemIdxUnderNode = -1;
        TInt nodeIdx = -1;
        TFsTreeItemId parentNodeId = KFsTreeRootID;

        //iMailList->HideListL( EFalse, EFalse );
        TFsTreeItemId prevFocus = iMailList->FocusedItem();
        iMailList->SetFocusedItemL( iTreeItemArray[0].iListItemId ); // Try to prevent over indexing in generic list

        // iTreeItemArray is recreated on reordering.
        iTreeItemArray.Reset();
        SMailListItem mailListItem;

        for ( TInt i = 0 ; i < iModel->Count() ; ++i )
            {
            CFSEmailUiMailListModelItem* item = static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(i) );
            TFsTreeItemId itemId = item->CorrespondingListId();

            if ( item->ModelItemType() == ETypeSeparator )
                {
                nodeIdx++;
                itemIdxUnderNode = -1;
                parentNodeId = itemId;
                if ( iMailList->ChildIndex( itemId, KFsTreeRootID ) != nodeIdx )
                    {
                    iMailList->MoveItemL( itemId, KFsTreeRootID, nodeIdx );
                    }
                }
            else
                {
                itemIdxUnderNode++;
                if ( iMailList->Parent(itemId) != parentNodeId ||
                     iMailList->ChildIndex( parentNodeId, itemId ) != itemIdxUnderNode )
                    {
                    iMailList->MoveItemL( itemId, parentNodeId, itemIdxUnderNode );
                    }
                }

            mailListItem.iListItemId = itemId;
            mailListItem.iTreeItemData = &iMailList->ItemData(itemId);
            mailListItem.iTreeItemVisualiser = &iMailList->ItemVisualizer(itemId);
            iTreeItemArray.AppendL( mailListItem );
            }

        iMailList->SetFocusedItemL( prevFocus );
        //iMailList->ShowListL( EFalse, EFalse );
        }
    iListOrderMayBeOutOfDate = EFalse;
    }

// ---------------------------------------------------------------------------
// Start refresh list items asynchronously
//
// ---------------------------------------------------------------------------
//
//
void CFSEmailUiMailListVisualiser::RefreshDeferred( TFSMailMsgId* aFocusToMessage /*= NULL*/ )
    {
    FUNC_LOG;
    if ( aFocusToMessage )
        {
        iMsgToFocusAfterRedraw = *aFocusToMessage;
        }
    else
        {
        // SetNullId sets just the null id flag,
        // so we need to null the actual id manually
        iMsgToFocusAfterRedraw.SetId( 0 );
        iMsgToFocusAfterRedraw.SetNullId();
        }

    if ( iAsyncRedrawer )
        {
        TCallBack asyncRefresh( DoRefresh, this );
        iAsyncRedrawer->Cancel();
        iAsyncRedrawer->Set( asyncRefresh );
        iAsyncRedrawer->CallBack();
        }
    }

// ---------------------------------------------------------------------------
// Static wrapper function for RefreshL() to enable asynchronous calling
//
// ---------------------------------------------------------------------------
//
//
TInt CFSEmailUiMailListVisualiser::DoRefresh( TAny* aSelfPtr )
    {
    FUNC_LOG;
    CFSEmailUiMailListVisualiser* self =
        static_cast< CFSEmailUiMailListVisualiser* >( aSelfPtr );
    TRAPD( err, self->RefreshL( &self->iMsgToFocusAfterRedraw ) );
    return err;
    }

// ---------------------------------------------------------------------------
// Force any pending refresh event to be completed immediately
//
// ---------------------------------------------------------------------------
//
//
void CFSEmailUiMailListVisualiser::CompletePendingRefresh()
    {
    FUNC_LOG;

    if ( iAsyncRedrawer && iAsyncRedrawer->IsActive() )
        {
        iAsyncRedrawer->Cancel();
        DoRefresh( this );
        }

    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::RefreshListItemsL()
	{
    FUNC_LOG;
	// IMPLEMENTATION OF FILLING UP THE LIST
	TFsTreeItemId latestNodeId = KFsTreeRootID; // items will go under root node if no other nodes found in the model
    CFSEmailUiMailListModelItem* item( NULL );
    SetMailListItemsExtendedL();

    TInt count(0);
    count = iModel->Count();
    for ( TInt i=0; i < count; i++ )
		{
		item = static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(i));

        const TBool allowRefresh(i == 0 || (i == count - 1));

		// Append separator item text into the list
		if ( item && item->ModelItemType() == ETypeSeparator )
			{
			latestNodeId = InsertNodeItemL( i, KErrNotFound, allowRefresh );
			}
		// Append mail item into the list
		else if ( item && item->ModelItemType() == ETypeMailItem )
			{
			InsertListItemL( i, latestNodeId, KErrNotFound, allowRefresh );
			}
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::RefreshListItemsL(TFsTreeItemId& aLatestNodeId, const TInt aStartIndex, const TInt aEndIndex)
    {
    FUNC_LOG;
    // IMPLEMENTATION OF FILLING UP THE LIST
    iMailList->BeginUpdate();
    CFSEmailUiMailListModelItem* item( NULL );
    if (aLatestNodeId == KFsTreeRootID && !aStartIndex)
        {
        iMailList->RemoveAllL();
        iTreeItemArray.Reset();
        SetMailListItemsExtendedL();
        }
    for ( TInt i = aStartIndex; i < aEndIndex; i++ )
        {
        item = static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(i));
        // Append separator item text into the list
        if ( item && item->ModelItemType() == ETypeSeparator )
            {
            aLatestNodeId = InsertNodeItemL( i, KErrNotFound, EFalse );
            }
        // Append mail item into the list
        else if ( item && item->ModelItemType() == ETypeMailItem )
            {
            InsertListItemL( i, aLatestNodeId, KErrNotFound, EFalse );
            }
        }
    iMailList->EndUpdateL();
    }

void CFSEmailUiMailListVisualiser::SetMailListItemsExtendedL()
	{
    FUNC_LOG;
	// Set items always extended in double line preview on mode.
	if ( iListMode == EListControlTypeDoubleLinePreviewOn ||
		 iListMode == EListControlTypeDoubleLinePreviewOff )
		{
		if ( iMailTreeListVisualizer )
			{
	        iMailTreeListVisualizer->SetItemsAlwaysExtendedL( ETrue );
			}
 		}
	else
		{
		// Set the extendedability and extended size
		if ( iMailTreeListVisualizer )
			{
  			iMailTreeListVisualizer->SetItemsAlwaysExtendedL( EFalse );
			}
 		}
	}


// ---------------------------------------------------------------------------
// Create and insert one list node item according to given model item.
// Omitting the argument aChildIdx causes the new node to be appended as last
// child of the root node.
// ---------------------------------------------------------------------------
//
TFsTreeItemId CFSEmailUiMailListVisualiser::InsertNodeItemL( TInt aModelIndex,
                                                             TInt aChildIndex,
                                                             const TBool aAllowRefresh )
    {
    FUNC_LOG;
    TFsTreeItemId nodeId;
    CFsTreePlainOneLineNodeData* plainNodeData(0);
    CFsTreePlainOneLineNodeVisualizer* plainNodeVisualizer(0);

    CFSEmailUiMailListModelItem* item =
        static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(aModelIndex) );

    CreatePlainNodeL( item->SeparatorText(), plainNodeData, plainNodeVisualizer );
    CleanupStack::PushL( plainNodeData );
    CleanupStack::PushL( plainNodeVisualizer );
    // Set text aling for western or A&H layout
   	plainNodeVisualizer->SetTextAlign( EAlfAlignHLocale  );
   	//new node is expanded
   	plainNodeVisualizer->SetExpanded( ETrue );

    // In mail list, scrollbar does not need to be updated after node, since node is always followed by item
    if ( aChildIndex >= 0 )
        {
        nodeId = iMailList->InsertNodeL( *plainNodeData, *plainNodeVisualizer, KFsTreeRootID, aChildIndex, aAllowRefresh );
        }
    else
        {
        nodeId = iMailList->InsertNodeL( *plainNodeData, *plainNodeVisualizer, KFsTreeRootID, KErrNotFound, aAllowRefresh );
        }

    CleanupStack::Pop( 2, plainNodeData );

    SMailListItem mailListItem;
    mailListItem.iListItemId = nodeId;
    mailListItem.iTreeItemData = plainNodeData;
    mailListItem.iTreeItemVisualiser = plainNodeVisualizer;
    iTreeItemArray.InsertL( mailListItem, aModelIndex );
    item->AddCorrespondingListId( nodeId );

    return nodeId;
    }

// ---------------------------------------------------------------------------
// Create and insert one list item according the given model item. The item is
// added under the given node. Omitting the argument aChildIdx causes the new
// item to be appended as last child of the node.
// ---------------------------------------------------------------------------
//
TFsTreeItemId CFSEmailUiMailListVisualiser::InsertListItemL( TInt aModelIndex,
                                                             TFsTreeItemId aParentNodeId,
                                                             TInt aChildIdx, /*= KErrNotFound*/
                                                             TBool aAllowRefresh )
    {
    FUNC_LOG;
    TRect screenRec( iAppUi.ClientRect() );
    CFsTreePlainTwoLineItemData* itemData = NULL;
    CFsTreePlainTwoLineItemVisualizer* itemVisualizer = NULL;
    TRgb focusedColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor();
    TRgb normalColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor();

    CFSEmailUiMailListModelItem* item =
        static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(aModelIndex) );

    // Create data
    itemData = CFsTreePlainTwoLineItemData::NewL();
    CleanupStack::PushL(itemData);

    // Read the data from the message
    UpdateItemDataL( itemData, &item->MessagePtr() );

    // Set placeholder for body preview
    itemData->SetPreviewPaneDataL( KMissingPreviewDataMarker );

    // Create item visualiser
    itemVisualizer = CFsTreePlainTwoLineItemVisualizer::NewL(
            *iMailList->TreeControl() );
    CleanupStack::PushL( itemVisualizer );

   	itemVisualizer->SetTextAlign( EAlfAlignHLocale );

   	TBool previewOn = ( iListMode == EListControlTypeDoubleLinePreviewOn ||
                        iListMode == EListControlTypeSingleLinePreviewOn );
   	itemVisualizer->SetPreviewPaneOn( previewOn );
   	itemVisualizer->SetExtendable( ETrue );

    itemVisualizer->SetFocusedStateTextColor( focusedColor );
    itemVisualizer->SetNormalStateTextColor( normalColor );

    // Set font height
    itemVisualizer->SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() );

    //Update icons and text bolding
    //DOES NOT update the item - will be drawn automatically (if needed) during InsertItemL
    UpdateMsgIconAndBoldingL( itemData, itemVisualizer, &item->MessagePtr() );

    // Insert or append under the given node
    TFsTreeItemId itemId(0);
    itemId = iMailList->InsertItemL( *itemData, *itemVisualizer, aParentNodeId, aChildIdx, aAllowRefresh );

    // The visualizer and data are now owned by the iMailList and should be removed from
    // the cleanup stack
    CleanupStack::Pop( itemVisualizer );
    CleanupStack::Pop( itemData );

    // Insert corresponding item to iTreeItemArray
    SMailListItem mailListItem;
    mailListItem.iListItemId = itemId;
    mailListItem.iTreeItemData = itemData;
    mailListItem.iTreeItemVisualiser = itemVisualizer;
    iTreeItemArray.InsertL( mailListItem, aModelIndex );
    item->AddCorrespondingListId( itemId );

    // Updating the preview pane must be handled separately in this case;
    // generic logic in TreeListEvent handler doesn't work while we are
    // still in the middle of adding the item.
    if ( iMailList->FocusedItem() == itemId )
        {
        UpdatePreviewPaneTextIfNecessaryL( itemId, ETrue );
        }

    return itemId;
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
HBufC* CFSEmailUiMailListVisualiser::GetListFirstTextLineL( const CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
	HBufC* ret( NULL );

	TDesC* displayName( NULL );
	TDesC* emailAddress( NULL );

	TInt folderType( EFSInbox );
    if( iMailFolder )
     {
     folderType = iMailFolder->GetFolderType();
     }

	// Use sender in all other folders than outbox, sent, and drafts
	if ( folderType != EFSOutbox &&
		 folderType != EFSSentFolder &&
		 folderType != EFSDraftsFolder )
		{
		CFSMailAddress* fromAddress = aMsgPtr->GetSender();
	    if ( fromAddress )
		    {
		    displayName = &fromAddress->GetDisplayName();
		    emailAddress = &fromAddress->GetEmailAddress();

		    if ( displayName && displayName->Length() != 0 )
                {
                ret = displayName->AllocL();
                }
            else if ( emailAddress && emailAddress->Length() != 0 )
                {
                ret = emailAddress->AllocL();
                }
		    }
		else // no fromAddress in that case we show "(No sender info available)",
		    // in case sender sends MR to himself/herself
		    {
		    ret = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE);
		    }
	    }
	// Use first recipient in case of outgoing folders
	else // folderType == EFSOutbox || folderType == EFSSentFolder || folderType == EFSDraftsFolder
		{
		CFSMailMessage* msgPtr = const_cast<CFSMailMessage*>( aMsgPtr ); // there's no const function in FW to get recipient data
		RPointerArray<CFSMailAddress>& toArray = msgPtr->GetToRecipients();
		if ( toArray.Count() )
			{
			CFSMailAddress* toAddress = toArray[0]; // Use first
			if ( toAddress )
				{
				displayName = &toAddress->GetDisplayName();
				emailAddress = &toAddress->GetEmailAddress();

	            if ( displayName && displayName->Length() )
	                {
	                ret = displayName->AllocL();
	                }
	            else if ( emailAddress && emailAddress->Length() )
	                {
	                ret = emailAddress->AllocL();
	                }
				}
			}
		}

	// Allocate empty string if everything else fails
    if ( !ret )
         {
         ret = KNullDesC().AllocL();
         }

	// Drop out unwanted characters from display name such as <> and ""
	TFsEmailUiUtility::StripDisplayName( *ret );

	return ret;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateItemDataL( CFsTreePlainTwoLineItemData* aData, const CFSMailMessage* aMsgPtr )
    {
    FUNC_LOG;
    // Set first line of data
    HBufC* firstLineText = GetListFirstTextLineL( aMsgPtr );
    if ( firstLineText )
        {
        CleanupStack::PushL( firstLineText );
        aData->SetDataL( *firstLineText );
        CleanupStack::PopAndDestroy( firstLineText );
        }
    else
        {
        aData->SetDataL( KNullDesC );
        }

    // Set second line of data
    HBufC* subjectText = TFsEmailUiUtility::CreateSubjectTextLC( aMsgPtr );
    aData->SetSecondaryDataL( *subjectText );
    CleanupStack::PopAndDestroy( subjectText );

    // Set time item in mail
    HBufC* timeText = NULL;
    if ( iCurrentSortCriteria.iField == EFSMailSortByDate )
        {
        timeText = TFsEmailUiUtility::ListMsgTimeTextFromMsgLC( aMsgPtr, iNodesInUse );
        }
    else
        {
        // Use dates also in other sort criterias that sort by date.
        timeText = TFsEmailUiUtility::ListMsgTimeTextFromMsgLC( aMsgPtr, EFalse );
        }
    aData->SetDateTimeDataL( *timeText );
    CleanupStack::PopAndDestroy( timeText );
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextForItemL( TInt aListItemId, CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
	if ( aMsgPtr && ( iListMode == EListControlTypeSingleLinePreviewOn ||
         iListMode == EListControlTypeDoubleLinePreviewOn ) )
        {
        CFsTreePlainTwoLineItemData* twoLineItemData = static_cast<CFsTreePlainTwoLineItemData*>( ItemDataFromItemId( aListItemId ) );
        UpdatePreviewPaneTextForItemL( twoLineItemData, aMsgPtr  );
        }
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextForItemL(
        CFsTreePlainTwoLineItemData* aTwoLineItemData, CFSMailMessage* aMsgPtr )
    {
    FUNC_LOG;
	// Preview pane data update
	if ( aTwoLineItemData && aMsgPtr && ( iListMode == EListControlTypeSingleLinePreviewOn ||
		 iListMode == EListControlTypeDoubleLinePreviewOn ) )
		{
		TBool previewSet = EFalse;
		CFSMailMessagePart* textPart = aMsgPtr->PlainTextBodyPartL();
		CleanupStack::PushL( textPart );
		if ( textPart && ( textPart->FetchLoadState() == EFSPartial ||
			 textPart->FetchLoadState() == EFSFull ) )
			{
			TInt previewSize = Min( KMaxPreviewPaneLength, textPart->FetchedContentSize() );
			HBufC* plainTextData16 = HBufC::NewLC( previewSize );
			TPtr textPtr = plainTextData16->Des();

			// Getting the content needs to be trapped as it seems to leave in some error cases
			// at least with IMAP
			TRAP_IGNORE( textPart->GetContentToBufferL( textPtr, 0 ) ); // Zero is start offset
            // Crop out line feed, paragraph break, and tabulator
            TFsEmailUiUtility::FilterListItemTextL( textPtr );

            if ( textPtr.Length() )
                {
                aTwoLineItemData->SetPreviewPaneDataL( *plainTextData16 );
                previewSet = ETrue;
                }

			CleanupStack::PopAndDestroy( plainTextData16 );
			}

		// Display message size in preview pane if we got no body content
		if ( !previewSet )
			{
			TUint contentSize = aMsgPtr->ContentSize();
			HBufC* sizeDesc = TFsEmailUiUtility::CreateSizeDescLC( contentSize );
			HBufC* msgSizeText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_PREV_PANE_MSG_SIZE, *sizeDesc );
			aTwoLineItemData->SetPreviewPaneDataL( *msgSizeText );
			CleanupStack::PopAndDestroy( msgSizeText );
			CleanupStack::PopAndDestroy( sizeDesc );
			}
		CleanupStack::PopAndDestroy( textPart );
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextIfNecessaryL( TFsTreeItemId aListItemId, TBool aUpdateItem )
    {
    FUNC_LOG;
    if ( iFirstStartCompleted && aListItemId != KFsTreeNoneID )
        {
        if ( iListMode == EListControlTypeSingleLinePreviewOn ||
             iListMode == EListControlTypeDoubleLinePreviewOn )
            {
            if ( !iMailList->IsNode( aListItemId ) )
                {
                TInt idx = ModelIndexFromListId( aListItemId );
                if ( idx != KErrNotFound )
                    {
                    CFsTreePlainTwoLineItemData* data =
                        static_cast<CFsTreePlainTwoLineItemData*>( iTreeItemArray[idx].iTreeItemData );
                    if ( data->PreviewPaneData() == KMissingPreviewDataMarker )
                        {
                        CFSEmailUiMailListModelItem* modelItem =
                            static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(idx) );
                        CFSMailMessage& msgRef = modelItem->MessagePtr();
                        UpdatePreviewPaneTextForItemL( aListItemId, &msgRef );
                        if ( aUpdateItem )
                            {
                            iMailTreeListVisualizer->UpdateItemL( aListItemId );
                            }
                        }
                    }
                }
            }
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::CreatePlainNodeL( const TDesC* aItemDataBuff,
                                                     CFsTreePlainOneLineNodeData* &aItemData,
                                                     CFsTreePlainOneLineNodeVisualizer* &aNodeVisualizer ) const
	{
    FUNC_LOG;
    aItemData = CFsTreePlainOneLineNodeData::NewL();
    CleanupStack::PushL( aItemData );

    aItemData->SetDataL( *aItemDataBuff );
	aItemData->SetIconExpanded( iAppUi.FsTextureManager()->TextureByIndex( EListTextureNodeExpanded ));
    aItemData->SetIconCollapsed( iAppUi.FsTextureManager()->TextureByIndex( EListTextureNodeCollapsed ));
    aNodeVisualizer = CFsTreePlainOneLineNodeVisualizer::NewL(*iMailList->TreeControl());
    CleanupStack::PushL( aNodeVisualizer );
    TRect screenRect = iAppUi.ClientRect();
    TInt nodeHeight = iAppUi.LayoutHandler()->OneLineListNodeHeight();
    aNodeVisualizer->SetSize( TSize(screenRect.Width(), nodeHeight) );
    aNodeVisualizer->SetExtendable(EFalse);
  	// Set correct skin text colors for the list items
   	TRgb focusedColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor();
   	TRgb normalColor = iAppUi.LayoutHandler()->ListNodeTextColor();
    aNodeVisualizer->SetFocusedStateTextColor( focusedColor );
    aNodeVisualizer->SetNormalStateTextColor( normalColor );
	// Set font height
	aNodeVisualizer->SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() );
	// Set font always bolded in nodes
	aNodeVisualizer->SetTextBold( ETrue );

    //<cmail>
    CAlfBrush* titleDividerBgBrush =
        iAppUi.FsTextureManager()->TitleDividerBgBrushL();
    // ownership is not transfered
	aNodeVisualizer->SetBackgroundBrush( titleDividerBgBrush );
    //</cmail>

	CleanupStack::Pop( aNodeVisualizer );
	CleanupStack::Pop( aItemData );
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleDynamicVariantSwitchL(
    CFsEmailUiViewBase::TDynamicSwitchType aType )
	{
    FUNC_LOG;
    CFsEmailUiViewBase::HandleDynamicVariantSwitchL( aType );

    if ( iFirstStartCompleted ) // Safety
        {
        if ( aType == EScreenLayoutChanged )
        	{
            SetStatusBarLayout();
            UpdateButtonTextsL();
        	}

        if ( aType == ESkinChanged )
            {
            UpdateTheme();
            }
        else
            {
            iMailTreeListVisualizer->HideList();
            // screen layout changed
            iCurrentClientRect = iAppUi.ClientRect();
            iScreenAnchorLayout->SetSize( iCurrentClientRect.Size() );
            SetMailListLayoutAnchors();
            // Set branded watermark
            SetBrandedListWatermarkL();
            iMailTreeListVisualizer->ShowListL();

            ScaleControlBarL();
            SetBrandedMailBoxIconL();
            }
        // Update the folder/sort popup layout in case it happened to be open
        if ( iAppUi.FolderList().IsPopupShown() )
            {
            iAppUi.FolderList().HandleDynamicVariantSwitchL( aType );
            }
        }
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleDynamicVariantSwitchOnBackgroundL(
        CFsEmailUiViewBase::TDynamicSwitchType aType )
    {
    FUNC_LOG;
    CFsEmailUiViewBase::HandleDynamicVariantSwitchOnBackgroundL( aType );
    if ( aType == ESkinChanged )
        {
        UpdateTheme();
        }
    else if ( aType == EScreenLayoutChanged )
        {
        UpdateButtonTextsL();
        }
    }

// ---------------------------------------------------------------------------
// Update texts for command area buttons
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateButtonTextsL()
    {
    if ( !Layout_Meta_Data::IsLandscapeOrientation() )
        {
        // No texts in portrait mode
        iNewEmailButton->SetTextL( KNullDesC() );
        iSortButton->SetTextL( KNullDesC() );
        }
    else
        {
        // Set button text if necessary
        HBufC* buttonText = GetSortButtonTextLC();
        if ( buttonText )
            {
            iSortButton->SetTextL( *buttonText );
            CleanupStack::PopAndDestroy( buttonText );
            }

        iNewEmailButton->SetTextL( *iNewEmailText );
        }
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::HitTest(
        const CAlfControl& aControl, const TPoint& aPoint ) const
    {
    FUNC_LOG;
    TBool contains( EFalse );
    const TInt visualCount( aControl.VisualCount() );
    for( TInt index( 0 ); index < visualCount && !contains; ++index )
        {
        TRect rect( aControl.Visual( index ).DisplayRectTarget() );
        if( rect.Contains( aPoint ) )
            {
            contains = ETrue;
            }
        }
    return contains;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::HandleArrowEventInPortraitL(
        const TInt aScancode,
        const TAlfEvent& aEvent,
        const TBool aShiftState )
    {
    FUNC_LOG;
    TBool result( EFalse );

    if( aScancode == EStdKeyLeftArrow )
        {
        if( ( iControlBarControl ) &&
            ( iFocusedControl == EMailListComponent ) )
            {
            // Move focus to control bar (focused button is
            // sort button).
            HandleCommandL( EFsEmailUiCmdGoToSwitchSorting );
            result = ETrue;
            }
        else if( ( iControlBarControl ) &&
                 ( iFocusedControl == EControlBarComponent  ) )
            {
            TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() );
            if ( focusedButtonId == iNewEmailButtonId )
                {
                // Change focus to mail list if there are any
                // emails in it.
                if( iModel->Count() )
                    {
                    iFocusedControl = EMailListComponent;
                    result = EFalse;
                    }
                // Leave focus to control bar because there are no
                // mails in mail list.
                else
                    {
                    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                    iFocusedControl = EControlBarComponent;
                    result = ETrue; // Do not set focus to empty list
                    }
                }
            else
                {
                iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                iFocusedControl = EControlBarComponent;
                result = EFalse;
                }
            }
        else
            {
            iFocusedControl = EMailListComponent;
            result = EFalse;
            }
        SetMskL();
        }
    else if( aScancode == EStdKeyRightArrow )
        {
        // Show toolbar if there is data on the list
        const TInt modelCount( iModel->Count() );
        TBool focusShown( IsFocusShown() );

        // If control bar is focused.
        if( ( iControlBarControl ) &&
            ( iFocusedControl == EControlBarComponent ) )
            {
            TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() );

            // If sort button is focused and there are mails in mail
            // list then focus is moved to mail list, otherwise
            // leave focus to control bar
            if( focusedButtonId == iSortButtonId )
                {
                if ( modelCount > 0 ) // Check for empty folder
                    {
                    iFocusedControl = EMailListComponent;
                    result = EFalse;
                    }
                else
                    {
                    iFocusedControl = EControlBarComponent;
                    iControlBarControl->MakeSelectorVisible( focusShown );
                    result = ETrue; // Do not set focus to empty list
                    }
                }
            else
                {
                iFocusedControl = EControlBarComponent;
                iControlBarControl->MakeSelectorVisible( focusShown );
                result = EFalse;
                }
            }
        else if( ( iControlBarControl ) &&
                 ( iFocusedControl == EMailListComponent ) )
            {
            HandleCommandL( EFsEmailUiCmdGoToSwitchNewEmail );
            result = ETrue;
            }
        else
            {
            iFocusedControl = EMailListComponent;
            result = EFalse;
            }
        SetMskL();
        }
    else if( aScancode ==  EStdKeyDownArrow )
        {
        const TInt itemCount( iModel->Count() );
        if ( iFocusedControl == EMailListComponent )
            {
            result = iMailList->TreeControl()->OfferEventL( aEvent );
            if ( aShiftState )
                {
                DoScrollMarkUnmarkL(); // marking is done after moving the cursor
                }
            }
        else if( ( iFocusedControl == EControlBarComponent ) &&
                 ( itemCount == 0 ) )
            {
            result = ETrue; // Do not set focus to empty list
            }
        else if( ( iFocusedControl == EControlBarComponent ) &&
                 ( itemCount > 0 ) )
            {
            iFocusedControl = EMailListComponent;

            result = iMailList->TreeControl()->OfferEventL(aEvent);
            if ( aShiftState )
                {
                DoScrollMarkUnmarkL(); // marking is done after moving the cursor
                }
            }
        else
            {
            result = EFalse;
            }
        SetMskL();
        }
    else if( aScancode == EStdKeyUpArrow )
        {
        iControlBarControl->MakeSelectorVisible( IsFocusShown() );
        if ( iFocusedControl == EMailListComponent )
            {
            if ( HighlightedIndex() == 0 )
                {
                HandleCommandL( EFsEmailUiCmdGoToSwitchFolder );
                result = ETrue;
                }
            else
                {
                result = iMailList->TreeControl()->OfferEventL( aEvent );
                if ( aShiftState )
                    {
                    // marking is done after moving the cursor
                    DoScrollMarkUnmarkL();
                    }
                SetMskL();
                }
            }
        else if( iFocusedControl == EControlBarComponent )
            {
            result = ETrue;
            }
        else
            {
            result = EFalse;
            }
        }

    return result;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::HandleArrowEventInLandscapeL(
        const TInt aScancode,
        const TAlfEvent& aEvent,
        const TBool aShiftState )
    {
    FUNC_LOG;
    TBool result( EFalse );
    if( aScancode == EStdKeyRightArrow )
        {
        if ( iFocusedControl == EMailListComponent )
            {
            HandleCommandL( EFsEmailUiCmdGoToSwitchFolder );
            result = ETrue;
            }
        else if( iFocusedControl == EControlBarComponent )
            {
            iControlBarControl->MakeSelectorVisible( IsFocusShown() );
            result = ETrue;
            }
        }
    else if( aScancode == EStdKeyLeftArrow )
        {
        if ( iFocusedControl == EControlBarComponent )
            {
            const TInt modelCount( iModel->Count() );
            if( modelCount > 0 )
                {
                iFocusedControl = EMailListComponent;
                result = iMailList->TreeControl()->OfferEventL( aEvent );
                if( aShiftState )
                    {
                    // marking is done after moving the cursor
                    DoScrollMarkUnmarkL();
                    }
                }
            else
                {
                iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                // Do not set focus to empty list
                result = ETrue;
                }
            }
        else if( iFocusedControl == EMailListComponent )
            {
            result = iMailList->TreeControl()->OfferEventL( aEvent );
            if ( aShiftState )
                {
                // marking is done after moving the cursor
                DoScrollMarkUnmarkL();
                }
           }
        SetMskL();
        }
    if( aScancode == EStdKeyUpArrow )
        {
        if( iFocusedControl == EMailListComponent )
            {
            result = iMailList->TreeControl()->OfferEventL( aEvent );
            if ( aShiftState )
                {
                // marking is done after moving the cursor
                DoScrollMarkUnmarkL();
                }
            }
        else if( iFocusedControl == EControlBarComponent )
            {
            TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() );
            if ( focusedButtonId == iNewEmailButtonId )
                {
                // Change focus to mail list if there are any
                // mails in it.
                if( iModel->Count() > 0 )
                    {
                    iFocusedControl = EMailListComponent;
                    result = EFalse;
                    }
                // Leave focus to control bar because there are no
                // mails in mail list.
                else
                    {
                    // Do not set focus to empty list
                    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                    result = ETrue;
                    }
                }
            else
                {
                iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                result = static_cast<CAlfControl*>( iControlBarControl )->OfferEventL( aEvent );
                }
            }
        SetMskL();
        }
    else if( aScancode == EStdKeyDownArrow )
        {
        if( iFocusedControl == EMailListComponent )
            {
            result = iMailList->TreeControl()->OfferEventL( aEvent );
            if( aShiftState )
                {
                // marking is done after moving the cursor
                DoScrollMarkUnmarkL();
                }
            }
        else if( iFocusedControl == EControlBarComponent )
            {
            const TInt modelCount( iModel->Count() );
            TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() );
            // If sort button is focused and there are mails in mail
            // list then focus is moved to mail list, otherwise
            // leave focus to control bar
            if( focusedButtonId == iSortButtonId )
                {
                if ( modelCount > 0 ) // Check for empty folder
                    {
                    iFocusedControl = EMailListComponent;
                    result = EFalse;
                    }
                else
                    {
                    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                    result = ETrue; // Do not set focus to empty list
                    }
                }
            else
                {
                iControlBarControl->MakeSelectorVisible( IsFocusShown() );
                result = static_cast<CAlfControl*>( iControlBarControl )->OfferEventL( aEvent );
                }
            }
        SetMskL();
        }

    return result;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateTheme(const TBool aSystemUpdate)
    {
    iSkinChanged = aSystemUpdate;

    TRgb focusedTextColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor();
    TRgb normalTextColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor();

    iNewEmailButton->SetNormalTextColor( normalTextColor );
    iNewEmailButton->SetFocusedTextColor( focusedTextColor );

    iFolderListButton->SetNormalTextColor( normalTextColor );
    iFolderListButton->SetFocusedTextColor( focusedTextColor );

    iSortButton->SetNormalTextColor( normalTextColor );
    iSortButton->SetFocusedTextColor( focusedTextColor );
    }

// ---------------------------------------------------------------------------
// HandleForegroundEventL
// Function checks in foregroundevent that whether settings have changed and
// If there is a need to refresh the list.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleForegroundEventL( TBool aForeground )
	{
    FUNC_LOG;
    if( iMailFolder )
        {
        //emailindicator handling, we dont care if something goes wrong in the mailindicator update. User can still open the mailbox
        TRAP_IGNORE(TFsEmailStatusPaneIndicatorHandler::StatusPaneMailIndicatorHandlingL( iMailFolder->GetMailBoxId().Id()));
        //Update mailbox widget index status in homescreen
        TFsEmailUiUtility::ToggleEmailIconL(EFalse, iMailFolder->GetMailBoxId() );
        }
    
	if ( aForeground && iFirstStartCompleted ) // Safety
	    {
	    // Update mail list settings and date formats, is done every time
	    // the user might have changed these in settings, so the list needs to refresh
	    // Store previous modes
	    TInt prevListMode = iListMode;
	    TInt prevNodesmode = iNodesInUse;
	    TAknUiZoom prevZoomLevel = iCurrentZoomLevel;
	    STimeDateFormats prevDateFormats = MailListTimeDateSettings();

	    // Get new settings and list drawing modes
	    CAknEnv::Static()->GetCurrentGlobalUiZoom( iCurrentZoomLevel );
	    UpdateMailListSettingsL();
	    UpdateMailListTimeDateSettings();

	    // Check sync icon timer and sync status
	    ConnectionIconHandling();

	    // Updates the folder list's size after the screensaver
	    iAppUi.FolderList().HandleForegroundEventL();

	    // Check for changed settings, in that case a complete list refresh is needed
	    if ( iSkinChanged
	         || iDateChanged
	         || iListMode != prevListMode
	         || iNodesInUse != prevNodesmode
	         || iCurrentZoomLevel != prevZoomLevel
	         || prevDateFormats.iDateFormat != iDateFormats.iDateFormat
	         || prevDateFormats.iTimeFormat != iDateFormats.iTimeFormat
	         || prevDateFormats.iAmPmPosition != iDateFormats.iAmPmPosition
	         || prevDateFormats.iDateSeparator != iDateFormats.iDateSeparator
	         || prevDateFormats.iTimeSeparator != iDateFormats.iTimeSeparator )
	        {
	        // Store the list of marked items. The markings are erased when the list
	        // is repopulated and, hence, the markings need to be reset after the
	        // refreshing is done. The marked items must be identified by the message
	        // ID rather than with the list ID because refreshing may change the list IDs.
	        RArray<TFSMailMsgId> markedMessages;
	        CleanupClosePushL( markedMessages );
	        GetMarkedMessagesL( markedMessages );
	        // Store the message ID of the focused item
	        TFSMailMsgId msgIdBeforeRefresh = MsgIdFromListId( iMailList->FocusedItem() );
	        TFsTreeItemId firstVisibleListId = iMailTreeListVisualizer->FirstVisibleItem();
	        TInt modelFirstIndexBeforeUpdate = ModelIndexFromListId( firstVisibleListId );
	        TInt highlightedIndexBeforeUpdate = HighlightedIndex();
	        TInt modelCountBeforeUpdate = iModel->Count();

	        UpdateMailListModelL();
	        if ( markedMessages.Count() )
	            {
	            RefreshL( &msgIdBeforeRefresh );
	            // Restore the marking status
	            MarkMessagesIfFoundL( markedMessages );
	            }
	        else
	            {
	            RefreshDeferred( &msgIdBeforeRefresh );
	            }
	        CleanupStack::PopAndDestroy( &markedMessages );
	        iSkinChanged = EFalse; // Toggle handled
	        iDateChanged = EFalse; // Toggle handled
	        }
	    }
	}


// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleCommandL( TInt aCommand )
    {
    FUNC_LOG;
    TIMESTAMP( "Message list command for handling" );
    CompletePendingRefresh();

    // custom command handling for launching plugin settings
   	if ( EFsEmailUiCmdSettingsBaseCommandId <= aCommand
   		 && EFsEmailUiCmdSettingsBaseCommandIdMax > aCommand )
   		{
		CESMailSettingsPlugin::TSubViewActivationData activationData;
		activationData.iAccount = iAppUi.GetActiveMailbox()->GetId();
		// which settings plugin subview will be activated
		TInt selectedCommand = aCommand - EFsEmailUiCmdSettingsBaseCommandId;
		activationData.iSubviewId = selectedCommand;

		TUid pluginUid = iAppUi.GetActiveMailbox()->GetSettingsUid();

        // If plugin view does not exist, create and register it to app ui.
        if ( !iAppUi.View( pluginUid ) )
            {
            CESMailSettingsPlugin* plugin = CESMailSettingsPlugin::NewL( pluginUid );
            CleanupStack::PushL( plugin );
            iAppUi.AddViewL( plugin ); // Ownership is transferred.
            CleanupStack::Pop( plugin );
            }
   		TUid messageId = TUid::Uid( CESMailSettingsPlugin::EActivateMailSettingsSubview );
		const TPckgBuf<CESMailSettingsPlugin::TSubViewActivationData> pluginMessagePkg( activationData );

        StatusPane()->SwitchLayoutL( R_AVKON_STATUS_PANE_LAYOUT_USUAL );
        iAppUi.EnterPluginSettingsViewL( pluginUid, messageId, pluginMessagePkg );
   		}

   	// Many commands may be targetted either to the focused item or to the marked item(s).
   	// Get list of marked or focused items.
    RFsTreeItemIdList actionTargetItems;
    CleanupClosePushL( actionTargetItems );
    GetActionsTargetEntriesL( actionTargetItems );

    // Check if the focus needs to be removed.
    if ( ( iStylusPopUpMenuVisible ) &&
         ( aCommand == KErrCancel ||
           aCommand == EFsEmailUiCmdActionsDelete ||
    	   aCommand == EFsEmailUiCmdMarkAsRead ||
    	   aCommand == EFsEmailUiCmdMarkAsUnread ||
    	   aCommand == EFsEmailUiCmdActionsMove ||
    	   aCommand == EFsEmailUiCmdActionsMoveMessage ||
    	   aCommand == EFsEmailUiCmdMarkUnmarkToggle ||
    	   aCommand == EFsEmailUiCmdActionsCollapseAll ||
    	   aCommand == EFsEmailUiCmdActionsExpandAll ) )
    	{
   		// We end up here if the user selects an option from the pop up menu
    	// or exits the menu by tapping outside of it's area.
    	// Remove the focus from a list item if an item is focused.
    	iStylusPopUpMenuVisible = EFalse;
    	iAppUi.SetFocusVisibility( EFalse );
    	}

    switch( aCommand )
        {
    	case EAknSoftkeyOpen:
            {
            TIMESTAMP( "Open email selected from message list" );
            if( !iAppUi.IsFocusShown() )
                {
                iAppUi.SetFocusVisibility( ETrue );
                break;
                }
            }
       	case EAknSoftkeySelect:
       	    {
       	    TIMESTAMP( "Open email selected from message list" );
       	    if ( iFocusedControl == EMailListComponent )
       	        {
       	        CFSEmailUiMailListModelItem* item = dynamic_cast<CFSEmailUiMailListModelItem*>(iModel->Item(HighlightedIndex()));
       	        // MAIL ITEM; OPEN MAIL
       	        if ( item && item->ModelItemType() == ETypeMailItem )
       	            {
       	            CFSMailMessage* messagePtr = &item->MessagePtr();
       	            if ( messagePtr )
       	                {
       	                OpenHighlightedMailL();
       	                }
       	            }
       	        }
       	    }
       	    break;
       	case EAknSoftkeyChange:
       	    {
    		if( !iAppUi.IsFocusShown() )
    			{
    			iAppUi.SetFocusVisibility( ETrue );
    			break;
    			}
       	    if( iFocusedControl == EControlBarComponent )
       	        {
       	        TInt focusedButtonId = iControlBarControl->GetFocusedButton()->Id();
       	        if ( focusedButtonId == iFolderListButtonId )
       	            {
                    //<cmail>
                    //Set touchmanager not active for preventing getting events.
                    DisableMailList(ETrue);
                    //</cmail>
       	            iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton );
       	            }
       	        else if( focusedButtonId == iSortButtonId )
       	            {
       	            TFSFolderType folderType;
       	            if( iMailFolder )
       	                {
       	                folderType = iMailFolder->GetFolderType();
       	                }
       	            else
       	                {
       	                folderType = EFSInbox;
       	                }
                    // <cmail> Sorting set possible even for empty mailbox
                    // Show sort if model has data.
                    //if ( iModel->Count() )
                    //    {
                    // </cmail>
                        //<cmail>
                        //Set touchmanager not active for preventing getting events.
                        DisableMailList(ETrue);
                        //</cmail>
                        iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton );
                    // <cmail>
                    //    }
                    // </cmail>
       	            }
       	        }
       	    }
       	    break;
        case EAknSoftkeyBack:
       		if ( !iAppUi.ViewSwitchingOngoing() )
				{
				NavigateBackL();
				}
        	break;
        case EEikCmdExit:
        case EAknSoftkeyExit:
        case EFsEmailUiCmdExit:
            TIMESTAMP( "Exit selected from message list" );
            iAppUi.Exit();
            break;
       	case EFsEmailUiCmdCalActionsReplyAsMail:
		case EFsEmailUiCmdActionsReply:
			{
			TIMESTAMP( "Reply to selected from message list" );
   	   	 	ReplyL( NULL ); // Function will check marked/highlighted msg
			}
            break;
		case EFsEmailUiCmdActionsReplyAll:
			{
			TIMESTAMP( "Reply to all selected from message list" );
			ReplyAllL( NULL ); // Function will check marked/highlighted msg
			}
            break;
       	case EFsEmailUiCmdCalActionsForwardAsMail:
		case EFsEmailUiCmdActionsForward:
			{
			TIMESTAMP( "Forward selected from message list" );
           	ForwardL( NULL ); // Function will check marked/highlighted msg
			}
            break;
       	case EFsEmailUiCmdActionsCallSender:
			{
       		if ( !iAppUi.ViewSwitchingOngoing() )
				{
				if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox &&
					 iMailFolder->GetFolderType() != EFSDraftsFolder )
					{
					// Calling can happen only when there's exactly one message marked or in focus
					if ( actionTargetItems.Count() == 1 )
						{
						CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] );
						CFSMailAddress* fromAddress = message.GetSender();
						TDesC* mailAddress(0);
						if ( fromAddress )
						    {
						    mailAddress = &fromAddress->GetEmailAddress();
						    }
						if ( mailAddress && mailAddress->Length() )
						    {
						    if ( iMailFolder->GetFolderType() == EFSSentFolder )
						        {
	                            CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL(
	                                    *mailAddress, iAppUi.GetActiveMailbox(), this, EFalse );
						        }
						    else
						        {
                                CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL(
                                        *mailAddress, iAppUi.GetActiveMailbox(), this, ETrue );
						        }
						    }
						}
					}
				}
			}
			break;
        case EFsEmailUiCmdMarkAsRead:
        	{
			// Change status of marked or highlighted
			if ( CountMarkedItemsL() )
				{
				ChangeReadStatusOfMarkedL( ETrue );
				}
			else
				{
                ChangeReadStatusOfHighlightedL( ETrue );
				}
        	}
        	break;
        case EFsEmailUiCmdMarkAsUnread:
        	{
            // Change status of marked or highlighted
			if ( CountMarkedItemsL() )
				{
				ChangeReadStatusOfMarkedL( EFalse );
				}
			else
				{
                ChangeReadStatusOfHighlightedL( EFalse );
				}
        	}
			break;
		case EFsEmailUiCmdGoToTop:
			{
			// Safety check, ignore command if the list is empty
			if( iTreeItemArray.Count() )
			    {
	            if ( iFocusedControl != EMailListComponent )
	                {
	                iFocusedControl = EMailListComponent;
	                iMailList->SetFocusedL( ETrue );
	                iControlBarControl->SetFocusL( EFalse );
	                }
	            // No need to check for nodes as in move to bottom.
	            iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[0].iListItemId );
			    }
            }
            break;
		case EFsEmailUiCmdGoToBottom:
			{
	         // Safety check, ignore command if the list is empty
            if( iTreeItemArray.Count() )
                {
             	if ( iFocusedControl != EMailListComponent )
            		{
            		iFocusedControl = EMailListComponent;
            		iMailList->SetFocusedL( ETrue );
            		iControlBarControl->SetFocusL( EFalse );
            		}

    		 	TFsTreeItemId bottomItem = iTreeItemArray[iTreeItemArray.Count()-1].iListItemId;
    		 	TFsTreeItemId parentItem = ParentNode( bottomItem ); // parent node of the bottom item

    			// Check whether the parent is node and is collapsed
    			if ( parentItem>0 && !iMailList->IsExpanded( parentItem ) )
    				{
    				bottomItem = parentItem;
    				}
    	       	iMailTreeListVisualizer->SetFocusedItemL( bottomItem );
                }
   			}
            break;
        case EFsEmailUiCmdPageUp:
            {
            TKeyEvent simEvent = { EKeyPageUp, EStdKeyPageUp, 0, 0 };
            iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
            }
            break;
        case EFsEmailUiCmdPageDown:
            {
            TKeyEvent simEvent = { EKeyPageDown, EStdKeyPageDown, 0, 0 };
            iCoeEnv->SimulateKeyEventL( simEvent, EEventKey );
            }
            break;
       	case EFsEmailUiCmdActionsDeleteCalEvent:
		case EFsEmailUiCmdActionsDelete:
			{
			TIMESTAMP( "Delete to selected from message list" );
			TInt index = HighlightedIndex();
			CFSEmailUiMailListModelItem* item =
				dynamic_cast<CFSEmailUiMailListModelItem*>(
						iModel->Item( index ) );

			// If selected item is separator (divider) mark/unmark all messages
			// under it.

			// Delete message only if mail list component is focused
			// or if there are some marked items
			TInt markedItems( CountMarkedItemsL() );
            const TBool isNode(iMailList->IsNode(iMailList->FocusedItem()));
            if (iFocusedControl == EMailListComponent || markedItems
                    || isNode)
                {
                DeleteMessagesL();
                }
            }
            break;
		case EFsEmailUiCmdCompose:
			{
			TIMESTAMP( "Create new message selected from message list" );
			CreateNewMsgL();
			}
			break;
       	case EFsEmailUiCmdMessageDetails:
			{
            // Message details can be viewed only when there's exactly one message marked or in focus
            if ( actionTargetItems.Count() == 1 )
                {
                CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] );
	  			TMsgDetailsActivationData msgDetailsData;
	  			msgDetailsData.iMailBoxId = iAppUi.GetActiveMailboxId();
	  			msgDetailsData.iFolderId = FolderId();
	  			msgDetailsData.iMessageId = message.GetMessageId();
				const TPckgBuf<TMsgDetailsActivationData> pkgOut( msgDetailsData );
				iAppUi.EnterFsEmailViewL( MsgDetailsViewId, KStartMsgDetailsToBeginning, pkgOut );
				}
			}
			break;
       	case EFsEmailUiCmdSettingsGlobal:
       		{
  			iAppUi.EnterFsEmailViewL( GlobalSettingsViewId );
       		}
       		break;
       	case EFsEmailUiCmdSettingsService:
       	case EFsEmailUiCmdSettingsMailbox:
       		{
			CESMailSettingsPlugin::TSubViewActivationData activationData;
			activationData.iAccount = iAppUi.GetActiveMailbox()->GetId();
			activationData.iSubviewId = 0;
			if ( EFsEmailUiCmdSettingsService == aCommand )
		 		{
				activationData.iSubviewId = 1;
				}

			TUid pluginUid = iAppUi.GetActiveMailbox()->GetSettingsUid();
			// register plugin view if not exists so that activation can be made
			if ( !iAppUi.View( pluginUid ) )
				{
				CESMailSettingsPlugin* plugin = CESMailSettingsPlugin::NewL( pluginUid );
				CleanupStack::PushL( plugin );
				iAppUi.AddViewL( plugin );
				CleanupStack::Pop( plugin );
				}
       		TUid messageId = TUid::Uid( CESMailSettingsPlugin::EActivateMailSettingsSubview );
			const TPckgBuf<CESMailSettingsPlugin::TSubViewActivationData> pluginMessagePkg( activationData );
			iAppUi.EnterPluginSettingsViewL( pluginUid, messageId, pluginMessagePkg );
       		}
       		break;
       	case EFsEmailUiCmdOpen:
        case EFsEmailUiCmdActionsOpen:
        	{
        	TIMESTAMP( "Open email selected from message list" );
	        if ( iFocusedControl == EMailListComponent )
	            {
	            // Opening can happen only when there's exactly one message marked or in focus
	            if ( actionTargetItems.Count() == 1 )
	                {
	                OpenMailItemL( actionTargetItems[0] );
	                }
	            }
			}
        	break;
        case EFsEmailUiCmdActionsFlag:
	        {
            SetMessageFollowupFlagL();
	        }
	        break;
        case EFsEmailUiCmdActionsCollapseAll:
            // Safety check, ignore command if the list is empty
            if( iMailList->Count() )
                {
            	CollapseAllNodesL();
                }
        	break;
       	case EFsEmailUiCmdActionsExpandAll:
       	    // Safety check, ignore command if the list is empty
       	    if( iMailList->Count() )
       	        {
           		ExpandAllNodesL();
                }
			break;
        case EFsEmailUiCmdCollapse:
    		if( !iAppUi.IsFocusShown() )
    			{
    			iAppUi.SetFocusVisibility( ETrue );
    			break;
    			}
            // Safety check, ignore command if the list is empty
            if( iMailList->Count() )
                {
                ExpandOrCollapseL();
                }
            break;
        case EFsEmailUiCmdExpand:
    		if( !iAppUi.IsFocusShown() )
    			{
    			iAppUi.SetFocusVisibility( ETrue );
    			break;
    			}
            // Safety check, ignore command if the list is empty
            if( iMailList->Count() )
                {
                ExpandOrCollapseL();
                }
            break;
        case EFsEmailUiCmdSearch:
        	{
			TSearchListActivationData tmp;
			tmp.iMailBoxId = iAppUi.GetActiveMailbox()->GetId();
			const TPckgBuf<TSearchListActivationData> pkgOut( tmp );
			iAppUi.EnterFsEmailViewL( SearchListViewId, KStartNewSearch, pkgOut );
        	}
        	break;
// <cmail> Prevent Download Manager opening with attachments
//       	case EFsEmailUiCmdDownloadManager:
//  			iAppUi.EnterFsEmailViewL( DownloadManagerViewId );
//			break;
// </cmail>
       	case EFsEmailUiCmdMarkMark:
       		{
            iListMarkItemsState = ETrue; // shift-scrolling does marking after one item is marked
  	        iMailList->MarkItemL( iMailList->FocusedItem(), ETrue );
       		}
			break;
		case EFsEmailUiCmdMarkMarkAll:
			{
			MarkAllItemsL();
			}
			break;
		case EFsEmailUiCmdMarkUnmark:
			{
            iListMarkItemsState = EFalse; // shift-scrolling does unmarking after one item is unmarked
  	        iMailList->MarkItemL( iMailList->FocusedItem(), EFalse );
			}
			break;
		case EFsEmailUiCmdMarkUnmarkAll:
			{
			UnmarkAllItemsL();
			}
			break;

		case EFsEmailUiCmdMarkSubAll:
			{
			MarkAllItemsL();
			}
			break;
		case EFsEmailUiCmdUnmarkSubAll:
			{
			UnmarkAllItemsL();
			}
			break;
		case EFsEmailUiCmdReadEmail:
			{
			iAppUi.StartReadingEmailsL();
			}
			break;
       	case EFsEmailUiCmdSync:
			{
			TBool supportsSync = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaSupportsSync );
			if ( supportsSync )
			    {
			    //If synchronizing is ongoing and a new sync is started we ignore it
			    if(!GetLatestSyncState())
			        {
			        iAppUi.SyncActiveMailBoxL();
			        // Sync was started by the user
			        ManualMailBoxSync(ETrue);
                    iAppUi.ManualMailBoxSync( ETrue );
			        }
			    }
			  else
			    {
			    //POP3 synchronise
				iAppUi.DoAutoConnectL();
				}
			}
			break;
       	case EFsEmailUiCmdCancelSync:
       		{
            TBool supportsSync = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaSupportsSync );
            if ( supportsSync )
		       {
	            iAppUi.StopActiveMailBoxSyncL();
	            // Sync was started by the user
	            ManualMailBoxSync(ETrue);
	            iAppUi.ManualMailBoxSync( ETrue );
                }
		     else
		        {
		         //POP3
                 iAppUi.GetActiveMailbox()->GoOfflineL();
                }
       		}
       		break;
        case EFsEmailUiCmdGoOffline:
        	{
    	   	iAppUi.GetActiveMailbox()->GoOfflineL();
        	}
        	break;
        case EFsEmailUiCmdGoOnline:
        	{
			CFSMailBox* mb = iAppUi.GetActiveMailbox();
            iAppUi.ManualMailBoxSync( ETrue );
        	mb->GoOnlineL();
        	}
        	break;
       	case EFsEmailUiCmdHelp:
			{

			TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID );
			}
			break;


    	case EFsEmailUiCmdActionsAddContact:
    		{
    		// contact can be got from message only when there's exactly one target message
    		if ( actionTargetItems.Count() == 1 && iMailFolder )
				{
				CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] );

				CFSMailAddress* addressToBeStored(0);
				TInt folderType = iMailFolder->GetFolderType();
				// Use first to recepient in outbox, drafts and sent if found.
				if ( folderType == EFSOutbox || folderType == EFSDraftsFolder || folderType == EFSSentFolder )
				    {
				    RPointerArray<CFSMailAddress>& toArray = message.GetToRecipients();
				    if ( toArray.Count() )
				        {
				        addressToBeStored = toArray[0];
				        }
				    }
				// Use sender in all other "normal" folders
				else
				    {
				    addressToBeStored = message.GetSender();
				    }
				TDesC* emailAddressText(0);
				if ( addressToBeStored )
				    {
				    emailAddressText = &addressToBeStored->GetEmailAddress();
				    }
				if ( emailAddressText && emailAddressText->Length() )
				    {
				    TAddToContactsType type;
				    //Query to "update existing" or "Create new" --> EFALSE = user choosed "cancel"
				    if ( CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddtoContactsQueryL( type ) )
				        {
				        CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddToContactL(
				                *emailAddressText, EContactUpdateEmail, type, this );
				        }
				    }
				}
    		}
			break;
       	case EFsEmailUiCmdActionsMove:
       	case EFsEmailUiCmdActionsMoveMessage:
			{
			TFSMailMsgId folderID;
			folderID.SetNullId(); // Selection is popped up with NULL
			MoveMsgsToFolderL( folderID );
			}
			break;
       	case EFsEmailUiCmdActionsMoveToDrafts:
			{
			MoveMessagesToDraftsL();
			}
			break;
        case EFsEmailUiCmdActionsCopyMessage:
            {
            }
            break;
        case EFsEmailUiCmdActionsCollapseExpandAllToggle:
            {
           	ShortcutCollapseExpandAllToggleL();
            }
            break;
        case EFsEmailUiCmdMarkAsReadUnreadToggle:
            {
			ShortcutReadUnreadToggleL();
            }
            break;
        case EFsEmailUiCmdMarkUnmarkToggle:
            {
            TInt focusedItem = iMailList->FocusedItem();
            if ( focusedItem > 0 && iFocusedControl == EMailListComponent )
                {
                CFSEmailUiMailListModelItem* item = dynamic_cast<CFSEmailUiMailListModelItem*>(iModel->Item(HighlightedIndex()));
				if ( item && item->ModelItemType() == ETypeMailItem )
				    {
                    if ( iMailList->IsMarked( focusedItem ) )
                        {
                        HandleCommandL(EFsEmailUiCmdMarkUnmark);
                        }
                    else
                        {
                        HandleCommandL(EFsEmailUiCmdMarkMark);
                        }
					}
				else if ( item && item->ModelItemType() == ETypeSeparator )
					{
					// Currently only mark is done since mark should activate
					// marking mode for messages. Unmark can be done via message long tap menu.
					TInt index = HighlightedIndex();
					MarkItemsUnderSeparatorL( ETrue, index );
					}
                }
            }
            break;
        case EFsEmailUiCmdGoToSwitchFolder:
            {
            iControlBarControl->SetFocusByIdL( iFolderListButtonId );
            iControlBarControl->MakeSelectorVisible( IsFocusShown() );
            iFocusedControl = EControlBarComponent;
            iMailList->SetFocusedL( EFalse );
            }
            break;
        case EFsEmailUiCmdGoToSwitchSorting:
            {
            iControlBarControl->SetFocusByIdL( iSortButtonId );
            iControlBarControl->MakeSelectorVisible( IsFocusShown() );
            iFocusedControl = EControlBarComponent;
           	iMailList->SetFocusedL( EFalse );
            }
            break;
        case EFsEmailUiCmdGoToSwitchNewEmail:
            {
            iControlBarControl->SetFocusByIdL( iNewEmailButtonId );
            iControlBarControl->MakeSelectorVisible( IsFocusShown() );
            iFocusedControl = EControlBarComponent;
            iMailList->SetFocusedL( EFalse );
            break;
            }
        case EFsEmailUiCmdCalActionsAccept:
        case EFsEmailUiCmdCalActionsTentative:
        case EFsEmailUiCmdCalActionsDecline:
        case EFsEmailUiCmdCalRemoveFromCalendar:
			{
			if ( actionTargetItems.Count() == 1 )
                {
                TInt mrItemIdx = ModelIndexFromListId( actionTargetItems[0] );
                CFSEmailUiMailListModelItem* item =
                    dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item(mrItemIdx) );
                if ( item && item->MessagePtr().IsFlagSet( EFSMsgFlag_CalendarMsg ) )
                    {
                    // Respond to meeting request
                    if (  iAppUi.MrViewerInstanceL() &&  iAppUi.MrViewerInstanceL()->CanViewMessage( item->MessagePtr() ) )
                        {
                        ChangeReadStatusOfHighlightedL( ETrue );
                        iAppUi.MailViewer().HandleMrCommandL( aCommand,
                                                              iAppUi.GetActiveMailbox()->GetId(),
                                                              FolderId(),
                                                              item->MessagePtr().GetMessageId() );
                        }
                    }
			    }
			}
			break;
       	case EFsEmailUiCmdActionsEmptyDeleted:
       		{
       		// <cmail>
            if ( iMailFolder && iMailFolder->GetFolderType() == EFSDeleted &&
       			 iModel->Count() != 0 )
       		// </cmail>
       			{
    			TBool okToDelete( EFalse );
				HBufC* msg = StringLoader::LoadLC( R_FREESTYLE_EMAIL_QUERY_NOTE_PERMANENTLY_DELETE );
 	    		CAknQueryDialog *queryNote = new ( ELeave ) CAknQueryDialog();
				CleanupStack::PushL( queryNote );
				queryNote->SetPromptL( *msg );
				CleanupStack::Pop( queryNote );
				CleanupStack::PopAndDestroy( msg );
				okToDelete = queryNote->ExecuteLD( R_FSEMAIL_QUERY_DIALOG );
				if ( okToDelete )
 					{
					// Empty deleted items folder
					RArray<TFSMailMsgId> msgIds;
					CleanupClosePushL( msgIds );
					for ( TInt i=0 ; i<iModel->Count();i++ )
						{
						CFSEmailUiMailListModelItem* item =
	    					static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(i));
	    				if ( item && item->ModelItemType() == ETypeMailItem )
	    					{
							msgIds.Append( item->MessagePtr().GetMessageId() );
	    					}
						}
					TFSMailMsgId folderId = FolderId();
					TFSMailMsgId mailBox = iAppUi.GetActiveMailbox()->GetId();
					iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds );
		            RemoveMsgItemsFromListIfFoundL( msgIds );
					CleanupStack::PopAndDestroy( &msgIds );
 					}
       			}
       		}
			break;
        case EFsEmailUiCmdSettings:
            {
            TInt tmp = 0;
            const TPckgBuf<TInt> pkgBuf( tmp );
            iAppUi.EnterFsEmailViewL( SettingsViewId,
                                      TUid::Uid(KMailSettingsOpenMainList), pkgBuf );
            }
            break;


	    default:
        	break;
        } // switch ( aCommand )
    CleanupStack::PopAndDestroy( &actionTargetItems );
    TIMESTAMP( "Message list selected operation done" );
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::MoveMsgsToFolderL( const TFSMailMsgId& aDestinationFolderId )
    {
    FUNC_LOG;
    TInt ret(KErrGeneral);
    RFsTreeItemIdList targetEntries;
    CleanupClosePushL( targetEntries );
    GetActionsTargetEntriesL( targetEntries );
    TBool supportsMove = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder );
    // Moving is not possible, if there are no items or the focus is on separator and
    // there are no marked items. In outbox, moving is allowed only to the drafts folder;
    // folder selection popup is not allowed.
    // These have to be checked before launching the folder view.
    if ( targetEntries.Count() && supportsMove )
        {
        TBool outbox = (iMailFolder && iMailFolder->GetFolderType() == EFSOutbox);

        if ( !(outbox && aDestinationFolderId.IsNullId()) )
            {
            // If destination folder is not set, it needs to be asked messages are moved after callbak
            if ( aDestinationFolderId.IsNullId() )
                {
                // Activate folder selection view and handle moving after callback gets destination
                iMoveToFolderOngoing = ETrue;
                TFolderListActivationData folderListData;
                folderListData.iCallback = this;
                if(iMailFolder) // Coverity error fix , assuming that inbox is best bet for safe data. 
                    {
                    folderListData.iSourceFolderType = iMailFolder->GetFolderType();
                    }
                else
                    {
                    folderListData.iSourceFolderType = EFSInbox;
                    }
                const TPckgBuf<TFolderListActivationData> pkgOut( folderListData );
                if ( targetEntries.Count() == 1 )
                    {
                    iAppUi.EnterFsEmailViewL( FolderListId, KFolderListMoveMessage, pkgOut );
                    }
                else
                    {
                    iAppUi.EnterFsEmailViewL( FolderListId, KFolderListMoveMessages, pkgOut );
                    }
                ret = KErrNotReady;
                }
            // Destination folder is set, move message(s) immediately
            else
                {
                iMoveToFolderOngoing = EFalse;
                // Get message IDs from target list IDs
                RArray<TFSMailMsgId> msgIds;
                CleanupClosePushL( msgIds );
                for ( TInt i = 0 ; i < targetEntries.Count() ; i++)
                    {
                    msgIds.Append( MsgIdFromListId( targetEntries[i] ) );
                    }

                if ( iMailFolder && msgIds.Count() ) // Something to move
                    {
                    // check that source and destination are different
                    if( iMailFolder->GetFolderId() != aDestinationFolderId )
                        {
                        // Trap is needed because protocol might return KErrNotSupported
                        // If move away from current folder is not supprted
                        TRAPD( errMove, iAppUi.GetActiveMailbox()->MoveMessagesL( msgIds, iMailFolder->GetFolderId(), aDestinationFolderId ) );
                        if ( errMove != KErrNotSupported )
                            {
                            if ( errMove == KErrNone )
                                {
                                RemoveMsgItemsFromListIfFoundL( msgIds );
                                if ( !iMsgNoteTimer )
                                    {
                                    iMsgNoteTimer = CMsgMovedNoteTimer::NewL( &iAppUi, this );
                                    }
                                iMsgNoteTimer->Cancel();
                                iMsgNoteTimer->Start( msgIds.Count(), aDestinationFolderId );
                                ret = KErrNone;
                                }
                            else
                                {
                                User::Leave(errMove);
                                }
                            }
                        }
                    }
                CleanupStack::PopAndDestroy( &msgIds );
                }
            }
        }
    CleanupStack::PopAndDestroy( &targetEntries );
    return ret;
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::MoveMessagesToDraftsL()
	{
    FUNC_LOG;
	if ( iMailFolder && iMailFolder->GetFolderType() == EFSOutbox ) // Move to drafts should only be available from outbox, safety
		{
		MoveMsgsToFolderL( iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSDraftsFolder ) );
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::CollapseAllNodesL()
	{
    FUNC_LOG;
    // Safety check, ignore command if the list is empty
    if ( iMailList->Count() > 0 )
        {
    	iMailTreeListVisualizer->CollapseAllL();
        }
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ExpandAllNodesL()
	{
    FUNC_LOG;
    // Safety check, ignore command if the list is empty
	if ( iMailList->Count() > 0 )
	    {
    	TFsTreeItemId prevId = iMailList->FocusedItem();
    	iMailTreeListVisualizer->ExpandAllL();
    	iMailTreeListVisualizer->SetFocusedItemL( prevId );
        }
	}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ExpandOrCollapseL()
    {
    FUNC_LOG;
    CFSEmailUiMailListModelItem* item =
        dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );
    if ( item && item->ModelItemType() == ETypeSeparator )
        {
        if ( iMailList->IsExpanded( iMailList->FocusedItem() ) )
            {
            //ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE );
            iMailList->CollapseNodeL( iMailList->FocusedItem() );
            }
        else
            {
            //ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND );
            iMailList->ExpandNodeL( iMailList->FocusedItem() );
            }
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetMessageFollowupFlagL()
	{
    FUNC_LOG;
	if ( TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() ) )
		{
	    RFsTreeItemIdList targetItems;
	    CleanupClosePushL( targetItems );
	    GetActionsTargetEntriesL( targetItems );

		// If there are marked or focused item(s)
		if ( targetItems.Count() )
			{
			// Convert list IDs to message IDs because it's possible that list refresh
			// causes list IDs to change while the flag dialog is open
			RArray< TFSMailMsgId > targetMsgIds;
			CleanupClosePushL( targetMsgIds );
			for ( TInt i = 0 ; i < targetItems.Count() ; ++i )
			    {
			    TFSMailMsgId msgId = MsgIdFromIndex( ModelIndexFromListId( targetItems[i] ) );
			    targetMsgIds.AppendL( msgId );
			    }

			TFollowUpNewState newFollowUpState = EFollowUpNoChanges;
			if ( TFsEmailUiUtility::RunFollowUpListDialogL( newFollowUpState ) )
				{
				// Update the target messages
				for ( TInt i = 0 ; i < targetMsgIds.Count() ; ++i )
				    {
	                // Confirm that message is still in the list after selection has closed
				    TInt itemIndex = ItemIndexFromMessageId( targetMsgIds[i] );
				    CFSEmailUiMailListModelItem* modelItem =
				        static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( itemIndex ) );
	                CFSMailMessage* confirmedPtr = NULL; // owned by the model
	                if ( modelItem )
	                    {
	                    confirmedPtr = &modelItem->MessagePtr();
	                    }
	                if ( confirmedPtr )
	                    {
	                    // Store flags to confirmed pointer for saving
	                    TInt currentFlags = confirmedPtr->GetFlags();
	                    switch ( newFollowUpState )
	                        {
	                        case EFollowUp:
	                            {
	                            confirmedPtr->SetFlag( EFSMsgFlag_FollowUp );
	                            confirmedPtr->ResetFlag( EFSMsgFlag_FollowUpComplete );
	                            }
	                            break;
	                        case EFollowUpComplete:
	                            {
	                            confirmedPtr->SetFlag( EFSMsgFlag_FollowUpComplete );
	                            confirmedPtr->ResetFlag( EFSMsgFlag_FollowUp );
	                            }
	                            break;
	                        case EFollowUpClear:
	                            {
	                            confirmedPtr->ResetFlag( EFSMsgFlag_FollowUp | EFSMsgFlag_FollowUpComplete );
	                            }
	                            break;
	                        }

	                    TInt newFlags = confirmedPtr->GetFlags();
	                    if ( newFlags != currentFlags )
	                        {
	                        // Save confirmed message
	                        confirmedPtr->SaveMessageL();

	                        // Update flag icon
                            UpdateMsgIconAndBoldingL( itemIndex );

                            // In case we are in flag sort mode, resetting the flag may cause the list order to be out of date.
                            if ( iCurrentSortCriteria.iField == EFSMailSortByFlagStatus )
	                            {
	                            iListOrderMayBeOutOfDate = ETrue;
	                            }
	                        }
	                    }
				    }
				}
			CleanupStack::PopAndDestroy( &targetMsgIds );
			}
		CleanupStack::PopAndDestroy( &targetItems );
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetViewSoftkeysL( TInt aResourceId )
	{
    FUNC_LOG;
    Cba()->SetCommandSetL( aResourceId );
    Cba()->DrawDeferred();
	}

// ---------------------------------------------------------------------------
// Method to set Middle SoftKey
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetMskL()
    {
    FUNC_LOG;
    // If there is no keyboard present, than Msk buttom must not be shown
    if ( iAppUi.ShortcutBinding().KeyBoardType() == 
                                    CFSEmailUiShortcutBinding::ENoKeyboard )
        {
        return;
        }
    // Get the mail list count
    TInt listCount(0);
    if ( iMailList )
        {
        listCount = iMailList->Count();
        }

    if ( iFocusedControl == EControlBarComponent )
        {
        ChangeMskCommandL( R_FSE_QTN_MSK_CHANGE ); // change - switch focus on
        }
    else  if ( iFocusedControl == EMailListComponent )
        {
        if ( listCount ) // Safety check
            {
            CFSEmailUiMailListModelItem* item =
                dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item(HighlightedIndex()) );
            // SHIFT DEPRESSED. SELECTION KEY DOES MARK/UNMARK
            if ( iShiftDepressed )
                {
                // Nodes may not be marked
                if ( iMailList->IsNode( iMailList->FocusedItem() ) )
                    {
                    ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY ); // nothing
                    }
                else
                    {
                    if ( iMailList->IsMarked( iMailList->FocusedItem() ) )
                        {
                        ChangeMskCommandL( R_FSE_QTN_MSK_UNMARK ); // unmark item
                        }
                    else
                        {
                        ChangeMskCommandL( R_FSE_QTN_MSK_MARK ); // mark item
                        }
                    }
                }
            else
                {
                // MAIL ITEM; OPEN MAIL
                if ( item && item->ModelItemType() == ETypeMailItem )
                    {
                    CFSMailMessage* messagePtr = &item->MessagePtr();
                    if ( messagePtr )
                        {
                        if ( iMailFolder && iMailFolder->GetFolderType() == EFSOutbox )
                            {
                            ChangeMskCommandL( R_FSE_QTN_MSK_OPEN_BLOCKED ); // blocked email opening 
                            }
                        else
                            {
                            ChangeMskCommandL( R_FSE_QTN_MSK_OPEN ); // open email
                            }
                        }
                    }

                // SEPARAOR ITEM; COLLAPSE / EXPAND NODE
                else if ( item && item->ModelItemType() == ETypeSeparator )
                    {
                    if( iMailList->IsNode( iMailList->FocusedItem() ) )
                        {
                        if ( iMailList->IsExpanded( iMailList->FocusedItem() ) )
                            {
                            ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE ); // collapse folder
                            }
                        else
                            {
                            ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND ); // expand folder
                            }
                        }
                    }
                }
            }
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::OfferEventL( const TAlfEvent& aEvent )
    {
    FUNC_LOG;
    TBool result( EFalse );

    if ( !aEvent.IsKeyEvent() )
        {
        // Only handle key events
        if ( aEvent.IsPointerEvent() )
            {
            if( aEvent.PointerDown() )
                {
                // If pointer down event was made on control bar area
                // focus needs to be changed to control bar control, if it
                // didn't already have focus.
               if( HitTest( *iControlBarControl, aEvent.PointerEvent().iPosition ) )
                    {
                    if( iFocusedControl != EControlBarComponent )
                        {
                        SetControlBarFocusedL();
                        }
                    }
                else
                    {
                    // If pointer down event was not made on control bar area
                    // then focus need to be set to mail list component, if it
                    // didn't already have focus. If mail list is empty, then
                    // focus is hidden and control bar stays as a focused item.
                    if( ( iFocusedControl != EMailListComponent ) &&
                        ( iMailList->Count() > 0 ) )
                        {
                        SetTreeListFocusedL();
                        }
                    else
                        {
                        iAppUi.SetFocusVisibility( EFalse );
                        }
                    }
                }

            // Offer event to focused control.
            if( iFocusedControl == EMailListComponent )
                {
                result = iMailList->TreeControl()->OfferEventL( aEvent );
                }
            else // iFocusedControl == EControlBarComponent
                {
                result = static_cast<CAlfControl*>(
                    iControlBarControl )->OfferEventL( aEvent );
                }
            }
        return result;
        }

    TInt scanCode = aEvent.KeyEvent().iScanCode;
    // Swap right and left controls in mirrored layout
    if ( AknLayoutUtils::LayoutMirrored() )
        {
        if ( scanCode == EStdKeyRightArrow )
            {
            scanCode = EStdKeyLeftArrow;
            }
        else if ( scanCode == EStdKeyLeftArrow )
            {
            scanCode = EStdKeyRightArrow;
            }
        }

    // Toggle mark items state when shift key is pressed or released
    if ( iFocusedControl == EMailListComponent &&
    	 ( scanCode == EStdKeyLeftShift ||
    	   scanCode == EStdKeyRightShift ||
    	   scanCode == EStdKeyHash ) )
        {
        if ( aEvent.Code() == EEventKeyDown )
            {
            iShiftDepressed = ETrue;
            iOtherKeyPressedWhileShiftDepressed = EFalse;
            if ( iModel->Count() && iMailList->IsMarked( iMailList->FocusedItem() ) )
                {
                iListMarkItemsState = EFalse; // Unmark state
                }
            else
                {
                iListMarkItemsState = ETrue; // Mark items state
                }
            }
        else if ( aEvent.Code() == EEventKeyUp )
            {
            iShiftDepressed = EFalse;
            }
        }

    // If any other key event is gained while hash is depressed, the hash key is used only
    // as shift and not as individual key.
    if ( iShiftDepressed && scanCode &&
            scanCode != EStdKeyHash && scanCode != EStdKeyLeftShift && scanCode != EStdKeyRightShift )
        {
        iOtherKeyPressedWhileShiftDepressed = ETrue;
        }

    // MSK label can now be updated when shift key has been handled
    SetMskL();
    // On KeyUp of EStdKeyYes usually Call application is called - prevent it
    if ( iConsumeStdKeyYes_KeyUp && (aEvent.Code() == EEventKeyUp ))
		{
		iConsumeStdKeyYes_KeyUp = EFalse; // in case call button was consumed elsewhere first key up enables calling Call application
		if ( EStdKeyYes == scanCode)
			{
			  result = ETrue; // consume not to switch to Call application when call to contact was processed
			  return result;
			}
		}

    if ( aEvent.IsKeyEvent() && aEvent.Code() == EEventKey )
        {
        TBool shiftState = ( aEvent.KeyEvent().iModifiers & EModifierShift );

        // Do the (un)marking if in shift state and suitable key is received
        if ( shiftState )
            {
            switch ( aEvent.KeyEvent().iScanCode )
                {
                case EStdKeyDownArrow:
                case EStdKeyUpArrow:
                    {
                    DoScrollMarkUnmarkL();
                    result = EFalse; // event is not consumed yet, because it must also move the cursor
                    }
                    break;
                case EStdKeyEnter:
                case EStdKeyDevice3:
                    {
                    if ( !aEvent.KeyEvent().iRepeats ) // no repeated (un)marking by holding selection key depressed
                        {
                        // The selection key always toggles the marking state of the current item.
                        // It also toggles the scroll marking/unmarking state.
                        if ( iModel->Count() )
                            {
                            CFSEmailUiMailListModelItem* item =
                                static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );

                            if ( item->ModelItemType() == ETypeMailItem )  // Separators are not markable
                                {
                                if ( iMailList->IsMarked( iMailList->FocusedItem() ) )
                                    {
                                    iMailList->MarkItemL( iMailList->FocusedItem(), EFalse );
                                    iListMarkItemsState = EFalse;
                                    }
                                else
                                    {
                                    iMailList->MarkItemL( iMailList->FocusedItem(), ETrue );
                                    iListMarkItemsState = ETrue;
                                    }
                                }
                            }
                        }
                    result = ETrue; // shift + selection is always consumed
                    }
                    break;
                default:
                    break;
                }

            }

        // If event not handled by now
        if ( !result )
            {
            // Handle possible focus visibility change
            if ( ( scanCode == EStdKeyRightArrow ) ||
                 ( scanCode == EStdKeyLeftArrow ) ||
                 ( scanCode == EStdKeyUpArrow ) ||
                 ( scanCode == EStdKeyDownArrow ) ||
                 ( scanCode == EStdKeyEnter ) ||
                 ( scanCode == EStdKeyDeviceA ) ||
                 ( scanCode ==EStdKeyDevice3 ) )
                {
                // If the focus was not active already, ignore the key press
                if( !iAppUi.SetFocusVisibility( ETrue ) )
                    {
                    return ETrue;
                    }
                }

            switch ( scanCode )
                {
                case EStdKeyDevice3: // CENTER CLICK
                case EStdKeyEnter:  // ENTER EITHER SELECTS ITEM IN TOOLBAR OR OPENS MAIL
                case EStdKeyNkpEnter:
                case EAknSoftkeySelect:
                    {
                    SetMskL();
                    if ( iFocusedControl == EMailListComponent )
                        {
                        TInt modelCount( modelCount = iModel->Count() );
                        if ( modelCount ) // Safety check
                            {
                            CFSEmailUiMailListModelItem* item =
                                dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );
                            // MAIL ITEM; OPEN MAIL
                            if ( item && item->ModelItemType() == ETypeMailItem )
                                {
                                CFSMailMessage* messagePtr = &item->MessagePtr();
                                if ( messagePtr )
                                    {
                                    TIMESTAMP( "Open email selected from message list" );
                                    OpenHighlightedMailL();
                                    return EKeyWasConsumed;
                                    }
                                }
                            // SEPARAOR ITEM; COLLAPSE / EXPAND NODE
                            else if ( item && item->ModelItemType() == ETypeSeparator )
                                {
                                if ( iMailList->IsExpanded( iMailList->FocusedItem()) )
                                    {
                                    ExpandOrCollapseL();
                                    }
                                else
                                    {
                                    ExpandOrCollapseL();
                                    }
                                return EKeyWasConsumed;
                                }
                            }
                        }
                    else
                        {
                        TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() );
                        if ( focusedButtonId == iNewEmailButtonId )
                            {
                            HandleCommandL(EFsEmailUiCmdCompose);
                            }
                        else if ( focusedButtonId == iFolderListButtonId )
                            {
                            // Set touchmanager not active for preventing getting events.
                            DisableMailList( ETrue );
                            iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton );
                            }
                        else if ( focusedButtonId == iSortButtonId )
                            {
                            TFSFolderType folderType;
                            if( iMailFolder )
                                {
                                folderType = iMailFolder->GetFolderType();
                                }
                            else
                                {
                                folderType = EFSInbox;
                                }
                            // Show sort if model has data.
                            if ( iModel->Count() )
                                {
                                // Set touchmanager not active for preventing getting events.
                                DisableMailList(ETrue);
                                iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton );
                                }
                            else
                                {
                                // hide selector focus if popup is not opened
                                // and selection was not made via HW-keys
                                iControlBarControl->MakeSelectorVisible(
                                    IsFocusShown() );
                                }
                            }
                        return ETrue; // iControlBar->OfferEventL( aEvent );
                        }
                    }
                    break;
                case EStdKeyLeftArrow:
                case EStdKeyRightArrow:
                case EStdKeyDownArrow:
                case EStdKeyUpArrow:
                    {
                    if( Layout_Meta_Data::IsLandscapeOrientation() )
                        {
                        result = HandleArrowEventInLandscapeL( scanCode,
                                    aEvent, shiftState );
                        }
                    else
                        {
                        result = HandleArrowEventInPortraitL( scanCode,
                                    aEvent, shiftState );
                        }
                    break;
                    }
                case EStdKeyYes:
                    {
                    if ( !iAppUi.ViewSwitchingOngoing() )
                        {
                        if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox &&
                                iMailFolder->GetFolderType() != EFSDraftsFolder )
                            {
                            TInt modelCount = iModel->Count();
                            if ( modelCount ) // Safety check
                                {
                                CFSEmailUiMailListModelItem* item =
                                    dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );
                                if ( item && item->ModelItemType() == ETypeMailItem )
                                    {
                                    CFSMailAddress* fromAddress = item->MessagePtr().GetSender();
                                    TDesC* mailAddress(0);
                                    if ( fromAddress )
                                        {
                                        mailAddress = &fromAddress->GetEmailAddress();
                                        }
                                    if ( mailAddress && mailAddress->Length() )
                                        {
                                        if ( iMailFolder->GetFolderType() == EFSSentFolder )
                                            {
                                            CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL(
                                                    *mailAddress, iAppUi.GetActiveMailbox(), this, EFalse );
                                            }
                                        else
                                            {
                                            CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL(
                                                    *mailAddress, iAppUi.GetActiveMailbox(), this, ETrue );
                                            }
// consume following KyUp event to prevent execution of Call application when call to contact processing
                                        iConsumeStdKeyYes_KeyUp = result = ETrue;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                case EStdKeyHash:
                    {
                    // Consume hash key events before they go to our shortcut framework. We do not want
                    // to react to those until the in the key up event. There hash key works as mark/unmark shortcut only
                    // if it hasn't been used as shift modifier.
                    result = ETrue;
                    }
                    break;
               // Backspace (C key) must be handled on Key-Down instead of Key-Up
               // ( this was the reason that deleted two emails from opened mail in viewer )
               case EStdKeyBackspace:
                   {
                   TInt shortcutCommand = iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(),
                                  CFSEmailUiShortcutBinding::EContextMailList );

                   if ( shortcutCommand != KErrNotFound )
                       {
                       HandleCommandL( shortcutCommand );
                       result = ETrue;
                       }
                   else result = EFalse;
                   }
                   break;
                default:
                    {
                    if ( iFocusedControl == EMailListComponent )
                        {
                        result = iMailList->TreeControl()->OfferEventL(aEvent);
                        }
                    else
                        {
                        result = EFalse;
                        }
                    }
                    break;
                }
            }
        }
    else if ( aEvent.IsKeyEvent() && aEvent.Code() == EEventKeyUp )
        {
        // Check keyboard shortcuts on key up events. These can't be checked on key event
        // because half-QWERTY keyboad has shortcuts also on shift and chr keys which do
        // no send any key events, only key down and key up.
        TInt shortcutCommand =
            iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(),
                CFSEmailUiShortcutBinding::EContextMailList );

        // Hash/shift key of ITU-T and half-QWERTY keyboards is an exception case to other
        // shortcuts: it is handled only if it hasn't been used as shift modifier
        if ( (scanCode == EStdKeyHash || scanCode == EStdKeyLeftShift || scanCode == EStdKeyRightShift) &&
             iOtherKeyPressedWhileShiftDepressed )
            {
            shortcutCommand = KErrNotFound;
            }

        // block Backspace (C key) handle on Key-Up
        if ( scanCode == EStdKeyBackspace )
            {
            shortcutCommand = KErrNotFound; // handled on Key-Down, see above
            }

        if ( shortcutCommand != KErrNotFound )
            {
            HandleCommandL( shortcutCommand );
            result = ETrue;
            }
        else
            {
            result = EFalse;
            }
        }

    return result;
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::DoHandleListItemOpenL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DoHandleListItemOpenL()
    {
    FUNC_LOG;
    if ( 0 < iModel->Count() ) // Safety check
        {
        CFSEmailUiMailListModelItem* item =
            dynamic_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );
        // MAIL ITEM; OPEN MAIL
        if ( item && item->ModelItemType() == ETypeMailItem )
            {
            CFSMailMessage* messagePtr = &item->MessagePtr();
            if ( messagePtr )
                {
                TIMESTAMP( "Open email selected from message list" );
                OpenHighlightedMailL();
                }

            // Give feedback to user (vibration)
            iTouchFeedBack->InstantFeedback(ETouchFeedbackBasic);
            }
        // SEPARATOR ITEM; COLLAPSE / EXPAND NODE
        else if ( item && item->ModelItemType() == ETypeSeparator )
            {
                ExpandOrCollapseL();
                SetMskL();
            }
        }
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::DoHandleControlBarOpenL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DoHandleControlBarOpenL( TInt aControlBarButtonId )
    {
    FUNC_LOG;

    if ( aControlBarButtonId == iNewEmailButtonId )
        {
        HandleCommandL(EFsEmailUiCmdCompose);
        }
    else if ( aControlBarButtonId == iFolderListButtonId )
        {
        //FOLDERLIST
        //Set touchmanager not active for preventing getting events.
        DisableMailList(ETrue);
        iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton );
        }
    else if ( aControlBarButtonId == iSortButtonId )
        {
        //SORTLIST
        TFSFolderType folderType;
        if ( iMailFolder )
            {
            folderType = iMailFolder->GetFolderType();
            }
        else
            {
            folderType = EFSInbox;
            }
        if ( iModel->Count() )
            {
            //Set touchmanager not active for preventing getting events.
            DisableMailList(ETrue);
            iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton );
            }
        else
            {
            // hide selector focus if popup is not opened and selection was not
            // made via HW-keys
            iControlBarControl->MakeSelectorVisible(  IsFocusShown() );
            }
        }
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::DoHandleListItemLongTapL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DoHandleListItemLongTapL( const TPoint& aPoint )
    {
    FUNC_LOG;

    if ( 0 < iModel->Count() ) // Safety check
        {
        RFsTreeItemIdList markedEntries;
        iMailList->GetMarkedItemsL( markedEntries );
        if ( markedEntries.Count() >= 0 )
            {
            LaunchStylusPopupMenuL( aPoint );
            }
        }
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::GetFocusedControl
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::GetFocusedControl() const
    {
    FUNC_LOG;
    return iFocusedControl;
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::SetControlBarFocusedL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetControlBarFocusedL()
    {
    FUNC_LOG;
    iFocusedControl = EControlBarComponent;
    iMailList->SetFocusedL( EFalse );
    SetMskL();
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::SetTreeListFocusedL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetTreeListFocusedL()
    {
    FUNC_LOG;
    iFocusedControl = EMailListComponent;
    iMailList->SetFocusedL( ETrue );
    iControlBarControl->SetFocusL( EFalse );
    SetMskL();
    }

// -----------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::FlipStateChangedL
// -----------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::FlipStateChangedL( TBool aKeyboardFlipOpen )
    {
    FUNC_LOG;
    CFsEmailUiViewBase::FlipStateChangedL( aKeyboardFlipOpen );
    iMailTreeListVisualizer->SetFlipState( iKeyboardFlipOpen );
    }

// -----------------------------------------------------------------------------
//  CFSEmailUiMailListVisualiser::HandleTimerFocusStateChange
// -----------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::FocusVisibilityChange( TBool aVisible )
    {
    FUNC_LOG;

    CFsEmailUiViewBase::FocusVisibilityChange( aVisible );

    if( iFocusedControl == EControlBarComponent )
        {
        iControlBarControl->MakeSelectorVisible( aVisible );
        }

    if ( iStylusPopUpMenuVisible && !aVisible )
    	{
    	// Do not allow to remove the focus from a list element if the pop up
    	// menu was just launched.
    	return;
    	}

    iMailTreeListVisualizer->SetFocusVisibility( aVisible );
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::DisableMailList
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DisableMailList( TBool aValue )
    {
    FUNC_LOG;
    iTouchManager->SetDisabled( aValue );
    iControlBarControl->EnableTouch( (aValue) ? EFalse : ETrue  );
    }
//</cmail>

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ShortcutCollapseExpandAllToggleL()
	{
    FUNC_LOG;
	if ( !AllNodesCollapsed() )
		{
		CollapseAllNodesL();
		}
	else
		{
		ExpandAllNodesL();
		}
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::AllNodesCollapsed() const
    {
    FUNC_LOG;
	for ( TInt i=0;i<iTreeItemArray.Count();i++)
		{
		if ( iMailList->IsNode( iTreeItemArray[i].iListItemId ) )
			{
			if ( iMailList->IsExpanded( iTreeItemArray[i].iListItemId ) )
				{
				return EFalse;
				}
			}
		}

	return ETrue;
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::AllNodesExpanded() const
    {
    FUNC_LOG;
	for ( TInt i=0;i<iTreeItemArray.Count();i++)
		{
		if ( iMailList->IsNode( iTreeItemArray[i].iListItemId ) )
			{
			if ( !iMailList->IsExpanded( iTreeItemArray[i].iListItemId ) )
				{
				return EFalse;
				}
			}
		}

	return ETrue;
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::IsMarkAsReadAvailableL()
// Function checks if mark as read option should be available for user
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::IsMarkAsReadAvailableL() const
    {
    FUNC_LOG;
    TBool available = EFalse;

    // In outbox the mark as read is always inavailable
    if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox )
        {
        RFsTreeItemIdList targetEntries;
        CleanupClosePushL( targetEntries );
        GetActionsTargetEntriesL( targetEntries );

        // Mark as read is available if at least one of the target entries is unread
        for ( TInt i = 0 ; i < targetEntries.Count() ; ++i )
            {
            const CFSMailMessage& message = MsgPtrFromListIdL( targetEntries[i] );
            if ( !message.IsFlagSet(EFSMsgFlag_Read) )
                {
                available = ETrue;
                break;
                }
            }

        CleanupStack::PopAndDestroy( &targetEntries );
        }

    return available;
    }

// ---------------------------------------------------------------------------
// CFSEmailUiMailListVisualiser::IsMarkAsUnreadAvailableL()
// Function checks if mark as unread option should be available for user
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::IsMarkAsUnreadAvailableL() const
    {
    FUNC_LOG;
    TBool available = EFalse;

    // In outbox the mark as unread is always inavailable
    if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox )
        {
        RFsTreeItemIdList targetEntries;
        CleanupClosePushL( targetEntries );
        GetActionsTargetEntriesL( targetEntries );

        // Mark as unread is available if at least one of the target entries is read
        for ( TInt i = 0 ; i < targetEntries.Count() ; ++i )
            {
            const CFSMailMessage& message = MsgPtrFromListIdL( targetEntries[i] );
            if ( message.IsFlagSet(EFSMsgFlag_Read) )
                {
                available = ETrue;
                break;
                }
            }

        CleanupStack::PopAndDestroy( &targetEntries );
        }

    return available;
    }

// ---------------------------------------------------------------------------
// Utility function to get list of entries which will be targeted by the
// Actions menu commands. The list contains either marked entries or the
// focused message entry or is empty.
// ---------------------------------------------------------------------------
void CFSEmailUiMailListVisualiser::GetActionsTargetEntriesL( RFsTreeItemIdList& aListItems ) const
    {
    FUNC_LOG;
    if ( iMailList )
        {
        iMailList->GetMarkedItemsL( aListItems );

        // If there are no marked entries the command target is the focused item.
        if ( !aListItems.Count() )
            {
            TFsTreeItemId focusedId = iMailList->FocusedItem();
            if ( iFocusedControl == EMailListComponent &&
                 focusedId != KFsTreeNoneID &&
                 !iMailList->IsNode( focusedId ) )
                {
                aListItems.AppendL( focusedId );
                }
            }
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ShortcutReadUnreadToggleL()
    {
    FUNC_LOG;
    // Setting the read status is not possible in outbox
    // <cmail>
    if ( iModel->Count() && iMailFolder && iMailFolder->GetFolderType() != EFSOutbox )
    // </cmail>
        {
        RFsTreeItemIdList targetEntries;
        CleanupClosePushL( targetEntries );
        GetActionsTargetEntriesL( targetEntries );
        TInt targetCount = targetEntries.Count();

        // figure out are we marking items as read or unread
        TBool toggleAsRead(ETrue);
        for ( TInt i=0 ; i<targetCount ; i++ )
            {
            CFSMailMessage& msgPtr = MsgPtrFromListIdL( targetEntries[i] );
            if ( msgPtr.IsFlagSet(EFSMsgFlag_Read) )
                {
                toggleAsRead = EFalse;
                break;
                }
            }

        // change the status of the target items
        for ( TInt i=0 ; i<targetCount ; i++ )
            {
            TInt msgIndex = ModelIndexFromListId( targetEntries[i] );
            ChangeReadStatusOfIndexL( toggleAsRead, msgIndex );
            }

        CleanupStack::PopAndDestroy( &targetEntries );
        }
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleControlBarEvent( TFsControlBarEvent aEvent, TInt aData )
	{
    FUNC_LOG;

    switch( aEvent )
        {
        case EEventFocusLostAtBottom:
        case EEventFocusLostAtSide:
            {
            iFocusedControl = EMailListComponent;
            TRAP_IGNORE( iMailList->SetFocusedL( ETrue ) );
            break;
            }
        case EEventFocusGained:
            {
            break;
            }
        case EEventButtonPressed:
            {
            // Handle 2 control buttons
            if ( aData == iFolderListButtonId )
                {
                }
            else if ( aData == iSortButtonId )
                {
                }
            break;
            }
        case EEventFocusVisibilityChanged:
            {
            // Hide focus after button release
            iAppUi.SetFocusVisibility( EFalse );
            break;
            }
        default:
            {
            // No need to handle other events
            break;
            }
        }
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::CreateControlBarLayoutL()
	{
    FUNC_LOG;
    iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() );

    // New email button
    iNewEmailButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA );
    iNewEmailButton = iControlBarControl->ButtonById( iNewEmailButtonId );
    const TRect mailButtonRect( iAppUi.LayoutHandler()->GetControlBarNewEmailButtonRect() );
    iNewEmailButton->SetPos( mailButtonRect.iTl );
    iNewEmailButton->SetSize( mailButtonRect.Size() );
    ControlGroup().AppendL(iNewEmailButton->AsAlfControl());

    // Folder list button
    iFolderListButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA );
    iFolderListButton = iControlBarControl->ButtonById( iFolderListButtonId );
    const TRect folderButtonRect( iAppUi.LayoutHandler()->GetControlBarFolderListButtonRect() );
    iFolderListButton->SetPos( folderButtonRect.iTl );
    iFolderListButton->SetSize( folderButtonRect.Size() );
    ControlGroup().AppendL(iFolderListButton->AsAlfControl());

    // Sort order button
    iSortButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA );
    iSortButton = iControlBarControl->ButtonById( iSortButtonId );
    const TRect sortButtonRect( iAppUi.LayoutHandler()->GetControlBarSortButtonRect() );
    iSortButton->SetPos( sortButtonRect.iTl );
    iSortButton->SetSize( sortButtonRect.Size() );
    ControlGroup().AppendL(iSortButton->AsAlfControl());
// </cmail>

    // Set the text alignment according the layout
    TAlfAlignHorizontal horizontalAlign = EAlfAlignHLeft;
    if ( AknLayoutUtils::LayoutMirrored() )
        {
        horizontalAlign = EAlfAlignHRight;
        }

    // Icons and sort button text
    iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) );
    iNewEmailButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListTextureNewEmailDefaultIcon ) );
    SetSortButtonTextAndIconL();

    iNewEmailButton->SetElemAlignL(
        ECBElemIconA,
        EAlfAlignHCenter,
        EAlfAlignVCenter );

    iFolderListButton->SetElemAlignL(
        ECBElemLabelFirstLine,
        horizontalAlign,
        EAlfAlignVCenter );
    iSortButton->SetElemAlignL(
        ECBElemLabelFirstLine,
        horizontalAlign,
        EAlfAlignVCenter );
    iSortButton->SetElemAlignL(
        ECBElemIconA,
        EAlfAlignHCenter,
        EAlfAlignVCenter );

	// Show the buttons
  	iNewEmailButton->ShowButtonL();
    iFolderListButton->ShowButtonL();
    iSortButton->ShowButtonL();
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ScaleControlBarL()
	{
    FUNC_LOG;
    TRect screenRect = iAppUi.ClientRect();

	// First set pos, widht and height
  	iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() );

    const TRect newEmailButtonRect( iAppUi.LayoutHandler()->GetControlBarNewEmailButtonRect() );
    iNewEmailButton->SetPos( newEmailButtonRect.iTl );
    iNewEmailButton->SetSize( newEmailButtonRect.Size() );

    const TRect folderButtonRect( iAppUi.LayoutHandler()->GetControlBarFolderListButtonRect() );
  	iFolderListButton->SetPos( folderButtonRect.iTl );
  	iFolderListButton->SetSize( folderButtonRect.Size() );

    const TRect sortButtonRect( iAppUi.LayoutHandler()->GetControlBarSortButtonRect() );
   	iSortButton->SetPos( sortButtonRect.iTl );
    iSortButton->SetSize( sortButtonRect.Size() );

	TInt var = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
	TAknLayoutText textLayout;
	textLayout.LayoutText(TRect(0,0,0,0), AknLayoutScalable_Apps::main_sp_fs_ctrlbar_ddmenu_pane_t1(var));
	iNewEmailButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() );
 	iFolderListButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() );
 	iSortButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() );

 	UpdateTheme(EFalse);

	iNewEmailButton->ShowButtonL();
  	iFolderListButton->ShowButtonL();
	iSortButton->ShowButtonL();
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetSortButtonTextAndIconL()
	{
    FUNC_LOG;

    // Set button text if necessary
    HBufC* buttonText = GetSortButtonTextLC();

	if ( !Layout_Meta_Data::IsLandscapeOrientation() )
		{
		if ( buttonText )
			{
			buttonText->Des().Zero();
			}
		}

	if ( buttonText )
		{
		iSortButton->SetTextL( *buttonText );
		}
	CleanupStack::PopAndDestroy( buttonText );

	// Set icon
    TFSEmailUiTextures textureIndex( ETextureFirst );

	switch ( iCurrentSortCriteria.iField )
		{
		case EFSMailSortBySubject:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListSubjectDescTexture :
						   ESortListSubjectAscTexture;
			}
			break;
		case EFSMailSortByAttachment:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListAttachmentDescTexture :
						   ESortListAttachmentAscTexture;
			}
			break;
		case EFSMailSortByFlagStatus:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListFollowDescTexture :
						   ESortListFollowAscTexture;
			}
			break;
		case EFSMailSortByRecipient:
		case EFSMailSortBySender:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListSenderDescTexture :
						   ESortListSenderAscTexture;
			}
			break;
		case EFSMailSortByPriority:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListPriorityDescTexture :
						   ESortListPriorityAscTexture;
			}
			break;
		case EFSMailSortByUnread:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListUnreadDescTexture :
						   ESortListUnreadAscTexture;
			}
			break;
		case EFSMailSortByDate:
		default:
			{
			textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ?
						   ESortListDateDescTexture :
						   ESortListDateAscTexture;
			}
			break;
		}

	iSortButton->SetIconL(
			iAppUi.FsTextureManager()->TextureByIndex( textureIndex ),
			ECBElemIconA );
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
HBufC* CFSEmailUiMailListVisualiser::GetSortButtonTextLC()
	{
    FUNC_LOG;
	HBufC* buttonText( 0 );

	switch ( iCurrentSortCriteria.iField )
		{
		case EFSMailSortBySubject:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_SUBJECT );
			}
			break;
		case EFSMailSortByAttachment:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_ATTACHMENT );
			}
			break;
		case EFSMailSortByFlagStatus:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_FLAG );
			}
			break;
		case EFSMailSortByRecipient:
		case EFSMailSortBySender:
			{
			TFSFolderType folderType( EFSInbox );
            if( iMailFolder )
               {
               folderType = iMailFolder->GetFolderType();
               }
			switch( folderType )
				{
				case EFSSentFolder:
				case EFSDraftsFolder:
				case EFSOutbox:
					{
					buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_RECIPIENT );
					}
					break;
				default:
					buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_SENDER );
					break;
				}
			}
			break;
		case EFSMailSortByPriority:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_PRIORITY );
			}
			break;
		case EFSMailSortByUnread:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_UNREAD );
			}
			break;
		case EFSMailSortByDate:
		default:
			{
			buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_DATE );
			}
			break;
		}
	return buttonText;
	}

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SetMailListLayoutAnchors()
	{
    FUNC_LOG;
 	// Set anchors so that list leaves space for control bar
    iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 0,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricRelativeToSize, EAlfAnchorMetricRelativeToSize,
        TAlfTimedPoint(0, 0 ));
    iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 0,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricRelativeToSize, EAlfAnchorMetricAbsolute,
        TAlfTimedPoint(1, iAppUi.LayoutHandler()->ControlBarHeight() ));

    // <cmail> Platform layout changes
    TRect listRect = iAppUi.LayoutHandler()->GetListRect();
	// Set anchors so that list leaves space for control bar
    iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 1,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute,
        TAlfTimedPoint(listRect.iTl.iX, listRect.iTl.iY));
    iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 1,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute,
        TAlfTimedPoint(listRect.iBr.iX, listRect.iBr.iY));
    // </cmail> Platform layout changes

 	// Set anchors for connection icon

    // <cmail> Platform layout changes
    TRect connectionIconRect( iAppUi.LayoutHandler()->GetControlBarConnectionIconRect() );
    const TPoint& tl( connectionIconRect.iTl );
 	iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 2,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute,
        TAlfTimedPoint( tl.iX, tl.iY ));
    const TPoint& br( connectionIconRect.iBr );
    iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 2,
        EAlfAnchorOriginLeft, EAlfAnchorOriginTop,
        EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute,
        TAlfTimedPoint( br.iX, br.iY ));
    // </cmail> Platform layout changes

    iScreenAnchorLayout->UpdateChildrenLayout();
    }

// ---------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ChangeReadStatusOfHighlightedL( TBool aRead )
	{
    FUNC_LOG;
	ChangeReadStatusOfIndexL( aRead, HighlightedIndex() );
	}

// ---------------------------------------------------------------------------
// ChangeReadStatusOfMarkedL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ChangeReadStatusOfMarkedL( TBool aRead )
	{
    FUNC_LOG;
	RFsTreeItemIdList markedEntries;
	CleanupClosePushL( markedEntries );
	iMailList->GetMarkedItemsL( markedEntries );
	for ( TInt i=0; i<markedEntries.Count();i++ )
		{
		TInt msgIndex = ModelIndexFromListId( markedEntries[i] );
		ChangeReadStatusOfIndexL( aRead, msgIndex );
		}
	UnmarkAllItemsL();
	CleanupStack::PopAndDestroy( &markedEntries );
	}

void CFSEmailUiMailListVisualiser::ChangeReadStatusOfIndexL( TBool aRead, TInt aIndex )
    {
    FUNC_LOG;
    // <cmail>
    if ( iModel->Count() )
    // </cmail>
        {
        CFSEmailUiMailListModelItem* selectedItem =
            static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( aIndex ));
        CFSMailMessage& msgPtr = selectedItem->MessagePtr();
        TBool msgWasReadBefore = msgPtr.IsFlagSet( EFSMsgFlag_Read );
        if ( aRead != msgWasReadBefore )
            {
            if ( aRead )
                {
                // Send flags, local and server
                msgPtr.SetFlag( EFSMsgFlag_Read );
                }
            else
                {
                // Send flags, local and server
                msgPtr.ResetFlag( EFSMsgFlag_Read );
                }
            msgPtr.SaveMessageL();  // Save flag

            // Switch icon to correct one if mail list is visible
            // UpdateMsgIconAndBoldingL( aIndex );

            if ( iCurrentSortCriteria.iField == EFSMailSortByUnread )
                {
                // Attribute affecting the current sorting order has been changed.
                // Thus, the list order may now be incorrect.
                iListOrderMayBeOutOfDate = ETrue;
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// DeleteMessagesL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DeleteMessagesL()
	{
    FUNC_LOG;
    const TInt markedCount(CountMarkedItemsL());
    const TFsTreeItemId focusedId(iMailList->FocusedItem());

    // Delete either marked items or the focused one
    if (markedCount)
        {
        DeleteMarkedMessagesL();
        }
    else if (iMailList->IsNode(focusedId))
        {
        DeleteMessagesUnderNodeL(focusedId);
        }
    else
        {
        DeleteFocusedMessageL();
        }

	// Set highlight to control bar if no items after delete
    // <cmail>
	if ( iModel->Count() == 0 )
    // </cmail>
		{
		iFocusedControl = EControlBarComponent;
		iMailList->SetFocusedL( EFalse );
		iControlBarControl->SetFocusL();
		}
	}

// ---------------------------------------------------------------------------
// UpdateItemAtIndexL
// Reload message pointer from mail client and update list item contents to
// match it. Item is removed if it isn't valid anymore.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateItemAtIndexL( TInt aIndex )
    {
    FUNC_LOG;
    // <cmail>

    if ( aIndex >= 0 && aIndex < iModel->Count() )
    // </cmail>
        {
        CFSEmailUiMailListModelItem* modelItem =
            static_cast<CFSEmailUiMailListModelItem*>( Model()->Item( aIndex ) );
        if ( modelItem->ModelItemType() == ETypeMailItem )
            {
            // This is beacause message deleted event migh have occured.
            CFSMailMessage* confirmedMsgPtr = NULL;
            TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(),
                                                                                     iMailFolder->GetFolderId(),
                                                                                     modelItem->MessagePtr().GetMessageId() ,
                                                                                     EFSMsgDataEnvelope ) );
            if ( confirmedMsgPtr )
                {
                // Replace message pointer in model with newly fetched one
                Model()->ReplaceMessagePtr( aIndex, confirmedMsgPtr );

                const SMailListItem& item = iTreeItemArray[aIndex];

                // Update the list item contents and formating to match the message pointer
                CFsTreePlainTwoLineItemData* itemData =
                    static_cast<CFsTreePlainTwoLineItemData*>( item.iTreeItemData );
                CFsTreePlainTwoLineItemVisualizer* itemVis =
                    static_cast<CFsTreePlainTwoLineItemVisualizer*>( item.iTreeItemVisualiser );

                UpdateItemDataL( itemData, confirmedMsgPtr );
                UpdatePreviewPaneTextForItemL( itemData, confirmedMsgPtr );
                UpdateMsgIconAndBoldingL( itemData, itemVis, confirmedMsgPtr );
                iMailTreeListVisualizer->UpdateItemL( item.iListItemId );
                }
            else
                {
                // No confirmed message for highlighted, remove from list also
                iMailList->RemoveL( iTreeItemArray[aIndex].iListItemId ); // remove from list
                iTreeItemArray.Remove( aIndex ); // remove from internal array.
                iModel->RemoveAndDestroy( aIndex ); // Remove from model
                if ( iNodesInUse )
                    {
                    RemoveUnnecessaryNodesL();
                    }
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// CheckValidityOfHighlightedMsgL
// Check validity of highlighted msg, and remove from list if needed
// Typically called after view is returned from editot or viewer.
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::CheckValidityOfHighlightedMsgL()
	{
    FUNC_LOG;
	TBool ret(EFalse);
    // <cmail>
	if ( iModel->Count() )
    // </cmail>
		{
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>( Model()->Item( HighlightedIndex() ) );
		if ( item->ModelItemType() == ETypeMailItem )
			{
			// This is beacause message deleted event migh have occured.
			CFSMailMessage* confirmedMsgPtr = NULL;
			TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(),
								                                                     iMailFolder->GetFolderId(),
								                                                     item->MessagePtr().GetMessageId() ,
								                                                     EFSMsgDataEnvelope ) );
			if ( confirmedMsgPtr )
				{
			   	ret = ETrue;
				delete confirmedMsgPtr;
				confirmedMsgPtr = NULL;
				}
			else
				{
				// No confirmed message for highlighted, remove from list also
				ret = EFalse;
				SMailListItem item;
				item.iListItemId = iMailList->FocusedItem();
				TInt IndexToBeDestroyed = iTreeItemArray.Find( item );
				iTreeItemArray.Remove( IndexToBeDestroyed ); // remove from internal array.
		 		iModel->RemoveAndDestroy( IndexToBeDestroyed ); // Remove from model
				iMailList->RemoveL( iMailList->FocusedItem() );		// remove from list
				if ( iNodesInUse )
					{
					RemoveUnnecessaryNodesL();
					}
				}
			}
		}
	return ret;
	}

// ---------------------------------------------------------------------------
// UpdateMsgIconAndBoldingL
// Updates our own message object with the data from a given message object.
// The messages are matched with the message ID.
// ---------------------------------------------------------------------------
void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
    // <cmail>
	if ( aMsgPtr && iModel->Count() )
    // </cmail>
		{
		TInt mailItemIdx = ItemIndexFromMessageId( aMsgPtr->GetMessageId() );
		if ( mailItemIdx >= 0 )
			{
			CFSEmailUiMailListModelItem* item =
				static_cast<CFSEmailUiMailListModelItem*>( Model()->Item( mailItemIdx ) );

			// Update all flags
			TUint32 prevFlags = item->MessagePtr().GetFlags();
			TUint32 newFlags = aMsgPtr->GetFlags();
			if ( prevFlags != newFlags )
			    {
			    item->MessagePtr().ResetFlag( prevFlags );
			    item->MessagePtr().SetFlag( newFlags );

			    // Save changed flags in internal model array
			    item->MessagePtr().SaveMessageL();
			    }

			// Update the list item graphics
			UpdateMsgIconAndBoldingL( mailItemIdx );
			}
		}
	}

// ---------------------------------------------------------------------------
// UpdateMsgIconAndBoldingL
// Updates list item at given index to match the state of the message object
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( TInt aListIndex, TBool aRefreshItem )
    {
    FUNC_LOG;
    CFSEmailUiMailListModelItem* item =
        static_cast<CFSEmailUiMailListModelItem*>( Model()->Item(aListIndex) );
    if ( item && item->ModelItemType() == ETypeMailItem )
        {
        CFSMailMessage* msgPtr = &item->MessagePtr();
        CFsTreePlainTwoLineItemData* itemData =
            static_cast<CFsTreePlainTwoLineItemData*>( iTreeItemArray[aListIndex].iTreeItemData );
        CFsTreePlainTwoLineItemVisualizer* itemVis =
            static_cast<CFsTreePlainTwoLineItemVisualizer*>( iTreeItemArray[aListIndex].iTreeItemVisualiser );

        UpdateMsgIconAndBoldingL( itemData, itemVis, msgPtr );

        //refresh item if requested
        if ( aRefreshItem )
            {
            iMailTreeListVisualizer->UpdateItemL( iTreeItemArray[aListIndex].iListItemId );
            }
        }
    }

// ---------------------------------------------------------------------------
// UpdateMsgIconAndBoldingL
// Updates list item at given index to match the state of the message object
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( CFsTreePlainTwoLineItemData* aItemData,
                                                             CFsTreePlainTwoLineItemVisualizer* aItemVis,
                                                             CFSMailMessage* aMsgPtr )
    {
    FUNC_LOG;

    if ( aItemData && aItemVis && aMsgPtr )
        {
        CAlfTexture* itemTexture = &TFsEmailUiUtility::GetMsgIcon( aMsgPtr, *iAppUi.FsTextureManager() );

        aItemData->SetIcon( *itemTexture );

        // Set font according the read status
        if ( aMsgPtr->IsFlagSet( EFSMsgFlag_Read ) )
            {
            CAlfTextStyle* textStyle = iAppUi.LayoutHandler()->FSTextStyleFromIdL( EFSFontTypeSmall );
            aItemVis->SetTextStyleId ( textStyle->Id() );
            aItemVis->SetTextBold( EFalse );
            }
        else
            {
            CAlfTextStyle* textStyle = iAppUi.LayoutHandler()->FSTextStyleFromIdL( EFSFontTypeSmallBold );
            aItemVis->SetTextStyleId ( textStyle->Id() );
            aItemVis->SetTextBold( ETrue );
            }

        // Set follow up flag icon
        if ( aMsgPtr->IsFlagSet( EFSMsgFlag_FollowUp ) )
            {
            aItemData->SetFlagIcon( iAppUi.FsTextureManager()->TextureByIndex( EFollowUpFlagList ) );
            aItemVis->SetFlagIconVisible( ETrue );
            }
        else if ( aMsgPtr->IsFlagSet( EFSMsgFlag_FollowUpComplete ) )
            {
            aItemData->SetFlagIcon( iAppUi.FsTextureManager()->TextureByIndex( EFollowUpFlagCompleteList ) );
            aItemVis->SetFlagIconVisible( ETrue );
            }
        else
            {
            aItemVis->SetFlagIconVisible( EFalse );
            }
        }
    }

// ---------------------------------------------------------------------------
// RemoveMsgItemsFromListIfFoundL
// Message removing from list if found. Does not panic or return found status.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::RemoveMsgItemsFromListIfFoundL( const RArray<TFSMailMsgId>& aEntryIds )
	{
    FUNC_LOG;
	for ( TInt i=0 ; i<aEntryIds.Count() ; ++i )
	    {
	    const TFSMailMsgId& entryId = aEntryIds[i];
    	if ( !entryId.IsNullId() )
    		{
        	TInt idx = ItemIndexFromMessageId( entryId );
        	if ( idx >= 0 )
        	    {
    			iMailList->RemoveL( iTreeItemArray[idx].iListItemId ); // remove from list
    			iTreeItemArray.Remove( idx ); // remove from internal array.
    	 		iModel->RemoveAndDestroy( idx ); // Remove from model
        	    }
    		}
	    }
	if ( aEntryIds.Count() > 0  )
		{
        if ( iMailListUpdater )
            {
            if ( iMailListUpdater->IsActive() )
                {
                iMailListUpdater->Stop();
                }
             iMailListUpdater->StartL();
             }
		}
	if ( iNodesInUse )
		{
		RemoveUnnecessaryNodesL();
		}

	// Set highligh to control bar if no items left after
	// deleted items have been revoved from the list
	// Otherwise mail list takes care of highlight
    // <cmail>
	if ( iModel->Count() == 0 )
    // </cmail>
		{
		iFocusedControl = EControlBarComponent;
		iMailList->SetFocusedL( EFalse );
		iControlBarControl->SetFocusL();
		}
	}

// ---------------------------------------------------------------------------
// DeleteFocusedMessageL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DeleteFocusedMessageL()
	{
    FUNC_LOG;
	TInt currentItemIndex = HighlightedIndex();
	if ( Model()->Count() )
		{
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>( Model()->Item(currentItemIndex) );
		if ( item && item->ModelItemType() == ETypeMailItem )
			{
			CFSMailMessage& messagePtr = item->MessagePtr();

			TInt okToDelete(ETrue);
			if ( iAppUi.GetCRHandler()->WarnBeforeDelete() )
			    {
	            TInt queryTextId(0);
	            if ( messagePtr.IsFlagSet( EFSMsgFlag_CalendarMsg ))
	                {
	                queryTextId = R_FREESTYLE_EMAIL_DELETE_CALEVENT_NOTE;
	                }
	            else
	                {
	                queryTextId = R_FREESTYLE_EMAIL_DELETE_MAIL_NOTE;
	                }
	            HBufC* msgSubject = TFsEmailUiUtility::CreateSubjectTextLC( &messagePtr );

	            okToDelete = TFsEmailUiUtility::ShowConfirmationQueryL( queryTextId, *msgSubject );

	            CleanupStack::PopAndDestroy( msgSubject );
			    }

			if ( okToDelete )
 				{
 				// Delete message from framework, and perform internal housekeeping
 				TFSMailMsgId msgId = messagePtr.GetMessageId();
 				RArray<TFSMailMsgId> msgIds;
 				CleanupClosePushL( msgIds );
 				msgIds.Append( msgId );
				TFSMailMsgId folderId = FolderId();
				TFSMailMsgId mailBox = iAppUi.GetActiveMailbox()->GetId();
				iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds );
                RemoveMsgItemsFromListIfFoundL( msgIds );
                CleanupStack::PopAndDestroy( &msgIds );
				}
			else
				{
				UnmarkAllItemsL();
				}
			}
		}
	}

// ---------------------------------------------------------------------------
// DeleteMessagesUnderNodeL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DeleteMessagesUnderNodeL(
        const TFsTreeItemId aNodeId)
    {
    FUNC_LOG;
    iModel->GetItemIdsUnderNodeL(aNodeId, iDeleteTask->Entries());
    ConfirmAndStartDeleteTaskL(iDeleteTask);
    }

// ---------------------------------------------------------------------------
// DeleteMarkedMessagesL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DeleteMarkedMessagesL()
    {
    FUNC_LOG;
    iMailList->GetMarkedItemsL(iDeleteTask->Entries());
    ConfirmAndStartDeleteTaskL(iDeleteTask);
    }

// ---------------------------------------------------------------------------
// ConfirmAndStartDeleteTaskL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::ConfirmAndStartDeleteTaskL(
        TDeleteTask<CFSEmailUiMailListVisualiser>* aTask )
    {
    FUNC_LOG;
    const RFsTreeItemIdList& entries(aTask->Entries());
    if (entries.Count())
        {
        if (ConfirmDeleteL(entries.Count(), entries[0]))
            {
            if (entries.Count() > KMsgDeletionWaitNoteAmount)
                {
                TFsEmailUiUtility::ShowWaitNoteL(iDeletingWaitNote,
                        R_FSE_WAIT_DELETING_TEXT, EFalse, ETrue);
                }
            if (iAsyncCallback)
                {
                // Call actual deletion asynchronously because we must give wait
                // note time to show up before deletion begins.
                iAsyncCallback->Cancel();
                iAsyncCallback->Set(TCallBack(DoExecuteDeleteTask, aTask));
                iAsyncCallback->CallBack();
                }
            }
        else
            {
            aTask->Reset();
            }
        }
    }

// ---------------------------------------------------------------------------
// DoExecuteDeleteTask
//
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::DoExecuteDeleteTask( TAny* aSelfPtr )
    {
    FUNC_LOG;
    TRAPD( error, 
            reinterpret_cast<TDeleteTask<CFSEmailUiMailListVisualiser>*>(aSelfPtr)->ExecuteL() );
    return error;
    }

// ---------------------------------------------------------------------------
// HandleDeleteTaskL
// This is called asynchronously by ConfirmAndStartDeleteTaskL
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleDeleteTaskL( const RFsTreeItemIdList& aEntries )
    {
    FUNC_LOG;
    // Close wait note if it was used
    if ( iDeletingWaitNote )
        {
        TRAPD( result, HandleDeleteTaskLeavingCodeL(aEntries) );
        // closing the "Deleting" dialog message should not be skipped by leaving
        TRAP_IGNORE( iDeletingWaitNote->ProcessFinishedL() ); 
        if ( KErrNone != result )
            {
            // Handle error.
            User::Leave( result );
            }
        }
    else
        {
        HandleDeleteTaskLeavingCodeL( aEntries );
        }
    }

// ---------------------------------------------------------------------------
// original code HandleDeleteTaskL which may leave - help function to enable 
// calling iDeletingWaitNote->ProcessFinishedL() 
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleDeleteTaskLeavingCodeL( const RFsTreeItemIdList& aEntries )
    {
    FUNC_LOG;
    TFSMailMsgId folderId = FolderId();
    TFSMailMsgId mailBox = iAppUi.GetActiveMailboxId();
    RArray<TFSMailMsgId> msgIds;
    CleanupClosePushL( msgIds );
    for ( TInt i = 0; i < aEntries.Count(); i++ )
        {
        msgIds.AppendL( MsgIdFromListId( aEntries[i] ) );
        }
    iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds );
    // Remove from mail list if not already removed by mailbox events
    RemoveMsgItemsFromListIfFoundL( msgIds );
    CleanupStack::PopAndDestroy(); // msgIds.Close()
    }

// ---------------------------------------------------------------------------
// ConfirmDeleteL
//
// ---------------------------------------------------------------------------
//
TBool CFSEmailUiMailListVisualiser::ConfirmDeleteL(const TInt aItemCount,
        const TFsTreeItemId aItemId) const
    {
    FUNC_LOG;
    TBool result(ETrue);
    if (iAppUi.GetCRHandler()->WarnBeforeDelete())
        {
        HBufC* noteText(NULL);
        // The note depends on the amount and type of message(s)
        if (aItemCount == 1)
            {
            const CFSMailMessage& msgPtr(MsgPtrFromListIdL(aItemId));
            HBufC* msgSubject = TFsEmailUiUtility::CreateSubjectTextLC(
                    &msgPtr);
            if (msgPtr.IsFlagSet(EFSMsgFlag_CalendarMsg))
                {
                noteText = StringLoader::LoadL(
                        R_FREESTYLE_EMAIL_DELETE_CALEVENT_NOTE, *msgSubject);
                }
            else
                {
                noteText = StringLoader::LoadL(
                        R_FREESTYLE_EMAIL_DELETE_MAIL_NOTE, *msgSubject);
                }
            CleanupStack::PopAndDestroy(msgSubject);
            CleanupStack::PushL(noteText);
            }
        else // markedEntries.Count() > 1
            {
            noteText = StringLoader::LoadLC(
                    R_FREESTYLE_EMAIL_DELETE_N_MAILS_NOTE, aItemCount);
            }

        // Show the note
        result = TFsEmailUiUtility::ShowConfirmationQueryL(*noteText);
        CleanupStack::PopAndDestroy(noteText);
        }
    return result;
    }

// ---------------------------------------------------------------------------
// RemoveUnnecessaryNodesL
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::RemoveUnnecessaryNodesL()
	{
    FUNC_LOG;
	RArray<TInt> nodesToBeRemoved;
	CleanupClosePushL( nodesToBeRemoved );
	for ( TInt i=0;i<iTreeItemArray.Count();i++)
		{
		if ( iMailList->IsNode( iTreeItemArray[i].iListItemId ) )
			{
			if ( iMailList->CountChildren( iTreeItemArray[i].iListItemId ) == 0)
				{
				nodesToBeRemoved.Append( iTreeItemArray[i].iListItemId );
				}
			}
		}
	// Remove from the list itself and from iTreeItemArray
	for ( TInt a = 0; a < nodesToBeRemoved.Count(); a++ )
		{
		iMailList->RemoveL( nodesToBeRemoved[a] );
		SMailListItem item;
		item.iListItemId = nodesToBeRemoved[a];
		TInt IndexToBeDestroyed = iTreeItemArray.Find( item );
		iTreeItemArray.Remove( IndexToBeDestroyed ); // remove from internal array.
		// Remove from model
 		iModel->RemoveAndDestroy( IndexToBeDestroyed );
		}
	CleanupStack::PopAndDestroy( &nodesToBeRemoved );
	}

// ---------------------------------------------------------------------------
// MsgIdFromIndex
// Helper function to get message id from list index
// ---------------------------------------------------------------------------
//
TFSMailMsgId CFSEmailUiMailListVisualiser::MsgIdFromIndex( TInt aItemIdx ) const
    {
    FUNC_LOG;
	TFSMailMsgId msgId; // constructs null ID
    // <cmail>
    if ( 0 <= aItemIdx && aItemIdx < iModel->Count() )
    // </cmail>
        {
        CFSEmailUiMailListModelItem* item =
    			static_cast<CFSEmailUiMailListModelItem*>(iModel->Item(aItemIdx));
    	if ( item->ModelItemType() == ETypeMailItem )
    	    {
    	    msgId = item->MessagePtr().GetMessageId();
    	    }
        }

    return msgId;
    }

// ---------------------------------------------------------------------------
// MsgIdFromListId
// Get message ID corresponding given list ID. If the list ID is for a node,
// the message ID of its first child is returned
// ---------------------------------------------------------------------------
//
TFSMailMsgId CFSEmailUiMailListVisualiser::MsgIdFromListId( TFsTreeItemId aListId ) const
	{
    FUNC_LOG;
    TFSMailMsgId msgId; // constructs null ID

    if ( aListId != KFsTreeNoneID )
        {
        // Find corresponding message from the model
        const TInt modelCount( iModel->Count() );
        for( TInt i( 0 ) ; i < modelCount ; ++i )
            {
            CFSEmailUiMailListModelItem* item =
                static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( i ) );
            if ( aListId == item->CorrespondingListId() )
                {
                msgId = item->MessagePtr().GetMessageId();
                // if list id points to separator
                // set flag on. This is made for improving focus handling.
                if( item->ModelItemType() == ETypeSeparator )
                    {
                    msgId.SetSeparator( ETrue );
                    }
                break;
                }
            }
        }

	return msgId;
	}

// ---------------------------------------------------------------------------
// MsgPtrFromListIdL
//
// ---------------------------------------------------------------------------
//
CFSMailMessage& CFSEmailUiMailListVisualiser::MsgPtrFromListIdL( TFsTreeItemId aListId )
	{
    FUNC_LOG;
	TInt index = ModelIndexFromListId( aListId );
	if ( index >= 0 )
	    {
    	CFSEmailUiMailListModelItem* item =
    		static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(index) );
    	return item->MessagePtr();
	    }
	else
	    {
    	// Leave if no message found. As the function returns a reference, it is not
    	// possible to return any meaningful null value.
    	User::Leave( KErrNotFound );
	    }

	CFSMailMessage* dummy = NULL;
	return *dummy; // to surpress warning about missing return value; this is not really ever run
	}

// ---------------------------------------------------------------------------
// MsgPtrFromListIdL
//
// ---------------------------------------------------------------------------
//
const CFSMailMessage& CFSEmailUiMailListVisualiser::MsgPtrFromListIdL( TFsTreeItemId aListId ) const
    {
    FUNC_LOG;
    TInt index = ModelIndexFromListId( aListId );
    if ( index >= 0 )
        {
        CFSEmailUiMailListModelItem* item =
            static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(index) );
        return item->MessagePtr();
        }
    else
        {
        // Leave if no message found. As the function returns a reference, it is not
        // possible to return any meaningful null value.
        User::Leave( KErrNotFound );
        }

    const CFSMailMessage* dummy = NULL;
    return *dummy; // to surpress warning about missing return value; this is not really ever run
    }

// ---------------------------------------------------------------------------
// ItemDataFromItemId
// Function returns a valid pointer to list item data based on item id
// ---------------------------------------------------------------------------
//
MFsTreeItemData* CFSEmailUiMailListVisualiser::ItemDataFromItemId( TFsTreeItemId aItemId )
	{
    FUNC_LOG;
	MFsTreeItemData* itemData = NULL;
	if ( aItemId != KFsTreeNoneID )
	    {
	    itemData = &iMailList->ItemData( aItemId );
	    }
	return itemData;
	}

// ---------------------------------------------------------------------------
// ItemVisualiserFromItemId
// Function returns a valid pointer to list item visualiser based on item id
// ---------------------------------------------------------------------------
//
MFsTreeItemVisualizer* CFSEmailUiMailListVisualiser::ItemVisualiserFromItemId( TFsTreeItemId aItemId )
	{
    FUNC_LOG;
	MFsTreeItemVisualizer* itemVis = NULL;
    if ( aItemId != KFsTreeNoneID )
        {
        itemVis = &iMailList->ItemVisualizer( aItemId );
        }
	return itemVis;
	}

// ---------------------------------------------------------------------------
// ItemIndexFromMessageId
// Function returns list index based on message pointer. KErrNotFound if
// ID is not included in the list
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::ItemIndexFromMessageId( const TFSMailMsgId& aMessageId ) const
    {
    FUNC_LOG;
	TInt idx = KErrNotFound;

	// Check first the special case; if searched id is null id, there's no
	// point to loop the whole list. There shouldn't be any null id's in
	// the model anyway. There is currently also an error in FW's equality
	// operator implementation; it doesn't check the iNullId flag at all.
	if( !aMessageId.IsNullId() )
	    {
	    const TInt modelCount( iModel->Count() );
    	for ( TInt i( 0 ); i < modelCount ; ++i )
    		{
    		CFSEmailUiMailListModelItem* item =
                static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( i ) );
			// when the item is a separator check whether its MessagePtr is valid (actually it's a reference)
			if( &(item->MessagePtr()) != NULL)
				{
    		if ( aMessageId == item->MessagePtr().GetMessageId() )
    			{
    			TModelItemType itemType = item->ModelItemType();
    			TBool separator( aMessageId.IsSeparator() );

    			// Because separator and the first message after separator
    			// have same message id, we need to separate these cases
    			// and that is made with separator flag which is stored to
    			// TFSMailMsgId object. If separator flag is on item need to be
    			// separator if it is not on item needs to be mail item.
    			if( ( separator && itemType == ETypeSeparator ) ||
    			    ( !separator && itemType == ETypeMailItem ) )
                    {
                    idx = i;
                    break;
                    }
    			}
    		}
        }
		}
	return idx;
    }

// ---------------------------------------------------------------------------
// NextMessageIndex
// Function returns next message index from highlighted index
// KErrNotFound if there is no next message
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::NextMessageIndex( TInt aCurMsgIdx ) const
    {
    FUNC_LOG;
	TInt idx = KErrNotFound;
	for ( TInt i=aCurMsgIdx+1 ; i<iModel->Count() ; i++ )
		{
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(i) );
		if ( item && item->ModelItemType() == ETypeMailItem )
			{
			idx = i;
			break;
			}
		}

	return idx;
    }

// ---------------------------------------------------------------------------
// PreviousMessageIndex
// Function returns previous message index from highlighted index
// KErrNotFound if there is no previous message
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::PreviousMessageIndex( TInt aCurMsgIdx ) const
    {
    FUNC_LOG;
	TInt idx( KErrNotFound );
	if ( aCurMsgIdx < iModel->Count() )
	    {
    	for ( TInt i=aCurMsgIdx-1 ; i>=0 ; i-- )
    		{
    		CFSEmailUiMailListModelItem* item =
    			static_cast<CFSEmailUiMailListModelItem*>( iModel->Item(i) );
    		if ( item && item->ModelItemType() == ETypeMailItem )
    			{
    			idx = i;
    			break;
    			}
    		}
	    }
	return idx;
    }

// ---------------------------------------------------------------------------
// ModelIndexFromListId
// Function returns a model index corresponding the given tree list item ID
// ---------------------------------------------------------------------------
//
TInt CFSEmailUiMailListVisualiser::ModelIndexFromListId( TFsTreeItemId aItemId ) const
	{
    FUNC_LOG;
    TInt ret = KErrNotFound;
    const TInt count = iModel->Count();
    for ( TInt i=0; i < count; i++ )
    	{
    	const CFSEmailUiMailListModelItem* item =
		    static_cast<const CFSEmailUiMailListModelItem*>( iModel->Item(i) );
    	if ( aItemId == item->CorrespondingListId() )
    		{
    		ret = i;
    		break;
    		}
    	}
    return ret;
	}

// ---------------------------------------------------------------------------
// FolderSelectedL
// Folder list selection callback. Function updates list when folder is changed
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::FolderSelectedL(
	TFSMailMsgId aSelectedFolderId,
	TFSEmailUiCtrlBarResponse aResponse )
	{
    FUNC_LOG;
    // hide selector if keys are not pressed
    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
	if ( iMoveToFolderOngoing )
		{
		iMoveToFolderOngoing = EFalse;
		switch ( aResponse )
			{
			case EFSEmailUiCtrlBarResponseCancel:
			    SetMskL();
				return;
			case EFSEmailUiCtrlBarResponseSelect:
			    {
				MoveMsgsToFolderL( aSelectedFolderId );
				SetMskL();
			    }
				break;
			default:
				break;
			}
		}
	else
		{
		// Ignore if cancel selected
		switch ( aResponse )
			{
			case EFSEmailUiCtrlBarResponseSwitchList:
				{
				TFSFolderType folderType;
				if ( iMailFolder )
					{
					folderType = iMailFolder->GetFolderType();
					}
				else
					{
					folderType = EFSInbox;
					}
			    iControlBarControl->SetFocusByIdL( iSortButtonId );
			    iControlBarControl->MakeSelectorVisible( IsFocusShown() );

			    // Sorting empty mail list disabled
                // Show sort list only if mail list is not empty
                if ( iModel->Count() )
                    {
                    iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton );
                    }
				}
				return;
			case EFSEmailUiCtrlBarResponseCancel:
			    SetMskL();
			    // <cmail> Touch
                //Set touchmanager back to active
                DisableMailList(EFalse);
                // </cmail>
				return;
			case EFSEmailUiCtrlBarResponseSelect:
			    SetMskL();
			    // <cmail> Touch
                //Set touchmanager back to active
                DisableMailList(EFalse);
                // </cmail>
			default:
				break;
			}

		if ( !iMailFolder || ( iMailFolder && iMailFolder->GetFolderId() != aSelectedFolderId ) )
		    {
		    iMailListModelUpdater->Cancel();
		    SafeDelete(iMailFolder);
            iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( iAppUi.GetActiveMailboxId(), aSelectedFolderId );

            if ( !iMailFolder )
                {
                // Do nothing if can't get the folder object
                return;
                }

            // Set new text to folder button in control bar
            HBufC* newFolderName = CreateFolderNameLC( iMailFolder );
            iFolderListButton->SetTextL( *newFolderName );
            CleanupStack::PopAndDestroy( newFolderName );

            // Set initial sort criteria when folder has changed
            iCurrentSortCriteria.iField = EFSMailSortByDate;
            iCurrentSortCriteria.iOrder = EFSMailDescending;
            // reload node state because in file sort mode this is disabled even when globally enabled
            iNodesInUse = iAppUi.GetCRHandler()->TitleDividers();
            SetSortButtonTextAndIconL();

            // Update the mail list contents
            UpdateMailListModelL();
            RefreshL();
		    }
        iFocusedControl = EControlBarComponent;
        SetListAndCtrlBarFocusL();
        iMoveToFolderOngoing = EFalse;
		}
	SetMskL();
	}

// ---------------------------------------------------------------------------
// MailboxSelectedL
// Mailbox selection callback. Function updates list when mailbox is changed
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::MailboxSelectedL( TFSMailMsgId aSelectedMailboxId )
	{
    FUNC_LOG;
    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
    //Set touchmanager back to active
    DisableMailList(EFalse);
	iAppUi.SetActiveMailboxL( aSelectedMailboxId );
	iMailListModelUpdater->Cancel();
	SafeDelete(iMailFolder);
	iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( iAppUi.GetActiveMailboxId(), iAppUi.GetActiveBoxInboxId() );

	// Set initial sort criteria when folder has changed
    iCurrentSortCriteria.iField = EFSMailSortByDate;
    iCurrentSortCriteria.iOrder = EFSMailDescending;
    // reload node state because in file sort mode this is disabled even when globally enabled
    iNodesInUse = iAppUi.GetCRHandler()->TitleDividers();
    SetSortButtonTextAndIconL();

    // Set folder name to the control bar button
    HBufC* newFolderName = CreateFolderNameLC( iMailFolder );
    iFolderListButton->SetTextL( *newFolderName );
    CleanupStack::PopAndDestroy( newFolderName );

    // Set mailbox name and icons
    SetMailboxNameToStatusPaneL();
    SetBrandedListWatermarkL();
    SetBrandedMailBoxIconL();

    // Update model
    UpdateMailListModelL();
    iMailList->RemoveAllL();
    RefreshDeferred();

	// Check sync icon timer and sync status
    ConnectionIconHandling();
	iFocusedControl = EControlBarComponent;
	}

// ---------------------------------------------------------------------------
// FolderButtonRect
// Getter for folder button rectangle. Folder popup needs to get this
// information when screen layout changes.
// ---------------------------------------------------------------------------
//
TRect CFSEmailUiMailListVisualiser::FolderButtonRect()
    {
    FUNC_LOG;
    const TPoint& buttonPos = iFolderListButton->Pos().Target();
    const TPoint& buttonSize = iFolderListButton->Size().Target();
    TRect buttonRect( buttonPos, buttonSize.AsSize() );
    return buttonRect;
    }

// ---------------------------------------------------------------------------
// SortOrderChangedL
// Sort order selection callback. Function updates list when sorting is changed
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::SortOrderChangedL(
	TFSMailSortField aSortField, TFSEmailUiCtrlBarResponse aResponse )
	{
    FUNC_LOG;
	// Ignore if cancel selected
	switch( aResponse )
		{
		case EFSEmailUiCtrlBarResponseSwitchList:
			{
			iControlBarControl->MakeSelectorVisible( IsFocusShown() );
		    iControlBarControl->SetFocusByIdL( iFolderListButtonId );
	   		iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton );
			}
            return;
		case EFSEmailUiCtrlBarResponseCancel:
		    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
		    SetMskL();
		    // <cmail> Touch
            //Set touchmanager back to active
            DisableMailList(EFalse);
            return;

		case EFSEmailUiCtrlBarResponseSelect:
		    iControlBarControl->MakeSelectorVisible( IsFocusShown() );
            //Set touchmanager back to active
            DisableMailList(EFalse);
            // </cmail>
		default:
			break;
		}

	// Check is the selected sort field same as the previous one
	if( iCurrentSortCriteria.iField == aSortField )
		{
		// If same sort field selected, switch the sorting order
		if( iCurrentSortCriteria.iOrder == EFSMailAscending )
			{
			iCurrentSortCriteria.iOrder = EFSMailDescending;
			}
		else
			{
			iCurrentSortCriteria.iOrder = EFSMailAscending;
			}
		}
	else if ( aSortField == EFSMailSortBySubject ||
			  aSortField == EFSMailSortBySender ||
			  aSortField == EFSMailSortByUnread || // <cmail>
			  aSortField == EFSMailSortByRecipient )
		{
		iCurrentSortCriteria.iOrder = EFSMailAscending;
		}
	else
		{
		iCurrentSortCriteria.iOrder = EFSMailDescending;
		}

	iCurrentSortCriteria.iField = aSortField;

	// Size sorting does not use nodes, so disable those, otherwise check from CR
	iNodesInUse = iAppUi.GetCRHandler()->TitleDividers();
	SetSortButtonTextAndIconL();

	iFocusedControl = EControlBarComponent;
	iMailList->SetFocusedL( EFalse );
    iControlBarControl->SetFocusByIdL( iSortButtonId );

    // <cmail>
	if ( iMailListUpdater )
	    {
    	// Start updating mail list with sorting parameter.
    	iMailListUpdater->StartL( ETrue );
	    }
    // </cmail>
	SetMskL();
	}

// ---------------------------------------------------------------------------
// SortButtonRect
// Getter for sort button rectangle. Sort popup needs to get this
// information when screen layout changes.
// ---------------------------------------------------------------------------
//
TRect CFSEmailUiMailListVisualiser::SortButtonRect()
    {
    FUNC_LOG;
    const TPoint& buttonPos = iSortButton->Pos().Target();
    const TPoint& buttonSize = iSortButton->Size().Target();
    TRect buttonRect( buttonPos, buttonSize.AsSize() );
    return buttonRect;
    }

// ---------------------------------------------------------------------------
// OpenHighlightedMailL
// Function opens highlighted mail either to internal viewer or to mrui if
// message type is meeting
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::OpenHighlightedMailL()
    {
    FUNC_LOG;
    OpenMailItemL( iMailList->FocusedItem() );
    }

// ---------------------------------------------------------------------------
// OpenHighlightedMailL
// Function opens given mail item either to internal viewer or to mrui if
// message type is meeting
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::OpenMailItemL( TFsTreeItemId aMailItem )
	{
    FUNC_LOG;
	TInt idx = ModelIndexFromListId( aMailItem );
	if ( idx >= 0 )
	    {
	    CFSEmailUiMailListModelItem* item =
	        static_cast<CFSEmailUiMailListModelItem*>( Model()->Item(idx) );
	    if ( item->ModelItemType() == ETypeMailItem )
	        {
	        // First make sure that the highlighted message really exists in the store
	        // Get confirmed msg ptr
	        CFSMailMessage* confirmedMsgPtr(0);
	        confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL(iAppUi.GetActiveMailboxId(),
	                iMailFolder->GetFolderId(), item->MessagePtr().GetMessageId(), EFSMsgDataEnvelope );
	        if ( confirmedMsgPtr )
	            {
	            iMailOpened = ETrue;

	            ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY );
	            // Pointer confirmed, store Id and delete not needed anymore
	            TFSMailMsgId confirmedId = confirmedMsgPtr->GetMessageId();
	      		TBool isCalMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_CalendarMsg );
	      		TBool isReadMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_Read );
	            delete confirmedMsgPtr;
	            // Open to editor from drafts
	            if ( iMailFolder->GetFolderType() == EFSDraftsFolder )
	                {
	                if ( !isCalMessage ) // Open only normal messages for now
	                	{
		                TEditorLaunchParams params;
		                params.iMailboxId = iAppUi.GetActiveMailboxId();
		                params.iActivatedExternally = EFalse;
		                params.iMsgId = confirmedId;
		                params.iFolderId = iMailFolder->GetFolderId();
		                iAppUi.LaunchEditorL( KEditorCmdOpen, params );
	                	}
	                else
	               	 	{
	                	//Try to open to editor if support for that is needed
	                	}
	                }
	            else if ( iMailFolder->GetFolderType() == EFSOutbox )
	                {
	                TFsEmailUiUtility::ShowErrorNoteL( R_FREESTYLE_EMAIL_UI_OPEN_FROM_OUTBOX_NOTE, ETrue );
	                }
	            else
	                {
                    THtmlViewerActivationData htmlData;
                    htmlData.iActivationDataType = THtmlViewerActivationData::EMailMessage;
                    htmlData.iMailBoxId = iAppUi.GetActiveMailbox()->GetId();
                    htmlData.iFolderId = FolderId();
                    htmlData.iMessageId = confirmedId;
                    TPckgBuf<THtmlViewerActivationData> pckgData( htmlData );

                    // Change read status only if needed
                    if ( !isReadMessage )
                        {
                        ChangeReadStatusOfHighlightedL( ETrue );
                        }

                    // Opening viewer seems to take more time than other views,
                    // so we do longer fade out in this case
                    SetNextTransitionOutLong( ETrue );

                    iAppUi.EnterFsEmailViewL( HtmlViewerId, KHtmlViewerOpenNew, pckgData );
	                }
	            }
	        }
	    }
	}

// ---------------------------------------------------------------------------
// 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 CFSEmailUiMailListVisualiser::OperationCompleteL(
    TContactHandlerCmd /*aCmd*/, const RPointerArray<CFSEmailUiClsItem>& /*aContacts*/ )
    {
    FUNC_LOG;
    }

// ---------------------------------------------------------------------------
// From MFSEmailUiContactHandlerObserver
// Handles error in contact handler operation.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::OperationErrorL( TContactHandlerCmd /*aCmd*/,
    TInt /*aError*/ )
    {
    FUNC_LOG;
    }

// ---------------------------------------------------------------------------
// NotifyDateChangedL
// Called when CDateChangeTimer completes. This happens when either when date
// changes or when user alters the system time. Redraws the list to ensure
// that time stamp texts in emails and nodes are up-to-date.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::NotifyDateChangedL()
    {
    FUNC_LOG;
    iDateChanged = ETrue;
    if ( iAppUi.IsForeground() )
        {
        HandleForegroundEventL(ETrue);
        }
    }

// ---------------------------------------------------------------------------
// CreateFolderNameLC
// Creates folder name from folder ptr. Localised if standard folder.
// ---------------------------------------------------------------------------
//
HBufC* CFSEmailUiMailListVisualiser::CreateFolderNameLC( const CFSMailFolder* aFolder ) const
	{
    FUNC_LOG;
	TInt resourceId(0);
	HBufC* ret(0);
	if ( !aFolder || aFolder->GetFolderId().IsNullId() )
		{
		// INBOX FOR NULL ID
		resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_INBOX;
		}
	else
		{
		TInt folderType = aFolder->GetFolderType();
		switch ( folderType )
			{
			case EFSInbox:
				{
				resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_INBOX;
				}
				break;
			case EFSOutbox:
				{
				resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_OUTBOX;
				}
				break;
			case EFSDraftsFolder:
				{
				resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_DRAFTS;
				}
				break;
			case EFSSentFolder:
				{
				resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_SENT;
				}
				break;
			case EFSDeleted:
				{
				resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_DELETED;
				}
				break;
			default:
				// Not a standard folder
				break;
			}
		}
	if ( resourceId )
		{
		ret = StringLoader::LoadLC( resourceId );
		}
	else
		{
		ret = aFolder->GetFolderName().AllocLC();
		}
	return ret;
	}

// ---------------------------------------------------------------------------
// LaunchStylusPopupMenuL
// Function launches avkon stylus popup menu based on the selected message item/items
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::LaunchStylusPopupMenuL( const TPoint& aPoint )
	{
	// Irrelevant items for focused mail list item get dimmed at runtime

	// Check mail list item's type
	CFSEmailUiMailListModelItem* item =
		static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );
	if ( item )
		{
		if ( item->ModelItemType() == ETypeMailItem )
			{
			// Add mark as read / unread options
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, !IsMarkAsUnreadAvailableL() );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsRead, !IsMarkAsReadAvailableL() );

			// Check support for object mail iten moving
			TBool supportsMoving = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, !supportsMoving );

			// Hide / show follow up
			TBool supportsFlag = TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsFlag, !supportsFlag );

			// Hide mark if applicable
			if ( iMailList->IsMarked( iMailList->FocusedItem() ) )
				{
				iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMark, ETrue );
				}

			// Hide collapse / expand all
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, ETrue );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, ETrue );
			}
		else if ( item->ModelItemType() == ETypeSeparator )
			{
			// Hide mark as read / unread options
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, ETrue );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsRead, ETrue );

			// Hide move & follow up
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, ETrue );
			iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsFlag, ETrue );

			// Hide collapse / expand all when applicable
			if ( iNodesInUse == EListControlSeparatorDisabled || !iModel->Count() )
				{
				iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, ETrue );
				iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, ETrue );
				}
			else
				{
				iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, AllNodesCollapsed() );
				iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, AllNodesExpanded() );
				}
			}
		}

	// Set the position for the popup
	iStylusPopUpMenu->SetPosition( aPoint );

	// Display the popup and set the flag to indicate that the menu was
	// launched.
	iStylusPopUpMenu->ShowMenu();
	iStylusPopUpMenuVisible = ETrue;
	}

// ---------------------------------------------------------------------------
// CreateNewMsgL
// Launches editor.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::CreateNewMsgL()
	{
    FUNC_LOG;
	TEditorLaunchParams params;
	params.iMailboxId = iAppUi.GetActiveMailboxId();
	params.iActivatedExternally = EFalse;
    iAppUi.LaunchEditorL( KEditorCmdCreateNew, params );
	}

void CFSEmailUiMailListVisualiser::ReplyL( CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
    // Replying not possible from drafts folder
    if ( iMailFolder && iMailFolder->GetFolderType() != EFSDraftsFolder )
        {
        DoReplyForwardL( KEditorCmdReply, aMsgPtr );
        }
	}

void CFSEmailUiMailListVisualiser::ReplyAllL(  CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
    // Replying all not possible from drafts folder
    if ( iMailFolder && iMailFolder->GetFolderType() != EFSDraftsFolder )
        {
        DoReplyForwardL( KEditorCmdReplyAll, aMsgPtr );
        }
	}

void CFSEmailUiMailListVisualiser::ForwardL( CFSMailMessage* aMsgPtr )
	{
    FUNC_LOG;
    DoReplyForwardL( KEditorCmdForward, aMsgPtr );
	}

// ---------------------------------------------------------------------------
// DoReplyForwardL
// Launches editor with either reply all forward command
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::DoReplyForwardL( TEditorLaunchMode aMode, CFSMailMessage* aMsgPtr )
    {
    FUNC_LOG;
    // Reply, reply all, and forward commands are inavailable in the outbox
    // <cmail>
    if ( iModel->Count() && iMailFolder && iMailFolder->GetFolderType() != EFSOutbox )
    // </cmail>
        {
        CFSMailMessage* messagePointer = aMsgPtr;
    	if ( !messagePointer  )
    		{
    		RFsTreeItemIdList targetEntries;
    		CleanupClosePushL( targetEntries );
    		GetActionsTargetEntriesL( targetEntries );
    		// action is possible only when there's exactly one marked or focused mail item
    		if ( targetEntries.Count() == 1 )
    			{
    			messagePointer = &MsgPtrFromListIdL( targetEntries[0] );
    			}
    		CleanupStack::PopAndDestroy( &targetEntries );
    		}
    	if ( messagePointer )
    		{
            // Opening editor is slower than opening most other views.
    		// Use longer transition effect to mask this.
            SetNextTransitionOutLong( ETrue );

    		TEditorLaunchParams params;
    		params.iMailboxId = iAppUi.GetActiveMailboxId();
    		params.iActivatedExternally = EFalse;
    		params.iMsgId = messagePointer->GetMessageId();
    		iAppUi.LaunchEditorL( aMode, params );
    		}
        }
    }

// ---------------------------------------------------------------------------
// HandleMailBoxEventL
// Mailbox event handler, responds to events sent by the plugin.
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::HandleMailBoxEventL( TFSMailEvent aEvent,
    TFSMailMsgId aMailboxId, TAny* aParam1, TAny* aParam2, TAny* aParam3 )
    {
    FUNC_LOG;

    // Complete any pending asynchronous redrawing before handling the event
    // to make sure that all the arrays are in consistent state
    CompletePendingRefresh();

    // Handle the event
    if ( iFirstStartCompleted &&
         aMailboxId == iAppUi.GetActiveMailboxId() ) // Safety, in list events that only concern active mailbox are handled
        {
		if ( aEvent == TFSEventFoldersDeleted )
            {
			// Check whether the current folder gets deleted
			// Change mail item icon or read status
			RArray<TFSMailMsgId>* removedEntries = static_cast<RArray<TFSMailMsgId>*>( aParam1 );
			if ( iMailFolder && removedEntries && removedEntries->Count() )
				{
				TFSMailMsgId currentFolderId = iMailFolder->GetFolderId();
				for ( TInt i = 0; i < removedEntries->Count(); i++ )
					{
					TFSMailMsgId entryId = (*removedEntries)[i];
					if ( entryId == currentFolderId )
						{
						// Current folder deleted, try to revert back to standard folder inbox.
						iMailListModelUpdater->Cancel();
						SafeDelete(iMailFolder);
						TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox );
						if ( !inboxId.IsNullId() )
						    {
						    iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, inboxId );
						    UpdateMailListModelL();
					        RefreshL();
							HBufC* newFolderName = CreateFolderNameLC( iMailFolder );
						    iFolderListButton->SetTextL( *newFolderName );
							CleanupStack::PopAndDestroy( newFolderName );
						    }
						else
							{
							// No standard folder inbox, go back to grid as a last option
							HandleCommandL( EAknSoftkeyBack );
							}
						break;
						}
					}
				}
			}
		else if ( aEvent == TFSEventMailboxRenamed )
            {
			if ( iThisViewActive )
				{
				SetMailboxNameToStatusPaneL();
				}
			}
	 	else if ( (aEvent == TFSEventMailDeleted || aEvent == TFSEventMailDeletedFromViewer) && iMailFolder ) // <cmail> Added iMailFolder null safety check </cmail>
			{
			// Change mail item icon or read status
			RArray<TFSMailMsgId>* removedEntries = static_cast<RArray<TFSMailMsgId>*>(aParam1);
			if ( removedEntries && removedEntries->Count() )
				{
				TFSMailMsgId* parentFolderId = static_cast<TFSMailMsgId*>( aParam2 );
				TFSMailMsgId currentFolderId = iMailFolder->GetFolderId();
				if ( parentFolderId && ( *parentFolderId == currentFolderId ) )
					{
	 				// Refresh mailfolder to get correct actual data
                    /*
                    iMailListModelUpdater->Cancel();
					SafeDelete(iMailFolder);
					iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId );
					*/
					RemoveMsgItemsFromListIfFoundL( *removedEntries );
					}
				}
			}
		else if ( aEvent == TFSEventNewMail )
		    {
			// Switch to standardfolder inbox if we have null folderid.
			// This is usually the case with first time sync.
			if ( FolderId().IsNullId() )
				{
				// Refresh mailfolder to standard folder inbox in case of zero id
                iMailListModelUpdater->Cancel();
				SafeDelete(iMailFolder);
				TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox );
				if ( !inboxId.IsNullId() )
				    {
				    iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, inboxId );
				    // Check that mailfolder fetching succeeded
				    if ( iMailFolder )
				    	{
						HBufC* newFolderName = CreateFolderNameLC( iMailFolder );
					    iFolderListButton->SetTextL( *newFolderName );
						CleanupStack::PopAndDestroy( newFolderName );
				    	}
				    }
				}
			// Null pointer check is needed here because of special cases such as new mail
			// creation in POP/IMAP before first sync where folder does not exists
			if ( iMailFolder )
				{
	            RArray<TFSMailMsgId>* newMessages = static_cast< RArray<TFSMailMsgId>* >( aParam1 );
				TFSMailMsgId* parentFolderId = static_cast<TFSMailMsgId*>( aParam2 );
				TFSMailMsgId currentFolderId = iMailFolder->GetFolderId();
				// Update the mail list only if the event is related to the currently open folder
				if ( *parentFolderId == currentFolderId )
				    {
				    InsertNewMessagesL( *newMessages );
				    }
				}
		    }
		else if ( aEvent == TFSEventMailMoved && iMailFolder )	// Added iMailFolder null safety check
			{
            // If message was moved FROM this folder, just remove the entry from the list.
            // If message is moved TO this folder, update the list completely.
            // Otherwise, the event does not have an influence on the current folder.
			RArray<TFSMailMsgId>* entries = static_cast< RArray<TFSMailMsgId>* >( aParam1 );
			TFSMailMsgId* toFolderId = static_cast<TFSMailMsgId*>( aParam2 );
			TFSMailMsgId* fromFolderId = static_cast<TFSMailMsgId*>( aParam3 );
			TFSMailMsgId currentFolderId = iMailFolder->GetFolderId();

            if ( toFolderId && ( currentFolderId == *toFolderId ) )
                {
                InsertNewMessagesL( *entries );
                }
            else if ( fromFolderId && ( currentFolderId == *fromFolderId ) )
                {
 	 			// Refresh mailfolder to get correct actual data
                /*
                iMailListModelUpdater->Cancel();
                SafeDelete(iMailFolder);
				iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId );
				*/
				RemoveMsgItemsFromListIfFoundL( *entries );
                }
            else
                {
                // event is not related to the current folder => do nothing
                }
			}
		else if ( aEvent == TFSEventMailChanged && iMailFolder ) // Added iMailFolder null safety check
			{
			//if ( !iMailOpened ) // do not handle mail changed while viewer/editor is open. This may cause flickering
			    {
    			// Change mail item icon or read status
    			RArray<TFSMailMsgId>* entries = static_cast<RArray<TFSMailMsgId>*>( aParam1 );
    			TFSMailMsgId* parentFolderId = static_cast<TFSMailMsgId*>( aParam2 );
    			TFSMailMsgId currentFolderId = iMailFolder->GetFolderId();
    			if ( *parentFolderId == currentFolderId )
    				{
     	 			// Refresh mailfolder to get correct actual data
    				/*
                    iMailListModelUpdater->Cancel();
                    SafeDelete(iMailFolder);
    				iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId );
    				*/
    				for ( TInt i=0 ; i<entries->Count() ; i++ )
    					{
    					TFSMailMsgId msgId = (*entries)[i];
    					TInt idx = ItemIndexFromMessageId( msgId );
    					if ( idx != KErrNotFound )
    					    {
    					    UpdateItemAtIndexL( idx );
    					    }
    					}
    				}
			    }
			}
   		else if ( aEvent == TFSEventMailboxSyncStateChanged )
   			{
	  		TSSMailSyncState* newSyncState = static_cast<TSSMailSyncState*>( aParam1 );
    		if ( newSyncState != 0 && *newSyncState != 0 )
    			{
	    		switch ( *newSyncState )
	    			{
	    			case StartingSync:
	   			    {
	   			    //If sync was started by user, show the synchronisation indicator
	   			    if ( iManualMailBoxSync )
	   			        {
			   		ManualMailBoxSync(EFalse);
	   				}
		   		    }
				    break;

	    			case SyncCancelled:
	    			    {
	    			    //If sync was started by user, show the synchronisation indicator
	    			    if ( iManualMailBoxSync )
	    			        {
	    			        ManualMailBoxSync(EFalse);
	    			        }
	    			    }
	    			    break;

	    			}
    			}
			}
		}
	}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::TreeListEventL( const TFsTreeListEvent aEvent,
                                                   const TFsTreeItemId aId,
                                                   const TPoint& /*aPoint*/ )
	{
    FUNC_LOG;
    switch( aEvent )
        {
        case EFsTreeListItemWillGetFocused:
            {
            if( aId != KFsTreeNoneID )
                {
                UpdatePreviewPaneTextIfNecessaryL( aId, EFalse );
                }
            break;
            }
        case EFsTreeListItemTouchFocused:
            {
            break;
            }
        case EFsFocusVisibilityChange:
            {
            iAppUi.SetFocusVisibility( EFalse );
            break;
            }
        default:
            {
            // Do not handle other events
            break;
            }

        }
	}

// ---------------------------------------------------------------------------
// UpdateMailListSettingsL
// Function reads and updates mail list specific settings from the cen rep
// ---------------------------------------------------------------------------
//
void CFSEmailUiMailListVisualiser::UpdateMailListSettingsL()
	{
    FUNC_LOG;
	if ( iAppUi.GetCRHandler() )
		{
		iNodesInUse = iAppUi.GetCRHandler()->TitleDividers();
		TInt lineValue = iAppUi.GetCRHandler()->MessageListLayout();
		TInt bodyPreviewValue = iAppUi.GetCRHandler()->BodyPreview();
		if ( lineValue == 1 ) // 1-line layouts
			{
			if ( bodyPreviewValue == 0 )
				{
				iListMode = EListControlTypeSingleLinePreviewOff;
				}
			else
				{
				iListMode = EListControlTypeSingleLinePreviewOn;
				}
			}
		else //
			{
			if ( bodyPreviewValue == 0 )
				{
				iListMode = EListControlTypeDoubleLinePreviewOff;
				}
			else
				{
				iListMode = EListControlTypeDoubleLinePreviewOn;
				}
			}
		}
	else
		{
		iNodesInUse = EListControlSeparatorDisabled;
		iListMode = EListControlTypeDoubleLinePreviewOff;
		}
	}

void CFSEmailUiMailListVisualiser::UpdateMailListTimeDateSettings()
	{
    FUNC_LOG;
    TLocale currentLocaleSettings;
	iDateFormats.iTimeFormat = currentLocaleSettings.TimeFormat();
	iDateFormats.iDateFormat = currentLocaleSettings.DateFormat();
	iDateFormats.iAmPmPosition = currentLocaleSettings.AmPmSymbolPosition();
	// Second time separartor
	iDateFormats.iTimeSeparator = currentLocaleSettings.TimeSeparator( 1 );
	// Second date separartor
	iDateFormats.iDateSeparator = currentLocaleSettings.DateSeparator( 1 );
	}

STimeDateFormats CFSEmailUiMailListVisualiser::MailListTimeDateSettings()
	{
    FUNC_LOG;
	return iDateFormats;
	}


void CFSEmailUiMailListVisualiser::SetMailboxNameToStatusPaneL()
	{
    FUNC_LOG;
    iAppUi.SetActiveMailboxNameToStatusPaneL();
	}

void CFSEmailUiMailListVisualiser::SetBrandedMailBoxIconL()
	{
    FUNC_LOG;
	// Get and draw branded mailbox icon
	MFSMailBrandManager& brandManager = iAppUi.GetMailClient()->GetBrandManagerL();
	CGulIcon* mailBoxIcon(0);
	TRAPD( err, mailBoxIcon = brandManager.GetGraphicL( EFSMailboxIcon,  iAppUi.GetActiveMailboxId() ) );
	if ( err == KErrNone && mailBoxIcon )
		{
		CleanupStack::PushL( mailBoxIcon );
        //<cmail>
		TSize defaultIconSize(iAppUi.LayoutHandler()->GetControlBarMailboxIconRect().Size());
        //</cmail>
    	AknIconUtils::SetSize(mailBoxIcon->Bitmap(), defaultIconSize);
	    AknIconUtils::SetSize(mailBoxIcon->Mask(), defaultIconSize);
		// Create texture into TextureManager, If not already existing
	    iAppUi.FsTextureManager()->CreateBrandedMailboxTexture( mailBoxIcon,
	    		                                                iAppUi.GetActiveMailboxId().PluginId(),
	    		                                                iAppUi.GetActiveMailboxId().Id(),
	    		                                                defaultIconSize );
	    // Get branded mailbox icon
	    iMailBoxIconTexture = &iAppUi.FsTextureManager()->TextureByMailboxIdL( iAppUi.GetActiveMailboxId().PluginId(),
	    		                                                               iAppUi.GetActiveMailboxId().Id(),
	    		                                                               defaultIconSize );
		iFolderListButton->SetIconL( *iMailBoxIconTexture );
		CleanupStack::PopAndDestroy( mailBoxIcon );
		}
	else
		{
		iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) );
		}
	}


void CFSEmailUiMailListVisualiser::SetBrandedListWatermarkL()
	{
    FUNC_LOG;
	MFSMailBrandManager& brandManager = iAppUi.GetMailClient()->GetBrandManagerL();
	CGulIcon* mailBoxWatermarkIcon(0);
	TRAPD( err, mailBoxWatermarkIcon = brandManager.GetGraphicL( EFSWatermark,  iAppUi.GetActiveMailboxId() ) );
	if ( err == KErrNone && mailBoxWatermarkIcon )
		{
		CleanupStack::PushL( mailBoxWatermarkIcon );
		TRect mainPaneRect;
	 	AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
		TInt xPos = mainPaneRect.iBr.iX/100*40; // 40% of main pane width
		TInt yPos = mainPaneRect.iBr.iY/100*40; // 40% of main pane height
	    TSize defaultWaterMarkSize(xPos,yPos);
    	AknIconUtils::SetSize(mailBoxWatermarkIcon->Bitmap(), defaultWaterMarkSize);
	    AknIconUtils::SetSize(mailBoxWatermarkIcon->Mask(), defaultWaterMarkSize);
		if ( !iMailBoxWatermarkTexture )
			{
			// iMailBoxWatermarkTexture = CAlfTexture::NewL( *iEnv, Id() ); // DOLATER - Replaced by line below, creates blank texture until UploadL's replaced by something
			iMailBoxWatermarkTexture = &CAlfStatic::Env().TextureManager().BlankTexture();
			}
		// DOLATER - Gone from Alfred, needs to be replaced with something
		//iMailBoxWatermarkTexture->UploadL( *mailBoxWatermarkIcon->Bitmap(), mailBoxWatermarkIcon->Mask() );
		CleanupStack::PopAndDestroy( mailBoxWatermarkIcon );
		TPoint watermarkPosition( mainPaneRect.iBr.iX-xPos-20, mainPaneRect.iBr.iY-yPos-20  );
   		iMailTreeListVisualizer->SetWatermarkPos( watermarkPosition );
		iMailTreeListVisualizer->SetWatermarkSize( defaultWaterMarkSize );
		iMailTreeListVisualizer->SetWatermarkOpacity( 0.3 );
		iMailTreeListVisualizer->SetWatermarkL( iMailBoxWatermarkTexture );
		}
	else
		{
		// Not found, hide watermark
		iMailTreeListVisualizer->SetWatermarkOpacity( 0 );
		}
	}

TFsTreeItemId CFSEmailUiMailListVisualiser::ParentNode( TFsTreeItemId aItemId ) const
    {
    FUNC_LOG;
	if ( iNodesInUse )
		{
		TFsTreeItemId parentNodeId = iMailList->Parent( aItemId );
		if ( iMailList->IsNode( parentNodeId ) )
			{
			return parentNodeId;
			}
		}
	return KErrNotFound;
    }

TBool CFSEmailUiMailListVisualiser::DoScrollMarkUnmarkL()
    {
    FUNC_LOG;
    TBool ret = EFalse;

    // <cmail>
    if ( iFocusedControl == EMailListComponent && iModel->Count() )
    // </cmail>
        {
		CFSEmailUiMailListModelItem* item =
			static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( HighlightedIndex() ) );

		if ( item->ModelItemType() == ETypeMailItem )  // Separators are not markable
		    {
			if ( !iListMarkItemsState )
				{
       			iMailList->MarkItemL( iMailList->FocusedItem(), EFalse );
				}
			else
				{
       			iMailList->MarkItemL( iMailList->FocusedItem(), ETrue );
				}
			ret = ETrue;
           	}
        }

    return ret;
    }

// Mark / unmark all items under current separator
void CFSEmailUiMailListVisualiser::MarkItemsUnderSeparatorL( TBool aMarked, TInt aSeparatorId )
	{
	FUNC_LOG;

	if ( iTreeItemArray.Count() )
		{
		// Find all items under wanted separator.
		for ( TInt i = aSeparatorId + 1; i < iTreeItemArray.Count(); i++ )
			{
			CFSEmailUiMailListModelItem* item =
						static_cast<CFSEmailUiMailListModelItem*>( iModel->Item( i ) );

			// Mark / unmark mail items.
			if ( item &&
				 item->ModelItemType() == ETypeMailItem &&
				 !iMailList->IsNode( iTreeItemArray[i].iListItemId ) )
				{
				iMailList->MarkItemL( iTreeItemArray[i].iListItemId, aMarked );
				}
			else
				{
				// Stop iteration since another iterator was reached.
				break;
				}
			}
		}
	}
// Navigation functions, used mainly from viewer
TBool CFSEmailUiMailListVisualiser::IsNextMsgAvailable( TFSMailMsgId aCurrentMsgId,
														TFSMailMsgId& aFoundNextMsgId,
														TFSMailMsgId& aFoundNextMsgFolder ) const
	{
    FUNC_LOG;
	TBool ret(EFalse);
	TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId );
	if ( curIdx >= 0 )
	    {
	    TInt nextIdx = NextMessageIndex(curIdx);
	    if ( nextIdx >= 0 )
	        {
	        ret = ETrue;
	        aFoundNextMsgId = MsgIdFromIndex(nextIdx);
	        aFoundNextMsgFolder = iMailFolder->GetFolderId();
	        }
	    }

	return ret;
	}

TBool CFSEmailUiMailListVisualiser::IsPreviousMsgAvailable( TFSMailMsgId aCurrentMsgId,
															TFSMailMsgId& aFoundPreviousMsgId,
															TFSMailMsgId& aFoundPrevMsgFolder ) const
	{
    FUNC_LOG;
	TBool ret(EFalse);
	TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId );
	if ( curIdx >= 0 )
	    {
	    TInt prevIdx = PreviousMessageIndex(curIdx);
	    if ( prevIdx >= 0 )
	        {
	        ret = ETrue;
	        aFoundPreviousMsgId = MsgIdFromIndex(prevIdx);
	        aFoundPrevMsgFolder = iMailFolder->GetFolderId();
	        }
	    }

	return ret;
	}

TInt CFSEmailUiMailListVisualiser::MoveToNextMsgL( TFSMailMsgId aCurrentMsgId, TFSMailMsgId& aFoundNextMsgId )
	{
    FUNC_LOG;
	TInt ret(KErrNotFound);

	TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId );
	TInt nextIdx = NextMessageIndex( curIdx );

	if ( curIdx >= 0 && nextIdx >= 0 )
	    {
	    // Focus the new message
	    // <cmail>
	    iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[nextIdx].iListItemId, EFalse );
	    // </cmail>
	    ChangeReadStatusOfHighlightedL( ETrue );

        aFoundNextMsgId = MsgIdFromIndex( nextIdx );
	    ret = KErrNone;
	    }
	if ( ret == KErrNone )
		{
		OpenHighlightedMailL();
		}
	return ret;
	}

TInt CFSEmailUiMailListVisualiser::MoveToPreviousMsgL( TFSMailMsgId aCurrentMsgId, TFSMailMsgId& aFoundPreviousMsgId )
	{
    FUNC_LOG;
	TInt ret(KErrNotFound);

	TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId );
	TInt prevIdx = PreviousMessageIndex( curIdx );

	if ( curIdx >= 0 && prevIdx >= 0 )
	    {
	    // Focus the new message
	    // <cmail>
	    iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[prevIdx].iListItemId, EFalse );
	    // </cmail>
	    ChangeReadStatusOfHighlightedL( ETrue );
        aFoundPreviousMsgId = MsgIdFromIndex( prevIdx );
	    ret = KErrNone;
	    }

	if ( ret == KErrNone )
		{
		OpenHighlightedMailL();
		}
	return ret;
	}

TInt CFSEmailUiMailListVisualiser::MoveToPreviousMsgAfterDeleteL( TFSMailMsgId aFoundPreviousMsgId )
	{
	FUNC_LOG;
	TInt ret(KErrNotFound);

	TInt idx = ItemIndexFromMessageId( aFoundPreviousMsgId );
	if ( idx >= 0 )
		{
		// Focus the previous message
		iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[idx].iListItemId, EFalse );
		ChangeReadStatusOfHighlightedL( ETrue );
		ret = KErrNone;
		}

	if ( ret == KErrNone )
		{
		OpenHighlightedMailL();
		}

	return ret;
	}

void CFSEmailUiMailListVisualiser::ManualMailBoxSync( TBool aManualMailBoxSync )
	{
    FUNC_LOG;
	iManualMailBoxSync = aManualMailBoxSync;
	}

TBool CFSEmailUiMailListVisualiser::GetLatestSyncState()
	{
    FUNC_LOG;
	CFSMailBox* activeMailbox = iAppUi.GetActiveMailbox();

    TBool ret = EFalse;

    if ( activeMailbox )
        {
    	TSSMailSyncState latestSyncstate = activeMailbox->CurrentSyncState();
    	if(latestSyncstate == InboxSyncing ||
    	   latestSyncstate == StartingSync ||
    	   latestSyncstate == EmailSyncing ||
    	   latestSyncstate == OutboxSyncing ||
    	   latestSyncstate == SentItemsSyncing ||
    	   latestSyncstate == DraftsSyncing ||
    	   latestSyncstate == CalendarSyncing ||
    	   latestSyncstate == ContactsSyncing ||
    	   latestSyncstate == TasksSyncing ||
    	   latestSyncstate == NotesSyncing ||
    	   latestSyncstate == FilesSyncing ||
    	   latestSyncstate == DataSyncStarting )
    		{
    		ret = ETrue;
    		}
        }

	return ret;
	}

void CFSEmailUiMailListVisualiser::ConnectionIconHandling()
    {
    FUNC_LOG;
    iAppUi.UpdateTitlePaneConnectionStatus();
    }

void CFSEmailUiMailListVisualiser::SetListAndCtrlBarFocusL()
    {
    FUNC_LOG;
    if ( iFocusedControl == EMailListComponent )
        {
        iMailList->SetFocusedL( ETrue );
        iControlBarControl->SetFocusL( EFalse );
        }
    else
        {
        if( iStylusPopUpMenuVisible )
        	{
        	return;
        	}

        iMailList->SetFocusedL( EFalse );
        TInt focusedBtnId = KErrNotFound;
        MFsControlButtonInterface* focusedBtn = iControlBarControl->GetFocusedButton();
        if ( focusedBtn )
            {
            focusedBtnId = focusedBtn->Id();
            }
        iControlBarControl->SetFocusL( ETrue );
        if ( focusedBtnId != KErrNotFound )
            {
            iControlBarControl->SetFocusByIdL( focusedBtnId );
            }
        iControlBarControl->MakeSelectorVisible( IsFocusShown() );
        }
    }

void CFSEmailUiMailListVisualiser::GetParentLayoutsL( RPointerArray<CAlfVisual>& aLayoutArray ) const
    {
    aLayoutArray.AppendL( iScreenAnchorLayout );
    aLayoutArray.AppendL( iControlBarControl->Visual() );
    }

// Sets aActiveMailboxId and aActiveFolderId from iMailFolder if available
TInt CFSEmailUiMailListVisualiser::GetActiveFolderId(TFSMailMsgId& aActiveMailboxId, TFSMailMsgId& aActiveFolderId) const
    {
    if (iMailFolder != NULL)
        {
        aActiveMailboxId = iMailFolder->GetMailBoxId();
        aActiveFolderId = iMailFolder->GetFolderId();
        return KErrNone;
        }
    else
        {
         return KErrNotFound;
        }
    }

void CFSEmailUiMailListVisualiser::CreateExtensionL()
    {
    CFSMailBox* box = iAppUi.GetActiveMailbox();
    CEmailExtension* ext=NULL;
    if (box)
        {
        ext = box->ExtensionL( KEmailMailboxStateExtensionUid );
        }
    if (ext)
        {
        iExtension = reinterpret_cast<CMailboxStateExtension*>( ext );
        iExtension->SetStateDataProvider( this );
        }
    }

//////////////////////////////////////////////////////////////////
// Class implementation CMailListUpdater
///////////////////////////////////////////////////////////////////


// -----------------------------------------------------------------------------
// CMailListUpdater::NewL
// NewL function. Returns timer object.
// -----------------------------------------------------------------------------
//
CMailListUpdater* CMailListUpdater::NewL( CFSEmailUiMailListVisualiser* aMailListVisualiser )
    {
    FUNC_LOG;
    CMailListUpdater* self = new (ELeave) CMailListUpdater( aMailListVisualiser );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
// CMailListUpdater::~CMailListUpdater
// D'tor
// -----------------------------------------------------------------------------
//
CMailListUpdater::~CMailListUpdater()
    {
    FUNC_LOG;
    Cancel();
    }

// -----------------------------------------------------------------------------
// CMailListUpdater::CMailListUpdater
// C'tor
// -----------------------------------------------------------------------------
//
CMailListUpdater::CMailListUpdater( CFSEmailUiMailListVisualiser* aMailListVisualiser  )
	: CTimer( EPriorityStandard ),
	iMailListVisualiser( aMailListVisualiser )
    {
    FUNC_LOG;
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// CMailListUpdater::RunL
// Timer trigger function.
// -----------------------------------------------------------------------------
//
void CMailListUpdater::RunL()
    {
    FUNC_LOG;
    if ( iIsSorting )
    	{
	   	iMailListVisualiser->UpdateMailListModelL();
	   	iMailListVisualiser->RefreshL();
		// Sorting is completed
		iIsSorting = EFalse;
	   	// Dismiss wait note.
	   	if ( iWaitNote )
	   		{
		   	iWaitNote->ProcessFinishedL();
	   		}
    	}
    else
    	{
		// Store the list of marked items. The markings are erased when the list
		// is repopulated and, hence, the markings need to be reset after the
		// refreshing is done. The marked items must be identified by the message
		// ID rather than with the list ID because refreshing may change the list IDs.
		RArray<TFSMailMsgId> markedMessages;
		CleanupClosePushL( markedMessages );
		iMailListVisualiser->GetMarkedMessagesL( markedMessages );

		// Store the message ID of the focused item
	    TFSMailMsgId msgIdBeforeRefresh;
	   	TFsTreeItemId firstVisibleListId = iMailListVisualiser->iMailTreeListVisualizer->FirstVisibleItem();
	    TInt modelFirstIndexBeforeUpdate = iMailListVisualiser->ModelIndexFromListId( firstVisibleListId );
	  	TInt highlightedIndexBeforeUpdate = iMailListVisualiser->HighlightedIndex();
	    TInt modelCountBeforeUpdate = iMailListVisualiser->iModel->Count();
	    if ( iMailListVisualiser->iModel->Count() )
	    	{
	  		CFSEmailUiMailListModelItem* item =
				static_cast<CFSEmailUiMailListModelItem*>(iMailListVisualiser->iModel->Item( highlightedIndexBeforeUpdate ) );
			if ( item && item->ModelItemType() == ETypeMailItem )
				{
			    msgIdBeforeRefresh = item->MessagePtr().GetMessageId();
				}
	    	}

	   	iMailListVisualiser->UpdateMailListModelL();
	   	iMailListVisualiser->RefreshL( &msgIdBeforeRefresh );

		// Focus is set to last focused item. After this, try to keep the same first item that previous
		// Check how many messages have been added
	  	TInt modelIndexDifference = highlightedIndexBeforeUpdate-modelFirstIndexBeforeUpdate; // 0 or more
		if ( modelIndexDifference < 0 )
			{
			modelIndexDifference = 0; // safety
			}
		TInt toBeFirstIdx = iMailListVisualiser->HighlightedIndex() - modelIndexDifference;
		CFSEmailUiMailListModelItem* toBeFirstVisItem =
			static_cast<CFSEmailUiMailListModelItem*>( iMailListVisualiser->iModel->Item(toBeFirstIdx) );
		if ( toBeFirstVisItem )
			{
			// <cmail>
			iMailListVisualiser->iMailTreeListVisualizer->SetFirstVisibleItemL( toBeFirstVisItem->CorrespondingListId() );
			// </cmail>
			}

		// Restore the marking status
		iMailListVisualiser->MarkMessagesIfFoundL( markedMessages );
		CleanupStack::PopAndDestroy( &markedMessages );
    	}
    Cancel();
   }

// -----------------------------------------------------------------------------
// CMailListUpdater::Start
// Timer starting function.
// -----------------------------------------------------------------------------
//
void CMailListUpdater::StartL( TBool aIsSorting )
    {
    FUNC_LOG;
    if ( iWaitNote )
    	{
    	iWaitNote->ProcessFinishedL();
    	}

    iIsSorting = aIsSorting;
    Cancel();
    if ( iIsSorting )
    	{
		// Start wait note
    	TFsEmailUiUtility::ShowWaitNoteL( iWaitNote, R_FSE_WAIT_SORTING_TEXT, EFalse, ETrue );
	 	After( 10 ); // Update shortly after selection has been made.
    	}
    else
    	{
    	 // Mail added update
	 	After( KMsgUpdaterTimerDelay ); // Update after 1,5 seconds
    	}
   	}

// -----------------------------------------------------------------------------
// CMailListUpdater::Stop
// Timer stopping function
// -----------------------------------------------------------------------------
//
void CMailListUpdater::Stop()
    {
    FUNC_LOG;
    Cancel();
    }



//////////////////////////////////////////////////////////////////
// Class implementation CMsgMovedNoteTimer
///////////////////////////////////////////////////////////////////


// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::NewL
// NewL function. Returns timer object.
// -----------------------------------------------------------------------------
//
CMsgMovedNoteTimer* CMsgMovedNoteTimer::NewL(  CFreestyleEmailUiAppUi* aAppUi, CFSEmailUiMailListVisualiser* aMailListVisualiser  )
    {
    FUNC_LOG;
    CMsgMovedNoteTimer* self = new (ELeave) CMsgMovedNoteTimer( aAppUi, aMailListVisualiser );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::CMsgMovedNoteTimer
// D'tor
// -----------------------------------------------------------------------------
//
CMsgMovedNoteTimer::~CMsgMovedNoteTimer()
    {
    FUNC_LOG;
    Cancel();
    }

// -----------------------------------------------------------------------------
// CMailListUpdater::CMailListUpdater
// C'tor
// -----------------------------------------------------------------------------
//
CMsgMovedNoteTimer::CMsgMovedNoteTimer(  CFreestyleEmailUiAppUi* aAppUi, CFSEmailUiMailListVisualiser* aMailListVisualiser   )
	: CTimer( EPriorityStandard ),
	iAppUi( aAppUi),
	iMailListVisualiser( aMailListVisualiser )
    {
    FUNC_LOG;
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::RunL
// Timer trigger function.
// -----------------------------------------------------------------------------
//
void CMsgMovedNoteTimer::RunL()
    {
    FUNC_LOG;
 	TFsEmailUiUtility::DisplayMsgsMovedNoteL( iMsgCount, iDestinationFolderId, EFalse );
    Cancel();
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::Start
// Timer starting function.
// -----------------------------------------------------------------------------
//
void CMsgMovedNoteTimer::Start(  TInt aMsgCount, const TFSMailMsgId aDestinationFolderId  )
    {
    FUNC_LOG;
    Cancel();
	iMsgCount = aMsgCount,
	iDestinationFolderId = aDestinationFolderId;
	TInt viewSlideinTime = iAppUi->LayoutHandler()->ViewSlideEffectTime();
	if ( viewSlideinTime == 0 )
		{
		viewSlideinTime = 100;
		}
 	After( viewSlideinTime );
   	}

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::Stop
// Timer stopping function
// -----------------------------------------------------------------------------
//
void CMsgMovedNoteTimer::Stop()
    {
    FUNC_LOG;
    Cancel();
    }


//////////////////////////////////////////////////////////////////
// Class implementation CDateChnageTimer
///////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::NewL
// Two phased constructor
// -----------------------------------------------------------------------------
//
CDateChangeTimer* CDateChangeTimer::NewL( CFSEmailUiMailListVisualiser& aMailListVisualiser )
    {
    FUNC_LOG;
    CDateChangeTimer* self = new ( ELeave ) CDateChangeTimer( aMailListVisualiser );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::CDateChangeTimer
// First phase constructor
// -----------------------------------------------------------------------------
//
CDateChangeTimer::CDateChangeTimer( CFSEmailUiMailListVisualiser& aMailListVisualiser )
    : CTimer( EPriorityStandard ), iMailListVisualiser( aMailListVisualiser )
    {
    FUNC_LOG;
    CActiveScheduler::Add( this );
    iDayCount = DayCount();
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::~CDateChangeTimer
// Destructor
// -----------------------------------------------------------------------------
//
CDateChangeTimer::~CDateChangeTimer()
    {
    FUNC_LOG;
    // no implementation needed
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::Start
// Request event at 00:00 tomorrow
// -----------------------------------------------------------------------------
//
void CDateChangeTimer::Start()
    {
    FUNC_LOG;
    TTime now;
    now.HomeTime();

    // Construct target time
    TTime eventTime = now + TTimeIntervalDays( 1 );
    TDateTime eventDateTime = eventTime.DateTime();
    eventDateTime.SetHour(0);
    eventDateTime.SetMinute(0);
    eventDateTime.SetSecond(0);
    eventDateTime.SetMicroSecond(0);
    eventTime = TTime( eventDateTime );

    // Issue the request
    At( eventTime );
    }

// -----------------------------------------------------------------------------
// CMsgMovedNoteTimer::RunL
// Function gets called when system time reaches the 00:00 in the next day or
// when the system time has been changed by the user. Both cases can be handled
// in the same way.
// -----------------------------------------------------------------------------
//
void CDateChangeTimer::RunL()
    {
    FUNC_LOG;

    if (iStatus.Int() != KErrNone)
        {
        	INFO_1("### CDateChangeTimer::RunL (err=%d) ###", iStatus.Int());
        }


    TBool dayChanged = EFalse;
    TInt dayCount = DayCount();
    if (dayCount != iDayCount)
        {

        iDayCount = dayCount;
        dayChanged = ETrue;
        }


    if ( KErrCancel == iStatus.Int() )
        {
        ;
        }
    else if ( KErrAbort == iStatus.Int() ) // System time changed
        {
        if (dayChanged)
            {
            TRAP_IGNORE( iMailListVisualiser.NotifyDateChangedL() );
            }
        Start();
        }
    else  // interval is over
        {
        // Update mail list and reissue the request for timer event
        TRAP_IGNORE( iMailListVisualiser.NotifyDateChangedL() );
        Start();
        }

    }


TInt CDateChangeTimer::DayCount()
    {
    TTime now;
    now.HomeTime();
    TTime minTime = Time::MinTTime();
    TTimeIntervalDays days = now.DaysFrom(minTime);
    return days.Int();
    }








