LOCAL_C void DoTestL(TestFunc aTestFuncL, const TDesC& aDesc)
	{
	test.Next(aDesc);

	// Set up for heap leak checking
	__UHEAP_MARK;

	// and leaking thread handles
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;

	// Test Starts...

	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);

	(*aTestFuncL)();

	REComSession::FinalClose(); // Don't want leaks outside the test

	//--------------
	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);

	test(startThreadHandleCount == endThreadHandleCount);

	__UHEAP_MARKEND;

	DoOomTestL(aTestFuncL, aDesc);

	}
/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0755
@SYMTestCaseDesc	    Create and delete test of CBackUpNotifier
@SYMTestPriority 	    High
@SYMTestActions  	    Check for handle leak after deletion of object.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void CreateDeleteTestL()
	{
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0755 CreateDeleteTestL "));
	// Set up for heap leak checking
	__UHEAP_MARK;

	// and leaking thread handles
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;

	// Test Starts...
	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);

	CBackUpNotifierTest* notifierTest = CBackUpNotifierTest::NewL();

	test(notifierTest!=NULL);

	delete notifierTest;

	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
	test(startThreadHandleCount == endThreadHandleCount);

	__UHEAP_MARKEND;
	}
/**
@SYMTestCaseID          SYSLIB-ECOM-CT-1808
@SYMTestCaseDesc	    Tests the uninstallation of an active plugin
@SYMTestPriority 	    High
@SYMTestActions  	    Creates a plugin implementation and then uninstalls the
                        plugin's files from the C: Drive and waits for an ECOM
                        notification completion, upon which it deletes the
                        plugin.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
void TestUninstallL()
	{
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1808 TestUninstallL "));

	// Set up for heap leak checking and leaking thread handles
	__UHEAP_MARK;
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;
	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);

    // Step 1: Setup the session to ECOM
    TInt err = KErrNone;
    REComSession& ecomSession = REComSession::OpenL();
	CleanupClosePushL(ecomSession);

    // Step 2: Register for ECOM Server notification.
	TRequestStatus notifyStatus;
    ecomSession.NotifyOnChange(notifyStatus);
	TEST2(notifyStatus.Int(), KRequestPending);

    // Step 3. Create the plugin implementation we will uninstall
    TheTest.Printf(_L("CHeapTestInterface::NewL()\n"));
    CHeapTestInterface* implPtr = 0;
    TRAP(err, implPtr = CHeapTestInterface::NewL());
	TEST2(err, KErrNone);

    // Step 4. Simulate the uninstall of the plugin files
    TheTest.Printf(_L("Deleting HTI plugin - attempt 1, wait 5s...\n"));
  	//TRAP(err, EComTestUtils::FileManDeleteFileL(KHTI_PluginInstalledOnC));
  	TRAP(err, EComTestUtils::RLoaderDeleteFileL(KHTI_PluginInstalledOnC));
#if defined(__WINS__) || defined (__WINSCW__)
   	TEST2(err, KErrAccessDenied); // DLL File locked under Windows emulator due to it being demand paged
   	TheTest.Printf(_L("Error -21 (KErrAccessDenied) expected due to Windows keeping the DLL mapped in the emulator process adress space due to Windows demand paging/virtual memory system\n"));
#elif defined(__EPOC32__)
   	TEST2(err, KErrNone); // DLL File not locked on target hardware under SOS
//#else Do no test at all as its an unexpected platform.
#endif

 	TRAP(err, EComTestUtils::FileManDeleteFileL(KHTIr_PluginInstalledOnC));
   	TEST2(err, KErrNone);

    // Step 5. Wait for ECOM Server notification to arrive, with precautionary hang timer.
	RTimer timer;
	CleanupClosePushL(timer);
	User::LeaveIfError(timer.CreateLocal());
	TRequestStatus timerStatus;
	timer.After(timerStatus, KWaitDuration);
	TEST2(timerStatus.Int(), KRequestPending);

    TheTest.Printf(_L("Before calling WaitForAnyRequest(): Timer Status: %d; ECOM Notif Status: %d\n"), timerStatus.Int(), notifyStatus.Int());
    TheTest.Printf(_L("Checking notification recieved for ECOM Server...\n"));
    User::WaitForRequest(timerStatus, notifyStatus);

	TEST2(timerStatus.Int(), KRequestPending);
	TEST2(notifyStatus.Int(), KErrNone);
	timer.Cancel();

    // Step 6. Destroy the plugin
    TheTest.Printf(_L("DELETE implPtr\n"));
    delete implPtr;


	//CleanupStack::PopAndDestroy(&timer);
    TheTest.Printf(_L("Test over, cleanup...\n"));
   	CleanupStack::PopAndDestroy(&timer);
	CleanupStack::PopAndDestroy(&ecomSession);
	REComSession::FinalClose();

	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
	TEST(startThreadHandleCount == endThreadHandleCount);

	// Test Ends...
	__UHEAP_MARKEND;

	}
/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0658
@SYMTestCaseDesc	    Tests for REComSession::NotifyOnChange() function
@SYMTestPriority 	    High
@SYMTestActions  	    Tests for changing the implementation dll(timestamp change) and checks for the notify status
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
void TestNotifyL()
	{
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0658 TestNotifyL "));

	// Set up for heap leak checking
	__UHEAP_MARK;

	// and leaking thread handles
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;

	// Test Starts...
	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);


	//-----
    REComSession& ecomSession = REComSession::OpenL();
	CleanupClosePushL(ecomSession);

	RTimer timer;
	CleanupClosePushL(timer);
	User::LeaveIfError(timer.CreateLocal());

	TRequestStatus timerStatus;
	TRequestStatus notifyStatus;

	// 1st disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 2nd disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 3rd disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 4th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 5th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 6th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 7th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 8th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 9th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 10th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 11th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteBaflL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 12th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change, but no regigstry data changed
	SimulatePluginCopyBaflL();

	User::WaitForAnyRequest();

	//since the file copied is same as before, no notify will be send
	TEST(notifyStatus==KRequestPending);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();


	// 13th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteFileManL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 14th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginCopyFileManL();

	User::WaitForAnyRequest();

	//since the file copied is same as before, no notify will be send
	TEST(notifyStatus==KRequestPending);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();


	// 15th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteRFsL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 16th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginReplaceRFsL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Replace back the deleted plugin.
	TRAPD(err, EComTestUtils::FileManCopyFileL(KExample5TmpRscOnC, KExample5RscOnC));
	TEST2(err, KErrNone);

	CleanupStack::PopAndDestroy(&timer);
	CleanupStack::PopAndDestroy(&ecomSession);
	//-----

	// Test Ends...
	REComSession::FinalClose();

	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
	TEST(startThreadHandleCount == endThreadHandleCount);

	__UHEAP_MARKEND;

	}