devicediagnosticsfw/diagframework/src/diagpluginexecplanimpl.cpp
branchRCL_3
changeset 25 b183ec05bd8c
parent 24 13d7c31c74e0
child 26 19bba8228ff0
--- a/devicediagnosticsfw/diagframework/src/diagpluginexecplanimpl.cpp	Thu Aug 19 10:44:50 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1577 +0,0 @@
-/*
-* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:  Class definition of CDiagPluginExecPlanImpl
-*
-*/
-
-
-// CLASS DECLARATION
-#include "diagpluginexecplanimpl.h"
-
-// SYSTEM INCLUDE FILES
-#include <e32def.h>
-#include <cstack.h>                     // CStack
-#include <DiagPlugin.h>                 // MDiagPlugin
-#include <DiagSuitePlugin.h>            // MDiagSuitePlugin
-#include <DiagTestPlugin.h>             // MDiagTestPlugin
-#include <DiagPluginPool.h>             // CDiagPluginPool
-#include <DiagResultsDatabase.h>        // RDiagResultsDatabaseRecord
-#include <DiagResultsDbItemBuilder.h>   // CDiagResultsDbItemBuilder
-#include <DiagResultDetail.h>           // MDiagResultDetail
-#include <DiagFrameworkDebug.h>         // For debug log
-#include <DiagResultsDbRecordEngineParam.h> // CDiagResultsDbRecordEngineParam
-
-// USER INCLUDE FILES
-#include "diagframework.pan"            // panic codes
-#include "diagexecplanentryimpl.h"      // CDiagExecPlanEntryImpl
-#include "diagexecplanentryimpltest.h"  // CDiagExecPlanEntryImplTest
-#include "diagexecplanentryimplsuite.h" // CDiagExecPlanEntryImplSuite
-#include "diagcleanupresetanddestroy.h" // CleanupRPointerArrayPushL
-#include "diagengineconfig.h"           // TDiagEngineConfig
-
-
-// DATA
-
-// MACROS
-// Uncomment the line below to enable more plan creation log.
-// #define _DEBUG_EXEC_PLAN
-
-
-// LOCAL DATA TYPES
-/**
-* Used for keeping track of suite level stack.
-* It is used in InsertSuiteTransitionsL() function. ( STEP_5 )
-*/
-struct TTransitionStackEntry
-    {
-    /**
-    * iLeavelUid - Uid of the current level. 
-    */
-    TUid  iLevelUid;
-    
-    /**
-    * iPrepareIndex - Index in the plan where ETypeSuitePrepare entry is. 
-    *   This information is used to update the suite iAsDependent field.
-    */
-    TInt    iPrepareIndex;         
-    };    
-
-
-// ======== LOCAL FUNCTIONS ========
-
-
-// ======== MEMBER FUNCTIONS ========
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::NewL
-// ---------------------------------------------------------------------------
-//
-CDiagPluginExecPlanImpl* CDiagPluginExecPlanImpl::NewL( 
-        MDiagEngineCommon& aEngine,
-        const TDiagEngineConfig& aEngineConfig,
-        MDiagExecPlanEntryImplObserver& aEntryObserver )
-    {
-    CDiagPluginExecPlanImpl* self = new ( ELeave ) CDiagPluginExecPlanImpl( 
-        aEngine,
-        aEngineConfig,
-        aEntryObserver );
-
-    return self;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::CDiagPluginExecPlanImpl
-// ---------------------------------------------------------------------------
-//
-CDiagPluginExecPlanImpl::CDiagPluginExecPlanImpl( 
-        MDiagEngineCommon& aEngine,
-        const TDiagEngineConfig& aEngineConfig,
-        MDiagExecPlanEntryImplObserver& aEntryObserver )
-    :   CActive( EPriorityLow ),
-        iEngine( aEngine ),
-        iEngineConfig( aEngineConfig ),
-        iPlanEntryObserver( aEntryObserver )
-    {
-    CActiveScheduler::Add( this );
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::~CDiagPluginExecPlanImpl
-// ---------------------------------------------------------------------------
-//
-CDiagPluginExecPlanImpl::~CDiagPluginExecPlanImpl()
-    {
-    Cancel();
-    iPlan.ResetAndDestroy();
-    iPlan.Close();
-    iExecutedEntries.ResetAndDestroy();
-    iExecutedEntries.Close();
-    }
-
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::InitaliazeL
-//      Creating a fresh session.
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::InitializeL( TRequestStatus& aStatus, 
-                                           const RPointerArray< MDiagPlugin >& aBatch )
-    {
-    LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: new session")
-
-    __ASSERT_ALWAYS( iState == EStateIdle, Panic( EDiagFrameworkInternal ) );
-
-    aStatus = KRequestPending;
-    iClientStatus = &aStatus;
-
-    iExecutedEntries.ResetAndDestroy();
-    iPlan.ResetAndDestroy();
-    iResumeIndex = 0;
-
-    // pre-step execution step. copy the argument to a local plan
-    TInt i;
-    for ( i = 0; i < aBatch.Count();  i++ )
-        {
-        __ASSERT_ALWAYS( aBatch[i] != NULL, Panic( EDiagFrameworkBadArgument ) );
-
-        CDiagExecPlanEntryImpl* newEntry = CreateDefaultPlanEntryLC(
-            *(aBatch[i]),
-            EFalse );   // aAsDependency
-
-        iPlan.AppendL( newEntry );  // ownership transferred.
-        CleanupStack::Pop( newEntry ); 
-        newEntry = NULL;
-        }
-
-    LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: Initial Batch" )
-    LogPlanL();
-
-    ChangeState( EStateExpandDependencyAndSuites );
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::InitializeL
-//      Continuing from incomplete session.
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::InitializeL( TRequestStatus& aStatus )
-    {
-    LOGSTRING( "CDiagPluginExecPlanImpl::InitaliazeL: continue" )
-
-    // validate input.
-    __ASSERT_ALWAYS( iState == EStateIdle, Panic( EDiagFrameworkInternal ) );
-
-    // if we are resuming incomplete session, it must incomplete.
-    TBool isRecordCompleted = EFalse;
-    User::LeaveIfError( iEngine.DbRecord().IsTestCompleted( isRecordCompleted ) );
-    __ASSERT_ALWAYS( !isRecordCompleted, Panic( EDiagFrameworkBadArgument ) );
-
-    aStatus = KRequestPending;
-    iClientStatus = &aStatus;
-    iResumeIndex = 0;
-
-    iExecutedEntries.ResetAndDestroy();
-    iPlan.ResetAndDestroy();
-
-    // Retrieve records from database and use it as base for creating 
-    // a new plan.
-    RPointerArray< CDiagResultsDatabaseItem > previousResults;
-    DiagFwInternal::CleanupRPointerArrayPushL< CDiagResultsDatabaseItem >( &previousResults );
-
-    User::LeaveIfError( 
-        iEngine.DbRecord().GetTestResults( previousResults ) );
-
-    TInt resultCount = previousResults.Count();
-    for( TInt i = 0; i < resultCount; i++ )
-        {
-        // Get the test plug-in.
-        // Note that FindPlugin does not transfer ownership and hence testPlugin
-        // and does not need to be deallocated.
-        MDiagPlugin& testPlugin = 
-            iEngine.PluginPool().FindPluginL( previousResults[i]->TestUid() );
-
-        // This should have been a test plug-in
-        __ASSERT_DEBUG( testPlugin.Type() == MDiagPlugin::ETypeTestPlugin,
-            Panic( EDiagFrameworkInternal ) );
-
-        CDiagExecPlanEntryImplTest* testEntry = 
-            CDiagExecPlanEntryImplTest::NewLC( 
-                iEngine,
-                iEngineConfig,
-                iPlanEntryObserver,
-                static_cast< MDiagTestPlugin& >( testPlugin ),
-                previousResults[i]->WasDependency(),
-                previousResults[i]->TestResult() );
-
-        if ( testEntry->Result() == CDiagResultsDatabaseItem::EQueuedToRun )
-            {
-            // it was queued to be executed.
-            iPlan.AppendL( testEntry ); // ownership transferred.
-            }
-        else
-            {
-            // it was already executed. 
-            iExecutedEntries.AppendL( testEntry ); // ownership transferred.
-            }
-        CleanupStack::Pop( testEntry );
-        testEntry = NULL;
-        }
-
-    CleanupStack::PopAndDestroy( &previousResults );
-
-    iResumeIndex = iExecutedEntries.Count();
-
-    if ( iResumeIndex != 0 )
-        {
-        LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: Queued Items" )
-        LogPlanL();
-
-        ChangeState( EStateExpandDependencyAndSuites );
-        }
-    else
-        {
-        LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: "
-            L"Items in DB may be invalid. Fully recreate plan" )
-
-        // If iResumeIndex is 0, it means that all items in the db are 
-        // marked as EQueuedToRun. Because of the async nature of db,
-        // it could also indicate that not previous plan was not fully
-        // written to the database. In this case, read the engine parameter
-        // and try to recreate the plan from scratch.
-        //
-        // If it was already fully written but hadn't had a chance to really
-        // execute anything, this will not cause any ill effects since
-        // plan created should be identical and simply reset 
-        // all results in db to EQueuedToRun.
-        iExecutedEntries.ResetAndDestroy();
-        iPlan.ResetAndDestroy();
-
-        RPointerArray< MDiagPlugin > batch;
-        CleanupClosePushL( batch );    // items are not owned, so no need for "Destroy"
-
-        CDiagResultsDbRecordEngineParam* engineParam = NULL;
-        User::LeaveIfError( 
-            iEngine.DbRecord().GetEngineParam( engineParam ) );
-
-        CleanupStack::PushL( engineParam );
-
-        const RArray< TUid >& batchUids = engineParam->ExecutionsUidArray();
-
-        // Read original Uids from previous engine param.
-        for( TInt i = 0; i < batchUids.Count(); i++ )
-            {
-            MDiagPlugin* testPlugin = NULL;
-            User::LeaveIfError( 
-                iEngine.PluginPool().FindPlugin( batchUids[i], testPlugin ) );
-
-            __ASSERT_DEBUG( testPlugin != NULL, Panic( EDiagFrameworkInternal ) );
-            if ( testPlugin )  //lint !e774 This will be evaluated on non-debug build.
-                {
-                batch.AppendL( testPlugin );
-                }
-            }
-
-        CleanupStack::PopAndDestroy( engineParam );
-        engineParam = NULL;
-
-        // Call the normal InitializeL() method as if it is a new session.
-        InitializeL( aStatus, batch );
-
-        CleanupStack::PopAndDestroy( &batch );  // calls Close()
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::operator[]
-// ---------------------------------------------------------------------------
-//
-CDiagExecPlanEntryImpl& CDiagPluginExecPlanImpl::operator[]( TInt aIndex )
-    {
-    return *iPlan[aIndex];
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::CurrentExecutionItem
-// ---------------------------------------------------------------------------
-//
-CDiagExecPlanEntryImpl& CDiagPluginExecPlanImpl::CurrentExecutionItem() 
-    {
-    return *iPlan[iExecutionCursor];
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::ResetExecutionCursor
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::ResetExecutionCursor()
-    {
-    iExecutionCursor = 0;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::MoveCursorToNext
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::MoveCursorToNext()
-    {
-    TBool value = EFalse;
-
-    if ( iExecutionCursor < iPlan.Count() - 1 )
-        {
-        iExecutionCursor++;
-        value = ETrue;
-        }
-    else
-        {
-        // cannot move beyond the last item.
-        }
-
-    return value;
-    }
-
-// ======== From CActive =========
-// ---------------------------------------------------------------------------
-// From CActive
-// CDiagPluginExecPlanImpl::RunL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::RunL()
-    {
-    /*----------------------------------------------------------------------
-       Create execution plan:
-       Overview:
-       
-            STEP_1. Expand Dependency 
-            STEP_2. Expand Suites.
-            STEP_3. Repeat STEP_1 & STEP_2 until no changes are made to the plan
-            STEP_4. Check and remove empty suites
-            STEP_5. Add Prepare/Finalize suite execution.
-            STEP_6. Store execution plan to results db. 
-            STEP_7. Append items that were executed in the previous test
-                    to the beginning of the test.
-       
-       Details:
-        STEP_1. Expand Dependency
-            In this step, each item is checked for dependency and 
-            dependent items will be inserted into plan.
-            Note that if dependent item also depends on something else, those
-            will be added immediately.
-       
-            All items inserted during this phase is inserted as dependent.
-       
-        STEP_2. Expand suites
-            Suites are expandeded to individual tests or suites. Suite
-            item will be expanded between parent suite's Prepare and 
-            Finalize items. 
-            
-            iAsDependent value will be inherited from the parent suite
-            that it expanded from. E.g. if suite was dependent, then so will
-            all the items that included from that suite.
-        
-            Note that it does not remove the original suite entry in the plan. 
-            This is to make sure that dependencies inserted will be grouped
-            within the same group as the plug-ins that depended on it.
-            If they are removed, and re-inserted later in STEP_5, it will
-            cause the dependent items to be outside of the original grouping.
-                e.g.  S1 = {P1}
-                      S2 = {P2, P3}
-
-                      and P2 depends on P1
-
-                When dependency and suites are expanded with original
-                suite removed, after STEP_3, the plan will look like this:
-                    (* indicates iAsDependent == ETrue)
-
-                      0     1    2
-                      *P1   P2   P3
-
-                When it tries to add suite transition back in to the plan,
-                it will look like this:
-                    (* indicates iAsDependent == ETrue)
-                    (< indicates suite prepare execution.)
-                    (> indicates suite finalize execution.)
-
-                      0    1    2    3    4   5   6
-                      <S1  *P1  S1>  <S2  P2  P3  S2>
-
-                which is somewhat incorrect since *P1 is added due to 
-                dependency. 
-                
-                Instead, if original suite grouping is kept, after STEP_3
-
-                    0    1    2    3    4
-                    <S2  *P1  P2   P3   S2>
-
-                After STEP_5
-
-                    0    1    2    3    4   5   6
-                    <S2  <S1  *P1  S1>  P2  P3  S2>
-                             
-                which is more correct.
-            
-            Note that this will be done in breadth first style. If there is a
-            nested suites, it will not be expanded until next cycle. 
-            This is to allow dependencies of the suite to be expanded before
-            being removed.
-       
-        STEP_3. Repeat STEP_1 & STEP_2 until no changes are made.
-            This step ensures that suites are expanded, and all dependent
-            items are added to the plan.
-       
-        STEP_4. Remove Empty suites
-            Because dependent items can be moved, it is possible that plan ends
-            up with empty suites. This section will check for 
-            suite prepare/finalize that has nothing inside, and remove them.
-
-        STEP_5. Add Prepare/Finalize steps for suites.
-            As a final step, it will navigate all the entries in the plan, and
-            insert proper prepare/finalize steps. This is based on stack,
-            where every suite prepare is pushed into a stack, and poped when
-            suite finalize is called. e.g. consider following plug-ins:
-
-                S1 = { P1, P2 }
-                S2 = { P3, P4 }
-
-                And P3 depends on P2.
-
-            And resulting plan after STEP_4 looked like this:
-
-                0    1     2    3    4
-                <S2  *P2   P3   P4   S2>
-
-            After STEP_5, it should look like this:
-
-                0    1    2    3    4    5    6
-                <S2  <S1  *P2  S1>  P3   P4   S2>
-
-        STEP_6. Store execution plan to results db. 
-            This allows continuation of the incomplete results.
-            Only test plug-ins are written to the database. 
-
-        STEP_7. Append items that were executed in the previous test
-            to the beginning of the test.
-
-        Other Notes:
-
-        NOTE_1) This logic currently does not check for circular dependencies.
-           If circular dependency exists, the program will go into an
-           infinite loop in ExpandDependenciesL().
-
-        NOTE_2) Inserting duplicate items.
-            Due to dependencies, duplicate entries may exist in the plan.
-
-            When items are inserted during STEP_1 - STEP_2, it will be checked
-            for duplicates.
-       
-            Duplicate removal policy is as follows:
-            RULE_A) If an item with "iAsDependent == ETrue" is being inserted,
-                AND if an item already exist in the plan before current index,
-                then it will not be inserted. 
-
-            RULE_B) Any items inserted with "iAsDependent == EFalse" will 
-               always be inserted at the requested index.
-               This is because they are considered to be user input, and
-               plan will not try to re-order the execution order that 
-               client or user has specified.
-
-            RULE_C) The first instance of an item has higher priority than later
-               instances. Later instace of duplicate will be removed, unless
-               it violates RULE_B. (e.g. item has "iAsDependent == EFalse".)
-
-            This has a side effect: item may execute twice in certain cases.
-            E.g. original plan has two plug-ins:  P1, P2, P3
-            P1 depends on P2, and P3 also depends ond P2
-
-            Original Input:   0   1   2
-                              P1  P2  P3
-
-            After STEP_3, it should look like this. 
-                    (* indicates iAsDependent == ETrue)
-
-                              0    1    2   3    4
-                              *P2  P1   P2  *P2  P3
-
-            During STEP_4, duplicates are removed, and it should look like this:
-                    (* indicates iAsDependent == ETrue)
-
-                              0    1    2   4
-                              *P2  P1   P2  P3
-
-            Note that there are two P2s in the plan; 
-            at 0 with iAsDependent == ETrue and at 2 with iAsDependent == EFalse
-
-            There may be some discussions on whether this is how it should be.
-            However, at this point, it seems that it is more important that
-            execution appears to the user in the order specified. 
-
-            To make sure that user sees that P2 is executed only once, plug-in
-            developer may need to make sure that if a plug-in provides services,
-            it should also handle cases where it is executed twice.
-
-            In reality, such cases can be avoided by grouping the plug-ins 
-            in the correct order, hence it should not be an issue.
-
-    ----------------------------------------------------------------------*/
-
-    // First, error handling.
-    LOGSTRING3( "CDiagPluginExecPlanImpl::RunL: State = %d, Err = %d",
-        iState, iStatus.Int() )
-
-    User::LeaveIfError( iStatus.Int() );
-
-    switch ( iState )
-        {
-        case EStateExpandDependencyAndSuites:
-            {
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_1")
-            // STEP_1. Expand dependency. 
-            if ( !iEngineConfig.IsDependencyDisabled() )
-                {
-                ExpandDependenciesL();
-                }
-
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_2")
-            // STEP_2. Expand suites.
-            if ( ExpandSuitesL() )
-                {
-                // STEP_3. Repeat STEP_1, STEP_2 until no changes are made.
-                // Do a self transition to repeat STEP_1 and STEP_2
-                ChangeState( EStateExpandDependencyAndSuites );
-                }
-            else
-                {
-                // no changes are made to the plan. Move to STEP_4
-                ChangeState( EStateRemoveEmptySuites );
-                }
-            }
-            break;
-
-        case EStateRemoveEmptySuites:
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_4")
-            // STEP_4. Remove empty suites. This can happen because of duplicate
-            // dependencies moving later dependent test to earlier position.
-            RemoveEmptySuites();
-
-            #ifdef _DEBUG_EXEC_PLAN
-            LOGSTRING( "CDiagPluginExecPlanImpl:CreatePlanL: "
-                L"Before Inserting Suite Transtions" )
-            LogPlanL();
-            #endif // _DEBUG_EXEC_PLAN
-
-            // Continue to STEP_5
-            ChangeState( EStateInsertSuiteTransitions );
-            break;
-
-        case EStateInsertSuiteTransitions:
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_5 - Insert Suite Transtions")
-            // STEP_5. Add pre/post suite execution
-            InsertSuiteTransitionsL();
-
-            // STEP_6. Store plan to db.
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_6 - Store to db")
-            // this time, manually update state, since storing 
-            // to database needs to use iStatus
-            iState = EStateStoreToDb;
-
-            // Move cursor to one before so that it can start checking from
-            // the beginning. StoreNextTestPluginToDbL() will move the cursor
-            // as soon as it enters.
-            iExecutionCursor = -1;
-            StoreNextTestPluginToDbL();
-            
-            break;
-
-        case EStateStoreToDb:
-            LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: STEP_6 - "
-                L"item 0x%08x stored.",
-                iPlan[iExecutionCursor]->Plugin().Uid().iUid )
-
-            StoreNextTestPluginToDbL();
-            break;
-
-        case EStatePlanCreated:
-            // STEP_7. Prepend the items that were executed in last session
-            // to the beginning of the execution plan.
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_7 - prepend executed items" )
-            PrependExecutedItemsL();
-
-            LOGSTRING( "CDiagPluginExecPlanImpl::RunL: Final Plan" )
-            LogPlanL();
-            
-            LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: Resume at index %d", iResumeIndex )
-
-            LogPlanInRecordL();
-
-            ResetExecutionCursor();
-
-            ReportResult( KErrNone );
-            break;
-
-        case EStateIdle:
-        default:
-            __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) );
-            break;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// From CActive
-// CDiagPluginExecPlanImpl::DoCancel
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::DoCancel()
-    {
-    iPlan.ResetAndDestroy();
-    iExecutedEntries.ResetAndDestroy();
-    iState = EStateIdle;
-
-    ReportResult( KErrCancel );
-    }
-
-// ---------------------------------------------------------------------------
-// From CActive
-// CDiagPluginExecPlanImpl::RunError
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::RunError( TInt aError )
-    {
-    iPlan.ResetAndDestroy();
-    iExecutedEntries.ResetAndDestroy();
-    iState = EStateIdle;
-
-    ReportResult( aError );
-
-    return KErrNone;
-    }
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::CurrentIndex
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::CurrentIndex() const
-    {
-    return iExecutionCursor;
-    }
-
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::CurrentTestIndex
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::CurrentTestIndex( TBool aIncludeDependency ) const
-    {
-    TInt count = 0;
-
-    for ( TInt i = 0; i < iPlan.Count() && i < iExecutionCursor; i++ )
-        {
-        if ( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
-            {
-            // if caller wants to include both explicit and dependent
-            // or if plug-in is not depentent test, count.
-            if ( aIncludeDependency || ( !iPlan[i]->AsDependency() ) )
-                {
-                count++;
-                }
-            }
-        }
-    
-    // subtract 1 if we only went past the last test.
-    if ( count >= TestCount( aIncludeDependency ) )
-        {
-        count--;
-        }
-    return count;
-    }
-
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::TestCount
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::TestCount( TBool aIncludeDependency ) const
-    {
-    TInt count = 0;
-
-    for ( TInt i = 0; i < iPlan.Count(); i++ )
-        {
-        if ( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
-            {
-            // if caller wants to include both explicit and dependent
-            // or if plug-in is not depentent test, count.
-            if ( aIncludeDependency || ( !iPlan[i]->AsDependency() ) )
-                count++;
-            }
-        }
-    return count;
-    }
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::operator[] () const
-// ---------------------------------------------------------------------------
-//
-const MDiagExecPlanEntry& CDiagPluginExecPlanImpl::operator[] ( TInt aIndex ) const
-    {
-    __ASSERT_ALWAYS( aIndex >= 0 && aIndex < iPlan.Count(), 
-                     Panic( EDiagFrameworkArrayBounds ) );
-    return *( static_cast< MDiagExecPlanEntry* >( iPlan[aIndex] ) );
-    }
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::CurrentExecutionItem const
-// ---------------------------------------------------------------------------
-//
-const MDiagExecPlanEntry& CDiagPluginExecPlanImpl::CurrentExecutionItem() const
-    {
-    __ASSERT_ALWAYS( iExecutionCursor >= 0 && iExecutionCursor < iPlan.Count(), 
-                     Panic( EDiagFrameworkArrayBounds ) );
-    return *( static_cast< MDiagExecPlanEntry* >( iPlan[iExecutionCursor] ) );
-    }
-
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::IsLastTest
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::IsLastTest() const
-    {
-    if ( TestCount( ETrue ) == 0 )
-        {
-        // there was no test in the plan.. 
-        // In this case, it is always ETrue.
-        return ETrue;
-        }
-
-    return ( CurrentTestIndex( ETrue ) == TestCount( ETrue ) - 1 );
-    }
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::IsLastPlugin
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::IsLastPlugin() const
-    {
-    if ( iPlan.Count() == 0 )
-        {
-        // if plan was empty, always consider it to be the last.
-        return ETrue;
-        }
-
-    return iExecutionCursor == ( iPlan.Count() -1 );
-    }
-
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::Count
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::Count() const
-    {
-    return iPlan.Count();
-    }
-
-// ---------------------------------------------------------------------------
-// From MDiagPluginExecPlan
-// CDiagPluginExecPlanImpl::ResumeIndex
-// ---------------------------------------------------------------------------
-//
-TInt CDiagPluginExecPlanImpl::ResumeIndex() const
-    {
-    return iResumeIndex;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::ChangeState
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::ChangeState( TState aState )
-    {
-    LOGSTRING3( "CDiagPluginExecPlanImpl::ChangeState: state change %d -> %d",
-        iState, aState )
-
-    iState = aState;
-
-    TRequestStatus* stat = &iStatus;
-    User::RequestComplete( stat, KErrNone );
-    SetActive();
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::ExpandDependenciesL
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::ExpandDependenciesL()
-    {
-    // STEP_1. Expand dependency.
-    // Before modifying this function, please see STEP_1 comments in CreatePlanL()
-    TInt planIdx = 0;
-    TBool planChanged( EFalse );
-    while ( planIdx < iPlan.Count() )
-        {
-        TBool itemAdded = EFalse;
-
-        // we are only interested in type ETypeTestExec or ETypeSuiteUnexpanded. 
-        // If it is ETypeSuitePrepare or ETypeSuiteFinalize, that means 
-        // that it is a suite and it has been already been expanded to 
-        // prepare/finalize. Since dependencies are resolved before suites 
-        // are expanded, we are not interested in re-evaluating expanded tests.
-        if ( iPlan[planIdx]->Type() == CDiagExecPlanEntryImpl::ETypeTestExec ||
-             iPlan[planIdx]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded )
-            {
-            // dependencies should be rare. So granuality 1 should be fine.
-            CPtrCArray* depList = new( ELeave )CPtrCArray( 1 );
-            CleanupStack::PushL( depList );
-            iPlan[planIdx]->Plugin().GetLogicalDependenciesL( *depList );
-
-            // iterate through the dependiencies BACKWARDS to make sure
-            // that dependencies are inserted in the same order 
-            // specified. If it is not added backwards, developers may 
-            // be surprised that dependencies are executed 
-            // in reverse order of what is specified in the XML.
-            for ( TInt depIdx = depList->Count() - 1; depIdx >= 0; depIdx-- )
-                {
-                // If dependency is specified, but the dependent plug-in is 
-                // not found in plug-in pool, this probably means 
-                // plug-in database is corrupted.
-                MDiagPlugin& plugin = iEngine.PluginPool().FindPluginL( ( *depList )[ depIdx ] );
-
-                if ( InsertPluginL( plugin, 
-                                    ETrue, 
-                                    planIdx ) )
-                    {
-                    itemAdded = ETrue;
-                    }
-                }
-            CleanupStack::PopAndDestroy( depList );
-            depList = NULL;
-            }
-
-        // Advance to next item in plan only if no new item is added.
-        // This ensures that items just added are re-evaluated for
-        // dependency, and expand if it is an unexpanded suite.
-        if ( !itemAdded )
-            {
-            planIdx++;
-            }
-        else
-            {
-            planChanged = ETrue;
-            }
-        }
-
-    return planChanged;
-    }
-
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::ExpandSuitesL
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::ExpandSuitesL() 
-    {
-    // STEP_2. Expand suites.
-    // Before modifying this function, please see STEP_1 comments in CreatePlanL()
-    TBool planChanged = EFalse;
-    TInt i = 0;
-    while ( i < iPlan.Count() )
-        {
-        if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded )
-            {
-            // If it is unexpanded, it must be a suite.
-            __ASSERT_DEBUG( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeSuitePlugin,
-                            Panic( EDiagFrameworkInternal ) );
-            planChanged = ETrue;
-
-            // Change type from ETestExec to ETypeSuitePrepare. This indicates
-            // that the suite item in the plan has been examined and
-            // expanded.
-            iPlan[i]->SetType( CDiagExecPlanEntryImpl::ETypeSuitePrepare );
-
-            // dependency is inherited
-            TBool asDependency = iPlan[i]->AsDependency();
-            
-            // Get Children from the plug-in
-            MDiagSuitePlugin& suite = static_cast<MDiagSuitePlugin&>( iPlan[i]->Plugin() );
-            RPointerArray<MDiagPlugin> children;
-            CleanupClosePushL( children );
-
-            suite.GetChildrenL( children, MDiagSuitePlugin::ESortByPosition );
-
-            i++; // insert rest after current item.
-
-            TInt childIdx = 0;
-            while ( childIdx < children.Count() )
-                {
-                if ( InsertPluginL( *( children[childIdx] ), 
-                                    asDependency, 
-                                    i ) )
-                    {
-                    // new item is added. Move to next
-                    i++;
-                    }
-                childIdx++;
-                }
-
-            children.Reset();   // children pointers are not owned 
-            CleanupStack::PopAndDestroy( &children );
-
-            // insert suite finalize entry into plan
-            CDiagExecPlanEntryImplSuite* finalizeEntry = 
-                CDiagExecPlanEntryImplSuite::NewLC(
-                    iEngine,
-                    iEngineConfig,
-                    iPlanEntryObserver,
-                    suite,
-                    asDependency,
-                    CDiagExecPlanEntryImpl::ETypeSuiteFinalize );
-
-            iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( finalizeEntry ), i );   
-            CleanupStack::Pop( finalizeEntry ); // owership transferred
-            finalizeEntry = NULL;
-            i++;
-            }
-        else
-            {
-            // this one is not suite, so examine the next one.
-            i++;    
-            }
-        }
-
-    return planChanged;
-    }
-
-// Looking for STEP_3?  It is in RunL() .. 
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::RemoveEmptySuites
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::RemoveEmptySuites()
-    {
-    // STEP_4. Remove empty suites
-    // Before modifying this function, please see STEP_1 comments in CreatePlanL()
-
-    // Checking for duplicate is done by checking if suite prepare/finalize
-    // is in the plan next to each other.
-    //
-    // NOTE_4
-    // After a empty suite is removed, step back one index.
-    // so that the previous item will be re-evaluated, in case removing them cased 
-    // the parent suite to be empty as well.
-    //      e.g
-    //      i == 1
-    //      index:   0   [1]  2   3
-    //               <A  <B   B>  A> 
-    //  after removal, now prepare/finalize A becomes next to each other
-    //
-    //      i == 1
-    //      index:   0   [1] 
-    //               <A  A> 
-    //
-    // in order to make sure that above case is handled, decrement i and
-    // re-evaluate from index 0
-    //
-    TInt i = 0;
-    while ( i < iPlan.Count() - 2 )  // no need to go beyond the last item
-        {
-        if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare &&
-                iPlan[i+1]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize )
-            {
-            // if these two do not match, then there may have been
-            // a problem during plan creation.
-            __ASSERT_DEBUG( iPlan[i]->Plugin().Uid() == iPlan[i+1]->Plugin().Uid(),
-                            Panic( EDiagFrameworkCorruptPlugin ) );
-
-
-            CDiagExecPlanEntryImpl* entry = iPlan[ i + 1 ];
-            iPlan.Remove( i+1 );
-            delete entry;
-            entry = NULL;
-
-            entry = iPlan[i];
-            iPlan.Remove( i );
-            delete entry;
-            entry = NULL;
-            
-            // Wondering why step back by one? See NOTE_4
-            if ( i > 0 )
-                {
-                i--;
-                }
-            }
-        else
-            {
-            // it's not empty. Examine next item.
-            i++;
-            }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::InsertSuiteTransitionsL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::InsertSuiteTransitionsL()
-    {
-    // STEP_5. Add pre/post suite execution based on test parent change.
-    // Before modifying this function, please see STEP_1 comments in CreatePlanL()
-    
-    // if plan is empty, nothing to do.
-    if ( iPlan.Count() == 0 )
-        {
-        return;
-        }
-    
-    // Create a new CStack. Second template parameter ETrue means that
-    // CStack owns the stack entries.
-    CStack<TTransitionStackEntry, ETrue>* stack = 
-        new( ELeave )CStack<TTransitionStackEntry, ETrue>;
-    
-    CleanupStack::PushL( stack );
-
-    // create a root entry
-    AddRootSuiteIfMissingL();
-    
-    // In this loop, iPlan.Count() cannot be cached because new item may be
-    // added within the loop
-    TInt i = 0;
-    while ( i < iPlan.Count() )
-        {
-        #ifdef _DEBUG_EXEC_PLAN
-        LOGSTRING2( "CDiagPluginExecPlanImpl::InsertSuiteTransitionsL: ------ %d", i )
-        LogPlanL();
-        #endif // _DEBUG_EXEC_PLAN
-            
-        // Case 1
-        // If current item is a suite prepare, push a new level into stack.
-        if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare )
-            {
-            // we are entering a new suite. Push current plan item into stack.
-            PushNewLevelL( *stack, i );
-            i++;
-            continue; //lint !e960  continue OK. examine next item.
-            }
-
-        // Case 2
-        // If current item is a suite finalize, pop a level from stack.
-        if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize && 
-                stack->Head() != NULL &&
-                stack->Head()->iLevelUid == iPlan[i]->Plugin().Uid() )
-            {
-            // we are leaving a suite. Pop top item from suite.
-            PopLevel( *stack );
-            i++;
-            continue; //lint !e960 : continue OK. examine next item.
-            }
-
-        // it was neither prepare or finalize. Examine item as current level.
-        const TTransitionStackEntry& level = *(stack->Head()); // Peek
-
-        TUid newLevelUid = iPlan[i]->Plugin().ParentUid();
-
-        // Case 3
-        if ( newLevelUid == level.iLevelUid )
-            {
-            // still in the same suite level.  No need to add new items.
-
-            // check if current item is non-dependent.
-            // If so, update the iAsDependent to reflect that it includes
-            // a non-dependent item.
-            if ( !(iPlan[i]->AsDependency()) )
-                {
-                // update the prepare item, indicating that it has
-                // an non-dependent item
-                iPlan[level.iPrepareIndex]->SetAsDependency( EFalse );
-                }
-            i++;
-            continue;   //lint !e960 : continue OK. examine next item.
-            }
-
-        // If parent UID is differnt from current level uid, 
-        // it can mean one of the following:
-        //  A ) We are entering a new suite.
-        //  B ) We leaving a suite.
-        // Case B ) can be deteced by checking whether the new parent is 
-        // already in the stack somewhere (stack will be popped until we are
-        // in the same level), or if there is no more item of the same
-        // level is in the plan, which means it is not needed.
-        // If case B ) fails, assume case A.
-        if ( IsLevelInStack( *stack, newLevelUid ) ||
-             !IsThisSuiteNeededAfterThisIndex( stack->Head()->iLevelUid, i ) )
-            {
-            // Case B) Insert a new Finalize item.
-            AddSuiteFinalizeL( level.iPrepareIndex, i );
-            }
-        else
-            {
-            // Case A) Insert a new prepare item.
-            AddSuitePrepareL( newLevelUid, i );
-            }
-        }
-
-    // When all done, stack must be empty.
-    __ASSERT_DEBUG( stack->IsEmpty(), Panic( EDiagFrameworkInternal ) );
-
-    CleanupStack::PopAndDestroy( stack );
-    stack = NULL;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::AddRootSuiteIfMissingL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::AddRootSuiteIfMissingL()
-    {
-    // Check to see if root element is already in the plan.
-    if ( iPlan[0]->Plugin().Uid() != KDiagRootSuiteUid )
-        {
-        // root( uid 0 ) does not exist in the plan.
-        // Add prepare and finalize root into the plan.
-        MDiagPlugin& rootPlugin = iEngine.PluginPool().FindPluginL( KDiagRootSuiteUid );
-
-        CDiagExecPlanEntryImplSuite* rootEntry = 
-            CDiagExecPlanEntryImplSuite::NewLC(
-                iEngine,
-                iEngineConfig,
-                iPlanEntryObserver,
-                static_cast< MDiagSuitePlugin& >( rootPlugin ),
-                ETrue,              // iAsDependent == ETrue. Updated as later.
-                CDiagExecPlanEntryImpl::ETypeSuitePrepare );
-
-        iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( rootEntry ), 0 );  
-        CleanupStack::Pop( rootEntry ); // ownership transferred above.
-        rootEntry = NULL;
-
-        rootEntry = CDiagExecPlanEntryImplSuite::NewLC(
-            iEngine,
-            iEngineConfig,
-            iPlanEntryObserver,
-            static_cast< MDiagSuitePlugin& >( rootPlugin ),
-            ETrue,              // iAsDependent == ETrue. Updated as later.
-            CDiagExecPlanEntryImpl::ETypeSuiteFinalize );
-
-        // insert same entry with finalize as type
-        iPlan.AppendL( static_cast< CDiagExecPlanEntryImpl* >( rootEntry ) );
-        CleanupStack::Pop( rootEntry ); // ownership transferred above
-        rootEntry = NULL;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::PushNewLevelL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::PushNewLevelL( 
-        CStack<TTransitionStackEntry, ETrue>& aStack, 
-        TInt aHeadIndex )
-    {
-    TTransitionStackEntry* level = new( ELeave )TTransitionStackEntry;
-
-    __ASSERT_ALWAYS( aHeadIndex >= 0 && aHeadIndex < iPlan.Count(),
-                     Panic( EDiagFrameworkInternal ) );
-
-    level->iLevelUid = iPlan[aHeadIndex]->Plugin().Uid();
-    level->iPrepareIndex = aHeadIndex;
-
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING2( "CDiagPluginExecPlanImpl:: Push 0x%08x", level->iLevelUid.iUid )
-    #endif // _DEBUG_EXEC_PLAN
-
-    aStack.PushL( level ); // owership transferred.
-    level = NULL; //lint !e423 Ownership transferred. No leak here.
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::PopLevel
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::PopLevel( CStack<TTransitionStackEntry, ETrue>& aStack )
-    {
-    TTransitionStackEntry* level = aStack.Pop();
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING2( "CDiagPluginExecPlanImpl:: Pop 0x%08x", level->iLevelUid.iUid )
-    #endif // _DEBUG_EXEC_PLAN
-    delete level;
-    level = NULL;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::IsLevelInStack
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::IsLevelInStack( 
-        CStack<TTransitionStackEntry, ETrue>& aStack,
-        TUid aLevelUid ) const
-    {
-    for ( TInt i = 0; i < aStack.Count(); i++ )
-        {
-        const TTransitionStackEntry& currEntry = *aStack[i];
-        if ( currEntry.iLevelUid == aLevelUid )
-            {
-            return ETrue;
-            }
-        }
-
-    return EFalse;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::IsThisSuiteNeededAfterThisIndex
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::IsThisSuiteNeededAfterThisIndex(
-        TUid aSuiteUid,
-        TInt aIndex ) const
-    {
-    for ( TInt i = aIndex; i < iPlan.Count(); i++ )
-        {
-        if ( iPlan[i]->Plugin().Uid() == aSuiteUid ||  // finalize already exists
-             iPlan[i]->Plugin().ParentUid() == aSuiteUid )
-            {
-            return ETrue;
-            }
-        }
-
-    return EFalse;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::AddSuitePrepareL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::AddSuitePrepareL( TUid aLevelUid, TInt aAt )
-    {
-    MDiagPlugin& suitePlugin = iEngine.PluginPool().FindPluginL( aLevelUid );
-
-    CDiagExecPlanEntryImplSuite* prepareEntry =
-        CDiagExecPlanEntryImplSuite::NewLC( 
-            iEngine,
-            iEngineConfig,
-            iPlanEntryObserver,
-            static_cast< MDiagSuitePlugin& >( suitePlugin ),
-            ETrue, // iAsDependent. Updated as later if not true.
-            CDiagExecPlanEntryImpl::ETypeSuitePrepare );
-
-    iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( prepareEntry ), aAt );
-    CleanupStack::Pop( prepareEntry ); // ownership transfer
-    prepareEntry = NULL;
-
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING2( "CDiagPluginExecPlanImpl:: InsertPrepare 0x%08x", aLevelUid )
-    #endif // _DEBUG_EXEC_PLAN
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::AddSuiteFinalizeL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::AddSuiteFinalizeL( TInt aPrepareIndex, TInt aAt )
-    {
-    // It is identical to the prepare entry, except that type is ETypeSuiteFinalize
-    __ASSERT_ALWAYS( aPrepareIndex >= 0 && aPrepareIndex < iPlan.Count(),
-                     Panic( EDiagFrameworkInternal ) );
-
-    CDiagExecPlanEntryImplSuite& prepareEntry = 
-        static_cast< CDiagExecPlanEntryImplSuite& > ( *(iPlan[aPrepareIndex]) );
-
-    CDiagExecPlanEntryImplSuite* finalizeEntry = 
-        CDiagExecPlanEntryImplSuite::NewLC( 
-            iEngine,
-            iEngineConfig,
-            iPlanEntryObserver,
-            prepareEntry.SuitePlugin(),
-            prepareEntry.AsDependency(),
-            CDiagExecPlanEntryImpl::ETypeSuiteFinalize );
-
-    iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( finalizeEntry ), aAt );
-    CleanupStack::Pop( finalizeEntry );  // ownership transmitted above
-    finalizeEntry = NULL;
-
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING2( "CDiagPluginExecPlanImpl:: InsertFinalize 0x%08x", prepareEntry.Plugin().Uid().iUid );
-    #endif // _DEBUG_EXEC_PLAN
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::StoreNextTestPluginToDbL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::StoreNextTestPluginToDbL()
-    {
-    // STEP_6. Store plan to DB. 
-    // In this step, all test entries must be stored in db with EQueuedToRun
-    // status. Since DbRecord().LogTestResult() is an async call, only one
-    // item can be written at a time. 
-    //
-    // To do this, this function will search for the next "TEST" plug-in that
-    // needs to be logged to DB. Once it is found, it will call async function
-    // LogTestResult() and wait for RunL() to execute again.
-    // In RunL(), StoreNextTestPluginToDbL() is called again, and it will look for the
-    // next test plugin to store until it loops through all items in plan.
-    while ( MoveCursorToNext() )
-        {
-        if ( CurrentExecutionItem().Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
-            {
-            LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: STEP_6 - storing item 0x%08x",
-                CurrentExecutionItem().Plugin().Uid().iUid )
-
-            CDiagResultsDatabaseItem* resultItem = 
-                CDiagResultsDbItemBuilder::CreateSimpleDbItemL( 
-                    CurrentExecutionItem().Plugin().Uid(),
-                    CurrentExecutionItem().AsDependency(),
-                    CDiagResultsDatabaseItem::EQueuedToRun );
-
-            // Record initial test result to db.
-            // StoreNextTestPluginToDbL() will be called again later from RunL()
-            iEngine.DbRecord().LogTestResult( iStatus, *resultItem );
-            SetActive();
-
-            delete resultItem;
-            resultItem = NULL;
-
-            // Exit here since we must wait for LogTestResult() to complete
-            // before moving on to the next item.
-            return;
-            }
-        }
-
-    // All items are stored now.
-    ChangeState( EStatePlanCreated );
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::PrependExecutedItemsL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::PrependExecutedItemsL()
-    {
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING( "CDiagExecPlanEntryImpl::PrependExecutedItemsL(). "
-        L" Before prepending executed entries" );
-    LogPlanL();
-    #endif // _DEBUG_EXEC_PLAN
-
-    for ( TInt lastIndex = iExecutedEntries.Count() - 1;
-          lastIndex >= 0 ;
-          lastIndex-- )
-        {
-        // Insert last entry from the executed list to the beginning.
-        iPlan.InsertL( iExecutedEntries[ lastIndex ], 0 );
-        iExecutedEntries.Remove( lastIndex );
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::ReportResult
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::ReportResult( TInt aError )
-    {
-    User::RequestComplete( iClientStatus, aError );
-    iClientStatus = NULL;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::InsertPluginL
-// ---------------------------------------------------------------------------
-//
-TBool CDiagPluginExecPlanImpl::InsertPluginL( MDiagPlugin& aPlugin,
-                                              TBool aAsDependency,
-                                              TInt aAt )
-    {
-    #ifdef _DEBUG_EXEC_PLAN
-    LOGSTRING4( "CDiagPluginExecPlanImpl::InsertPluginL:"
-            L"Id = 0x%x, Type = %s, At %d", 
-            aPlugin.Uid().iUid,  
-            ( aPlugin.Type() == MDiagPlugin::ETypeTestPlugin ? L"Test" : L"Suite" ),
-            aAt )
-    #endif // _DEBUG_EXEC_PLAN
-
-    __ASSERT_ALWAYS( aAt >= 0 && aAt <= iPlan.Count(), Panic( EDiagFrameworkArrayBounds ) );
-
-    // First, examine items before given index.
-    // If new item has iAsDependent == ETrue, and also found before the given index,
-    //   --> it is okay to not insert the item, since it will just be duplicates.
-    // if new item has iAsDependent == EFalse, 
-    //   --> no need to check for items prior to current position, since
-    //   explicit
-    // where it was requested.
-    TInt idx = 0;
-    if ( aAsDependency )
-        {
-        // check if it was already executed in the previous session.
-        for ( idx = 0; idx < iExecutedEntries.Count(); idx++ )
-            {
-            if ( iExecutedEntries[idx]->Plugin().Uid() == aPlugin.Uid() )
-                {
-                // matching item found.
-                // No need to instert a new item.
-                return EFalse;
-                }
-            }
-
-        // check for items in current plan.
-        for ( idx = 0; idx < aAt && idx < iPlan.Count(); idx++ )
-            {
-            if ( iPlan[idx]->Plugin().Uid() == aPlugin.Uid() )
-                {
-                // Matching item found. 
-                // No change to plan made.
-                return EFalse;
-                }
-            }
-        }
-
-    // Duplicate item not found before given index.
-    // An item will be inserted at the given index. Now, we search for
-    // duplicates after current index, and see if we can remove them.
-    idx = aAt;
-    while ( idx < iPlan.Count() )
-        {
-        if ( iPlan[idx]->Plugin().Uid() == aPlugin.Uid() && iPlan[idx]->AsDependency() )
-            {
-            // Item is found, and it was for dependency.
-            // We can move this item to current position. 
-            // For now, we just need to remove it, since it will be added at
-            // current position when for loop is done.
-            CDiagExecPlanEntryImpl* entry = iPlan[idx];
-            iPlan.Remove( idx );
-            delete entry;
-            entry = NULL;
-
-            // no need to increment idx, since current item is removed.
-            // idx should already be at the next item.
-            }
-        else
-            {
-            idx++;     // check next item.
-            }
-        }
-
-    // Either plug-in is not found, or we found one that we can move.
-    // Add to current position.
-    CDiagExecPlanEntryImpl* newEntry = CreateDefaultPlanEntryLC(
-        aPlugin,
-        aAsDependency );
-
-    iPlan.InsertL( newEntry, aAt );
-    CleanupStack::Pop( newEntry );
-    newEntry = NULL;
-
-    return ETrue;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::CreateDefaultPlanEntryL
-//
-// ---------------------------------------------------------------------------
-//
-CDiagExecPlanEntryImpl* CDiagPluginExecPlanImpl::CreateDefaultPlanEntryLC(
-        MDiagPlugin& aPlugin,
-        TBool aAsDependency ) const
-    {
-    CDiagExecPlanEntryImpl* newEntry = NULL;
-
-    if ( aPlugin.Type() == MDiagPlugin::ETypeTestPlugin )
-        {
-        newEntry = static_cast< CDiagExecPlanEntryImpl* >(
-            CDiagExecPlanEntryImplTest::NewLC(
-                iEngine,
-                iEngineConfig,
-                iPlanEntryObserver,
-                static_cast< MDiagTestPlugin& >( aPlugin ),
-                aAsDependency,
-                CDiagResultsDatabaseItem::EQueuedToRun ) );
-        }
-    else
-        {
-        newEntry = static_cast< CDiagExecPlanEntryImpl* >(
-            CDiagExecPlanEntryImplSuite::NewLC(
-                iEngine,
-                iEngineConfig,
-                iPlanEntryObserver,
-                static_cast< MDiagSuitePlugin& >( aPlugin ),
-                aAsDependency,
-                CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded ) );
-        }
-
-    return newEntry;
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::LogPlan
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::LogPlanL() const
-    {
-    #ifdef _DEBUG
-    LOGSTRING( "CDiagPluginExecPlanImpl::LogPlan(): Plan Dump." )
-    for ( TInt i = 0; i < iPlan.Count(); i++ )
-        {            
-        HBufC* pluginName = iPlan[i]->Plugin().GetPluginNameL( 
-            MDiagPlugin::ENameLayoutListSingle );
-
-        LOGSTRING5( "Plan Entry: Id = 0x%08x, %s, Dep=[%s], Name = %S",
-            iPlan[i]->Plugin().Uid().iUid,  
-            ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare ? L"<" : 
-                ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize ? L">" : L" " ) ),
-            ( iPlan[i]->AsDependency() ? L"*" : L" " ),
-            pluginName )
-
-        delete pluginName;
-        }
-    #endif // _DEBUG
-    }
-
-// ---------------------------------------------------------------------------
-// CDiagPluginExecPlanImpl::LogPlanInRecordL
-// ---------------------------------------------------------------------------
-//
-void CDiagPluginExecPlanImpl::LogPlanInRecordL() const
-    {
-    #ifdef _DEBUG
-
-    LOGSTRING( "CDiagPluginExecPlanImpl::LogPlanInRecord()" )
-
-    RPointerArray< CDiagResultsDatabaseItem > results;
-    DiagFwInternal::CleanupRPointerArrayPushL< CDiagResultsDatabaseItem >( &results );
-    User::LeaveIfError(
-        iEngine.DbRecord().GetTestResults( results ) );
-
-    TInt resultCount = results.Count();
-
-    LOGSTRING2( "  Result Count = %d", resultCount )
-
-    for ( TInt i = 0; i < resultCount; i++ )
-        {
-        LOGSTRING4( "   Test UID = 0x%08x, Result = %d, Dep = %d", 
-            results[i]->TestUid().iUid,
-            results[i]->TestResult(),
-            results[i]->WasDependency() )
-        }
-
-    CleanupStack::PopAndDestroy( &results );
-
-    #endif // _DEBUG
-    }
-
-// End of File
-