backupandrestore/backuptest/burtestserver/TestSteps/src/t_burteststepbase.cpp
changeset 0 d0791faffa3f
child 29 3ae5cb0b4c02
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/backupandrestore/backuptest/burtestserver/TestSteps/src/t_burteststepbase.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,1498 @@
+// Copyright (c) 2004-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:
+//
+
+/**
+ @file
+ @released
+*/
+
+#include "t_burteststepbase.h"
+
+namespace bur_ts
+	{
+	_LIT(KTabText, "\t|");
+	_LIT(KFormatText2, "%S%S");
+	_LIT(KFormatText3, "%S%S%S");
+	_LIT(KFormatText4, "%S%S%d");
+	_LIT(KFormatText5, "%S%S%X");
+	_LIT(KFormatText6, "%S%S%s");
+	
+	const TUint8 KMaxHexLength = 8;
+	
+	CBURTestStepBase::CBURTestStepBase(CBURTestServer& aParent) 
+		/**
+		C++ Constructor
+		
+		@internalComponent
+		@released
+		
+		@param aParent - The parent CBURTestServer of this child test step.
+		*/
+		:iParentTestServer(aParent),
+		iBackupClient(NULL),
+		iBackupIncType(EBackupBase),
+	 	iIsPartial(EFalse),
+	 	iExpectStatus(1),
+	 	iExpectStatus2(1),
+		iFailures(KErrNone),
+		iStorageManager(NULL),
+		iMode(EBackupMode),
+		iWaitedForActive(EFalse)
+		{}
+	
+	CBURTestStepBase::~CBURTestStepBase()
+		/**
+		C++ Destructor
+		@internalComponent
+		@released
+		*/
+		{
+		iDataOwners.ResetAndDestroy();
+		iDataOwners.Close();
+			
+		iSidArray.Close();
+		iJidArray.Close();
+		iPublicFileNames.Close();
+		iPrivateFileNames.Close();
+		iPrivateFileSizes.Close();
+		
+		iFs.Close();
+		
+		iTransferTypes.ResetAndDestroy();
+		iTransferTypes.Close();
+		
+		delete iStorageManager;
+		delete iActiveScheduler;
+		
+		delete iBackupClient;
+		}
+	
+	// LOGGING METHODS
+	void CBURTestStepBase::Log(TUint aIndentationLevel, const TDesC& aLog)
+		/**
+		Logs the data inside the string as text string at aIndentationLevel.
+		
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF3(KFormatText2, &ptr, &aLog);
+		delete indentation;
+		}
+	
+	void CBURTestStepBase::LogWithText(TUint aIndentationLevel, const TDesC& aLog, const TDesC& aText)
+		/**
+		Writes the message with a text string.
+		
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		@param aText - Textual data to be logged with the main message.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF4(KFormatText3, &ptr, &aLog, &aText);
+		delete indentation;
+		}
+	
+	void CBURTestStepBase::LogWithText8(TUint aIndentationLevel, const TDesC& aLog, const TDesC8& aText)
+		/**
+		8-bit variant of the above
+		
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		@param aText - 8-bit textual data to be logged with the main message.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF4(KFormatText3, &ptr, &aLog, &aText);
+		delete indentation;
+		}
+	
+	void CBURTestStepBase::LogWithNum(TUint aIndentationLevel, const TDesC& aLog, TInt aNum)
+		/**
+		Writes to the report a number along with a message.
+		
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		@param aNum - Number to be printed with the log.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF4(KFormatText4, &ptr, &aLog, aNum);
+		delete indentation;
+		}
+	
+	void CBURTestStepBase::LogWithSID(TUint aIndentationLevel, const TDesC& aLog, TSecureId aSecureId)
+		/**
+		Writes out a TSecureId as a hexadecimal number along with a message.
+		
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		@param aSecureId - A TSecureId to be printed as a hexadecimal number.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF4(KFormatText5, &ptr, &aLog, aSecureId.iId);
+		delete indentation;
+		}
+	
+	void CBURTestStepBase::LogWithChar(TUint aIndentationLevel, const TDesC& aLog, TChar aChar)
+		/**
+		@internalComponent
+		@released
+		
+		@param aIndentationLevel - The indentation level in the TestExecute test report.
+		@param aLog - The message to be logged.
+		@param aChar - A single char, appended at the end of the message.
+		*/
+		{
+		HBufC* indentation = NULL;
+		indentation = GetIndentation(aIndentationLevel);
+		TPtr ptr = indentation->Des();
+		INFO_PRINTF4(KFormatText6, &ptr, &aLog, &aChar);
+		delete indentation;
+		}
+	
+	HBufC* CBURTestStepBase::GetIndentation(TInt aLevel)
+		/**
+		Generates a string of indentation markers (based on KIndentationMarker) the 
+		level of depth specified by aLevel
+		
+		@internalComponent
+		@released
+		
+		@param aLevel - Level of depth required for indentation.
+		*/
+		{
+		HBufC* hbuf = NULL;
+		
+		// Indentation level times the length of the indentation marker, 
+		// plus room for a tab and a '|'
+		TInt indentationLength = aLevel * KIndentationMarker().Length() + 10;
+		hbuf = HBufC::NewL(indentationLength);
+		
+		hbuf->Des().Append(KTabText);
+		for(TInt i = 0; i < aLevel; ++i)
+			{
+			hbuf->Des().Append(KIndentationMarker);
+			}
+		
+		return hbuf;
+		}
+	
+	void CBURTestStepBase::CreateStorageManagerL()
+		/**
+		Must only be called after the user input has been processed.
+		@internalComponent
+		@released
+		*/
+		{
+		iStorageManager = CStorageManager::NewL(iBackupDirName, iDriveList, this);
+		}
+	
+	void CBURTestStepBase::ProcessUserOptionsL()
+		/**
+		This function uses TestExecute config file parsers to read in the user preferences
+		from ini files
+		
+		@internalComponent
+		@released
+		 */
+		{
+		TPtrC backupDir;
+		TInt isPartial = 0;
+		TInt isBase = 0;
+		TPtrC driveListText;
+		
+		// directory for archiving backup data
+		_LIT(KBackupDirText1, "BackupDir");
+		GetStringFromConfig(ConfigSection(), KBackupDirText1, backupDir);
+		
+		_LIT(KBackupDirText2, "Backup directory: ");
+		LogWithText(LOG_LEVEL3, KBackupDirText2, backupDir);
+		iBackupDirName.Copy(backupDir);
+		
+		// affected drives
+		_LIT(KDriveListText1, "DriveList");
+		GetStringFromConfig(ConfigSection(), KDriveListText1, driveListText);
+		_LIT(KDriveListText2, "Drives: ");
+		
+		LogWithText(LOG_LEVEL3, KDriveListText2, driveListText);
+		// extract all drives from the user input
+		iDriveList = CBURTestStepBase::StringToDriveListL(driveListText);
+		
+		// create the storage handler based on the drives and backup directory
+		CreateStorageManagerL();
+		
+		_LIT(KExpectStatusText1, "ExpectStatus");
+		GetIntFromConfig(ConfigSection(), KExpectStatusText1, iExpectStatus);
+		
+		_LIT(KExpectStatusText2, "ExpectStatus: ");
+		LogWithNum(LOG_LEVEL3, KExpectStatusText2, iExpectStatus);		
+		
+		_LIT(KExpectStatusText3, "ExpectStatus2");
+		GetIntFromConfig(ConfigSection(), KExpectStatusText3, iExpectStatus2);
+		
+		_LIT(KExpectStatusText4, "ExpectStatus2: ");
+		LogWithNum(LOG_LEVEL3, KExpectStatusText4, iExpectStatus2);			
+
+		// full/partial backup
+		_LIT(KPartialText1, "IsPartial");
+		GetIntFromConfig(ConfigSection(), KPartialText1, isPartial);
+		if (isPartial == 0)
+			{
+			iIsPartial = EFalse;
+			
+			_LIT(KPartialText2, "Full/Partial Type: Full");
+			Log(LOG_LEVEL3, KPartialText2);
+			} //if
+		else if (isPartial == 1)
+			{
+			iIsPartial = ETrue;
+			TSecureId sid;
+			
+			TChar ch;
+			TPtrC list;
+			
+			
+			// PARSING ID LIST //
+			
+			_LIT(KSIDList, "IDs");
+			GetStringFromConfig(ConfigSection(), KSIDList, list);
+			TLex sidLex(list);
+		
+			while (!sidLex.Eos())
+				{
+        		sidLex.Mark();
+	        	ch=sidLex.Peek();
+
+    	    	while(!sidLex.Eos() && ( ch=sidLex.Peek() ) != TChar(','))
+        			sidLex.Inc();
+ 
+        		if(!sidLex.TokenLength())
+        			continue;
+        		
+        		TPtrC pToken = sidLex.MarkedToken();
+        		TLex token(pToken);
+        		
+        		if (pToken.Length() <= KMaxHexLength && token.Val(sid.iId, EHex) == KErrNone)
+        			{
+        			iSidArray.Append(sid);
+					_LIT(KFound, "ID Found in ini file: ");
+					LogWithSID(LOG_LEVEL4, KFound, sid);		
+        			} //if
+        		else // must be a Java suite hash
+        			{
+        			iJidArray.Append(pToken);
+        			_LIT(KJFound, "Java ID Found in ini file: ");
+        			LogWithText(LOG_LEVEL4, KJFound, pToken);
+        			}
+				
+        		if(ch==TChar(','))
+        			sidLex.Inc();
+        		
+        		sidLex.SkipSpace();
+        
+				} //while
+				
+			
+			_LIT(KPartialText3, "Full/Partial Type: Partial");
+			Log(LOG_LEVEL3, KPartialText3);
+			} //if
+		else
+			{
+			_LIT(KPartialText4, "Full/Partial Type: UNKNOWN");
+			_LIT(KPartialText5, "** PLEASE USE 0 OR 1 ONLY **");
+			_LIT(KPartialText6, "** Using FULL as default  **");
+			Log(LOG_LEVEL4, KPartialText4);
+			Log(LOG_LEVEL4, KPartialText5);
+			Log(LOG_LEVEL4, KPartialText6);
+			}
+		
+		// base/incremental
+		_LIT(KIncrText1, "BaseOnly");
+		GetIntFromConfig(ConfigSection(), KIncrText1, isBase);
+		if (isBase == 1)
+			{
+			iBackupIncType = EBackupBase;
+			
+			_LIT(KIncrText2, "Base/Incremental Type: Base Only");
+			Log(LOG_LEVEL3, KIncrText2);
+			}
+		else if (isBase == 0)
+			{
+			iBackupIncType = EBackupIncrement;
+			
+			_LIT(KIncrText3, "Base/Incremental Type: Incremental by Default");
+			Log(LOG_LEVEL3, KIncrText3);
+			}
+		else
+			{
+			_LIT(KIncrText4, "Base/Incremental Type: UNKNOWN");
+			_LIT(KIncrText5, "** PLEASE USE 0 OR 1 ONLY **");
+			_LIT(KIncrText6, "** Using BASE as default  **");
+			Log(LOG_LEVEL4, KIncrText4);
+			Log(LOG_LEVEL4, KIncrText5);
+			Log(LOG_LEVEL4, KIncrText6);
+			}
+		
+		TChar delimiter(',');
+		
+		/** Read public files into array */
+		_LIT(KExpectPublicFiles, "ExpectPublicFiles");
+		ReadListIntoStringArray(KExpectPublicFiles, delimiter, iPublicFileNames);
+		
+		/** Read private files into array */
+		_LIT(KExpectPrivateFiles, "ExpectPrivateFiles");
+		ReadListIntoStringArray(KExpectPrivateFiles, delimiter, iPrivateFileNames);		
+		
+		/** Read private file sizes into array */
+		_LIT(KExpectPrivateFileSizes, "ExpectPrivateFileSizes");
+		ReadListIntoIntArray(KExpectPrivateFileSizes, delimiter, iPrivateFileSizes);
+		}
+		
+	void CBURTestStepBase::ReadListIntoStringArray(const TDesC& aSectionName, const TChar& aDelimiter, RArray<TPtrC>& aResultList)
+		{
+		TChar ch;
+		TPtrC list;
+		GetStringFromConfig(ConfigSection(), aSectionName, list);
+		TLex strLex(list);
+		
+		while (!strLex.Eos())
+			{
+			strLex.Mark();
+        	ch=strLex.Peek();
+
+	    	while( ( !strLex.Eos() ) && 
+	    		   ((ch=strLex.Peek()) != aDelimiter) )
+	    		{
+	    		strLex.Inc();
+	    		}
+
+    		if(!strLex.TokenLength())
+    			continue;
+    		
+    		TPtrC pToken = strLex.MarkedToken();
+    		aResultList.Append(pToken);
+			
+    		if(ch == aDelimiter)
+    			strLex.Inc();
+    		
+    		strLex.SkipSpace();    
+			} //while		
+		}
+	
+	void CBURTestStepBase::ReadListIntoIntArray(const TDesC& aSectionName, const TChar& aDelimiter, RArray<TInt>& aResultList)
+		{
+		RArray<TPtrC> strList;
+		CleanupClosePushL(strList);
+		ReadListIntoStringArray(aSectionName, aDelimiter, strList);
+		
+		TInt count = strList.Count();
+		for (TInt i=0; i<count; ++i)
+			{
+			TInt num = 0;
+			TLex token(strList[i]);
+			if (token.Val(num) == KErrNone)
+				{
+				aResultList.Append(num);
+				}
+			}
+		CleanupStack::PopAndDestroy(&strList); // strList
+		}	
+	
+	void CBURTestStepBase::PopulateListOfDataOwnersL()
+		/**
+		Uses CSBEClient::ListOfDataOwnersL() to extract a list of data owners that have 
+		registred for backup and restore. Populates iDataOwners.
+		
+		@internalComponent
+		@released
+		*/
+		{
+		_LIT(KTempText1, "Getting list of data owners from device");
+		Log(LOG_LEVEL2,KTempText1);
+		
+		TRAPD(err, iBackupClient->ListOfDataOwnersL(iDataOwners));
+		if (err != KErrNone)
+			{
+			_LIT(KTempText1, "Error getting list of data owners: ");
+			LogWithNum(LOG_LEVEL2,KTempText1, err);
+			iFailures++;
+			}
+
+		// Log
+		if (iDataOwners.Count() == 0)
+			{
+			_LIT(KTempText3, "No data owners found.");
+			Log(LOG_LEVEL3, KTempText3);
+			}
+		else
+			{
+			_LIT(KTempText4, "Number of data owners found on device: ");
+			LogWithNum(LOG_LEVEL3, KTempText4, iDataOwners.Count());
+			}
+		}
+		
+	void CBURTestStepBase::PopulateListOfDataOwnersAsyncL()
+		/**
+		Uses CSBEClient::ListOfDataOwnersL() to extract a list of data owners that have 
+		registred for backup and restore. Populates iDataOwners.
+		
+		@internalComponent
+		@released
+		*/
+		{
+		_LIT(KTempText1, "Getting list of data owners from device");
+		Log(LOG_LEVEL2,KTempText1);
+		CBURActiveObject* active = CBURActiveObject::NewL();
+		CleanupStack::PushL(active);
+		TRAPD(err, iBackupClient->ListOfDataOwnersL(iDataOwners, active->iStatus));
+		if (err == KErrNone)
+			{
+			active->StartL();
+			}
+			
+		if (err != KErrNone || active->Error() != KErrNone)
+			{
+			_LIT(KTempText1, "Error getting list of data owners: ");
+			LogWithNum(LOG_LEVEL2,KTempText1, err);
+			iFailures++;
+			}
+		CleanupStack::PopAndDestroy(active);
+		
+		// Log
+		if (iDataOwners.Count() == 0)
+			{
+			_LIT(KTempText3, "No data owners found.");
+			Log(LOG_LEVEL3, KTempText3);
+			}
+		else
+			{
+			_LIT(KTempText4, "Number of data owners found on device: ");
+			LogWithNum(LOG_LEVEL3, KTempText4, iDataOwners.Count());
+			}
+		}
+	
+	void CBURTestStepBase::SetBURModeL(TBURPartType aBURPartType, TBackupIncType aBackupIncType)
+		/**
+		Uses CSBEClient::SetBURModeL() to set backup and restore settings
+		
+		@internalComponent
+		@released
+		
+		@param aBURPartType - Full/Partial backup/restore.
+		@param aBackupIncType - Base/Incremental backup/restore.
+		*/
+		{
+		iBackupClient->SetBURModeL(iDriveList, aBURPartType, aBackupIncType);
+		}
+	
+	void CBURTestStepBase::SetBURModeAsyncL(TBURPartType aBURPartType, TBackupIncType aBackupIncType)
+		/**
+		Uses CSBEClient::SetBURModeL() Asyncrhonous version to set backup and restore settings
+		
+		@internalComponent
+		@released
+		
+		@param aBURPartType - Full/Partial backup/restore.
+		@param aBackupIncType - Base/Incremental backup/restore.
+		*/
+		{
+		CBURActiveObject* active = CBURActiveObject::NewL();
+		CleanupStack::PushL(active);
+		iBackupClient->SetBURModeL(iDriveList, aBURPartType, aBackupIncType, active->iStatus);
+		active->StartL();
+		User::LeaveIfError(active->Error());
+		CleanupStack::PopAndDestroy(active);
+		}
+	
+	void CBURTestStepBase::PrepareForPartialBURL()
+		/**
+		@internalComponent
+		@released
+		*/
+		{
+		TSecureId sid = NULL;
+		
+		// go through list of pids and sids
+		for (TInt index = 0; index < iDataOwners.Count(); index++)
+			{
+			TBool notFound = ETrue;
+			sid = ExtractIDL(*iDataOwners[index]);
+			
+			if (sid != NULL)
+				{
+				TInt position = iSidArray.Find(sid);
+				if (position != KErrNotFound)
+					{
+					_LIT(KTempText2, "ID found in list of data owners: ");
+					LogWithSID(LOG_LEVEL3, KTempText2, sid);
+					notFound = EFalse;
+					}
+				else if (position == KErrNotFound)
+					{
+					notFound = ETrue;
+					} // if else
+				} // if
+			else // possibly jid
+				{
+				HBufC* pSuiteHash = ExtractJavaIDL(*iDataOwners[index]);
+				TPtrC suiteHash = pSuiteHash->Des();
+				if (iJidArray.Find(suiteHash) != KErrNotFound)
+					{
+					_LIT(KTempText3, "Java ID found in list of data owners: ");
+					LogWithText(LOG_LEVEL3, KTempText3, suiteHash);
+					notFound = EFalse;
+					}
+				else // not found 
+					{
+					notFound = ETrue;
+					}
+				delete pSuiteHash;
+				pSuiteHash = NULL;
+				}
+			if (notFound)
+				{
+				delete iDataOwners[index];
+				iDataOwners[index] = NULL;
+				iDataOwners.Remove(index);
+				index--;
+				}
+			}
+		}
+		
+	void CBURTestStepBase::SetSIDListForPartialL()
+	/**
+	Set the list of active data owners for partial bur
+	
+	@param aDataOwners List of data owners for partial bur
+	*/
+		{
+		iSidArray.Reset();
+		for (TInt i=0; i< iDataOwners.Count(); i++)
+			{
+			if (iDataOwners[i]->CommonSettings() & EActiveBUR)
+				{
+				TSBDerivedType type = iDataOwners[i]->Identifier().DerivedTypeL();
+				if (type == ESIDDerivedType)
+					{
+					// means it is definately a sid
+					CSBSecureId* secureId = CSBSecureId::NewL(&(iDataOwners[i]->Identifier()));
+					CleanupStack::PushL(secureId);
+						
+					iSidArray.AppendL(secureId->SecureIdL());
+					CleanupStack::PopAndDestroy(secureId);
+					}
+				else if (type == EPackageDerivedType)
+					{
+					CSBPackageId* packageId = CSBPackageId::NewL(&(iDataOwners[i]->Identifier()));
+					CleanupStack::PushL(packageId);
+					
+					iSidArray.AppendL(packageId->SecureIdL());
+					CleanupStack::PopAndDestroy(packageId);
+					}
+				} //if
+			}// for
+		
+		// set active owners array	
+		TRAPD(err,iBackupClient->SetSIDListForPartialBURL(iSidArray));
+		if (err != KErrNone)
+			{
+			iFailures++;
+			_LIT(KSidP, "Error Setting list for partial : ");
+			LogWithNum(LOG_LEVEL3, KSidP, err);
+			}
+		}
+		
+	void CBURTestStepBase::GenerateSIDTransferTypesL(RTransferTypeArray& aTransferTypes, TTransferDataType aDataType)
+		/**
+		For each data owner in iDataOwners, this method creates CSBGenericTransferTypes
+		based on the TTransferDataType passed. One transfer type is created per drive that
+		the data owner in question has data on. Only creates transfer types supported by data owner
+		
+		@internalComponent
+		@released
+		
+		@param aTransferTypes - Array of transfer types.
+		@param aDataType - Trasnfer data type, passive base, active base, etc.
+		*/
+		{
+		TTransferDataType tempDataType = aDataType;
+		aTransferTypes.ResetAndDestroy();
+		TSecureId sid = NULL;
+		
+		TInt length = iDriveList.Length();
+		for (TInt driveCount = 0; driveCount < length; driveCount++)
+			{
+			if (iDriveList[driveCount])
+				{
+				for (TInt i = 0; i < iDataOwners.Count(); i++)
+					{
+					if ( (iDataOwners[i]->Identifier().DerivedTypeL() == ESIDDerivedType) &&
+					     (iDataOwners[i]->DriveList()[driveCount]) )
+						{
+						CSBSecureId* secureId = CSBSecureId::NewL(&(iDataOwners[i]->Identifier()));
+						CleanupStack::PushL(secureId);
+						
+						sid = secureId->SecureIdL();
+						
+						CleanupStack::PopAndDestroy(secureId);
+						}
+					else if ( (iDataOwners[i]->Identifier().DerivedTypeL() == EPackageDerivedType) &&
+					          (iDataOwners[i]->DriveList()[driveCount]) )
+						{						
+						CSBPackageId* pkgId = CSBPackageId::NewL(&(iDataOwners[i]->Identifier()));
+						CleanupStack::PushL(pkgId);
+					
+						sid = pkgId->SecureIdL();
+						
+						CleanupStack::PopAndDestroy(pkgId);	
+						} // else if
+					
+					if (sid != NULL)
+						{
+						// decides if data owner supports that data type
+						
+						TBool checkIfHaveBase = EFalse;
+						TBool baseOnly = EFalse;
+						TBool supports = EFalse;
+						switch (aDataType)
+							{
+							case ERegistrationData:
+								supports = EFalse;
+								break;
+							case EPassiveBaseData:
+								if (iDataOwners[i]->CommonSettings() & EPassiveBUR)
+									{
+									supports = ETrue;
+									}
+								break;
+							case EPassiveSnapshotData:
+								if (iDataOwners[i]->PassiveSettings() & EPassiveSupportsInc)
+									{
+									supports = ETrue;
+									}
+								break;
+							case EPassiveIncrementalData:
+								if (iDataOwners[i]->CommonSettings() & EPassiveBUR)
+									{
+									if (!(iDataOwners[i]->PassiveSettings() & EPassiveSupportsInc) && !iMode)
+										{
+										_LIT(KPsIncDt, "Base only for SID: ");
+										LogWithSID(LOG_LEVEL3, KPsIncDt, sid);
+										baseOnly = ETrue;
+										supports = ETrue;
+										aDataType = EPassiveBaseData;
+										}
+									else if (iDataOwners[i]->PassiveSettings() & EPassiveSupportsInc)
+										{
+										checkIfHaveBase = ETrue;
+										}
+									} // if
+								break;
+							case EActiveSnapshotData:
+								if (iDataOwners[i]->ActiveSettings() & EActiveSupportsInc)
+									{
+									supports = ETrue;
+									}
+								break;
+							case EActiveIncrementalData:
+								if (iDataOwners[i]->CommonSettings() & EActiveBUR)
+									{
+									if (!(iDataOwners[i]->ActiveSettings() & EActiveSupportsInc) && !iMode)
+										{
+										_LIT(KAcIncDt, "Base only for SID: ");
+										LogWithSID(LOG_LEVEL3, KAcIncDt, sid);
+										baseOnly = ETrue;
+										supports = ETrue;
+										aDataType = EActiveBaseData;
+										}
+									else if (iDataOwners[i]->ActiveSettings() & EActiveSupportsInc)
+										{
+										checkIfHaveBase = ETrue;
+										}	
+									} // if
+								break;
+							case EActiveBaseData:
+								if (iDataOwners[i]->CommonSettings() & EActiveBUR)
+									{
+									supports = ETrue;
+									}
+								break;
+							} //switch
+						
+						
+						if (checkIfHaveBase)
+							{
+							TTransferDataType dType;
+							if (aDataType == EActiveIncrementalData)
+								{
+								dType = EActiveBaseData;
+								}
+							else
+								{
+								dType = EPassiveBaseData;
+								} // if else
+								
+							CSBSIDTransferType* tType = CSBSIDTransferType::NewL(sid, TDriveNumber(driveCount), dType);
+							CleanupStack::PushL(tType);
+							TFileName fileName;
+							iStorageManager->GetFileNameL(tType, fileName, EFalse);
+							if(iStorageManager->IsFileExists(fileName))
+								{
+								supports = ETrue;
+								}
+							else 
+								{
+								_LIT(KTempText2, "No increments found use Base instead for SID: ");
+								LogWithSID(LOG_LEVEL3, KTempText2, sid);
+								supports = ETrue;
+								aDataType = dType;
+								baseOnly = ETrue;
+								}
+							CleanupStack::PopAndDestroy(tType);
+							} // if check if have base
+											
+						
+						if (supports)
+							{
+							CSBSIDTransferType* sidType = CSBSIDTransferType::NewL(sid, TDriveNumber(driveCount), aDataType);
+							CleanupStack::PushL(sidType);
+							aTransferTypes.AppendL(sidType);
+							CleanupStack::Pop(sidType);
+							} // if else
+						
+						// change to the proper dataType if base only true	
+						if (baseOnly)
+							{
+							aDataType = tempDataType;
+							}
+						sid = NULL;	
+						}// if
+					} // for		
+				} // if
+			} //for
+		}
+		
+	void CBURTestStepBase::GeneratePIDTransferTypesL(RTransferTypeArray& aTransferTypes, TPackageDataType aPkgDataType)
+		/**
+		For each data owner in iDataOwners, this method creates CSBGenericTransferTypes
+		based on the TTransferDataType passed. One transfer type is created per drive that
+		the data owner in question has data on.
+		
+		@internalComponent
+		@released
+		
+		@param aTransferTypes - Array of transfer types.
+		@param aDataType - Trasnfer data type, passive base, active base, etc.
+		*/
+		{
+		aTransferTypes.ResetAndDestroy();
+		TUid id;
+		//need array to avoid duplications
+		RArray<TUid> uidArray;
+		CleanupClosePushL(uidArray);
+		
+		TInt length = iDriveList.Length();
+		for (TInt driveCount = 0; driveCount < length; driveCount++)
+			{
+			if (iDriveList[driveCount])
+				{
+				TInt count = iDataOwners.Count();
+				for (TInt i = 0; i < count; i++)
+					{
+					if ( (iDataOwners[i]->Identifier().DerivedTypeL() == EPackageDerivedType) &&
+					     (iDataOwners[i]->DriveList()[driveCount]) )
+					    {
+					    CSBPackageId* pkgId = CSBPackageId::NewL(&(iDataOwners[i]->Identifier()));
+					    CleanupStack::PushL(pkgId);
+                        
+					    id = pkgId->PackageIdL();
+					    if (uidArray.Find(id) == KErrNotFound)
+					        {
+					        CSBPackageTransferType* idType = CSBPackageTransferType::NewL(id, TDriveNumber(driveCount), aPkgDataType);
+					        CleanupStack::PushL(idType);
+					        aTransferTypes.AppendL(idType);
+					        CleanupStack::Pop(idType);
+					        //add to uid array
+					        uidArray.AppendL(id);
+					        }
+					    CleanupStack::PopAndDestroy(pkgId); 					    
+					    }
+					} //for		
+				} //if	
+			} //for
+		CleanupStack::PopAndDestroy(&uidArray);
+		}
+		
+	void CBURTestStepBase::GenerateJavaTransferTypesL(RTransferTypeArray& aTransferTypes, TJavaTransferType aJavaTransferType)
+		/**
+		For each data owner in iDataOwners, this method creates CSBGenericTransferTypes
+		based on the TTransferDataType passed. One transfer type is created per drive that
+		the data owner in question has data on.
+		
+		@internalComponent
+		@released
+		
+		@param aTransferTypes - Array of transfer types.
+		@param aJavaTransferType - Trasnfer data type
+		*/
+		{
+		aTransferTypes.ResetAndDestroy();
+		
+		TInt length = iDriveList.Length();
+		for (TInt driveCount = 0; driveCount < length; driveCount++)
+			{
+			if (iDriveList[driveCount])
+				{
+				TInt count = iDataOwners.Count();
+				for (TInt i=0; i < count; i++)
+					{
+					if ( (iDataOwners[i]->Identifier().DerivedTypeL() == EJavaDerivedType) &&
+					     (iDataOwners[i]->DriveList()[driveCount]) )
+					    {
+					    if ((aJavaTransferType == EJavaMIDlet && (iDataOwners[i]->CommonSettings() & EHasSystemFiles)) || aJavaTransferType == EJavaMIDletData)
+					        {
+					        CSBJavaId* javaId = CSBJavaId   ::NewL(&(iDataOwners[i]->Identifier()));
+					        CleanupStack::PushL(javaId);
+					        const TDesC& suiteHash = javaId->SuiteHashL();
+					        CSBJavaTransferType* javaType = CSBJavaTransferType::NewL(suiteHash, TDriveNumber(driveCount), aJavaTransferType);
+					        CleanupStack::PushL(javaType);
+					        aTransferTypes.AppendL(javaType);
+					        CleanupStack::Pop(javaType);
+					        CleanupStack::PopAndDestroy(javaId);
+					        }//if					    
+					    }
+					} //for
+				} // if
+			} // for
+		}
+		
+	
+	void CBURTestStepBase::GeneratePublicTransferTypesL(RPointerArray<CSBGenericDataType>& aTransferTypes)
+		/**
+		For each data owner in iDataOwners, this method creates CSBGenericTransferTypes
+		based on the TTransferDataType passed. One transfer type is created per drive that
+		the data owner in question has data on.
+		
+		@internalComponent
+		@released
+		
+		@param aTransferTypes - Array of transfer types.
+		@param aDataType - Trasnfer data type, passive base, active base, etc.
+		*/
+		{
+		aTransferTypes.ResetAndDestroy();
+
+		TInt count = iDataOwners.Count();
+		for (TInt i = 0; i < count; i++)
+			{
+			switch (iDataOwners[i]->Identifier().DerivedTypeL())
+				{
+				case EPackageDerivedType:
+				case ESIDDerivedType:
+					if (iDataOwners[i]->PassiveSettings() & EHasPublicFiles)
+						{
+						const TDesC8& desc = iDataOwners[i]->Identifier().Externalise();
+						CSBGenericDataType* idType = CSBGenericDataType::NewL(desc);
+						CleanupStack::PushL(idType);
+						aTransferTypes.AppendL(idType);
+						CleanupStack::Pop(idType);
+						} //if
+					break;
+				} // switch
+			}
+		}
+	
+	
+	void CBURTestStepBase::SupplyDataL(RTransferTypeArray& aTransferTypes)
+		/**
+		Retrieves data from the storage handler and supplies to the backup client for 
+		the given transfer type
+		
+		@internalComponent
+		@released
+		
+		@param aTransferTypes - Array of transfer types.
+		*/
+		{
+		TInt transferTypesCount = aTransferTypes.Count();
+		for(TInt currentIndex = 0; currentIndex < transferTypesCount; ++currentIndex)
+			{
+			TInt error;		
+			TInt increments = 0;
+			TInt incrIndex = 1;
+			
+			TSBDerivedType dataType = aTransferTypes[currentIndex]->DerivedTypeL();
+			
+			// check for incremental data
+			switch(dataType)
+				{
+				case ESIDTransferDerivedType:
+					{
+					CSBSIDTransferType* type = CSBSIDTransferType::NewL(aTransferTypes[currentIndex]);
+					CleanupStack::PushL(type);
+					
+					_LIT(KSid, "Supplying data for ID: ");
+					LogWithSID(LOG_LEVEL3, KSid, type->SecureIdL());
+					
+					if (type->DataTypeL() == EActiveIncrementalData || type->DataTypeL() == EPassiveIncrementalData)
+						{
+						increments = iStorageManager->TotalIncFiles(type);
+						if (!increments)
+							{
+							_LIT(KErrorText2, "No increments found");
+							Log(LOG_LEVEL4, KErrorText2);
+							// cleanup
+							CleanupStack::PopAndDestroy(type);
+							continue;
+							}
+						else 
+							{
+							_LIT(KIncFound, "Number of increments found: ");
+							LogWithNum(LOG_LEVEL4, KIncFound, increments);
+							} // else if
+						} // if
+					CleanupStack::PopAndDestroy(type);
+					}
+					break;
+				case EPackageTransferDerivedType:
+					{
+					// package stuff
+					CSBPackageTransferType* pType = CSBPackageTransferType::NewL(aTransferTypes[currentIndex]);
+					CleanupStack::PushL(pType);
+					_LIT(KPid, "Supplying data for Package ID: ");
+					LogWithSID(LOG_LEVEL3, KPid, pType->PackageIdL());
+					CleanupStack::PopAndDestroy(pType);
+					}
+					break;
+				case EJavaTransferDerivedType:
+					{
+					// java stuff
+					CSBJavaTransferType* jType = CSBJavaTransferType::NewL(aTransferTypes[currentIndex]);
+					CleanupStack::PushL(jType);
+					_LIT(KJid, "Supplying data for Java SuiteHash: ");
+					LogWithText(LOG_LEVEL3, KJid, jType->SuiteHashL());
+					CleanupStack::PopAndDestroy(jType);
+					}
+					break;
+				
+				} // switch
+			TBool runAgain = ETrue;		
+			do 
+				{
+				TBool finished;				
+				TPtr8* bufferPtr = NULL;
+				TRAP(error, bufferPtr = &iBackupClient->TransferDataAddressL());
+				if (error != KErrNone)
+					{
+					_LIT(KErrTDA, "Error getting TransferDataAddress: ");
+					LogWithNum(LOG_LEVEL4, KErrTDA, error);
+					break;
+					}
+				TRAP(error, iStorageManager->RetrieveDataL(aTransferTypes[currentIndex], *bufferPtr, finished, incrIndex));
+				if (error != KErrNone)
+					{
+					iStorageManager->Reset();
+					if (error == KErrPathNotFound || error == KErrNotFound)
+						{
+						_LIT(KErrorText2, "Data doesn't exists");
+						Log(LOG_LEVEL4, KErrorText2);
+						}
+					else
+						{
+						_LIT(KErrorText1, "Error reading from archive: ");
+						LogWithNum(LOG_LEVEL4, KErrorText1, error);
+						iFailures++;
+						}
+					break;
+					} 
+				else
+					{
+					_LIT(KLogBytes, "Number of bytes to send: ");
+					LogWithNum(LOG_LEVEL4, KLogBytes, bufferPtr->Length());	
+			
+					TRAP(error, iBackupClient->SupplyDataL(*aTransferTypes[currentIndex], finished));
+					if (error != KErrNone)
+						{
+						_LIT(KErrorText2, "Error supplying data to backup server: ");
+						LogWithNum(LOG_LEVEL4, KErrorText2, error);
+						if (iExpectStatus != error && iExpectStatus2 != error)
+							{
+							iFailures++;
+							_LIT(KErrorText3, "Expect Error is: ");
+							LogWithNum(LOG_LEVEL4, KErrorText3, iExpectStatus);
+							}			
+						break;
+						}
+					else
+						{
+						_LIT(KSuccess, "Operation finished successfully");
+						Log(LOG_LEVEL4, KSuccess);
+						}
+					
+					} // else
+					
+				if ((finished && !increments) || (incrIndex == increments && finished)) // if finished 
+					{
+					runAgain = EFalse;
+					}
+				else if (finished && incrIndex < increments) // is incremental data move to next increment
+					{
+					incrIndex++;
+					runAgain = ETrue;
+					}
+				else 
+					{
+					runAgain = ETrue;
+					}
+				} // do
+				while (runAgain);
+			} // for
+			
+			if (!iFailures)
+				{
+				_LIT(KComp, "No errors found");
+				Log(LOG_LEVEL3, KComp);
+				}
+		// Do not delete bufferPtr, as it gets deleted by the iBackupClient
+		}
+	
+	TDriveList CBURTestStepBase::StringToDriveListL(TPtrC apText)
+		/**
+		@internalComponent
+		@released
+		
+		@param apText - String that needs to be converted into a TDriveList.
+		@return TDriveList with all the bytes set to 1 where a corresponding drive letter 
+				was found in apText
+		*/
+		{
+		TInt error;
+		RFs fsSession;
+		CleanupClosePushL(fsSession);
+		error = fsSession.Connect();
+		if (error != KErrNone)
+			{
+			User::Leave(error);
+			}
+		
+		TUint8 str[KMaxDrives];
+		for (TInt i = 0; i < KMaxDrives; ++i)
+			{ 
+			str[i] = 0; // Initialise to zero
+			}
+		
+		TInt length = apText.Length();
+		for (TInt i = 0; i < length; ++i)
+			{
+			TInt pos;
+			fsSession.CharToDrive(apText.Ptr()[i], pos);
+			str[pos] = 1;
+			}
+		
+		TDriveList driveList;
+		//driveList.FillZ(); // initialise to zeros
+		TPtr8 ptr(&str[0], KMaxDrives, KMaxDrives);
+		driveList.Copy(ptr);
+		
+		CleanupStack::PopAndDestroy();
+		return driveList;
+		}
+		
+	
+	void CBURTestStepBase::SaveDataOwners()
+		/**
+		Saves data owners to storage Manager
+		*/
+		{
+		TInt count = iDataOwners.Count();
+		for (TInt i =0; i < count; i++)
+			{
+			TRAPD(err, iStorageManager->SaveDataOwnerL(*iDataOwners[i]));
+			if (err != KErrNone)
+				{
+				_LIT(KDataOwnerErr, "Error saving Data Owner: ");
+				LogWithNum(LOG_LEVEL2, KDataOwnerErr, err);
+				}
+			}
+		}
+	
+	void CBURTestStepBase::CheckSIDStatusL(RTransferTypeArray& aTransferTypes, RTransferTypeArray& aReadyArray)
+		/**
+		Checks the readyness status for Active Data Owner. The ones are ready put into ready array and removed from the original
+		
+		@param aTransferTypes - TransferTypes to check for status
+		@param aReadyArray - array of transfer types where dataowners are ready
+		*/
+		{
+		aReadyArray.ResetAndDestroy();
+		if (aTransferTypes.Count())
+			{
+			// used for getting statuses
+			RSIDStatusArray statusArray;
+			CleanupClosePushL(statusArray);
+			// create array of sid for status request
+			for (TInt i =0; i< aTransferTypes.Count(); i++)
+				{
+				TSecureId id = NULL;
+				TSBDerivedType type = aTransferTypes[i]->DerivedTypeL();
+				if (type == ESIDTransferDerivedType)
+					{
+					CSBSIDTransferType* sidType = CSBSIDTransferType::NewL(aTransferTypes[i]);
+					CleanupStack::PushL(sidType);
+					id = sidType->SecureIdL();
+					CleanupStack::PopAndDestroy(sidType);
+					statusArray.Append(TDataOwnerAndStatus(id, EUnset, KErrNone));	
+					}
+				} //for
+						
+			// get status for data owners	
+			iBackupClient->SIDStatusL(statusArray);
+			
+			// check which sids ready
+			TInt total = statusArray.Count();
+			for (TInt j=0; j < total; j++)
+				{
+				TDataOwnerAndStatus test = statusArray[j];
+				if (statusArray[j].iStatus == EDataOwnerReady)
+					{
+					LogWithSID(LOG_LEVEL3, _L("Data Owner ready: "),statusArray[j].iSID.iId);
+					aReadyArray.Append(aTransferTypes[j]);
+					statusArray.Remove(j);
+					aTransferTypes.Remove(j);
+					j--;
+					total--;
+					}
+				else if (statusArray[j].iStatus == EDataOwnerReadyNoImpl || statusArray[j].iStatus == EDataOwnerFailed || statusArray[j].iStatus == EDataOwnerNotFound)
+					{
+					LogWithSID(LOG_LEVEL3, _L("Data Owner Failed, NotFound or Has No implementation : "),statusArray[j].iSID.iId);
+					statusArray.Remove(j);
+					delete aTransferTypes[j];
+					aTransferTypes[j] = NULL;
+					aTransferTypes.Remove(j);
+					j--;
+					total--;
+					}
+				else if(statusArray[j].iStatus == EDataOwnerNotConnected && EDataOwnerNotConnected == iExpectStatus)
+					{//ignore this error
+					LogWithSID(LOG_LEVEL3, _L("Data Owner not ready: "),statusArray[j].iSID.iId);
+					statusArray.Remove(j);
+					delete aTransferTypes[j];
+					aTransferTypes[j] = NULL;
+					aTransferTypes.Remove(j);
+					j--;
+					total--;
+					}
+				} //for	
+			statusArray.Reset();
+			CleanupStack::PopAndDestroy(&statusArray);
+			} // if
+		}
+		
+	TSecureId CBURTestStepBase::ExtractIDL(CDataOwnerInfo& aDataOwner)
+		/**
+		Gets Secure ID or UID from Data Owner
+		
+		@param aDataOwner Data Owner to get ID from
+		
+		@return TSecureId Secure ID of the data owner
+		*/
+		{
+		TSecureId id = NULL;
+		if (aDataOwner.Identifier().DerivedTypeL() == ESIDDerivedType)
+			{
+			CSBSecureId* secureId = CSBSecureId::NewL(&(aDataOwner.Identifier()));
+			CleanupStack::PushL(secureId);
+					
+			id = secureId->SecureIdL();
+												
+			CleanupStack::PopAndDestroy(secureId);
+			} // if				
+		else if (aDataOwner.Identifier().DerivedTypeL() == EPackageDerivedType)
+			{
+			CSBPackageId* pkgId = CSBPackageId::NewL(&(aDataOwner.Identifier()));
+			CleanupStack::PushL(pkgId);
+			
+			// package id		
+			id = pkgId->PackageIdL();
+				
+			CleanupStack::PopAndDestroy(pkgId);
+			} // else if
+		return id;
+		}
+		
+	HBufC* CBURTestStepBase::ExtractJavaIDL(CDataOwnerInfo& aDataOwner)
+		/**
+		Gets Suite Hash ID from the Data Owner
+		
+		@param aDataOwner - Data Owner to get suite hash from
+		
+		@return HBufC* pointe to a suite hash
+		*/
+		{
+		HBufC* jid = NULL;
+		if (aDataOwner.Identifier().DerivedTypeL() == EJavaDerivedType)
+			{
+			CSBJavaId* javaId = CSBJavaId::NewL(&(aDataOwner.Identifier()));
+			CleanupStack::PushL(javaId);
+			
+			const TDesC& suiteHash = javaId->SuiteHashL();
+			jid = HBufC::NewLC(suiteHash.Size());
+			*jid = suiteHash;
+			CleanupStack::Pop(jid);
+			CleanupStack::PopAndDestroy(javaId);
+			}
+		return jid;
+		}
+		
+	void CBURTestStepBase::CheckValidRegistrationL()
+		/**
+		Checks the list of data owners returned from the device for the validity of the registration file.
+		If registration is invalid the data owner is removed from the list and not backed up or restored.
+		*/
+		{
+		for (TInt i = 0; i < iDataOwners.Count(); i++)
+			{
+			switch (iDataOwners[i]->Identifier().DerivedTypeL())
+				{
+				case ESIDDerivedType:
+					{
+					_LIT(KFoundSid, "Sid in the list: ");
+					LogWithSID(LOG_LEVEL3, KFoundSid, ExtractIDL(*iDataOwners[i]));
+					}
+					break;
+		
+				case EPackageDerivedType:
+					{
+					_LIT(KFoundPid, "Package in the list: ");
+					LogWithSID(LOG_LEVEL3, KFoundPid, ExtractIDL(*iDataOwners[i]));
+					}
+					break;
+				
+				case EJavaDerivedType:
+					{	
+					HBufC* suiteHash = ExtractJavaIDL(*iDataOwners[i]);
+					_LIT(KJava, "Java ID found: ");
+					LogWithText(LOG_LEVEL3, KJava, *suiteHash);
+					delete suiteHash;
+					suiteHash = NULL;
+					}
+					break;
+				default:
+					_LIT(KLogErr, "Not supported type");
+					Log(LOG_LEVEL3, KLogErr);
+					break;
+				}
+			
+			TCommonBURSettings settings = iDataOwners[i]->CommonSettings();
+			// check if registration file was parsed correctly
+			if (!(settings & EPassiveBUR))
+				{
+				if (!(settings & EActiveBUR))
+					{
+					if (!(settings & EHasSystemFiles))
+						{
+						delete iDataOwners[i];
+						iDataOwners[i] = NULL;
+						iDataOwners.Remove(i);
+						i--;
+						if (iIsPartial)
+							{
+							iFailures++;
+							}
+						_LIT(KBadReg, "*** Error: Bad Registration file for ID above ^^^");
+						Log(LOG_LEVEL3, KBadReg);
+						}
+					
+					}//if
+				}//if
+			}// for
+		}
+		
+	void CBURTestStepBase::DoSupplyL(TTransferDataType aDataType)
+		/**
+		@internalComponent
+		@released
+		*/
+		{
+		GenerateSIDTransferTypesL(iTransferTypes, aDataType);
+		if (iTransferTypes.Count())
+			{
+			// TODO: need to check weather we can supply snapshot without waiting
+			if (aDataType == EActiveSnapshotData || aDataType == EActiveBaseData || aDataType == EActiveIncrementalData)
+				{
+			 	// used for sids which are ready
+				RTransferTypeArray readyArray;
+				CleanupClosePushL(readyArray);
+					
+				for (TInt i=0; i < KRetries;)
+					{
+					CheckSIDStatusL(iTransferTypes, readyArray);
+											
+					if (readyArray.Count()) // dataowners ready
+						{
+						// ========= Supply Data ================
+						SupplyDataL(readyArray);		
+						} 
+					else if (iTransferTypes.Count()) // data owners not ready
+						{
+						User::After(KDelay);
+						i++;
+						}
+					else // finished with all sids
+						{
+						break;
+						}
+					} // for
+				if (iTransferTypes.Count())
+					{
+					iFailures++;
+					_LIT(KLogNoTrans, "***Error: Some Data Owners were Not Ready or Failed to Connect");
+					Log(LOG_LEVEL3, KLogNoTrans);
+					}
+				readyArray.ResetAndDestroy();
+				CleanupStack::PopAndDestroy(&readyArray);
+				} //if
+			else 
+				{
+				SupplyDataL(iTransferTypes);
+				}	
+			} //if
+		}
+		
+	// CBURActiveObject //
+	
+	/**
+	Standard Symbian OS Constructor
+	@return pointer to newly allocated CBURActiveObject object
+	*/
+	CBURActiveObject* CBURActiveObject::NewL()
+		{
+		CBURActiveObject* self = new(ELeave) CBURActiveObject();
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		CleanupStack::Pop(self);
+		return self;
+		}
+		
+	/**
+	C++ Standard destructor
+	*/
+	CBURActiveObject::~CBURActiveObject()
+		{
+		Cancel();
+		delete iActiveScheduler;
+		}
+	
+	/**
+	C++ Standard Constructor
+	*/
+	CBURActiveObject::CBURActiveObject()
+		: CActive(EPriorityNormal), iError(KErrNone)
+		{
+		}
+	
+	/**
+	Symbian OS 2nd phase constructor
+	*/
+	void CBURActiveObject::ConstructL()
+		{
+		iActiveScheduler = new (ELeave) CActiveSchedulerWait();
+		CActiveScheduler::Add(this);		
+		}
+	
+	/**
+	CActive::DoCancel() implementation
+	Stops ActiveSchedulerWait if it is Started
+	*/
+	void CBURActiveObject::DoCancel()
+		{
+		if (iActiveScheduler->IsStarted())
+			{
+			iActiveScheduler->AsyncStop();
+			}
+		}
+	
+	/**
+	Waits for the Status to complete, remembers the iStatus code and calls AsyncStop
+	*/
+	void CBURActiveObject::RunL()
+		{
+		iError = iStatus.Int();
+		iActiveScheduler->AsyncStop();
+		}
+	/**
+	CActive::RunError() implementation
+	@param aError error code
+	@return KErrNone
+	*/
+	TInt CBURActiveObject::RunError(TInt aError)
+		{
+		iError = aError;
+		Cancel();
+		return KErrNone;
+		}
+	
+	/**
+	Starts and active object and Scheduler, the call will be complete when RunL is called
+	*/
+	void CBURActiveObject::StartL()
+		{
+		if (IsActive())
+			{
+			User::Leave(KErrInUse);
+			}
+		iStatus = KRequestPending;
+		SetActive();
+		iActiveScheduler->Start();
+		}
+	/**
+	Returns an error/completing code of the iStatus
+	*/
+	TInt CBURActiveObject::Error()
+		{
+		return iError;
+		}
+		
+	}	// end namespace
+