iaupdate/IAD/ui/src/iaupdateuicontroller.cpp
changeset 0 ba25891c3a9e
child 9 51c0f5edf5ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iaupdate/IAD/ui/src/iaupdateuicontroller.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,2721 @@
+/*
+* Copyright (c) 2007-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 module contains the implementation of CIAUpdateUiController
+*                class member functions.
+*
+*/
+
+
+
+// INCLUDES
+#include <avkon.hrh>
+#include <StringLoader.h> 
+#include <centralrepository.h>
+#include <AknUtils.h>
+#include <SWInstDefs.h>
+#include <avkon.rsg>
+#include <featurecontrol.h>
+#include <iaupdate.rsg>
+#include <iaupdateparameters.h>
+
+#include "iaupdateuicontroller.h"
+#include "iaupdateuicontrollerobserver.h"
+#include "iaupdateappui.h"
+#include "iaupdate.hrh"
+#include "iaupdatewaitdialog.h"
+#include "iaupdateprogressdialog.h"
+#include "iaupdatenode.h"
+#include "iaupdatefwnode.h"
+#include "iaupdatebasenode.h"
+#include "iaupdatenodefilter.h"
+#include "iaupdatefactory.h"
+#include "iaupdatestarter.h"
+#include "iaupdateprivatecrkeys.h"
+#include "iaupdatecontrollerfile.h"
+#include "iaupdateuiconfigdata.h"
+#include "iaupdatedialogutil.h"
+#include "iaupdateutils.h"
+#include "iaupdateagreement.h"
+#include "iaupdateautomaticcheck.h"
+#include "iaupdateroaminghandler.h"
+#include "iaupdatependingnodesfile.h"
+#include "iaupdaterestartinfo.h"
+#include "iaupdaterresultsfile.h"
+#include "iaupdaterresult.h"
+#include "iaupdateridentifier.h"
+#include "iaupdateruids.h"
+#include "iaupdaterdefs.h"
+#include "iaupdatetools.h"
+#include "iaupdateparametersfilemanager.h"
+#include "iaupdateerrorcodes.h"
+#include "iaupdatefileconsts.h"
+#include "iaupdatefirsttimeinfo.h"
+#include "iaupdaterefreshhandler.h"
+#include "iaupdatedebug.h"
+
+
+// cenrep in emulator:
+// copy 2000F85A.txt to '\epoc32\release\winscw\udeb\Z\private\10202be9\'
+// delete 2000F85A.txt from 'epoc32\winscw\c\private\10202be9\persists'
+//
+// cenrep in hardware:
+// copy 2000F85A.txt to '\epoc32\data\Z\private\10202be9'
+//
+
+
+// This is a static function that is used with RPointerArray::Sort to sort
+// the nodes according to their node depths and other special values.
+TInt SortSelectedNodes( const MIAUpdateNode& aNode1, const MIAUpdateNode& aNode2 )
+    {
+    // Temporarily use the const_cast here to get the base node.
+    // After that, base node is set back to const. So, the casting here
+    // is safe to do.
+    const MIAUpdateBaseNode& baseNode1( 
+        const_cast< MIAUpdateNode& >( aNode1 ).Base() );
+    const MIAUpdateBaseNode& baseNode2( 
+        const_cast< MIAUpdateNode& >( aNode2 ).Base() );
+
+    if ( baseNode1.Uid().iUid == KIAUpdaterUid
+         && baseNode2.Uid().iUid != KIAUpdaterUid )
+        {
+        // Self updater should always be the first one
+        // in the node array.
+        return -1;
+        }
+    else if ( baseNode2.Uid().iUid == KIAUpdaterUid
+              && baseNode1.Uid().iUid != KIAUpdaterUid )
+        {
+        // Self updater should always be the first one
+        // in the node array.
+        return 1;
+        }
+    else if ( aNode1.IsSelfUpdate() && !aNode2.IsSelfUpdate() )
+        {
+        // Self updates always before normal nodes.
+        return -1;
+        }
+    else if ( !aNode1.IsSelfUpdate() && aNode2.IsSelfUpdate() )
+        {
+        // Self updates always before normal nodes.
+        return 1;
+        }
+    else
+        {
+        // The depth can be used in normal cases to make sure that dependency
+        // nodes are handled before their dependants. Notice, that this is
+        // a safe way even if dependency chain contains hidden nodes.
+        // The dependency nodes should be before its dependants in the array.
+        // The depth value informs how deep in the dependency hierarchy the node is.
+        // A depth value zero means that the node is a root. If multiple branches lead to
+        // a same node, then the greatest depth value is used for the node.
+        // The node can not ever depend on the node that has the same or greater depth.
+
+        TInt depthDiff( aNode2.Depth() - aNode1.Depth() );
+
+        if ( depthDiff != 0 )
+            {
+            // Depths were different.
+            // In some cases, the user may have chosen a dependency node only
+            // and left the dependant out. Then this node may be moved unnecessarily
+            // in the array. But because dependecies may change the selection order
+            // usually quite much, the possible unnecessary movement here should not
+            // matter. Notice, that using the depth values is really safe way to make
+            // sure the dependency nodes are handled before their dependants.
+            return depthDiff;
+            }
+        else
+            {
+            // Because depthDiffs equal we need to do some additional checking.
+            // This kind of comparison is also used in the filter.
+            // See: CIAUpdateNodeFilter::CompareAndMarkFilterNodes
+            TInt importanceDiff( 
+                baseNode2.Importance() - baseNode1.Importance() );
+            if ( importanceDiff != 0 )
+                {
+                // Sort according to the importance because importances
+                // differ.
+                return importanceDiff;
+                }
+            else
+                {
+                // Because evertyhing else matched, we finally check
+                // the name. Items should be handled in alphabetical order
+                // now.
+                return baseNode1.Name().CompareC( baseNode2.Name() );
+                }
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CIAUpdateUiController* CIAUpdateUiController::NewLC( 
+    MIAUpdateUiControllerObserver& aObserver )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewLC() begin");
+    CIAUpdateUiController* self = 
+        new( ELeave ) CIAUpdateUiController( aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewLC() end");
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CIAUpdateUiController* CIAUpdateUiController::NewL( 
+    MIAUpdateUiControllerObserver& aObserver )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewL() begin");
+    CIAUpdateUiController* self = 
+        CIAUpdateUiController::NewLC( aObserver );
+    CleanupStack::Pop( self );
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewL() end");
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::CIAUpdateUiController
+// C++ constructor
+// -----------------------------------------------------------------------------
+//
+CIAUpdateUiController::CIAUpdateUiController( 
+    MIAUpdateUiControllerObserver& aObserver )
+: iObserver( aObserver ),
+  iState( EIdle )
+    {    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CIAUpdateUiController()");
+    iEikEnv = CEikonEnv::Static();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::ConstructL
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::ConstructL()
+    {    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() begin");
+        
+    iClosingAllowedByClient = ETrue;
+    iController = 
+        IAUpdateFactory::CreateControllerL( 
+            TUid::Uid( KIAUpdateFamilyUid ), *this );
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 1");
+    iFilter = CIAUpdateNodeFilter::NewL();
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 2");
+
+    // Notice, this will read the init values from the file
+    // if the file exists. Otherwise, default values are used.
+    iControllerFile = 
+        CIAUpdateControllerFile::NewL( IAUpdateFileConsts::KControllerFile );
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 3");
+    
+    iConfigData = CIAUpdateUiConfigData::NewL();
+    
+    iOffConfigurated = !IAUpdateEnabledL();
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() end");   
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::~CIAUpdateUiController
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CIAUpdateUiController::~CIAUpdateUiController()
+    {    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::~CIAUpdateUiController() begin");
+
+    CancelOperation();
+    delete iController;
+    iNodes.Reset();
+    iFwNodes.Reset();
+    iSelectedNodesArray.Reset();
+    iServicePackNodes.Reset();
+    delete iFilter;
+    delete iControllerFile;
+    delete iIdle;
+    delete iStarter;
+    delete iConfigData;
+    delete iRoamingHandler;
+    delete iParams;
+    delete iRefreshHandler;
+    delete iPreviousSelections;
+
+    // If dialogs have not been released yet, release them now.
+    // ProcessFinishedL() should normally be used for dialogs but
+    // here just use non-leaving delete. In normal cases, dialogs should
+    // already be released in the end of the update flow before coming here.
+    delete iWaitDialog;
+    delete iProgressDialog;
+        
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::~CIAUpdateUiController() end");
+    }        
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::ConfigData
+// Returns the configuration data from the config file.
+// -----------------------------------------------------------------------------
+//
+const CIAUpdateUiConfigData& CIAUpdateUiController::ConfigData() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConfigData()");
+    return *iConfigData;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::SetDefaultConnectionMethodL
+// Sets the connection method for the update network connection.
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::SetDefaultConnectionMethodL( const TIAUpdateConnectionMethod& aMethod )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetDefaultConnectionMethodL() begin");
+
+    iController->SetDefaultConnectionMethodL( aMethod );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetDefaultConnectionMethodL() end"); 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::CheckUpdatesL
+// Updates the update item list.
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::CheckUpdatesL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesL() begin");
+
+    iCountOfAvailableUpdates = 0;
+    
+    if ( iParams )
+        {
+    	iFilter->SetFilterParams( iParams ); //iParams ownership is changed
+    	iParams = NULL;
+        }
+     
+    TBool agreementAccepted( EFalse ); 
+    CIAUpdateAgreement* agreement = CIAUpdateAgreement::NewLC();
+    agreementAccepted = agreement->AgreementAcceptedL();
+    if ( ( !agreementAccepted )&& ( iRequestType != IAUpdateUiDefines::ECheckUpdates ) )
+        {
+        // agreement (disclaimer) dialog is not prompted when CheckUpdates is called
+        //
+        // Refresh from network is allowed when first time case 
+        iRefreshFromNetworkDenied = EFalse;
+    	agreementAccepted = agreement->AcceptAgreementL();	
+        }
+        	
+    CleanupStack::PopAndDestroy( agreement );
+             
+    if ( !agreementAccepted )
+        {
+        if ( iRequestType == IAUpdateUiDefines::ECheckUpdates )
+            {
+            CIAUpdateAutomaticCheck* automaticCheck = CIAUpdateAutomaticCheck::NewLC();
+            TBool autoUpdateCheckEnabled = automaticCheck->AutoUpdateCheckEnabledL();
+            CleanupStack::PopAndDestroy( automaticCheck );
+            if ( !autoUpdateCheckEnabled )
+                {
+                iObserver.RefreshCompleteL( ETrue, KErrNone );
+                return;
+                }
+            }
+        else if ( iRequestType == IAUpdateUiDefines::EShowUpdates )
+            {
+       	    iObserver.UpdateCompleteL( KErrNone ); 
+       	    return;
+       	    }
+       	else
+       	    {
+       	    CIAUpdateAppUi* appUi = 
+       	            static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
+            appUi->Exit();
+       	    return;	
+       	    }
+        }
+            
+    if ( iRequestType == IAUpdateUiDefines::EShowUpdates && iRefreshed )
+        {
+    	iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
+        iObserver.RefreshCompleteL( ETrue, KErrNone );
+        }
+    else
+        {
+        if ( IsStartedByLauncher() && AllowNetworkRefreshL() )
+            {
+        	iUserRoamingRejection = iRoamingHandler->RoamingRejectionL();
+            }
+
+        TInt ret( iController->Startup() );
+        if ( ret == KErrAlreadyExists )   
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Controller startup already done.");
+            // Controller startup has already been done. 
+            // So, no operation was started from the controller. 
+            // So, call StartupComplete directly from here. 
+    	    StartupComplete( KErrNone );
+            }
+        else
+            {
+            IAUPDATE_TRACE_1("[IAUPDATE] Controller startup error code: %d", ret);
+            // Something went wrong with controller startup if error code is not
+            // KErrNone here. Above, KErrAlreadyExists was handled separately.
+            // If ret is KErrInUse, then startup was still going on
+            // and new startup should not be called. Also, leave in that case.
+            User::LeaveIfError( ret );	
+            }	
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartUpdateL
+// Starts software updating
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::StartUpdateL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartUpdateL() begin");
+
+    // Just to be sure that self update related information
+    // is always in resetted state when new update flows are
+    // started.
+    iController->ResetSelfUpdate();
+
+    iUserRoamingRejection = iRoamingHandler->RoamingRejectionL();
+    if ( !iUserRoamingRejection )
+        {
+        CreateSelectedNodesArrayL();
+                
+        if ( !IAUpdateUtils::SpaceAvailableInInternalDrivesL( iSelectedNodesArray ) )
+            {
+    	    HBufC* noteText = NULL;
+            noteText = StringLoader::LoadLC( R_IAUPDATE_INSUFFICIENT_MEMORY );
+            IAUpdateDialogUtil::ShowInformationQueryL( *noteText ); 
+            CleanupStack::PopAndDestroy( noteText );
+            }
+        else
+            {
+            if ( !IsStartedByLauncher() )
+                {
+                if ( !iStarter )
+                    {
+                    // Notice, that the ownership of the filter parameters will
+                    // remain in the filter.
+                    CIAUpdateParameters* params = iFilter->FilterParams();
+        	        iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(), 
+        	                                           params->CommandLineArguments() );
+                    }
+                }
+            // Inform the controller that we are now starting updates. This way the
+            // controller can handle situations as a whole and not as one item at the
+            // time.
+            iController->StartingUpdatesL();
+            
+            iFileInUseError = EFalse;
+            // Set the node index to -1 because ContinueUpdateL increases it by one
+            // in the beginning of the function. So, we can use the ContinueUpdateL
+            // also in here.
+            iNodeIndex = -1;
+            ContinueUpdateL( EFalse );
+            }
+        }
+
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartUpdateL() end");
+    }
+
+  
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ContinueUpdateL
+// Continues software updating from the next node
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::ContinueUpdateL( TBool aSelfUpdateFinished )
+    {
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::ContinueUpdateL() begin: %d",
+                   aSelfUpdateFinished );
+    
+    // Get the node index of the next node.
+    // The node that is indexed by iNodeIndex has already been handled in
+    // previous loop. So, increase the temp index by one here as it will be done
+    // in the while loop below for real index.
+    TInt tmpIndex( iNodeIndex + 1 );
+    if ( tmpIndex > 0 
+        && tmpIndex < iSelectedNodesArray.Count()
+        && iSelectedNodesArray[ tmpIndex - 1 ]->IsSelfUpdate()
+        && !iSelectedNodesArray[ tmpIndex ]->IsSelfUpdate()
+        && !aSelfUpdateFinished
+        && iController->SelfUpdateDataExists() )
+        {
+        IAUPDATE_TRACE_1("[IAUPDATE] Self updates have been handled now: %d",
+                         iNodeIndex);
+        // Self update should be started now because
+        // current node is not anymore self update and previous nodes were.
+        // UpdateCompleteL will start the self updater and inform observers.
+        // If no self update data can be found, then there has been some error
+        // when self update data has been set. So, then there is no reason to start
+        // self updater here. In that case, continue normally in the while loop below if
+        // other items are waiting for update.
+        iNodeIndex++;
+        UpdateCompleteL( KErrNone );
+
+        // Do not continue after this.
+        return;
+        }
+
+    TBool nextUpdate( ETrue );
+    while ( nextUpdate )
+       {
+       IAUPDATE_TRACE_1("[IAUPDATE] Next update while loop: %d",
+                        iNodeIndex);
+       iNodeIndex++;
+       if ( iNodeIndex < iSelectedNodesArray.Count() )
+            {
+            MIAUpdateNode* selectedNode = iSelectedNodesArray[ iNodeIndex ];
+
+            // Only update items that have not been installed yet.
+            if ( !selectedNode->IsInstalled() )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Item not installed yet");    
+                if ( !selectedNode->IsDownloaded() )
+                    {
+                    // Because content has not been downloaded or installed yet,
+                    // it needs to be downloaded before it can be installed.
+                    IAUPDATE_TRACE("[IAUPDATE] Download");
+                    selectedNode->DownloadL( *this );
+                    iState = EDownloading;
+                    iClosingAllowedByClient = ETrue;
+                    ShowUpdatingDialogL( R_IAUPDATE_DOWNLOADING_NOTE,
+                                         selectedNode->Base().Name(),
+                                         iNodeIndex + 1,
+                                         iSelectedNodesArray.Count() ); 
+                    nextUpdate = EFalse;
+                    }
+                else
+                    {
+                    // Because content has been downloaded but not installed yet,
+                    // it needs to be installed now.
+                    IAUPDATE_TRACE("[IAUPDATE] Install");
+                    selectedNode->InstallL( *this );
+                    iState = EInstalling;
+                    iClosingAllowedByClient = EFalse;
+                    CIAUpdateAppUi* appUi = 
+                        static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
+                    appUi->StartWGListChangeMonitoring();
+                    ShowUpdatingDialogL( R_IAUPDATE_INSTALLING_NOTE,
+                                         selectedNode->Base().Name(),
+                                         iNodeIndex + 1,
+                                         iSelectedNodesArray.Count() ); 
+                    nextUpdate = EFalse;                     
+                    }      
+                }
+            }
+        else
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Update flow complete");
+            nextUpdate = EFalse;
+            UpdateCompleteL( KErrNone );	
+            }
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ContinueUpdateL() end");
+    }
+   
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartInstallL
+// Starts software installing
+// ---------------------------------------------------------------------------
+//    
+void CIAUpdateUiController::StartInstallL( MIAUpdateNode& aNode )   
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartInstallL() begin");
+   
+    if ( aNode.Type() == MIAUpdateNode::EPackageTypeServicePack )
+        {
+        iServicePackNodes.Reset();
+        aNode.GetDependenciesL( iServicePackNodes, ETrue );
+        }
+            
+    aNode.InstallL( *this );
+    iState = EInstalling;
+    CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
+    appUi->StartWGListChangeMonitoring();
+    iClosingAllowedByClient = EFalse;
+    ShowUpdatingDialogL( R_IAUPDATE_INSTALLING_NOTE,
+                         aNode.Base().Name(),
+                         iNodeIndex + 1,
+                         iSelectedNodesArray.Count()  );
+    
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartInstallL() end");
+    }
+
+    
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartRefreshL()
+// Starts meta data refresh
+// ---------------------------------------------------------------------------
+// 
+void CIAUpdateUiController::StartRefreshL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartRefreshL() begin");
+    
+    iCountOfAvailableUpdates = 0;
+    iClosingAllowedByClient = ETrue;
+    if ( iOffConfigurated  )
+        {
+        iObserver.RefreshCompleteL( ETrue, KErrNone );
+        }
+    else
+        {
+        iState = ERefreshing;    
+        TBool allowNetworkRefresh = AllowNetworkRefreshL();
+        iSelectedNodesArray.Reset();
+        iController->StartRefreshL( allowNetworkRefresh );
+            
+        if ( iRequestType == IAUpdateUiDefines::ECheckUpdates && iFilter->FilterParams() )
+            {
+            if ( iFilter->FilterParams()->ShowProgress() )
+                {
+                // to avoid flickering IAD is brought to foreground only when wait dialog is really shown
+                if ( allowNetworkRefresh )
+                    {
+                    iEikEnv->RootWin().SetOrdinalPosition( 0, ECoeWinPriorityNormal );
+                    HBufC* noteText = StringLoader::LoadLC( R_IAUPDATE_REFRESHING_UPDATE_LIST );
+                    ShowWaitDialogL( *noteText, ETrue );
+                    CleanupStack::PopAndDestroy( noteText );
+                    }
+                }
+            }
+        else
+            {
+            HBufC* noteText = StringLoader::LoadLC( R_IAUPDATE_REFRESHING_UPDATE_LIST );
+            ShowWaitDialogL( *noteText, EFalse );
+            CleanupStack::PopAndDestroy( noteText );
+            }
+        }
+    
+       
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartRefreshL() end");
+    }
+ 
+   
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::Nodes
+// 
+// ---------------------------------------------------------------------------
+//     
+const RPointerArray< MIAUpdateNode >& CIAUpdateUiController::Nodes() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Nodes()");
+    return iNodes;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::FwNodes
+// 
+// ---------------------------------------------------------------------------
+//     
+const RPointerArray<MIAUpdateFwNode>& CIAUpdateUiController::FwNodes() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::FwNodes()");
+    return iFwNodes;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::HistoryL
+// 
+// ---------------------------------------------------------------------------
+//  
+MIAUpdateHistory& CIAUpdateUiController::HistoryL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HistoryL()");
+    return iController->HistoryL();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::SetRequestType
+// 
+// ---------------------------------------------------------------------------
+void CIAUpdateUiController::SetRequestType( 
+    IAUpdateUiDefines::TIAUpdateUiRequestType aRequestType )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetRequestType() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] request type: %d", aRequestType );
+
+    iRequestType = aRequestType;    
+    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetRequestType() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::CancelOperation
+// 
+// ---------------------------------------------------------------------------    
+void CIAUpdateUiController::CancelOperation() 
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CancelOperation() begin");
+
+    // Set the flag to inform possible callback functions
+    // that operation cancell is going on.
+    iCancelling = ETrue;
+
+    if ( iIdle )
+        {
+    	iIdle->Cancel();
+        }
+    if ( iStarter )
+        {
+    	iStarter->Cancel();
+        }
+    if ( iRoamingHandler )
+        {
+    	iRoamingHandler->CancelPreparing();
+        }
+    
+	if ( iState == EDownloading || iState == EInstalling )
+	    {
+	    // Current node.
+        MIAUpdateNode* node( iSelectedNodesArray[ iNodeIndex ] );
+
+        // Cancel the operation of that node.
+    	node->CancelOperation();
+
+        // Also set the purchase history information to other nodes
+        // even if their operations were not started yet.
+        for ( TInt i = iNodeIndex + 1; i < iSelectedNodesArray.Count(); ++i )
+            {
+            node = iSelectedNodesArray[ i ];
+            if ( MIAUpdateNode::EPackageTypeServicePack == node->Type()
+                  && node->IsInstalled() )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Service pack was completed");
+                // Even if cancel occurred, some of the nodes inside the
+                // service pack were installed from some other dependency
+                // chain way. And, now there is nothing to be installed
+                // inside the service pack.
+                TRAP_IGNORE ( node->Base().
+                    SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue ) );
+                }
+            else
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Node cancelled");
+                // Notice, that this can also still be service pack node.
+                // Because we are handling nodes that are visible in UI,
+                // we can force the node as visible in history.
+                TRAP_IGNORE ( 
+                    node->Base().SetIdleCancelToPurchaseHistoryL( ETrue ) ); 
+                }
+            }
+	    }
+    else if ( iState == ERefreshing )
+        {
+        iController->CancelRefresh();
+        }
+
+    // Just to be sure that self update related information
+    // is always in resetted state when new update flows are
+    // started after operation cancel.
+	if ( iController )
+	    {
+	    iController->ResetSelfUpdate();
+	    }
+    // After cancellation, the new state is idle.
+    iState = EIdle;
+    iClosingAllowedByClient = ETrue;
+
+    // Cancelling is over. So, set the flag accrodingly.
+    iCancelling = EFalse;
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CancelOperation() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ResultsInfo
+// 
+// ---------------------------------------------------------------------------    
+TIAUpdateResultsInfo CIAUpdateUiController::ResultsInfo() const
+	{
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ResultsInfo() begin");
+
+	TIAUpdateResultsInfo resultsInfo( 0, 0, 0, iFileInUseError, EFalse );
+	for ( TInt i = 0; i < iSelectedNodesArray.Count(); ++i )
+	    {
+	    MIAUpdateNode* node( iSelectedNodesArray[ i ] );
+	    TInt lastErrorCode( KErrNone );
+	    TRAPD ( trapError, 
+	            lastErrorCode = node->Base().LastUpdateErrorCodeL() );
+	    if ( node->IsInstalled() )
+	        {
+	        // Because node is installed, update must have been a success.
+	        ++resultsInfo.iCountSuccessfull;
+	        if ( node->Base().RebootAfterInstall() )
+	            {
+	            resultsInfo.iRebootAfterInstall = ETrue;
+	            }
+	        }
+        else if ( trapError == KErrNone 
+                  && lastErrorCode == KErrCancel )
+            {
+            ++resultsInfo.iCountCancelled;
+            }
+        else
+            {
+            ++resultsInfo.iCountFailed;
+            }
+	    }
+	    
+	IAUPDATE_TRACE_1("[IAUPDATE] Successfull count: %d", resultsInfo.iCountSuccessfull );
+	IAUPDATE_TRACE_1("[IAUPDATE] Cancelled count: %d", resultsInfo.iCountCancelled );
+	IAUPDATE_TRACE_1("[IAUPDATE] Failed count: %d", resultsInfo.iCountFailed );
+	
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ResultsInfo() end");
+
+	return resultsInfo;
+	}
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::CountOfAvailableUpdates
+// 
+// ---------------------------------------------------------------------------    
+TInt CIAUpdateUiController::CountOfAvailableUpdates() const
+	{
+	IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::CountOfAvailableUpdates() count: %d",
+                     iCountOfAvailableUpdates );
+	return iCountOfAvailableUpdates;
+	}
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::Starter()
+// 
+// ---------------------------------------------------------------------------    
+const CIAUpdateStarter* CIAUpdateUiController::Starter() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Starter()");
+    return iStarter;	
+    }
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::Filter()
+// 
+// --------------------------------------------------------------------------- 
+const CIAUpdateNodeFilter* CIAUpdateUiController::Filter() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Filter()");
+    return iFilter;	
+    }
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::DoCancelIfAllowed
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::DoCancelIfAllowed()
+   {
+   IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DoCancelIfAllowed() begin");
+
+   if ( iClosingAllowedByClient )
+       {
+   	   CancelOperation();
+       }
+
+   IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DoCancelIfAllowed() end");
+
+   return iClosingAllowedByClient;	
+   }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::ClosingAllowedByClient
+// 
+// -----------------------------------------------------------------------------
+//  
+ TBool CIAUpdateUiController::ClosingAllowedByClient()
+     {
+     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ClosingAllowedByClient()");
+     IAUPDATE_TRACE_1("[IAUPDATE] closing allowed: %d", iClosingAllowedByClient );
+     TBool closingAllowed = iClosingAllowedByClient;
+     if ( iRequestType != IAUpdateUiDefines::EShowUpdates )
+         {
+         // iaupdate can be orphaned from its client only when ShowUpdates() was called  
+         closingAllowed = ETrue;
+         }
+ 	 return closingAllowed;
+     }
+ 	
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::CheckUpdatesDeferredL
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::CheckUpdatesDeferredL( CIAUpdateParameters* aParams, 
+                                                   TBool aRefreshFromNetworkDenied )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredL() begin");
+    
+    iClosingAllowedByClient = ETrue;
+    delete iParams;
+    iParams = aParams; //ownership of parameters is taken
+    iRefreshFromNetworkDenied = aRefreshFromNetworkDenied; 
+    delete iIdle;
+    iIdle = NULL;
+	iIdle = CIdle::NewL( CActive::EPriorityIdle ); 
+    iIdle->Start( TCallBack( CheckUpdatesDeferredCallbackL, this ) );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredL() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::PrepareRoamingHandlerL
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::PrepareRoamingHandlerL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::PrepareRoamingHandlerL() begin");
+	    
+    if ( !iRoamingHandler )
+        {
+    	iRoamingHandler = CIAUpdateRoamingHandler::NewL();
+        }
+    if ( !iRoamingHandler->Prepared() )
+        {
+    	iRoamingHandler->CancelPreparing();
+    	//async call that will return in RoamingHandlerPrepared()
+    	iRoamingHandler->PrepareL( *this );
+        }
+    else
+        {
+        CheckUpdatesL();	
+        }
+    
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::PrepareRoamingHandlerL() end");
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::HandlePossibleSelfUpdateRestartL
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::HandlePossibleSelfUpdateRestartL( TBool aShutdownRequest )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandlePossibleSelfUpdateRestartL() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] ShutdownRequest: %d", aShutdownRequest );
+
+    TBool restarted( EFalse );
+
+    CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() );
+
+    if ( info )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Self updater related info available.");
+
+        CleanupStack::PushL( info );
+
+        // Delete the unnecessary files because we will still have 
+        // required objects available.
+        // Notice, that if for some reason a leave occurs after this and the
+        // application does not continue the update, then next time the application
+        // is started, update restart is not rehandled any more.
+        info->DeleteFiles();
+
+        // Get the data for the updater results.            
+        CIAUpdaterResultsFile& results( info->ResultsFile() );
+
+        // This flag is set if self updater operation was cancelled.
+        TBool selfUpdateCancelled( EFalse );
+
+        // Because we have restarted the iaupdate after self updating,
+        // also start to gather possible new update flow reports into 
+        // a report bundle. Inform the controller, so the controller 
+        // can handle situations as a whole and not as one item at the
+        // time.
+        iController->StartingUpdatesL();
+
+        RPointerArray< CIAUpdaterResult >& resultArray( results.Results() );
+        // Because self updater will insert the possible hidden dependencies
+        // before the actual item, start from the beginning of the array to
+        // set the error codes. This way, the main item will be set last and
+        // it will get the latest time for the purchase history.
+        for ( TInt i = 0; i < resultArray.Count(); ++i )
+            {
+            CIAUpdaterResult* result( resultArray[ i ] );
+            
+            if ( result->ErrorCode() == KErrCancel )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Self Updater cancelled"); 
+            	selfUpdateCancelled = ETrue;
+                }
+
+            // Because, the self update installation was finished.
+            // Update the purchase history with the correct information.
+            // Notice, that we can just set the purchase history here for
+            // the self updater items. If some of the items were installed,
+            // before self updater items, then their information was already
+            // correctly into the history. Notice, that result nodes may be hidden
+            // nodes that were not initially visible in the UI. So, do not
+            // force the results visible in purchase history.
+            MIAUpdateNode& node( iController->NodeL( result->Identifier() ) );
+            node.Base().
+                SetInstallStatusToPurchaseHistoryL( 
+                    result->ErrorCode(), EFalse );
+            }
+
+        IAUPDATE_TRACE("[IAUPDATE] Self update info inserted to purchase history."); 
+
+           
+        // Get the data for the pending node info.
+        CIAUpdatePendingNodesFile& pendings(
+            info->PendingNodesFile() );
+
+
+        // Because ContinueUpdateL will use the counters and
+        // node index and iSelectedNodesArray, we set the correponding information
+        // here. Then, the update operation will continue correctly for the pending
+        // nodes.
+            
+
+        // Set the node index to -1 because ContinueUpdateL increases it by one
+        // in the beginning of the function. So, we can use the ContinueUpdateL
+        // also in the end of this function to start the actual update process.
+        iNodeIndex = -1;
+        iSelectedNodesArray.Reset();
+        
+        // Also, reset nodearray nodes as not selected because original parameter
+        // settings may have been overruled by the user before user started 
+        // the self update from UI. Correct nodes will be chosen in the for-loops below.
+        for ( TInt i = 0; i < iNodes.Count(); ++i )
+            {
+            MIAUpdateNode& node( *iNodes[ i ] );
+            node.Base().SetSelected( EFalse );
+            }
+        for ( TInt i = 0; i < iFwNodes.Count(); ++i )
+            {
+            MIAUpdateFwNode& fwNode( *iFwNodes[ i ] );  
+            fwNode.Base().SetSelected( EFalse );
+            }
+        
+
+        if ( !selfUpdateCancelled )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Self update not cancelled.");
+
+            // Notice, that the ownership of the filter parameters will
+            // remain in the filter.
+            CIAUpdateParameters* params( iFilter->FilterParams() );
+            if ( !IsStartedByLauncher() || params )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Self update handling will set parameters.");
+
+                // Check if IAD was started from the grid or through API.
+                // If IAD was started like from the grid but it still has parameters set,
+                // then act as it was started through API. Most likely, then the IAD was
+                // originally started through API but because of self update IAD was restarted
+                // and now it has original parameters set.
+
+                if ( !iStarter )
+                    {
+                    IAUPDATE_TRACE("[IAUPDATE] iStarter not set");
+            	    iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(), 
+            	                                       params->CommandLineArguments() );
+                    }
+                }
+            }
+
+        // Get list of nodes that were initially chosen for the flow.
+        RPointerArray< CIAUpdaterIdentifier >& pendingIdentifiers = 
+            pendings.PendingNodes();
+        TInt pendingIdentifiersCount( pendingIdentifiers.Count() );
+        // Get the index to the node that has not yet been handled.
+        TInt pendingsIndex( pendings.Index() );
+        iSelectedNodesArray.ReserveL( pendingIdentifiersCount );
+        for ( TInt i = 0; i < pendingIdentifiersCount; ++i )
+            {
+            CIAUpdaterIdentifier* identifier( pendingIdentifiers[ i ] );
+            MIAUpdateNode& node( 
+                iController->NodeL( *identifier ) );
+            iSelectedNodesArray.AppendL( &node );
+
+            // Also, set the node as selected because then UI can easily check
+            // which nodes should be marked when the UI is restarted after selfupdate.
+            node.Base().SetSelected( ETrue );
+
+            if ( i < pendingsIndex )
+                {
+                // We come here if index suggests that node has already been handled
+
+                // Increase the node index. So, it will already point
+                // to the correct place. Because, we want to omit these files
+                // when list is gone through.
+                ++iNodeIndex;
+
+            	if ( iStarter && node.IsInstalled() )
+            	    {
+                    IAUPDATE_TRACE("[IAUPDATE] Self update handling will set parameters, node installed");
+                    // Because application starting parameters may have been given through the
+                    // API, we need to pass UID of installed package to starter if it exists.
+                    // Then, the starter will start the given exe in the end of the install flow
+                    // if at least one file was succesfully installed.
+            		iStarter->CheckInstalledPackageL( node.Base().Uid() );
+            	    }
+                }
+            else if ( selfUpdateCancelled )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Set idle cancel info to purchase history");
+                // Check if self updater actions were cancelled.
+                // Set the purchase history information to nodes not handled yet.
+                // If visible service pack was changed to hidden during the operation
+                // then force the current history info visible. Then the history
+                // corresponds the situation that was when operation flow was started.
+                // This may occure if some of the items were installed after all.
+                // Notice, that here we can think that node was initially visible
+                // because all nodes in UI selection list are visible and possible
+                // hidden self update nodes have been handled already in the beginning
+                // of this for loop.
+                if ( MIAUpdateNode::EPackageTypeServicePack == node.Type()
+                      && node.IsInstalled() )
+                    {
+                    IAUPDATE_TRACE("[IAUPDATE] Service pack was completed");
+                    // Even if cancel occurred, some of the nodes inside the
+                    // service pack were installed. And, now there is nothing
+                    // to be installed inside the service pack.
+                    node.Base().
+                        SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue );
+                    }
+                else
+                    {
+                    IAUPDATE_TRACE("[IAUPDATE] Node cancelled");
+                    // Notice, that this can also still be service pack node.
+                    // Because we are handling nodes that are visible in UI,
+                    // we can force the node as visible in history.
+                    node.Base().SetIdleCancelToPurchaseHistoryL( ETrue ); 
+                    }
+                }
+            else if ( MIAUpdateNode::EPackageTypeServicePack == node.Type()
+                      && node.IsInstalled() )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Service pack has become installed");
+                // Because service pack has become installed during self update
+                // it means that the service pack was originally missing only
+                // the selfupdate. Set, the service pack as installed also into
+                // purchase history because no other operation will be done to
+                // it after this. Notice, that because service pack was originally
+                // in the list, it has been visible for UI. So, make sure that it
+                // is also visible in history. IAD Engine will set service packs
+                // whose all content is installed as hidden. Therefore, force the
+                // visibility here.
+                // Notice, that here we can think that node was initially visible
+                // because all nodes in UI selection list are visible and possible
+                // hidden self update nodes have been handled already in the beginning
+                // of this for loop.
+                node.Base().
+                    SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue );
+                }
+            }
+
+        // Info is not needed any more. 
+        // So, delete it before update flow will be continued below 
+        // if necessary.
+        CleanupStack::PopAndDestroy( info );
+
+        // Check if self updater actions was closed by using red key.
+        // If so, then do not continue update flow here. 
+        // Instead, this application should be closed.
+        if ( !aShutdownRequest )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Self update not closed with red key.");            
+            if ( selfUpdateCancelled )
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Self update cancelled.");
+                // Because self update is cancelled, do not continue here either.
+                // Instead end the update flow directly.
+                UpdateCompleteL( KErrCancel );
+                }
+            else
+                {
+                IAUPDATE_TRACE("[IAUPDATE] Self update finished, continue udpate.");
+                // Continue udpate normally.
+                ContinueUpdateL( ETrue );                
+                }
+            }
+        else
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Self update closed with red key. Handle dialogs.");
+            // Because shutdown was requested, we do not continue the update flow.
+            // A updating dialog may still show. So, release it here.
+            RemoveUpdatingDialogsL();
+            }
+
+        // Self updater provided some data that was handeld above.
+        restarted = ETrue;
+        }
+
+    IAUPDATE_TRACE_1("[IAUPDATE] restarted: %d", restarted );   
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandlePossibleSelfUpdateRestartL() end");
+
+    return restarted;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::TestRole
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::TestRole() const 
+    {
+    return iTestRole;	
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::RefreshComplete
+// 
+// -----------------------------------------------------------------------------
+//                            
+void CIAUpdateUiController::RefreshComplete( 
+    const RPointerArray< MIAUpdateAnyNode >& aNodes,
+    TInt aError )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshComplete() begin");
+    TInt completionError = KErrNone;
+    if ( iState == EUiRefreshing )
+        {
+    	iState = EIdle;
+    	TRAP( completionError, RefreshUiCompleteL( aNodes, aError ) );
+        }
+    else
+        {
+        iState = EIdle;
+        TRAP ( completionError, RemoveWaitDialogL() );
+        if ( completionError == KErrNone )
+            {
+    	    TRAP( completionError, RefreshCompleteL( aNodes, aError ) );
+            }	
+        }
+    if ( completionError == KErrNone )
+        {
+        iRefreshed = ETrue;
+        }
+    else
+        {
+        iObserver.HandleLeaveErrorWithoutLeave( completionError );
+        }
+    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshComplete() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::SelfUpdaterComplete
+// 
+// -----------------------------------------------------------------------------
+//                            
+void CIAUpdateUiController::SelfUpdaterComplete( TInt aErrorCode )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SelfUpdaterComplete() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aErrorCode );
+
+    // Self updater completed its job.
+    // Normally we should not come here because self update should shut down this
+    // application before installation. But, now because we came here, complete
+    // the update operation.
+
+    // Remove params file if it exists. This is a temporary file that would be
+    // otherwise read during next grid start if not removed here. There is no need
+    // to use that file now, because all the necessary parameters are already set
+    // because restart of IAD did not occur.
+    
+    iState = EIdle;
+    TRAP_IGNORE ( ParamsRemoveFileL() );
+
+    TInt err( KErrNone );
+    TBool restartDataWasAvailable( EFalse );
+    TRAP ( err, 
+           restartDataWasAvailable = 
+            HandlePossibleSelfUpdateRestartL( 
+                aErrorCode == IAUpdaterDefs::KIAUpdaterShutdownRequest ) );
+    if ( err != KErrNone )
+        {
+    	iObserver.HandleLeaveErrorWithoutLeave( err );
+        }
+    else if ( !restartDataWasAvailable )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Restart data not available");
+        // For some reason the self updater was not able to give the restart data.
+        // So, try to continue the update in a normal way.
+        TRAP ( err, UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( aErrorCode ) );
+        if ( err == KErrNone )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Continue update flow");
+        	TRAP ( err, ContinueUpdateL( EFalse ) );
+            }
+        if ( err != KErrNone )
+            {
+            IAUPDATE_TRACE_1("[IAUPDATE] Purchase history update error: %d", err);
+        	iObserver.HandleLeaveErrorWithoutLeave( err );
+            }
+        }
+
+    if ( aErrorCode == IAUpdaterDefs::KIAUpdaterShutdownRequest )
+        {
+        CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
+    	appUi->Exit();
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SelfUpdaterComplete() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::ServerReportSent
+// 
+// -----------------------------------------------------------------------------
+//                            
+void CIAUpdateUiController::ServerReportSent( TInt aError )
+    {
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::ServerReportSent() begin: %d",
+                     aError);
+
+    // This call back is called when MIAUpdateController::UpdateFinishedL
+    // function is called and that asynchronous operation completes.
+    // Report sending is done in the background.
+    if ( iState == ESendingReport )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] End the update flow now that report has been sent");
+        // Reports are sent only when update flow has finished. Also, in normal 
+        // flow, we wait that report sending finishes before continuing to the end. 
+        TRAP_IGNORE( EndUpdateFlowL( aError ) ); 
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ServerReportSent() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::ClientRole
+// 
+// -----------------------------------------------------------------------------
+//     
+void CIAUpdateUiController::ClientRole( const TDesC& aClientRole )
+    {
+	if ( aClientRole == IAUpdateUiDefines::KTestRole() )
+	    {
+	    iTestRole = ETrue;
+	    }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::DownloadProgress
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::DownloadProgress( MIAUpdateNode& /*aNode*/, 
+                                              TUint aProgress,
+                                              TUint aMaxProgress )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadProgress() begin");  
+
+    if ( iProgressDialog )
+        {
+    	TRAP_IGNORE ( iProgressDialog->SetProgressDialogFinalValueL( aMaxProgress ) );
+        TRAP_IGNORE ( iProgressDialog->UpdateProgressDialogValueL( aProgress ) );
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadProgress() end");  
+    }                            
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::DownloadComplete
+// 
+// -----------------------------------------------------------------------------
+//                            
+void CIAUpdateUiController::DownloadComplete( MIAUpdateNode& aNode,
+                                              TInt aError )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadComplete() begin");
+
+    iState = EIdle;
+	TRAPD ( completionError, DownloadCompleteL( aNode, aError ) );
+    if ( completionError != KErrNone )
+        {
+        // If we came here, DownloadCompleteL function may have left
+        // before dialog was removed. So, try one more time to remove it here
+        // before informing the observer.
+        TRAP_IGNORE( RemoveUpdatingDialogsL() );
+        iObserver.HandleLeaveErrorWithoutLeave( completionError );
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadComplete() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::InstallProgress
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::InstallProgress( MIAUpdateNode& /*aNode*/, 
+                                             TUint /*aProgress*/,
+                                             TUint /*aMaxProgress*/ )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallProgress()");    
+    }                            
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::InstallComplete
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::InstallComplete( MIAUpdateNode& aNode,
+                                             TInt aError )  
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallComplete() begin");
+
+    iState = EIdle;
+    CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
+    appUi->StopWGListChangeMonitoring();
+    if ( aError == SwiUI::KSWInstErrFileInUse )
+        {
+    	iFileInUseError = ETrue;
+        }
+    
+	TRAPD ( completionError, InstallCompleteL( aNode, aError ) );
+    if ( completionError != KErrNone )
+        {
+        // If we came here, InstallCompleteL function may have left
+        // before dialog was removed. So, try one more time to remove it here
+        // before informing the observer.
+        TRAP_IGNORE( RemoveUpdatingDialogsL() );
+        iObserver.HandleLeaveErrorWithoutLeave( completionError );
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallComplete() end");
+    }
+
+    
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartupComplete
+// 
+// ---------------------------------------------------------------------------
+// 
+void CIAUpdateUiController::StartupComplete( TInt aError )
+    {  
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartupComplete() begin");  
+
+    if ( aError == IAUpdateErrorCodes::KErrCacheCleared )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Cache cleared during startup.");  
+        // Because cache was cleared, change the refresh information data
+        // so that the network refresh will be done during refresh operation.
+        
+        // The values have been read from the file when the controller file 
+        // object was created or the defaul values are used if the file did
+        // not exist. So, no need to re-read them here.
+        // Replace the time with zero. So, the zero time will
+        // suggest that network refresh is required later on. 
+        iControllerFile->SetRefreshTime( 0 );
+
+        // Save data into the file.
+        // Change aError value to correct one. 
+        // aError will be KErrNone if everything goes ok inside trap,
+        // or else it will contain the correct error code.
+        TRAP ( aError, iControllerFile->WriteControllerDataL(); );
+        
+        CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() ); 
+        if ( info ) 
+            { 
+            IAUPDATE_TRACE("[IAUPDATE] Delete restart info because of cache clean.");
+            // Restart info was available. 
+            // Delete self upate files because otherwise a net connection
+            // may be prevented during refresh and the cleared cache can not
+            // be updated. If this is not done here, HandlePossibleSelfUpdateRestartL
+            // may leave because required nodes are not found. Notice, that also
+            // HandlePossibleSelfUpdateRestartL deletes these files but by handling
+            // this special case here, an application can continue without leave later.
+            info->DeleteFiles();
+            delete info; 
+            info = NULL; 
+            }
+        }
+        
+    iObserver.StartupComplete( aError );
+    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartupComplete() end");  
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartExecutableCompletedL
+// 
+// ---------------------------------------------------------------------------
+// 
+void CIAUpdateUiController::StartExecutableCompletedL( TInt /*aError*/ )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartExecutableCompletedL() begin"); 
+
+    // Before informing the observer, close the possible existing dialog.
+    RemoveUpdatingDialogsL();
+    
+    // Possible error is not passed to a client. Typically client is already closed. 
+    // Even in the case when client's request is still ongoing, it's disinformation to return
+    // error from failed executable start. 
+    TRAPD ( err, iObserver.UpdateCompleteL( KErrNone ) );
+    if ( err != KErrNone )
+        {
+    	iObserver.HandleLeaveErrorL( err );
+        }
+
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartExecutableCompletedL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RoamingHandlerPrepared
+// 
+// ---------------------------------------------------------------------------
+// 
+void CIAUpdateUiController::RoamingHandlerPrepared()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RoamingHandlerPrepared() begin");
+    TRAPD ( err, CheckUpdatesL() );
+	if ( err != KErrNone )
+        {
+    	iObserver.HandleLeaveErrorWithoutLeave( err );
+        }
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RoamingHandlerPrepared() end");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::HandleDialogExitL
+// Called when wait/progress dialog is about to be cancelled.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::HandleDialogExitL( TInt aButtonId )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleDialogExitL() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] button id: %d", aButtonId );
+    
+    TInt ret( ETrue );
+    if ( aButtonId == EAknSoftkeyCancel )
+        {  
+        TRAPD ( err, HandleUserCancelL() );
+        if ( err != KErrNone )
+            {
+        	iObserver.HandleLeaveErrorL( err );
+            }
+        }   
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleDialogExitL() end");
+
+    return ret;    
+    }
+
+// -----------------------------------------------------------------------------
+// CIAUpdateUiController::HandleUiRefreshL
+// 
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateUiController::HandleUiRefreshL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUiRefreshL() begin"); 
+
+	if ( iRequestType == IAUpdateUiDefines::ECheckUpdates )
+	    {
+	    iRefreshed = EFalse;
+	    }
+	else if ( iState == EIdle )
+	    {
+	    CIAUpdateAppUi* appUi = static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
+        if ( appUi->UiRefreshAllowed() )
+		    {
+	    	iState = EUiRefreshing;
+	        // store node identification (package UID and version) of currently selected nodes
+	        // to restore selections after refresh
+	        delete iPreviousSelections;
+	        iPreviousSelections = NULL;
+	        iPreviousSelections = new( ELeave ) CArrayFixFlat<SIAUpdateNodeId>( iNodes.Count() + 1 );
+	        for ( TInt i = 0; i < iNodes.Count(); ++i )
+                {
+                MIAUpdateNode* node( iNodes[ i ] );
+                SIAUpdateNodeId nodeId;
+                nodeId.iNodeType = MIAUpdateAnyNode::ENodeTypeNormal;
+                nodeId.iPackageUid = node->Base().Uid();
+                nodeId.iVersion = node->Base().Version();
+                nodeId.iSelected = node->Base().IsSelected();
+                iPreviousSelections->AppendL( nodeId );
+                }
+
+            if ( iFwNodes.Count() > 0 )
+                {   
+                MIAUpdateFwNode* fwNode( iFwNodes[ 0 ] );
+                SIAUpdateNodeId nodeId;
+                nodeId.iNodeType = MIAUpdateAnyNode::ENodeTypeFw;
+                nodeId.iSelected = fwNode->Base().IsSelected();
+                iPreviousSelections->AppendL( nodeId );
+                }
+        
+   	        iController->StartRefreshL( EFalse );
+	        }
+	    }
+	
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUiRefreshL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RefreshCompleteL
+// 
+// ---------------------------------------------------------------------------
+//        
+void CIAUpdateUiController::RefreshCompleteL( 
+    const RPointerArray< MIAUpdateAnyNode >& aNodes,
+    TInt aError )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshCompleteL() begin");
+
+    iState = EIdle;
+    if ( !iRefreshHandler  && !iOffConfigurated )
+        {
+        iRefreshHandler = CIAUpdateRefreshHandler::NewL();
+        }
+    if ( aError == KErrNone ) 
+        {
+        // Inform refresh to other IAD instances 
+        if ( !iOffConfigurated  && AllowNetworkRefreshL() && iRefreshHandler )
+            {
+            iRefreshHandler->InformRefreshL();   
+            }
+                  
+        // Because refresh was successfully completed,
+        // update the controller information to the controller file
+        UpdateControllerFileL();
+        }
+
+    // Even in a case when refresh failed, there may be old cache available.
+    // It's also possible that only firmware node or normal node refresh failed, so there is 
+    // partial list available
+    // ==> all nodes returned by engine are shown in UI
+    iNodes.Reset();
+    iFwNodes.Reset();
+    iNodes.ReserveL( aNodes.Count() );
+    for ( TInt i = 0; i < aNodes.Count(); ++i )
+        {
+        MIAUpdateAnyNode* anyNode( aNodes[ i ] );
+        if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeNormal )
+            {
+            MIAUpdateNode* node( 
+                static_cast< MIAUpdateNode* >( anyNode ) );
+            iNodes.AppendL( node );                
+            }
+        else if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw )
+            {
+            MIAUpdateFwNode* fwNode( 
+                static_cast< MIAUpdateFwNode* >( anyNode ) );
+            iFwNodes.AppendL( fwNode );
+            }
+        }
+
+    switch ( iRequestType )
+        {
+        case IAUpdateUiDefines::ECheckUpdates:
+        	
+            if ( iFilter->FilterParams() )
+                {
+           		iFilter->CountOfAvailableUpdatesL( 
+               		                         iNodes, 
+               		                         iFwNodes,
+               		                         iCountOfAvailableUpdates ); 
+                }
+            break;
+        
+        default: 
+            // Sort the nodes according to the filter values
+            // This function performs default marking also
+            iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
+                                          
+            break;
+        }
+
+    if ( aError == KErrNone )
+        {
+        // Now, that refresh has been done, 
+        // check if there is some self update related settings .
+        HandlePossibleSelfUpdateRestartL( EFalse );
+        }
+    
+    if ( !iOffConfigurated  && iRefreshHandler )
+        {
+        iRefreshHandler->StartListeningL( this );
+        }
+    iObserver.RefreshCompleteL( ETrue, aError );        
+        
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshCompleteL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RefreshUiCompleteL
+// 
+// ---------------------------------------------------------------------------
+//        
+void CIAUpdateUiController::RefreshUiCompleteL( 
+    const RPointerArray< MIAUpdateAnyNode >& aNodes,
+    TInt /*aError*/ )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshUiCompleteL() begin");
+    // : Is error handling needed?
+    iNodes.Reset();
+    iFwNodes.Reset();
+    iNodes.ReserveL( aNodes.Count() );
+    // Find out if there was umarked firmware update in old selections,
+    // that case needs special handling
+    TBool unmarkedFw = EFalse;
+    for ( TInt i = 0; i < iPreviousSelections->Count(); ++i )
+        {
+        SIAUpdateNodeId prevNodeId = iPreviousSelections->At( i );
+        if ( prevNodeId.iNodeType == MIAUpdateAnyNode::ENodeTypeFw  && !prevNodeId.iSelected )
+             {
+             unmarkedFw = ETrue;
+             }
+        }
+     
+    for ( TInt i = 0; i < aNodes.Count(); ++i )
+        {
+        MIAUpdateAnyNode* anyNode( aNodes[ i ] );
+        if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeNormal )
+            {
+            MIAUpdateNode* node( static_cast< MIAUpdateNode* >( anyNode ) );
+            iNodes.AppendL( node );                
+            }
+        else if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw && !unmarkedFw )
+            {
+            // if umarked firmware update in old selections, firmawares are not appended 
+            // before iFilter->FilterAndSortNodesL() is called
+            MIAUpdateFwNode* fwNode( 
+                    static_cast< MIAUpdateFwNode* >( anyNode ) );
+            iFwNodes.AppendL( fwNode );
+            }
+        }
+    iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
+    
+    if ( unmarkedFw )
+        {
+        for ( TInt i = 0; i < aNodes.Count(); ++i )
+            {
+            MIAUpdateAnyNode* anyNode( aNodes[ i ] );
+            if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw )
+                {
+                MIAUpdateFwNode* fwNode( 
+                        static_cast< MIAUpdateFwNode* >( anyNode ) );
+                iFwNodes.AppendL( fwNode );
+                }
+            }
+        }
+    
+    //restore previous selections/deselections  
+    for ( TInt i = 0; i < iNodes.Count(); ++i )
+        {
+        MIAUpdateNode* node( iNodes[ i ] );
+        for ( TInt j = 0; j < iPreviousSelections->Count(); ++j )
+            {
+            SIAUpdateNodeId prevNodeId = iPreviousSelections->At(j);
+        	if ( node->Base().Uid() == prevNodeId.iPackageUid &&
+        	     node->Base().Version() == prevNodeId.iVersion )
+                {
+        		node->Base().SetSelected( prevNodeId.iSelected );
+        	    }
+            }
+        }
+    
+    // When dependant is marked, all dependencies to be marked also
+    for ( TInt i = 0; i < iNodes.Count(); ++i )
+        {
+        MIAUpdateNode* node( iNodes[ i ] );
+        if ( node->Base().IsSelected() )
+            {
+            iFilter->SetDependenciesSelectedL( *node, iNodes );
+            }
+        }
+    
+    TBool firmwareSelected = EFalse;
+    for ( TInt i = 0; i < iFwNodes.Count(); ++i )
+        {
+        MIAUpdateFwNode* fwNode( iFwNodes[ i ] );
+    	for ( TInt j = 0; j < iPreviousSelections->Count(); ++j )
+    	    {
+    	    SIAUpdateNodeId prevNodeId = iPreviousSelections->At(j);
+    		if ( prevNodeId.iNodeType == MIAUpdateAnyNode::ENodeTypeFw )
+    		    {
+    			fwNode->Base().SetSelected( prevNodeId.iSelected );
+    		    }
+    	    }
+    	if ( fwNode->Base().IsSelected() )
+    	    {
+    	    firmwareSelected = ETrue;
+    	    }
+        }
+    
+    // if firmware is marked, normal nodes to be unmarked
+    if ( firmwareSelected )
+        {
+        for ( TInt i = 0; i < iNodes.Count(); ++i )
+            {
+            MIAUpdateNode* node( iNodes[ i ] );
+            node->Base().SetSelected( EFalse );
+            }
+        }
+    
+    CreateSelectedNodesArrayL();
+    iObserver.RefreshCompleteL( EFalse, KErrNone );
+     
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshUiCompleteL() end"); 
+    }
+    
+    
+    
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::DownloadCompleteL
+// 
+// ---------------------------------------------------------------------------
+//            
+void CIAUpdateUiController::DownloadCompleteL( MIAUpdateNode& aNode, TInt aError )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadCompleteL() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aError );
+
+    if ( aError == KErrAbort )
+        {
+        // Abort is interpreted so that a connection was not allowed by the user.
+        // So, do not continue to a new operation. 
+        // Instead, complete the update flow now.
+        // Set the purchase history information to nodes.
+        // Because the current node has KErrAbort as the last operation error code,
+        // change it to KErrCancel because we want to think it as cancellation instead
+        // of as abort error. This way, error counters and history info will show cancel
+        // instead of failed. Also, update cancel info to other pending nodes.
+        for ( TInt i = iNodeIndex; i < iSelectedNodesArray.Count(); ++i )
+            {
+            MIAUpdateNode* node( iSelectedNodesArray[ i ] );
+            // Because we are handling nodes that are visible in UI,
+            // we can force the node as visible in history.
+            TRAP_IGNORE ( 
+                node->Base().SetIdleCancelToPurchaseHistoryL( ETrue ) );
+            }
+        UpdateCompleteL( KErrNone );        
+        }
+    else if ( aError != KErrNone )
+        {
+    	InstallCompleteL( aNode, aError );
+        }
+    else   
+        {
+	    StartInstallL( aNode );
+        }    
+ 
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadCompleteL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::InstallCompleteL
+// 
+// ---------------------------------------------------------------------------
+//      
+void CIAUpdateUiController::InstallCompleteL( MIAUpdateNode& aNode, 
+                                              TInt aError )    
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aError );
+
+    // In release mode, we do not need the aError info, because
+    // success counters are counted by using the last operation error info
+    // when counter info is asked. In debug mode the error code is logged above.
+    (void)aError;
+    
+    // pass UID of installed package to starter
+    if ( iStarter )
+        {
+    	if ( aNode.Type() == MIAUpdateNode::EPackageTypeServicePack )
+    	    { 
+    	    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node type is service pack");
+     	    for ( TInt i = 0; i < iServicePackNodes.Count(); ++i )
+    	        {
+    	        if ( iServicePackNodes[i]->IsInstalled() )   
+    	            {
+    	            IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node is installed");
+    	            iStarter->CheckInstalledPackageL( iServicePackNodes[i]->Base().Uid() );
+    	            }
+    	        }
+    	    iServicePackNodes.Reset();
+    	    }
+    	else if ( aNode.IsInstalled() )
+    	    {
+    	    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node is installed");
+    	    iStarter->CheckInstalledPackageL( aNode.Base().Uid() );
+    	    }
+        }
+    
+    // If installation was marked as KErrCancel here,
+    // we think that it was just the disclaimer and
+    // let this continue.        
+    ContinueUpdateL( EFalse );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::UpdateCompleteL
+// 
+// ---------------------------------------------------------------------------
+//      
+void CIAUpdateUiController::UpdateCompleteL( TInt aError ) 
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateCompleteL() begin");
+
+    iState = EIdle;
+    iClosingAllowedByClient = EFalse;
+
+    // Remove installed nodes from the node array.
+	for ( TInt i = iNodes.Count() - 1; i >= 0; --i ) 
+        {   
+        MIAUpdateNode* node = iNodes[ i ];
+        if ( node->IsInstalled() ) 
+            {
+            iNodes.Remove( i );
+            }
+        }
+    
+    TInt error( aError );
+    TBool selfUpdaterStarted( EFalse );
+
+    if ( error == KErrNone )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Check self update start");
+        // Set the error to correspond to the trap error. So, 
+        // the observer will get correct information about the end result
+        // of the update.
+        TRAP ( error, 
+               selfUpdaterStarted = StartPossibleSelfUpdateL() );
+        if ( error != KErrNone )
+            {
+            IAUPDATE_TRACE_1("[IAUPDATE] trap error: %d", error);
+            // Because self update could not be started the counters may not be
+            // correct. Also, update purchase history with the error value 
+            // because install operation failed here.
+            UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( error ); 
+            }
+        }                   
+
+    // Check if self updater was started.
+    // If it was not, then there most likely was not any self updates set,
+    // or something went wrong when self updater was tried to be started.
+    if ( selfUpdaterStarted )
+        {
+        iState = ESelfUpdating;
+        }
+    else
+        {
+        IAUPDATE_TRACE("[IAUPDATE] SelfUpdater was not started");
+
+        // Notice, that if the self updater was started, then
+        // do not inform the UI here that the operation was completed.
+        // Also, do not start possible executable yet.
+        // Instead, let the self updater do its thing in the background.
+        // Most likely, the updater will close this application during installation.
+        // But, if it does not, it will result to the SelfUpdaterComplete function
+        // call, and we can continue the installation from there.
+
+        // Inform the controller that we finished the updates. This way the
+        // controller can handle situations as a whole and not as one item at the
+        // time. Notice, that this will start the asynchronous operation that sends
+        // possible reports to the server. Callback is called when operation is finished.
+        // Also notice, that this reporting operation is not part of the normal update
+        // flow but a separate action meant  after update flow finishes. 
+        // The destructor of the engine controller can handle the cancellation of 
+        // the reporting operation. Also, no callbacks are called back to UI when 
+        // cancellation occurs. Notice, that if close request for application is issued
+        // before reports are sent, then objects are delete immediately and we will not 
+        // wait report sending to finish but reports are sent next time the application 
+        // is started.
+        // Maximum wait time for server reports is given in micro seconds.
+        // Notice, that in case of cancellations there would not be any need
+        // for timer. But just use it as in normal cases. Then, server report
+        // completion or timer will call the callback later. But, that callback
+        // will be ignored in CIAUpdateUiController::ServerReportSent because
+        // iState is already then changed from ESendingReport to something else. 
+        const TInt KServerReportMaxWaitTime( 10000000 );
+        iController->FinishedUpdatesL( ETrue, KServerReportMaxWaitTime );
+        iState = ESendingReport;
+        }
+
+    // When reports are sent, EndUpdateFlowL is called via the callback functions
+    // and the update flow will be finished there. But, if we come here when cancel
+    // is pressed, then call EndUpdateFlowL directly because then we do not wait
+    // report sending to finish. This will also set the state to EIdle to inform
+    // that when cancelling, we do not wait for the report sending to complete.
+    if ( aError == KErrCancel )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Cancelling. Call EndUpdateFlowL directly");
+        EndUpdateFlowL( error );
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateCompleteL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::EndUpdateFlowL
+// 
+// ---------------------------------------------------------------------------
+//  
+void CIAUpdateUiController::EndUpdateFlowL( TInt aError )    
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::EndUpdateFlowL() begin");
+
+    // Because we are ending the flow, set the state to idle.
+    iState = EIdle;
+    
+    // Notice, that the ownership of the filter parameters will
+    // remain in the filter.
+    CIAUpdateParameters* params( iFilter->FilterParams() );
+    if ( !IsStartedByLauncher()
+         || params )
+        {
+        IAUPDATE_TRACE_1("[IAUPDATE] Request type check matched: %d", iRequestType);
+
+        // Check if IAD was started from the grid or through API.
+        // If IAD was started like from the grid but it still has parameters set,
+        // then act as it was started through API. Most likely, then the IAD was
+        // originally started through API but because of self update IAD was restarted
+        // and now it has original parameters set.
+
+        if ( !iStarter )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] iStarter not set");
+        	iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(), 
+        	                                   params->CommandLineArguments() );
+            }
+
+        // Notice, that when starter calls StartExecutableCompletedL callback function,
+        // the observer is informed from there about the completion of the update flow.
+        // So, do not inform observer here.
+        iStarter->StartExecutableL( *this );
+        }
+    else
+        {
+        // Do not try to start any application. 
+        // But, use the start application callback function
+        // to end the update flow correctly (same way as after 
+        // application start with other options).
+        IAUPDATE_TRACE_1("[IAUPDATE] Update complete error: %d", aError );
+        StartExecutableCompletedL( aError );
+        }    
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::EndUpdateFlowL() end");
+    }
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::CheckUpdatesDeferredCallbackL
+// CheckUpdates as deferred to get empty main view visible before CheckUpdates
+//
+// ---------------------------------------------------------------------------
+//
+TInt CIAUpdateUiController::CheckUpdatesDeferredCallbackL( TAny* aPtr )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredCallbackL() begin");
+
+    CIAUpdateUiController* uiCtrl = static_cast<CIAUpdateUiController*>( aPtr );
+    
+    TRAPD ( err, uiCtrl->PrepareRoamingHandlerL() );
+    if ( err != KErrNone )
+        {
+        uiCtrl->iObserver.HandleLeaveErrorL( err );
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredCallbackL() end");
+
+	return KErrNone;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ShowUpdatingDialogL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::ShowUpdatingDialogL( TInt aTextResourceId,
+                                                 const TDesC& aName,
+                                                 TInt aNumber,
+                                                 TInt aTotalCount )   
+                                                    
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowUpdatingDialogL() begin");
+
+    // Before trying ot create a new dialog,
+    // remove possible existing dialog.
+    RemoveUpdatingDialogsL();
+
+    CDesCArray* stringArray = new( ELeave ) CDesCArrayFlat( 1 );
+    CleanupStack::PushL( stringArray );
+    stringArray->AppendL( aName );
+    CArrayFix<TInt>* numberArray = new( ELeave ) CArrayFixFlat<TInt>( 2 );
+    CleanupStack::PushL( numberArray );
+    numberArray->AppendL( aNumber ); 
+    numberArray->AppendL( aTotalCount );
+    HBufC* noteText = NULL;
+    noteText = StringLoader::LoadLC( aTextResourceId, 
+                                     *stringArray, 
+                                     *numberArray );
+    TPtr ptr = noteText->Des();
+    AknTextUtils::DisplayTextLanguageSpecificNumberConversion( ptr ); 
+    if ( iState == EDownloading )
+        {
+    	ShowProgressDialogL( *noteText, ETrue );
+        }
+    else
+        {
+        ShowWaitDialogL( *noteText, ETrue );	
+        }
+    
+    CleanupStack::PopAndDestroy( noteText ); 
+    CleanupStack::PopAndDestroy( numberArray );
+    CleanupStack::PopAndDestroy( stringArray );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowUpdatingDialogL() end");
+    }
+ 
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ShowWaitDialogL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::ShowWaitDialogL( const TDesC& aDisplayString, 
+                                             TBool aVisibilityDelayOff ) 
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowWaitDialogL() begin");
+
+    if ( iWaitDialog )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Wait dialog already existed. Remove it first");
+        // in some rare cases previous dialog still exists
+        // it's now just deleted (not recommended way) to avoid forwarding problem(s). 
+        delete iWaitDialog;
+        iWaitDialog = NULL;
+        }
+    iWaitDialog = 
+        new( ELeave ) CIAUpdateWaitDialog( 
+            reinterpret_cast< CEikDialog** >( &iWaitDialog ),
+            aVisibilityDelayOff );
+                
+    iWaitDialog->SetTextL( aDisplayString );
+    iWaitDialog->SetCallback( this );        
+    iWaitDialog->ExecuteLD( R_IAUPDATE_WAIT_DIALOG );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowWaitDialogL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ShowProgressDialogL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::ShowProgressDialogL( const TDesC& aDisplayString, 
+                                                 TBool aVisibilityDelayOff ) 
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowProgressDialogL() begin");
+
+    if ( iProgressDialog )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Progress dialog already existed. Remove it first");
+        // in some rare cases previous dialog still exists
+        // it's now just deleted (not recommended way) to avoid forwarding problem(s). 
+        delete iProgressDialog;
+        iProgressDialog = NULL;
+        }
+    iProgressDialog = 
+        new( ELeave ) CIAUpdateProgressDialog( 
+            reinterpret_cast< CEikDialog** >( &iProgressDialog ),
+            aVisibilityDelayOff );
+                
+    iProgressDialog->SetTextL( aDisplayString );
+    iProgressDialog->SetCallback( this );        
+    iProgressDialog->ExecuteLD( R_IAUPDATE_PROGRESS_DIALOG );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowProgressDialogL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RemoveUpdatingDialogsL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::RemoveUpdatingDialogsL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveUpdatingDialogsL() begin");
+    
+    RemoveWaitDialogL();
+    RemoveProgressDialogL();
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveUpdatingDialogsL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RemoveWaitDialogL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::RemoveWaitDialogL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveWaitDialogL() begin");
+
+    if ( !iCancelling )  //that's needed because AVKON  in 3.2.3 wk12, returning
+                         //EFalse in TryToExitL() causes a crash   
+        {
+    	if ( iWaitDialog )
+            {
+    	    iWaitDialog->ProcessFinishedL();
+            }
+        }
+    
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveWaitDialogL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RemoveProgressDialogL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::RemoveProgressDialogL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveProgressDialogL() begin");
+
+    if ( !iCancelling )  //that's needed because AVKON  in 3.2.3 wk12, returning
+                         //EFalse in TryToExitL() causes a crash   
+        {
+    	if ( iProgressDialog )
+            {
+    	    iProgressDialog->ProcessFinishedL();
+            }
+        }
+    
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveProgressDialogL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::AllowNetworkRefreshL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::AllowNetworkRefreshL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::AllowNetworkRefreshL() begin");
+    
+    TBool allowRefresh( EFalse );
+    if ( IsStartedByLauncher() )
+        {
+    	if ( !iRefreshFromNetworkDenied && 
+    	     !iUserRoamingRejection && 
+    	     !RestartedFromSelfUpdate() )
+    	    {
+    		if ( LocalNodesExpiredL() )
+    		    {
+    			allowRefresh = ETrue;
+    		    }
+    	    }
+        }
+    else   
+        {
+        // started by an application
+        if ( iFilter )
+    	    {
+    	    CIAUpdateParameters* params( iFilter->FilterParams() );
+    	    if ( params )
+    	        {
+    	    	if ( params->Refresh() )
+    	    	    {
+      	      		// Check from the central repocitory what are the automatic checking and 
+                    // roaming settings.     
+                    TInt autoUpdateCheckValue( 0 );
+                    CRepository* cenrep( 
+                             CRepository::NewLC( KCRUidIAUpdateSettings ) );
+                    // Notice, that KIAUpdateSettingAutoUpdateCheck can give following values
+                    // 0 = No automatic update check
+                    // 1 = Automatic update check enabled when not roaming
+                    // 2 = Automatic update enabled
+
+                    User::LeaveIfError( cenrep->Get( KIAUpdateAutoUpdateCheck, 
+                                                     autoUpdateCheckValue ) );
+                    CleanupStack::PopAndDestroy( cenrep );
+                    if ( ( autoUpdateCheckValue == EIAUpdateSettingValueEnable ) || 
+    	               ( autoUpdateCheckValue == EIAUpdateSettingValueDisableWhenRoaming &&
+    	                 !iRoamingHandler->IsRoaming() ) )
+                        {
+                    	allowRefresh = ETrue;
+                        }
+     	    	    }
+    	        }
+    	    }
+        }
+    
+    IAUPDATE_TRACE_1("[IAUPDATE] allowRefresh: %d", allowRefresh );    
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::AllowNetworkRefreshL() end");  
+    return allowRefresh;
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::LocalNodesExpiredL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::LocalNodesExpiredL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() begin");
+
+    // Notice, that the values for the iControllerFile, that are used here for
+    // expiration checkings, are set after successfull completion of refresh
+    // operation. See, UpdateControllerFileL that is called when operation
+    // finishes successfully. 
+
+    const TTimeIntervalHours KExpirationDeltaInHours( 
+        ConfigData().GridRefreshDeltaHours() );
+    
+    // Make sure that the most current data is gotten from the file.
+    iControllerFile->ReadControllerDataL();
+
+    TLanguage currentLanguage = User::Language();
+    TLanguage lastTimeLanguage = iControllerFile->Language();
+    if ( lastTimeLanguage != currentLanguage )
+        {
+        // Think nodes as expired because the language 
+        // has been changed in the phone. By updating the nodes,
+        // the items in UI will show correct language.
+        // No need to set the language to the controller file here.
+        // The value is set when the operation is successfully completed.
+        IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() ETrue end");
+        return ETrue;
+        }
+        
+    // Because the language check has passed,
+    // check also the time expirations.
+
+    // Get the last recorded refresh time from the controller file    
+    TTime lastRefreshTime( iControllerFile->RefreshTime() );
+
+    // Initialize expireTime with the last refresh time. Notice,
+    // that this expire time will be increased below with the correct 
+    // value
+    TTime expireTime( lastRefreshTime );
+
+    expireTime += KExpirationDeltaInHours;
+
+    // Get the current time.
+    TTime universalTime;
+    universalTime.UniversalTime();
+
+    if ( expireTime < universalTime
+         || lastRefreshTime > universalTime )
+        {
+        // Database is expired because current time has passed the
+        // expiration time. Also, sanity check is made. If
+        // last refresh time is larger than current time, then the
+        // last refresh value has been set wrong, and the database can
+        // be thought as expired. This might be the case if the user has
+        // changed the time in the phone.
+        IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() ETrue end");
+        return ETrue;
+        }
+    else
+        {
+        // Database is not expired yet.
+        IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() EFalse end");
+        return EFalse;        
+        } 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::UpdateControllerFileL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::UpdateControllerFileL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateControllerFileL() begin");
+
+    // This function is called after the refresh operation has
+    // completed.
+
+    // Check if local nodes were updated from the server.
+    // Notice, that last refresh time and language are both checked
+    // here when LocalNodesExpiredL() is called from AllowNetworkRefreshL.
+    // AllowNetworkRefreshL is called here because autoupdate and roaming checks
+    // should also be done when deciding if the nodes were updated.
+    if ( AllowNetworkRefreshL() )
+        {
+        // Update controller file with current information 
+        // because old values were expired.
+        iControllerFile->SetCurrentData();
+
+        // Because data is not up to date,
+        // save new data into the file.
+        iControllerFile->WriteControllerDataL();        
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateControllerFileL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::IsStartedByLauncher
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::IsStartedByLauncher()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IsStartedByLauncher()");
+
+    if ( iRequestType == IAUpdateUiDefines::ENoRequest )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Started by launcher");
+        // This operation was started from the application that was
+        // started by launcher
+        // Currently it means that launching is originated 
+        // from application grid or background checker. There is only
+        // one iaupdate instance started by launcher
+        return ETrue;
+        }
+    else
+        {
+        IAUPDATE_TRACE("[IAUPDATE] NOT started by launcher");
+        // According to the request type, 
+        // API was used to start the operation.
+        return EFalse;        
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::StartPossibleSelfUpdateL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::StartPossibleSelfUpdateL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartPossibleSelfUpdateL() begin");
+
+    // If there exist some self updater files that need to be installed
+    // separately, start self updating process.
+    TBool started( 
+        iController->
+            StartPossibleSelfUpdateL( iNodeIndex, 
+                                      iSelectedNodesArray.Count(),
+                                      iSelectedNodesArray,
+                                      EFalse ) );
+            
+    // Because self updater has gotten all the information it needs now,
+    // we can reset the data that is meant for the updater.
+    iController->ResetSelfUpdate();
+
+    IAUPDATE_TRACE_1("[IAUPDATE] started: %d", started );
+    if ( started )
+        {
+        // Because self update was started, save possible parameters data 
+        // for the possible restart of IAD. The, IAD can continue correctly.
+        ParamsWriteFileL();
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartPossibleSelfUpdateL() end");
+    
+    return started;  
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( TInt aErrorCode )
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL() begin");
+    IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aErrorCode );
+
+    // Check all the items that have been updated so far.
+    // And, set the error info to purchase history accordingly.
+    for ( TInt i = 0; 
+          i < iSelectedNodesArray.Count()
+          && i < iNodeIndex + 1;
+          ++i )
+        {
+        MIAUpdateNode* node( iSelectedNodesArray[ i ] );
+        if ( node->IsSelfUpdate() )
+            {
+            TBool installSuccess( node->IsInstalled() );
+            if ( !installSuccess  )
+                {
+                // Notice, that we can just set the purchase history here for
+                // the self updater items. If some of the items were installed,
+                // before self updater items, then their information was already
+                // correctly into the history.
+                TInt error( aErrorCode );
+                if ( aErrorCode == KErrNone )
+                    {
+                    error = KErrUnknown;
+                    }
+
+                // Because we are handling nodes that are visible in UI,
+                // we can force the node as visible in history.                    
+                node->Base().SetInstallStatusToPurchaseHistoryL( error, ETrue );
+                }
+            }
+        }
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL() end");    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::HandleUserCancelL
+// 
+// ---------------------------------------------------------------------------
+//      
+void CIAUpdateUiController::HandleUserCancelL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUserCancelL() begin");
+
+    // Get the current state.
+    // CancelOperation will set a new value for the state and we do not 
+    // want to use that.
+    TState state( iState );
+    
+    CancelOperation();
+    
+    // Set the flag on. 
+    // So, dialogs are handled correctly.
+    iCancelling = ETrue;
+    
+    if ( state == EDownloading || state == EInstalling )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Cancel pressed while updating");
+        // Update flow is completed here.
+        // Notice, that this will also start the report sending,
+        // but we do not wait the sending to be complete before continuing.
+        UpdateCompleteL( KErrCancel );
+        }
+    else if ( state == ESendingReport )
+        {
+        IAUPDATE_TRACE("[IAUPDATE] Dialog cancel called while sending reports");
+        // Reports are sent only when update flow has finished.
+        // So, UpdateCompleteL has already been called and an update flow
+        // dialog is still being shown. Because cancel is called, complete 
+        // flow without waiting for the report sending to finish.
+        EndUpdateFlowL( KErrCancel ); 
+        }
+
+    // Set the flag off because cancellation is over.
+    iCancelling = EFalse;
+
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUserCancelL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::RestartedFromSelfUpdate
+// 
+// ---------------------------------------------------------------------------
+//      
+TBool CIAUpdateUiController::RestartedFromSelfUpdate()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RestartedFromSelfUpdate() begin");
+	
+    TBool restarted( EFalse );
+    
+    CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() ); 
+    if ( info ) 
+        { 
+        // Restart info was available. 
+        delete info; 
+        info = NULL; 
+        restarted = ETrue; 
+        }    
+
+	IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::RestartedFromSelfUpdate() end: %d", 
+	                 restarted);
+    
+    return restarted;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ParamsReadAndRemoveFileL
+// 
+// ---------------------------------------------------------------------------
+//  
+CIAUpdateParameters* CIAUpdateUiController::ParamsReadAndRemoveFileL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsReadAndRemoveFileL() begin");
+	
+    CIAUpdateParameters* params( NULL );
+
+    CIAUpdateParametersFileManager* mgr( CIAUpdateParametersFileManager::NewLC() );
+    params = mgr->ReadL();
+    mgr->RemoveFile();
+    CleanupStack::PopAndDestroy( mgr );
+        
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsReadAndRemoveFileL() end");    
+    
+    return params;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ParamsWriteFileL
+// 
+// ---------------------------------------------------------------------------
+//  
+void CIAUpdateUiController::ParamsWriteFileL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsWriteFileL() begin");
+	
+	// Ownership is not transferred here.
+	CIAUpdateParameters* params( iFilter->FilterParams() );
+	if ( params )
+	    {
+        CIAUpdateParametersFileManager* mgr( 
+            CIAUpdateParametersFileManager::NewLC() );
+        mgr->WriteL( *params );
+        CleanupStack::PopAndDestroy( mgr );
+	    }
+
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsWriteFileL() end");    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::ParamsRemoveFileL
+// 
+// ---------------------------------------------------------------------------
+//  
+void CIAUpdateUiController::ParamsRemoveFileL()
+    {
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsRemoveFileL() begin");
+	
+    CIAUpdateParametersFileManager* mgr( 
+        CIAUpdateParametersFileManager::NewL() );
+    mgr->RemoveFile();
+    delete mgr;
+    mgr = NULL;
+            
+	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsRemoveFileL() end");    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::CreateSelectedNodesArrayL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateUiController::CreateSelectedNodesArrayL()
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CreateSelectedNodesArrayL() begin");
+    iSelectedNodesArray.Reset();
+    for ( TInt i = 0; i < iNodes.Count(); ++i )
+        {
+        if ( iNodes[ i ]->Base().IsSelected() )
+            {
+            iSelectedNodesArray.AppendL( iNodes[ i ] );
+            }
+        }
+
+    // Dependency nodes to be updated before their dependants.
+    // Also, self update nodes should be handled correctly.
+    iSelectedNodesArray.Sort( 
+          TLinearOrder< MIAUpdateNode >( &SortSelectedNodes ) );
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CreateSelectedNodesArrayL() end");
+    }
+
+// ---------------------------------------------------------------------------
+// CIAUpdateUiController::IAUpdateEnabledL()
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateUiController::IAUpdateEnabledL() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() begin");
+    TBool enabled = EFalse;
+    RFeatureControl featureControl;
+    TInt error( KErrNone );
+
+    error = featureControl.Connect();
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() Connection to the Feature Manager Server: %d", error);
+    
+    User::LeaveIfError( error );
+    
+    TUid iaupdatefeature;
+    iaupdatefeature.iUid = KFeatureIdIAUpdate;
+    
+    TInt ret = featureControl.FeatureSupported( iaupdatefeature );
+    if ( ret == KFeatureSupported )
+        {
+        enabled = ETrue;
+        }
+    featureControl.Close(); 
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() end");
+    return enabled;        
+    }
+
+// End of File