common/tools/ats/smoketest/localisation/apparchitecture/apgrfx/APGAPLSTV2.CPP
changeset 793 0c32c669a39d
child 872 17498133d9ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/tools/ats/smoketest/localisation/apparchitecture/apgrfx/APGAPLSTV2.CPP	Fri Nov 27 12:22:12 2009 +0000
@@ -0,0 +1,3082 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "APGAPLST.H"
+#include "APGSTD.H" 
+#include "APFDEF.H"
+#include "../apparc/TRACE.H"
+#include "apgnotif.h"
+#include "../apfile/aprfndr.h"
+#include <e32math.h>
+#include <bautils.h>
+#include <s32mem.h>
+#include "APGPRIV.H"
+#include "APGAIR.H"
+#include "APGICNFL.H"
+#include "apprivate.h"
+#include <e32uid.h>
+#ifdef SYMBIAN_BAFL_SYSUTIL
+#include <bafl/sysutil.h>
+#endif
+
+
+// Delays in the pseudo idle object that builds the application list
+//
+
+const TInt KIdleStartDelay=0;
+const TInt KMaxOpaqueDataLength = 0x1000; // maximum length of opaque data that can be passed between client and apparc server via a TApaAppServiceInfo object - this can be increased in future if needed
+const TInt KBufferExpansionGranularity = 0x100;
+const TInt KNumberOfIconsInDefaultMbm = 3;
+const TInt KAppListToFileStartDelay = 60000000;
+#ifdef SYMBIAN_BAFL_SYSUTIL
+const TInt KInfoBufLength=KSysUtilVersionTextLength;
+//This file is used for storing the rom version. If actual rom version differs from the one stored here the applist is not restored.
+//This file is versioned to avoid a data compatability break on adding further information to this file.
+//On adding further info to this file, KROMVersionCacheFileMajorVersion or KROMVersionCacheFileMinorVersion or KROMVersionCacheFileBuildVersion needs to be incremented appropriately.
+_LIT(KROMVersionStringCacheFileName, "ROMVersionCache.bin");
+const TInt8 KROMVersionCacheFileMajorVersion=1;
+const TInt8 KROMVersionCacheFileMinorVersion=0;
+const TInt16 KROMVersionCacheFileBuildVersion=0;
+#endif
+
+//
+// Class CApaLangChangeMonitor
+//
+
+NONSHARABLE_CLASS(CApaAppList::CApaLangChangeMonitor) : public CActive
+		{
+	/**
+	Utility class used to monitor locale/language change event.
+	@internalComponent
+	*/
+	public:
+		static CApaLangChangeMonitor* NewL(CApaAppList& aAppList);
+		~CApaLangChangeMonitor();
+		void Start();
+		
+	private:
+		CApaLangChangeMonitor(CApaAppList& aAppList);
+		void ConstructL();
+		
+	private:	//from CActive
+		void RunL();
+		void DoCancel();
+		TInt RunError(TInt aError);
+		
+	private:
+		RChangeNotifier iLangNotifier;
+		CApaAppList& iAppList;
+		TLanguage iPrevLanguage;
+		};
+
+		
+//
+// Local functions
+//
+
+void CleanupServiceArray(TAny* aServiceArray)
+	{
+	__ASSERT_DEBUG(aServiceArray, Panic(EPanicNullPointer));
+	CArrayFixFlat<TApaAppServiceInfo>* serviceArray = static_cast<CArrayFixFlat<TApaAppServiceInfo>*>(aServiceArray);
+	TInt serviceCount = serviceArray->Count();
+	if (serviceCount > 0)
+		{
+		for (TInt i = serviceCount - 1; i >= 0; i--)
+			{
+			(*serviceArray)[i].Release();
+			}
+		}
+	delete serviceArray;
+	serviceArray = 0;
+	}
+
+
+//
+// Class CApaAppViewData
+//
+
+CApaAppViewData::~CApaAppViewData()
+	{
+	delete iIcons;
+	delete iCaption;
+	delete iIconFileName;
+	}
+
+CApaAppViewData::CApaAppViewData()
+	: iNonMbmIconFile(EFalse)
+	{
+	}
+
+void CApaAppViewData::ConstructL()
+	{
+	iIcons=CApaAppIconArray::NewL();
+	}
+
+CApaAppViewData* CApaAppViewData::NewLC()
+	{
+	CApaAppViewData* self=new(ELeave) CApaAppViewData();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;	
+	}
+
+void CApaAppViewData::SetUid(TUid aUid)
+	{
+	iUid=aUid;
+	}
+
+void CApaAppViewData::SetScreenMode(TInt aScreenMode)
+	{
+	iScreenMode=aScreenMode;
+	}
+
+EXPORT_C TInt CApaAppViewData::ScreenMode() const
+	{
+	return iScreenMode;
+	}
+
+void CApaAppViewData::SetCaptionL(const TDesC& aCaption)
+	{
+	HBufC* newCaption=aCaption.AllocL();
+	delete(iCaption); // after the AllocL succeeds
+	iCaption=newCaption;
+	}
+
+void CApaAppViewData::SetIconArray(CApaAppIconArray* aIcons)
+	{
+	delete iIcons;
+	iIcons = aIcons;
+	}
+
+void CApaAppViewData::SetIconFileNameL(const TDesC& aFileName)
+	{
+	HBufC* fileName = aFileName.AllocL();
+	delete iIconFileName; // after the AllocL succeeds
+	iIconFileName = fileName;
+	}
+
+void CApaAppViewData::SetNumOfViewIcons(TInt aNumOfViewIcons)
+	{
+	iNumOfViewIcons = aNumOfViewIcons;
+	}
+
+void CApaAppViewData::SetNonMbmIconFile(TBool aNonMbmIconFile)
+	{
+	iNonMbmIconFile = aNonMbmIconFile;
+	}
+
+EXPORT_C TUid CApaAppViewData::Uid() const
+	{
+	return iUid;
+	}
+
+EXPORT_C CApaMaskedBitmap* CApaAppViewData::Icon(const TSize& aSize) const
+	{
+	return iIcons->IconBySize(aSize);
+	}
+
+EXPORT_C CArrayFixFlat<TSize>* CApaAppViewData::IconSizesL() const
+	{
+	return iIcons->IconSizesL();
+	}
+
+EXPORT_C TPtrC CApaAppViewData::IconFileName() const
+	{
+	if (iIconFileName)
+		{
+		return *iIconFileName;
+		}
+	else
+		{
+		return TPtrC(KNullDesC);
+		}
+	}
+
+EXPORT_C TBool CApaAppViewData::NonMbmIconFile() const
+	{
+	return iNonMbmIconFile;
+	}
+
+
+//
+// class CApaAppEntry
+//
+
+CApaAppEntry* CApaAppEntry::NewL(const TApaAppEntry& aAppEntry)
+	{ // static
+	CApaAppEntry* self=new(ELeave) CApaAppEntry(aAppEntry.iUidType);
+	CleanupStack::PushL(self);
+	self->ConstructL(aAppEntry.iFullName);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CApaAppEntry::~CApaAppEntry()
+	{
+	delete iFullName;
+	}
+
+void CApaAppEntry::Get(TApaAppEntry& aAppEntry) const
+	{
+	aAppEntry.iFullName=*iFullName;
+	aAppEntry.iUidType=iUidType;
+	}
+
+CApaAppEntry::CApaAppEntry(const TUidType& aUidType)
+	: iUidType(aUidType)
+	{
+	}
+
+void CApaAppEntry::ConstructL(const TDesC& aFileName)
+	{
+	iFullName=aFileName.AllocL();
+	}
+
+
+//
+// class TApaAppServiceInfo
+//
+
+TApaAppServiceInfo::TApaAppServiceInfo()
+	: iUid(KNullUid),
+	  iDataTypes(0),
+	  iOpaqueData(NULL)
+	{
+	}
+
+TApaAppServiceInfo::TApaAppServiceInfo(TUid aUid, 
+	CArrayFixFlat<TDataTypeWithPriority>* aDataTypes, HBufC8* aOpaqueData)
+	: iUid(aUid),
+	  iDataTypes(aDataTypes),
+	  iOpaqueData(aOpaqueData)
+	{
+	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
+	__ASSERT_DEBUG(iOpaqueData, Panic(EPanicNullPointer));
+	}
+
+void TApaAppServiceInfo::ExternalizeL(RWriteStream& aStream) const
+	{
+	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
+	__ASSERT_DEBUG(iOpaqueData, Panic(EPanicNullPointer));
+	aStream << iUid;
+	aStream << *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
+	aStream << *iOpaqueData;//lint !e613 Possible use of null pointer - Asserted above
+	}
+
+void TApaAppServiceInfo::InternalizeL(RReadStream& aStream)
+	{
+	aStream >> iUid;
+	iDataTypes = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
+	aStream >> *iDataTypes;
+	iOpaqueData = HBufC8::NewL(aStream, KMaxOpaqueDataLength);
+	}
+
+void TApaAppServiceInfo::Release()
+	{
+	if (iDataTypes)
+		{
+		iDataTypes->Reset();
+		delete iDataTypes;		
+		}
+	if (iOpaqueData)
+		{
+		delete iOpaqueData;
+		iOpaqueData = NULL;
+		}
+	}
+
+CArrayFixFlat<TDataTypeWithPriority>& TApaAppServiceInfo::DataTypes()
+	{
+	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
+	return *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
+	}
+
+/** Returns the service UID.
+
+Note that some APIs may store a UID other than a service UID
+in a TApaAppServiceInfo object. Such APIs clearly state what
+the UID represents.
+
+@return the service UID.
+*/
+EXPORT_C TUid TApaAppServiceInfo::Uid() const
+	{
+	return iUid;
+	}
+	
+EXPORT_C const CArrayFixFlat<TDataTypeWithPriority>& TApaAppServiceInfo::DataTypes() const
+	{
+	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));	
+	return *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
+	}
+
+/** Returns the service implementation's opaque data.
+
+For each service UID registered by an application, the associated
+opaque data indicates how the service is implemented by that application.
+
+The meaning of the opaque data is not known to the framework, it will vary
+according to the service.
+
+For some services the opaque data may be a name intended for user display,
+for others it may be structured data that the service's client-side code can interpret.
+
+@return the service implementation's opaque data.
+*/
+EXPORT_C const TDesC8& TApaAppServiceInfo::OpaqueData() const
+	{
+	if (iOpaqueData)
+		{
+		return *iOpaqueData;
+		}
+	return KNullDesC8;
+	}
+
+//
+// class CApaAppServiceInfoArray
+//
+
+CApaAppServiceInfoArray::CApaAppServiceInfoArray()
+	{
+	}
+
+//
+// class CApaAppServiceInfoArrayWrapper
+//
+
+CApaAppServiceInfoArrayWrapper* CApaAppServiceInfoArrayWrapper::NewL(CArrayFix<TApaAppServiceInfo>* aServiceInfoArray)
+	{
+	CApaAppServiceInfoArrayWrapper* self = new CApaAppServiceInfoArrayWrapper(aServiceInfoArray);
+	if (!self)
+		{
+		CleanupServiceArray(aServiceInfoArray);
+		User::LeaveNoMemory();
+		}
+	return self;
+	}
+
+CApaAppServiceInfoArrayWrapper::CApaAppServiceInfoArrayWrapper(CArrayFix<TApaAppServiceInfo>* aServiceInfoArray)
+	: iServiceInfoArray(aServiceInfoArray)
+	{
+	}
+
+CApaAppServiceInfoArrayWrapper::~CApaAppServiceInfoArrayWrapper()
+	{
+	CleanupServiceArray(iServiceInfoArray);
+	iServiceInfoArray = NULL;
+	}
+
+TArray<TApaAppServiceInfo> CApaAppServiceInfoArrayWrapper::Array()
+	{
+	return iServiceInfoArray->Array();
+	}
+
+
+//
+// Class CApaAppData
+//
+
+EXPORT_C CApaAppData* CApaAppData::NewL(const TApaAppEntry& aAppEntry, RFs& aFs)
+	{
+	CApaAppData* self=new(ELeave) CApaAppData(aFs);
+	CleanupStack::PushL(self);
+	self->ConstructL(aAppEntry);
+	CleanupStack::Pop(); // self
+	return self;
+	}
+
+CApaAppData::CApaAppData(RFs& aFs)
+	:iCaption(NULL), iShortCaption(NULL), 
+	iIsPresent(CApaAppData::EIsPresent), iFs(aFs),
+	iNonMbmIconFile(EFalse),
+	iApplicationLanguage(ELangNone), iIndexOfFirstOpenService(-1),
+	iNonNativeApplicationType(TUid::Null()),
+	iShortCaptionFromResourceFile(NULL)
+	{
+	}
+
+void CApaAppData::ConstructL(const TApaAppEntry& aAppEntry)
+	{
+	iUidType = aAppEntry.iUidType; // if the 2nd UID is KUidAppRegistrationFile, iUidType will be updated in StoreApplicationInformation to reflect the TUidType for the application binary
+	if (ApaUtils::HandleAsRegistrationFile(aAppEntry.iUidType))
+		{
+		iRegistrationFile = aAppEntry.iFullName.AllocL();
+		}
+	else
+		{
+		iFullName = aAppEntry.iFullName.AllocL();
+		}
+
+	iCapabilityBuf.FillZ(iCapabilityBuf.MaxLength());
+	iIcons = CApaAppIconArray::NewL();
+	iViewDataArray=new(ELeave) CArrayPtrFlat<CApaAppViewData>(1);
+	iOwnedFileArray=new(ELeave) CDesCArraySeg(1);
+	User::LeaveIfError(StoreApplicationInformation());
+	}
+
+// Return a standard error code
+// The value returned only reflect the caption status
+// If there is errors setting up captions the old values are retained
+// All other errors are silently ignored
+// General notes:
+// 1. This method is deliberately very similar to the old CApaAppData::GetAifData
+//    in order to maintain behavioural compatibility for V1 apps
+// 2. Be very careful in this method, because it can be called on a newly constructed object,
+//    or on an existing object, so don't assume member data pointers will be NULL
+TInt CApaAppData::StoreApplicationInformation()
+	{
+	HBufC* caption = NULL;
+	HBufC* shortCaption = NULL;
+
+	iTimeStamp = TTime(0); // cannot init in constructor because this function can be called on an existing CApaAppData object
+
+	CApaAppInfoReader* appInfoReader = NULL;
+	TBool readSuccessful = EFalse;
+	TBool isNonNativeApp = EFalse;
+	if (iRegistrationFile != NULL)
+		{
+		if (TParsePtrC(*iRegistrationFile).Path().CompareF(KLitPathForNonNativeResourceAndIconFiles)==0)
+			{
+			isNonNativeApp = ETrue;
+			}
+
+		TRAPD(err,appInfoReader = CApaAppInfoReaderV2::NewL(iFs, *iRegistrationFile, iUidType[2]));
+		if(err != KErrNone)
+			{
+			appInfoReader = NULL;
+			}
+
+		if (appInfoReader == NULL)
+			{
+			if (iFullName == NULL)
+				{
+				// assume that if iFullName is NULL, this method has been called as part
+				// of constructing a new app data object. The CApaAppInfoReader derived object
+				// could not be created, therefore we have no way to determine the full filename
+				// of the app binary, so give up
+				return KErrNoMemory;
+				}
+			}
+		else
+			{
+			readSuccessful = appInfoReader->Read();
+			HBufC* appBinaryFullName=appInfoReader->AppBinaryFullName();
+			if (appBinaryFullName)
+				{
+				delete iFullName;
+				iFullName = appBinaryFullName;
+				}
+			if (iFullName == NULL)
+				{
+				delete appInfoReader;
+				return KErrNoMemory;
+				}
+			// if this object has just been constructed, iUidType is currently the TUidType
+			// of the registration file, it should be the TUidType of the app binary file
+			TUidType uidType = appInfoReader->AppBinaryUidType();
+			if (uidType[1].iUid != KNullUid.iUid)
+				{
+				iUidType = uidType;
+				}
+			}
+		}
+
+	if (appInfoReader != NULL)
+		{
+		// must get captions regardless of value of readSuccessful,
+		// because the V1 reader might have read captions
+		// this is done to maintain behavioural compatibility with V1
+		caption = appInfoReader->Caption();
+		shortCaption = appInfoReader->ShortCaption();
+
+		CApaAppIconArray* icons = appInfoReader->Icons();
+		if(icons)
+			{
+			delete iIcons;
+			iIcons = icons;
+			iIconLoader = appInfoReader->IconLoader();
+			}
+		else
+			{			
+			TRAPD(err, icons = CApaAppIconArray::NewL());
+			if(err == KErrNone)
+				{
+				delete iIcons;
+				iIcons = icons;
+				}
+			}
+		iTimeStamp = appInfoReader->TimeStamp();
+		delete iLocalisableResourceFileName;
+		iLocalisableResourceFileName = appInfoReader->LocalisableResourceFileName();
+		iLocalisableResourceFileTimeStamp = appInfoReader->LocalisableResourceFileTimeStamp();
+
+		if (isNonNativeApp)
+			{
+			// In the case of a non-native app, the resource file has been prefixed with a
+			// TCheckedUid, the second of whose UIDs is the non-native application type uid.
+			TEntry entry;
+			const TInt error=iFs.Entry(*iRegistrationFile, entry);
+			if (error!=KErrNone)
+				{
+				delete appInfoReader;
+				return error;
+				}
+			__ASSERT_DEBUG(entry.iType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile, Panic(EPanicUnexpectedUid));
+			iNonNativeApplicationType=entry.iType[1];
+			}
+
+		delete iOpaqueData;
+		iOpaqueData = appInfoReader->OpaqueData();
+
+		if (readSuccessful)
+			{
+			appInfoReader->Capability(iCapabilityBuf);
+
+			iDefaultScreenNumber = appInfoReader->DefaultScreenNumber();
+
+			delete iIconFileName;
+			iIconFileName = appInfoReader->IconFileName();
+			iIconFileTimeStamp = appInfoReader->IconFileTimeStamp();
+			iNonMbmIconFile = appInfoReader->NonMbmIconFile();
+			iNumOfAppIcons = appInfoReader->NumOfAppIcons();
+			iApplicationLanguage = appInfoReader->AppLanguage();
+					
+			// views
+			iViewDataArray->ResetAndDestroy();
+			CArrayPtrFlat<CApaAppViewData>* viewDataArray = appInfoReader->Views();
+			if (viewDataArray)
+				{
+				delete iViewDataArray;
+				iViewDataArray = viewDataArray;
+				
+				if(!iIconLoader && ViewMbmIconsRequireLoading())
+				    {
+				    //if VIEW_DATA contains a MBM icon we need to initialize iIconLoader
+				    iIconLoader = appInfoReader->IconLoader();
+				    }
+				}
+
+			// owned files
+			iOwnedFileArray->Reset();
+			CDesCArray* ownedFileArray = appInfoReader->OwnedFiles();
+			if (ownedFileArray)
+				{
+				delete iOwnedFileArray;
+				iOwnedFileArray = ownedFileArray;
+				}
+			
+			UpdateServiceArray(appInfoReader->ServiceArray(iIndexOfFirstOpenService));
+			}
+		delete appInfoReader;
+		}
+
+	if (!caption)
+		{
+		TParsePtrC parse (*iFullName);
+		caption = parse.Name().Alloc();
+		}
+
+	// Put the captions into place
+	if (caption)
+		{
+		if (!shortCaption)
+			{
+			shortCaption = caption->Alloc();
+			if (!shortCaption)
+				{
+				delete caption;
+				caption = NULL;
+				}
+			}
+		}
+	if (caption)
+		{
+		delete iCaption;
+		iCaption = caption;
+		delete iShortCaption;
+		iShortCaption = shortCaption;
+		}
+
+	return caption ? KErrNone : KErrNoMemory;
+	}
+
+EXPORT_C CApaAppData::~CApaAppData()
+// Just delete components, NOT iNext (next CApaAppData in the list).
+	{
+	delete iSuccessor;
+	delete iCaption;
+	delete iShortCaption;
+	delete iFullName;
+	delete iShortCaptionFromResourceFile;
+	delete iCaptionFromResourceFile;
+	delete iIcons;
+	delete iIconLoader;
+	if(iViewDataArray)
+		{
+		iViewDataArray->ResetAndDestroy();
+		delete iViewDataArray;
+		}
+	delete iOwnedFileArray;
+	delete iIconFileName;
+	delete iIconFileNameFromResourceFile;
+	delete iLocalisableResourceFileName;
+	if (iServiceArray)
+		{
+		CleanupServiceArray(iServiceArray);
+		iServiceArray = NULL;
+		}
+	delete iOpaqueData;
+	delete iRegistrationFile;
+	iNext = NULL;
+	}
+
+void CApaAppData::UpdateServiceArray(CArrayFixFlat<TApaAppServiceInfo>* aNewServiceArray)
+	{
+	// clear out any existing service info
+	if (iServiceArray)
+		{
+		CleanupServiceArray(iServiceArray);
+		iServiceArray = NULL;
+		}
+	// store new service array
+	iServiceArray = aNewServiceArray;
+	}
+	
+TDataTypePriority CApaAppData::DataType(const TDataType& aDataType, const CArrayFixFlat<TDataTypeWithPriority>& aDataTypeArray) const
+	{
+	TInt count=aDataTypeArray.Count();
+	for (TInt ii=0;ii<count;ii++)
+		{
+		const TDataTypeWithPriority& type=aDataTypeArray[ii];
+		if (type.iDataType==aDataType)
+			{
+			return type.iPriority;
+			}
+		else
+			{
+			TPtrC8 src=type.iDataType.Des8();
+			TPtrC8 trg=aDataType.Des8();
+			if (src.Match(trg)==0 || trg.Match(src)==0)
+				{
+				if (type.iPriority == KDataTypePrioritySystem)
+					{
+					// This is more or less a magic number so don't decrement
+					return KDataTypePrioritySystem;
+					}
+				else
+					{
+					return (TInt16)(type.iPriority-1);
+					}
+				}
+			}
+		}
+	return KDataTypePriorityNotSupported;
+	}
+
+/**
+ * Returns the CApaMaskedBitmap of size aSize for the application associated
+ * with this CApaAppData. If the icons for the application are not yet loaded then it would be loaded first.
+ * If there is not a bitmap of exact size aSize then 
+ * the icon closest to but smaller than the one asked for is returned, or NULL if
+ * none is smaller.
+ * 
+ * @since Uikon1.2
+ */
+EXPORT_C CApaMaskedBitmap* CApaAppData::Icon(TSize aSize) const
+	{
+	return iIcons->IconBySize(aSize);
+	}
+
+/**
+ * Returns a pointer to the small, medium or large application icon for aIconIndex equal to 0, 1 or 2 respectively.
+ * Panics if aIconIndex is not one of these three values.
+ *
+ * This method is superseded by an overload which returns the icon by finding the closest match to a specified size.
+ *
+ * @deprecated
+ */
+EXPORT_C CApaMaskedBitmap* CApaAppData::Icon(TInt aIconIndex) const
+	{
+	__ASSERT_DEBUG(aIconIndex>-1 && aIconIndex<3, Panic(EDPanicBadIconSize)); //only support old behaviour
+	TSize sizeExpected;
+	switch(aIconIndex)
+		{
+	case KApaIconIndexSmall:
+		sizeExpected=TSize(24,24);
+		break;
+	case KApaIconIndexMedium:
+		sizeExpected=TSize(32,32);
+		break;
+	case KApaIconIndexLarge:
+		sizeExpected=TSize(48,48);
+		break;
+	default:
+		break;
+		}
+	return Icon(sizeExpected);
+	}
+
+void CApaAppData::LoadIconsL()
+	{
+	iIconLoader->LoadAllIconsL();
+	}
+
+EXPORT_C CArrayFixFlat<TSize>* CApaAppData::IconSizesL()const
+/** Gets the sizes of icons available for the application. 
+* If the icons for the application are not yet loaded then it would be loaded first.
+
+@return A pointer to an array of the icon sizes. The caller takes ownership. */
+	{
+	return iIcons->IconSizesL();
+	}
+
+EXPORT_C TApaAppEntry CApaAppData::AppEntry() const
+/** Constructs an application entry based on this object.
+
+@return The application entry. */
+	{
+	return TApaAppEntry(iUidType,*iFullName);
+	}
+
+
+EXPORT_C void CApaAppData::Capability(TDes8& aCapabilityBuf)const
+/** Gets the application's capabilities.
+
+@param aCapabilityBuf On return, contains the application's capabilities, 
+specified as a TApaAppCapabilityBuf object. */
+	{
+	TApaAppCapability::CopyCapability(aCapabilityBuf,iCapabilityBuf);
+	}
+
+/**
+ * Returns a pointer to the array of view data objects current for this application. Does not imply transfer of ownership.
+ *
+ * @since App-Framework_6.1
+ */
+EXPORT_C CArrayPtrFlat<CApaAppViewData>* CApaAppData::Views() const
+	{
+	return iViewDataArray;
+	}
+
+/**
+ * Returns a pointer to the array of files for which this application claims ownership. Does not imply transfer of ownership.
+ *
+ * @since App-Framework_6.1
+ */
+EXPORT_C CDesCArray* CApaAppData::OwnedFiles() const
+	{
+	return iOwnedFileArray;
+	}
+
+TBool CApaAppData::Update()
+// returns true if changes were made to the cached data
+	{
+	__APA_PROFILE_START(17);
+	TBool changed=EFalse;
+
+	// Get app info file entry
+	TEntry entry;
+	TInt ret;
+	if (iRegistrationFile != NULL)
+		{
+		ret = iFs.Entry(*iRegistrationFile, entry);
+		if (ret==KErrNone && entry.iModified!=iTimeStamp)
+			{
+			// assume registration file may have changed
+			changed = ETrue;
+			}
+		else
+			{
+			if (iLocalisableResourceFileName)
+				{
+				// see if localisable resource information might have changed
+				TParse parse;
+				ret = parse.SetNoWild(KAppResourceFileExtension, iLocalisableResourceFileName, NULL);
+				if (ret == KErrNone)
+					{
+					TFileName resourceFileName(parse.FullName());
+					BaflUtils::NearestLanguageFile(iFs, resourceFileName);
+					if (resourceFileName.CompareF(*iLocalisableResourceFileName)!=0)
+						{
+						changed = ETrue;
+						}
+					else
+						{
+						ret = iFs.Entry(*iLocalisableResourceFileName, entry);
+						if ((ret==KErrNotFound && iLocalisableResourceFileTimeStamp!=TTime(0)) ||
+							(ret==KErrNone && entry.iModified!=iLocalisableResourceFileTimeStamp))
+							{
+							changed = ETrue;
+							}
+						}
+					}
+				}
+			}
+		}
+	if (changed)
+		{
+		// re-read data
+		// Ignore result, nothing we can do in case failure
+		// and the old values should be preserved
+#ifdef SYMBIAN_APPARC_APPINFO_CACHE
+		const TInt ignore = StoreApplicationInformation();
+#else
+        const TInt ignore = StoreApplicationInformation(aDefaultAppIconFileName);
+#endif // SYMBIAN_APPARC_APPINFO_CACHE
+		} //lint !e529 Symbol 'ignore' not subsequently referenced
+		
+	else 
+		{
+		if (iIconFileName)
+			{
+			ret = iFs.Entry(*iIconFileName, entry);
+			// See if the icon file has been "modified"
+			// It could have been replaced with a differnt version, deleted or added 
+			// if the icon file specified in the resource was missing
+			if ((ret==KErrNotFound && iIconFileTimeStamp!=TTime(0)) ||
+					(ret==KErrNone && entry.iModified!=iIconFileTimeStamp))
+					{
+					// Assume the icon file has changed
+					iIconFileTimeStamp = entry.iModified;
+					changed = ETrue;
+					}
+			}
+		}
+
+	__APA_PROFILE_END(17);
+	return changed;
+	}
+
+EXPORT_C TDataTypePriority CApaAppData::DataType(const TDataType& aDataType) const
+// returns the priority of the data type
+/** If the application supports the specified data type, the function returns 
+the priority with which it should be selected for handling it.
+
+If the application does not support the specified data type, 
+KDataTypePriorityNotSupported is returned.
+
+Note that the function supports wildcard matching, using "*" and "?". In the case 
+of a wildcard match, the priority value returned is reduced by 1, so that in this 
+case, the application could never have the maximum priority 
+(KDataTypePriorityUserSpecified).
+
+@param aDataType The data type of interest.
+@return The priority with which the application should be selected for handling 
+the specified data type, or KDataTypePriorityNotSupported if the data type is 
+not supported. */
+	{
+	if (iIndexOfFirstOpenService >= 0)
+		{
+		const CArrayFixFlat<TDataTypeWithPriority>& dataTypeArray = 
+			(*iServiceArray)[iIndexOfFirstOpenService].DataTypes();
+		return DataType(aDataType, dataTypeArray);
+		}
+	return KDataTypePriorityNotSupported;
+	}
+
+
+EXPORT_C TBool CApaAppData::IsPending() const
+/* Returns true if the app info is not yet updated by the current scan. */
+	{
+	return (iIsPresent==CApaAppData::EPresentPendingUpdate 
+		|| iIsPresent==CApaAppData::ENotPresentPendingUpdate);
+	}
+
+EXPORT_C TBool CApaAppData::CanUseScreenMode(TInt aScreenMode)
+/** Tests whether the specified screen mode is valid for any of 
+this application's views. If the app has no views, the function 
+assumes that only the default screen mode (at screen mode index 
+zero) is allowed. This function is used by CApaAppList to create 
+a list of valid applications.
+
+@param aScreenMode The index of the screen mode.
+@return True if screen mode is valid, otherwise false. */
+	{
+	const TInt count=iViewDataArray->Count();
+	// If there are no views, assume only the default screen mode is allowed
+	TBool ret=(count==0 && aScreenMode==0);
+	for(TInt ii=0;ii<count;ii++)
+		{
+		const CApaAppViewData* data=(*iViewDataArray)[ii];
+		if(data->ScreenMode()==aScreenMode)
+			{
+			ret=ETrue;
+			break;
+			}
+		}
+	return ret;
+	}
+
+EXPORT_C void CApaAppData::GetIconInfo(TInt& aIconCount, TInt& aDefaultIconsUsed) const
+/** Gets icon information for the app. If the icons for the application are not yet loaded then it would be loaded first.
+
+@param aIconCount On return, this contains the number of app icons
+@param aDefaultIconsUsed On return, this indicates whether the default icons have been used
+*/
+	{
+	aIconCount = iIcons->Count();
+	aDefaultIconsUsed = iIcons->DefaultIconsUsed();
+	}
+
+/** Gets the default screen number used by the application.
+
+A device may have more than once screen. This function
+returns the number associated with the screen which will
+be the default screen used by the application.
+
+@return The default screen number
+*/
+EXPORT_C TUint CApaAppData::DefaultScreenNumber() const
+	{
+	return iDefaultScreenNumber;
+	}
+
+/** Returns true if app info was provided by a registration file
+
+@return true if app info was provided by a registration file
+*/
+EXPORT_C TBool CApaAppData::RegistrationFileUsed() const
+	{
+	return iRegistrationFile != NULL;
+	}
+
+/** Returns the full filename of the registration resource file
+
+@return The full path and filename of the registration resource file.
+@internalTechnology
+*/
+EXPORT_C TPtrC CApaAppData::RegistrationFileName() const
+	{
+	if (iRegistrationFile)
+		{
+		return *iRegistrationFile;
+		}
+	else
+		{
+		return TPtrC(KNullDesC);
+		}
+	}
+
+
+/** Returns the full filename of the localisable resource file
+
+@return The full path and filename of the localisable resource file.
+@internalTechnology
+*/
+EXPORT_C TPtrC CApaAppData::LocalisableResourceFileName() const
+	{
+	if (iLocalisableResourceFileName)
+		{
+		return *iLocalisableResourceFileName;
+		}
+	else
+		{
+		return TPtrC(KNullDesC);
+		}
+	}
+
+
+/** Returns the non-native application opaque data
+
+@return The non-native application opaque data.
+@internalComponent
+*/
+EXPORT_C TPtrC8 CApaAppData::OpaqueData() const
+	{
+	if (iOpaqueData)
+		{
+		return *iOpaqueData;
+		}
+	else
+		{
+		return TPtrC8(KNullDesC8);
+		}
+	}
+
+EXPORT_C TUid CApaAppData::NonNativeApplicationType() const
+/** @internalComponent */
+	{
+	return iNonNativeApplicationType;
+	}
+
+/** Returns the full filename of the file containing application icons
+
+@return The full path and filename of the icon file.
+*/
+EXPORT_C TPtrC CApaAppData::IconFileName() const
+	{
+	if (iIconFileName)
+		{
+		return *iIconFileName;
+		}
+	else
+		{
+		return TPtrC(KNullDesC);
+		}
+	}
+
+/** Returns true if the application provides a non-MBM icon filename.
+
+If this function returns false, this does not necessarily mean
+an MBM icon filename is provided.
+
+@return true if the application provides a non-MBM icon filename.
+*/
+EXPORT_C TBool CApaAppData::NonMbmIconFile() const
+	{
+	return iNonMbmIconFile;
+	}
+
+
+/** Determines the current language the application is using to display its
+user interface.
+@return The current language.
+*/	
+EXPORT_C TLanguage CApaAppData::ApplicationLanguage() const
+	{
+	return iApplicationLanguage;
+	}
+
+/** Returns true if the application implements the specified service.
+@param aServiceUid The service UID.
+@return true if the application implements the specified service.
+@internalComponent
+*/
+EXPORT_C TBool CApaAppData::ImplementsService(TUid aServiceUid) const
+	{
+	if (iServiceArray)
+		{
+		TInt count = iServiceArray->Count();
+		for (TInt i = count-1; i >= 0; i--)
+			{
+			if ((*iServiceArray)[i].Uid() == aServiceUid)
+				{
+				return ETrue;
+				}
+			}
+		}
+	return EFalse;
+	}
+	
+/** Checks if the application implements the specified service and if the 
+service explicitly supports the datatype. Explicitly means that the datatype is
+listed in the service's list of datatype in the registration file and is
+not the general datatype associated with the application (aka the Open service).
+@param aServiceUid The service UID.
+@param aDataType The datattype
+@return The priority. KDataTypePriorityNotSupported if the app doesn't support
+this service with this datatype.
+@internalComponent
+*/
+TInt CApaAppData::ImplementsServiceWithDataType(TUid aServiceUid, const TDataType& aDataType) const
+	{
+	TInt result = KDataTypePriorityNotSupported;
+	if (iServiceArray)
+		{
+		TInt count = iServiceArray->Count();
+		for (TInt i = count-1; i >= 0; i--)
+			{
+			// There can be more than one instance of a given service so we iterate
+			// through the whole service list even if we have already found a suitable
+			// service.
+			if ((*iServiceArray)[i].Uid() == aServiceUid)
+				{
+				const CArrayFixFlat<TDataTypeWithPriority>& datatypes =
+					(*iServiceArray)[i].DataTypes();
+				TInt priority = DataType(aDataType, datatypes);
+				if (priority > result)
+					{
+					result = priority;
+					}
+				}
+			}
+		}
+	return result;
+	}
+
+EXPORT_C void CApaAppData::SetShortCaptionL(const TDesC& aShortCaption)
+	{
+	if(iShortCaption->Compare(aShortCaption) != 0)
+		{
+		HBufC* newShortCaption=aShortCaption.AllocL();
+		if (!iShortCaptionFromResourceFile)
+			{ // store the rsc file caption into iShortCaptionFromResourceFile so that it can be externalized.
+			iShortCaptionFromResourceFile = iShortCaption;
+			}
+		else
+			{
+			delete iShortCaption;
+			}
+		iShortCaption = newShortCaption;
+		}
+	}
+
+/** Sets the caption of the application. If the caption is from central repository,
+ it overrides tha value from the resource file.  
+*/
+EXPORT_C void CApaAppData::SetCaptionL(const TDesC& aCaption)
+	{
+	if(iCaption->Compare(aCaption) != 0)
+		{
+		HBufC* newCaption=aCaption.AllocL();
+		if (!iCaptionFromResourceFile)
+			{ // store the rsc file caption into iCaptionFromResourceFile so that it can be externalized.
+			iCaptionFromResourceFile = iCaption;
+			}
+		else
+			{
+			delete iCaption;
+			}
+		iCaption = newCaption;
+		}
+	}
+
+/** Sets the icon details of an application. If these details are from the central repository,
+ it overrides the value in the resource file and loads it.
+*/
+EXPORT_C void CApaAppData::SetIconsL(const TDesC& aFileName, TInt aNumIcons)
+	{
+	if (iIconFileName && 
+		iIconFileName->Compare(aFileName) == 0 &&
+		iNumOfAppIcons == aNumIcons)
+		return;
+
+	if (!iIconFileNameFromResourceFile)
+		{
+	 	iNumOfAppIconsFromResourceFile = iNumOfAppIcons;
+	 	iIconFileNameFromResourceFile = iIconFileName;
+	 	iIconFileName = NULL;
+	 	iNonMbmIconFileFromResourceFile = iNonMbmIconFile;
+	 	iIconFileTimeStampFromResourceFile = iIconFileTimeStamp;
+		}
+		
+	iNonMbmIconFile = !CApaAppInfoReaderV2::FileIsMbm(aFileName);
+	iNumOfAppIcons = aNumIcons;
+	
+	if (aFileName != KNullDesC)
+		{
+		iIconFileName = aFileName.AllocL();
+		if (!iNonMbmIconFile)
+			{
+			if (iNumOfAppIcons > 0)
+				{
+				// Creates an Application Icon Array
+				CApaAppIconArray* icons = CApaAppIconArray::NewAppIconsL(iNumOfAppIcons, *iIconFileName, *iIconLoader);
+				delete iIcons;
+				iIcons = icons;
+				}
+			}
+		else
+			{	// Creates an Empty Icon Array if application has Non-Mbm Icons
+			CApaAppIconArray* icons = CApaAppIconArray::NewL();
+			delete iIcons;
+			iIcons = icons;
+			}
+		}
+	else
+		{
+		CApaAppIconArray* icons = CApaAppIconArray::NewDefaultIconsL();
+		delete iIcons;
+		iIcons = icons;
+		}
+	}
+
+void CApaAppData::SetAppPending()
+	{
+	if (iIsPresent == CApaAppData::ENotPresent 
+		|| iIsPresent == CApaAppData::ENotPresentPendingUpdate)
+		{
+		iIsPresent = CApaAppData::ENotPresentPendingUpdate;
+		}
+	else
+		{
+		iIsPresent = CApaAppData::EPresentPendingUpdate;
+		}
+	}
+
+//
+// Class CApaAppList
+//
+
+EXPORT_C CApaAppList* CApaAppList::NewL(RFs& aFs,CApaAppRegFinder* aAppRegFinder, TBool aLoadMbmIconsOnDemand, TInt aIdlePeriodicDelay)
+	{
+	CApaAppList* self=new CApaAppList(aFs, aAppRegFinder, aLoadMbmIconsOnDemand, aIdlePeriodicDelay);
+	if (!self)
+		{
+		delete aAppRegFinder;
+		User::LeaveNoMemory();
+		}
+	else
+		{
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		CleanupStack::Pop(self);
+		}
+	return self;
+	}
+
+CApaAppList::CApaAppList(RFs& aFs, CApaAppRegFinder* aAppRegFinder, TBool aLoadMbmIconsOnDemand, TInt aIdlePeriodicDelay)
+	:iFs(aFs),
+	iFlags(0),
+	iAppRegFinder(aAppRegFinder),
+	iIdlePeriodicDelay(aIdlePeriodicDelay),
+	iLoadMbmIconsOnDemand(aLoadMbmIconsOnDemand),
+    iUninstalledApps(NULL)	
+	{
+	}
+
+void CApaAppList::ConstructL()
+	{
+	User::LeaveIfError(iFsShareProtected.Connect());
+	User::LeaveIfError(iFsShareProtected.ShareProtected());
+	User::LeaveIfError(Dll::SetTls(this));
+	
+	//Start language change monitor.
+	iAppLangMonitor = CApaLangChangeMonitor::NewL(*this);
+	GetAppsListCachePathL();
+	}
+	
+EXPORT_C CApaAppList::~CApaAppList()
+/** Frees all resources prior to destruction, including the application data list. */
+	{
+	iValidFirstAppData = NULL;
+	DeleteAppData();
+
+	iAppData = NULL;
+	iObserver = NULL;
+	iFsShareProtected.Close();
+
+	delete iDefaultIconArray;
+	delete iDefaultAppIconMbmFileName;
+	delete iAppRegFinder;
+	delete iAppIdler;
+	delete iAppListStorer;
+	delete iAppIconLoader;
+	delete iAppLangMonitor;
+	iAppsListCacheFileName.Close();
+	iAppsListCacheBackUpFileName.Close();
+	iAppsListCachePath.Close();
+	}
+
+// Stop scanning applications if and uninstallation has started	
+EXPORT_C void CApaAppList::StopScan(TBool aNNAInstall)
+	{
+	if (aNNAInstall)
+		{
+		iNNAInstallation = ETrue;
+		}
+	if (iAppIdler)
+		{
+		delete iAppIdler;
+		iAppIdler=NULL;
+		}
+	UndoSetPending(iAppData);
+	}
+	
+// Allow scanning when uninstallation is complete
+EXPORT_C void CApaAppList::RestartScanL()
+	{
+	TRAP_IGNORE(PurgeL());
+	StartIdleUpdateL();
+	}
+	
+EXPORT_C TBool CApaAppList::AppListUpdatePending()
+	{
+	return iNNAInstallation;
+	}
+
+void CApaAppList::UndoSetPending(CApaAppData* aAppData)
+	// Reset all apps to pevious pending state so they don't get purged
+	{
+  	for (; aAppData; aAppData = aAppData->iNext)
+		{
+		if (aAppData->iIsPresent == CApaAppData::EPresentPendingUpdate)
+			{
+			aAppData->iIsPresent = CApaAppData::EIsPresent;
+			}
+		}
+	}
+
+EXPORT_C void CApaAppList::StartIdleUpdateL()
+/** Updates the list asynchronously, using an idle time active object, 
+and no observer. When the update is finished, the resulting app 
+list is stored. */
+	{
+	// find the default icons (.mbm file) for applications, wrt current locale
+	CreateDefaultAppIconFileNameL();
+
+	// File operation is abandoned if it is in progress.
+	if (iAppListStorer && iAppListStorer->IsActive())
+		{
+		delete iAppListStorer;
+		iAppListStorer = NULL;
+		}
+
+	// Stops icon loading if it is in progress.
+	if (iAppIconLoader && iAppIconLoader->IsActive())
+		{
+		delete iAppIconLoader;
+		iAppIconLoader = NULL;
+		}
+
+	// DEF076594 - if changing locale, need to update the default icons here
+	// If updating the default icons array fails, the array is left in the state
+	// it was in before the call.
+	if(iDefaultIconArray)
+		{
+		TRAP_IGNORE(UpdateDefaultIconsL());
+		}
+
+	// start to scan.
+	if (iAppIdler)
+		{
+		delete iAppIdler;
+		iAppIdler=NULL;
+		}
+		
+	// DEF072701
+	// When performing the update scan let the idle object have lower priority.
+	if (IsFirstScanComplete())
+		{
+		iAppIdler=CPeriodic::NewL(CActive::EPriorityLow);
+		}
+	else
+		{
+		iAppIdler=CPeriodic::NewL(CActive::EPriorityStandard);
+		}
+	SetPending(iAppData);
+	iAppRegFinder->FindAllAppsL();
+ 
+ 	// DEF072701
+ 	// If this is the first scan i.e the boot scan then it may take some time. Thus
+ 	// the periodic delay value should be used so that this process will stop periodically 
+ 	// to allow time for other processes.
+ 	// If this is just a re-scan it should take much less time. Therefore it should just
+ 	// be completed in one go rather than periodically delayed. Thus the delay value
+ 	// should be set to 0.
+	iAppIdler->Start(KIdleStartDelay, IsFirstScanComplete()? 0 : iIdlePeriodicDelay, TCallBack(IdleUpdateCallbackL, this));
+	}
+
+EXPORT_C void CApaAppList::StartIdleUpdateL(MApaAppListObserver* aObserver)
+/** Updates the list asynchronously, using an idle time active object 
+and an observer. When the update is finished, the resulting app list 
+is stored and the observer is notified with an MApaAppListServObserver::EAppListChanged 
+message, if the list changed.
+@param aObserver Observer to be notified when the update has finished. */
+	{
+	iObserver=aObserver;
+
+	// Rename Appslist.bin file to AppsList_Backup.bin, so that it can be renamed back, if rescan/update scan does not change applist.
+	TInt replaceError = iFs.Replace(iAppsListCacheFileName, iAppsListCacheBackUpFileName);
+	if (replaceError != KErrNone)
+		{
+		iFs.Delete(iAppsListCacheFileName);
+		}
+	StartIdleUpdateL();
+	}
+
+void CApaAppList::CreateDefaultAppIconFileNameL()
+	{
+	TFileName tempFileName(KDefaultAppIconMbm);
+	BaflUtils::NearestLanguageFile(iFs, tempFileName);
+	delete iDefaultAppIconMbmFileName;
+	iDefaultAppIconMbmFileName = NULL;
+	iDefaultAppIconMbmFileName = tempFileName.AllocL();
+	}
+
+EXPORT_C void CApaAppList::InitListL(MApaAppListObserver* aObserver)
+/** It Restores the data present in the AppsList.bin file and updates the applist. 
+ * If Restore operation fails then it 
+ * starts updating the list asynchronously, by calling StartIdleUpdateL().
+
+@param aObserver Observer to be notified when the update has finished. */
+	{
+	DeleteAppsListBackUpAndTempFiles();
+	TInt ret = KErrGeneral;
+//#ifndef __WINS__ // on the emulator, don't read app list from file, as doing so means apps
+                 // built while the emulator isn't running won't appear in the list
+	TRAP(ret, RestoreL());
+//#endif
+	if (ret != KErrNone)
+		{
+		// There was an error during restore, so update the list asynchronously.
+		DeleteAppData();
+		iFs.Delete(iAppsListCacheFileName);
+		StartIdleUpdateL(aObserver);
+		}
+	else
+		{
+		iObserver = aObserver;
+		if (iLoadMbmIconsOnDemand)
+			{
+			InitiateStoringOfAppList();
+			}
+		else
+			{
+			StartIconLoadingL();
+			}
+		}
+	}
+
+void CApaAppList::StartIconLoadingL()
+	{
+	iAppIconLoader = new(ELeave) CApaIdleIconLoader(iAppData, iFs, *this);
+	iAppIconLoader->Start();
+	}
+
+void CApaAppList::ScanRemovableDrivesAndUpdateL()
+/** Rename Appslist.bin file to AppsList_Backup.bin, so that it can be renamed back, 
+     if the update scan on removable media drives does not change applist. */
+	{
+	const RArray<TDriveUnitInfo>& listOfRemovableMediaDrives = iAppRegFinder->DriveList();
+	const TInt count = listOfRemovableMediaDrives.Count();
+
+	// Removable media scan would take place only if removable drives are present.
+	if (count)
+		{
+		CApaAppData* appData = iAppData;
+		while (appData)
+			{
+			for (TInt driveIndex = 0; driveIndex < count; ++driveIndex)
+				{
+				if (TParsePtrC(*appData->iRegistrationFile).Drive() == listOfRemovableMediaDrives[driveIndex].iDriveUnit.Name())
+					{
+					appData->SetAppPending();
+					break;
+					}
+				}
+			appData = appData->iNext;
+			}
+
+		while (IdleUpdateL())
+			{ // It updates the removable media apps present in AppList if it has changed.
+
+			};
+		}
+	}
+
+void CApaAppList::DeleteAppsListBackUpAndTempFiles()
+/** Deletes all files inside AppsListCache folder except AppsList.bin */
+	{
+	_LIT(KTemp, "AppsList.bin");
+	CDir* cache = NULL;
+	TInt ret = iFs.GetDir(iAppsListCachePath, KEntryAttNormal, ESortNone, cache);
+	if (ret == KErrNone)
+		{
+		const TInt count = cache->Count();
+		for (TInt i = 0; i < count; ++i)
+			{
+			TBufC<KMaxFileName> cacheFileName = (*cache)[i].iName;
+	#if defined (SYMBIAN_BAFL_SYSUTIL)
+				if ((cacheFileName.Match(KTemp) == KErrNotFound) && (cacheFileName.Match(KROMVersionStringCacheFileName) == KErrNotFound)) 
+	#else
+				if ((cacheFileName.Match(KTemp) == KErrNotFound)) 
+	#endif
+				{
+				TFileName fileNameToDelete;
+				fileNameToDelete.Append(iAppsListCachePath);
+				fileNameToDelete.Append(cacheFileName);
+				iFs.Delete(fileNameToDelete);
+				}
+			}
+		delete cache;
+		}
+	}
+
+void CApaAppList::RestoreL()
+/** It restores the data present in the AppsList.bin file */
+	{
+	RFileReadStream theReadStream;
+	User::LeaveIfError(theReadStream.Open(iFs, iAppsListCacheFileName, EFileRead));
+	CleanupClosePushL(theReadStream);
+	
+	TLanguage appListFileLanguage = (TLanguage)theReadStream.ReadInt32L();
+	if (appListFileLanguage != User::Language())
+		{
+		User::Leave(KErrNotSupported);
+		}
+		
+#if defined (SYMBIAN_BAFL_SYSUTIL)
+	//Build the filename for the cache file
+	TInt maxSizeofFileName = iAppsListCachePath.Length() + KROMVersionStringCacheFileName().Length();
+	RBuf romVersionCacheFileName;
+	romVersionCacheFileName.CreateL(maxSizeofFileName);
+	romVersionCacheFileName.CleanupClosePushL();
+	romVersionCacheFileName.Append(iAppsListCachePath);
+	romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
+	
+	RFileReadStream romVerStream;
+	User::LeaveIfError(romVerStream.Open(iFs,romVersionCacheFileName,EFileRead));
+	CleanupClosePushL(romVerStream);
+	
+	TVersion actualROMVersionCacheFileVersion(KROMVersionCacheFileMajorVersion, KROMVersionCacheFileMinorVersion, KROMVersionCacheFileBuildVersion);
+	TVersionName actualROMVersionCacheFileVersionName = actualROMVersionCacheFileVersion.Name();
+	
+	//read the rom file version
+	TInt8 romVersionCacheFileMajorVersion = romVerStream.ReadInt8L();
+	TInt8 romVersionCacheFileMinorVersion = romVerStream.ReadInt8L();
+	TInt16 romVersionCacheFileBuildVersion = romVerStream.ReadInt16L();
+	TVersion romVersionCacheFileVersion(romVersionCacheFileMajorVersion, romVersionCacheFileMinorVersion, romVersionCacheFileBuildVersion);
+	TVersionName romVersionCacheFileVersionName = romVersionCacheFileVersion.Name();
+	
+	//If persisted file version differs from what apparc can handle, recreate rom version file and applist.bin
+	if (romVersionCacheFileVersionName.Compare(actualROMVersionCacheFileVersionName) != 0)
+		{
+		User::Leave(KErrGeneral);
+		}
+		
+	//Read the length & value of software version from it.
+	TBuf<KInfoBufLength> softwareVersion;
+	TUint32 length = romVerStream.ReadUint32L();
+	if (length>KInfoBufLength)
+		{
+		//File must be corrupt, an attempt to read will panic
+		User::Leave(KErrCorrupt);
+		}	
+	romVerStream.ReadL(softwareVersion, length);
+
+	//the persisted version has been successfully read
+	//read the actual current version string
+	TBuf<KInfoBufLength> actualSoftwareVersion;
+	TInt err = SysUtil::GetSWVersion(actualSoftwareVersion); //use the SysUtil implementation
+	if(err == KErrNone)
+		{
+		if (softwareVersion.Compare(actualSoftwareVersion) != 0)
+			{
+			//Leave if the current version is different from the previous stored version and recreate applist.
+#ifdef _DEBUG
+			RDebug::Print(_L("!!Firmware update detected!! Rebuilding AppList"));
+#endif
+			User::Leave(KErrGeneral);
+			}
+		}
+	else
+		{
+		//Leave if any error reading the version information, except if file is not present
+		if (err != KErrPathNotFound && err != KErrNotFound)
+			{
+#ifdef _DEBUG
+			RDebug::Print(_L("!!Error %d reading Firmware version.  Rebuilding AppList"),err);
+#endif
+			User::Leave(err);
+			}
+		}
+	CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
+#endif
+	
+	// Create Default Icon File Name
+	CreateDefaultAppIconFileNameL();
+	
+	TInt ret = KErrNone;
+	while (ret == KErrNone)
+		{
+		CApaAppData* const pApp = new (ELeave) CApaAppData(iFs);
+		CleanupStack::PushL(pApp);
+
+		// Restore entries till we leave
+		TRAP(ret, pApp->InternalizeL(theReadStream));
+		
+		if (ret != KErrNone && ret != KErrEof)
+			{
+			User::Leave(ret);
+			}
+		// Check that the app has not been added to the list twice
+		if (ret == KErrNone && !AppDataByUid(pApp->iUidType[2]))
+			{
+			AddToList(pApp);
+			CleanupStack::Pop(pApp);
+			}
+		else
+			{ // Delete pApp if an End of File condition is reached or the app has been added to the list twice
+			CleanupStack::PopAndDestroy(pApp);
+			}
+		}	
+	// Close the stream;
+	CleanupStack::PopAndDestroy(&theReadStream);
+
+	iFs.Rename(iAppsListCacheFileName, iAppsListCacheBackUpFileName);
+	iAppRegFinder->FindAllRemovableMediaAppsL();	// Builds the Removable Media Drive List
+
+	iFlags |= ENotifyUpdateOnFirstScanComplete;
+
+	// It runs an update scan on removable media apps.
+	ScanRemovableDrivesAndUpdateL();
+	}
+
+EXPORT_C TBool CApaAppList::IsLanguageChangePending() const
+/** Returns ETrue if a language change event is received and a re-scan is in progress otherwise EFalse. */
+	{
+	return (iFlags & ELangChangePending);
+	}
+
+void CApaAppData::InternalizeL(RReadStream& aReadStream)
+/** Internalizes the appdata from the AppsList.bin file */
+	{
+	TUint highTime = aReadStream.ReadUint32L();
+	TUint lowTime = aReadStream.ReadUint32L();
+	iTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));
+
+	highTime = aReadStream.ReadUint32L();
+	lowTime = aReadStream.ReadUint32L();
+	iIconFileTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));
+	iCaption = HBufC::NewL(aReadStream, KMaxFileName);	// Caption
+	iShortCaption = HBufC::NewL(aReadStream, KMaxFileName);	// Shortcaption
+	iFullName = HBufC::NewL(aReadStream, KMaxFileName);		// Filename of application binary
+
+	TUid uid1;
+	uid1.iUid = aReadStream.ReadUint32L();
+	TUid uid2;
+	uid2.iUid = aReadStream.ReadUint32L();	
+	TUid uid3;
+	uid3.iUid = aReadStream.ReadUint32L();
+	iUidType = TUidType(uid1, uid2, uid3);	// Application UID
+	
+	aReadStream >> iCapabilityBuf;
+
+	iRegistrationFile = HBufC::NewL(aReadStream, KMaxFileName);	// Registration Filename
+		
+	iDefaultScreenNumber = aReadStream.ReadUint32L();	// Default Screen number
+	
+	iNumOfAppIcons = aReadStream.ReadInt32L();	// No. of icons
+
+	iNonMbmIconFile = aReadStream.ReadUint32L();
+
+	HBufC* iconFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Icon Filename
+	if (*iconFileName != KNullDesC)
+		{
+		iIconFileName = iconFileName;
+		if (!iNonMbmIconFile)
+			{
+			if (iNumOfAppIcons > 0)
+				{ // Create IconLoader to load icons
+				iIconLoader = CApaIconLoader::NewL(iFs);
+				// Creates an Application Icon Array
+				iIcons = CApaAppIconArray::NewAppIconsL(iNumOfAppIcons, *iIconFileName, *iIconLoader);
+				}
+			else
+			    TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL()); // Creates and Loads Default Icons.
+			}
+		else
+			{	// Creates an Empty Icon Array if application has Non-Mbm Icons
+			iIcons = CApaAppIconArray::NewL();
+			}
+		}
+	else
+		{
+		delete iconFileName;
+		TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL()); // Creates and Loads Default Icons.
+		}
+
+	HBufC* localisableResourceFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Registration Filename
+	if (*localisableResourceFileName != KNullDesC)
+		{
+		iLocalisableResourceFileName = localisableResourceFileName;
+		}
+	else
+		{
+		delete localisableResourceFileName;
+		}	
+
+	highTime = aReadStream.ReadUint32L();
+	lowTime = aReadStream.ReadUint32L();
+	iLocalisableResourceFileTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));	// Localisable file timestamp
+
+	iApplicationLanguage = (TLanguage)aReadStream.ReadInt32L();	// Application Language
+
+	iIndexOfFirstOpenService = aReadStream.ReadUint32L();		// Index of first open service
+
+	iNonNativeApplicationType.iUid = aReadStream.ReadUint32L();
+
+	HBufC8* opaqueData = HBufC8::NewL(aReadStream, KMaxFileName);	// Opaque Data
+	if (*opaqueData != KNullDesC8)
+		{
+		iOpaqueData = opaqueData;
+		}
+	else
+		{
+		delete opaqueData;
+		}
+
+	iViewDataArray = new(ELeave) CArrayPtrFlat<CApaAppViewData>(1);	// ViewDataArray
+	const TInt viewCount = aReadStream.ReadInt32L();
+	TInt i;	
+	for (i = 0; i < viewCount; ++i)
+		{
+		CApaAppViewData* pView = CApaAppViewData::NewLC();
+
+		pView->iCaption = HBufC::NewL(aReadStream, KMaxFileName);
+		pView->iNumOfViewIcons = aReadStream.ReadUint32L();
+		pView->iNonMbmIconFile = aReadStream.ReadUint32L();
+		HBufC* iconFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Icon Filename		
+		if (*iconFileName != KNullDesC)
+			{
+			pView->iIconFileName = iconFileName;
+			if (!pView->iNonMbmIconFile)
+				{
+				if (pView->iNumOfViewIcons > 0)
+					{
+					if (!iIconLoader)
+						{	// Create Icon Loader if it was not done for App or any of the previous views for the App.
+						iIconLoader = CApaIconLoader::NewL(iFs);
+						}
+					// Creates an Application View Icon Array
+					CApaAppIconArray* iconViewArray = CApaAppIconArray::NewViewIconsL(pView->iNumOfViewIcons, *pView->iIconFileName, *iIconLoader);
+					pView->SetIconArray(iconViewArray);
+					}
+				}
+			}
+		else
+			{
+			delete iconFileName;
+			}
+		pView->iScreenMode = aReadStream.ReadUint32L();
+		pView->iUid.iUid = aReadStream.ReadUint32L();
+
+		iViewDataArray->AppendL(pView);
+		CleanupStack::Pop(pView);
+		}
+
+	iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(1);
+	const TInt serviceCount = aReadStream.ReadUint32L();
+
+	for (i = 0; i < serviceCount; ++i)
+		{
+		TApaAppServiceInfo serviceInfo ;
+		aReadStream >> serviceInfo;
+		iServiceArray->AppendL(serviceInfo);
+		}
+
+	iOwnedFileArray = new(ELeave) CDesCArraySeg(1);
+	const TInt fileCount = aReadStream.ReadUint32L();	
+	for (i = 0; i < fileCount; ++i)
+		{
+		TFileName ownedFile;
+		aReadStream >> ownedFile;
+		iOwnedFileArray->AppendL(ownedFile);
+		}
+	}
+
+TBool CApaAppData::ViewMbmIconsRequireLoading() const
+	{
+	const TInt count = iViewDataArray->Count();
+	for (TInt i = 0; i < count; ++i)
+		{
+		const CApaAppViewData* const viewData = iViewDataArray->At(i);
+		if ((!viewData->iNonMbmIconFile) && (!viewData->iIcons->AreViewIconsLoaded()))
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+	
+TBool CApaAppData::MbmIconsRequireLoading() const
+	{
+	if (!iNonMbmIconFile)
+		{
+		if (!iIcons->AreAppIconsLoaded())
+			{
+			return ETrue;
+			}
+		}
+
+	if (ViewMbmIconsRequireLoading())
+		{// if a view has mbm icons, and its not yet loaded we should load its icons.
+		return ETrue;
+		}
+	return EFalse; // icons were loaded already so no need to load them again.
+	}
+
+void CApaAppData::ExternalizeL(RWriteStream& aWriteStream) const
+	{
+	aWriteStream.WriteUint32L(I64HIGH(iTimeStamp.Int64()));
+	aWriteStream.WriteUint32L(I64LOW(iTimeStamp.Int64()));
+
+	if (iIconFileNameFromResourceFile)
+		{
+		aWriteStream.WriteUint32L(I64HIGH(iIconFileTimeStampFromResourceFile.Int64()));
+	    aWriteStream.WriteUint32L(I64LOW(iIconFileTimeStampFromResourceFile.Int64()));
+		}
+	else
+		{
+	aWriteStream.WriteUint32L(I64HIGH(iIconFileTimeStamp.Int64()));
+	aWriteStream.WriteUint32L(I64LOW(iIconFileTimeStamp.Int64()));
+		}
+		
+	if (iCaptionFromResourceFile)	// Caption present in the resource file would be externalized if the one in applist has dynamically changed
+		{
+		aWriteStream << *iCaptionFromResourceFile;
+		}
+	else
+		{
+		aWriteStream << *iCaption;
+		}
+		
+	if (iShortCaptionFromResourceFile)	// Short caption present in the resource file would be externalized if the one in applist has dynamically changed
+		{
+		aWriteStream << *iShortCaptionFromResourceFile;
+		}
+	else
+		{
+		aWriteStream << *iShortCaption;
+		}
+	aWriteStream << *iFullName;	// FullName
+
+	TInt i;
+	for (i = 0; i < 3; ++i)
+		{
+		aWriteStream << iUidType[i];	// Uid Type
+		}
+
+	aWriteStream << iCapabilityBuf;
+	aWriteStream << RegistrationFileName();	// Registration filename
+	aWriteStream.WriteUint32L(iDefaultScreenNumber);	// Default screen number
+
+	if (iIconFileNameFromResourceFile)
+		{
+		aWriteStream.WriteUint32L(iNumOfAppIconsFromResourceFile);	// number of icons
+
+		aWriteStream.WriteUint32L(iNonMbmIconFileFromResourceFile);
+
+		aWriteStream << *iIconFileNameFromResourceFile;
+		}
+	else
+		{
+	aWriteStream.WriteUint32L(iNumOfAppIcons);	// number of icons
+
+	aWriteStream.WriteUint32L(iNonMbmIconFile);
+
+	aWriteStream << IconFileName();
+		}
+
+	aWriteStream << LocalisableResourceFileName();
+
+	aWriteStream.WriteUint32L(I64HIGH(iLocalisableResourceFileTimeStamp.Int64()));
+	aWriteStream.WriteUint32L(I64LOW(iLocalisableResourceFileTimeStamp.Int64()));
+
+	aWriteStream.WriteInt32L(iApplicationLanguage);
+
+	aWriteStream.WriteUint32L(iIndexOfFirstOpenService);
+
+	aWriteStream.WriteUint32L(iNonNativeApplicationType.iUid);
+
+	aWriteStream << OpaqueData();
+	
+	TInt count = iViewDataArray->Count();
+	aWriteStream.WriteUint32L(count);
+
+	for (i = 0; i < count; ++i)
+		{
+		const CApaAppViewData* const viewData = iViewDataArray->At(i);
+		aWriteStream << *(viewData->iCaption);
+		aWriteStream.WriteUint32L(viewData->iNumOfViewIcons);
+		aWriteStream.WriteUint32L(viewData->iNonMbmIconFile);
+		aWriteStream << viewData->IconFileName();		
+		aWriteStream.WriteUint32L(viewData->iScreenMode);
+		aWriteStream.WriteUint32L(viewData->iUid.iUid);
+		}
+
+	// TApaAppServiceInfo service array
+	if (iServiceArray)
+		{
+		count = iServiceArray->Count();
+		aWriteStream.WriteUint32L(count);
+		for (i = 0; i < count; ++i)
+			{
+			aWriteStream << iServiceArray->At(i);
+			}
+		}
+	else
+		{
+		aWriteStream.WriteUint32L(NULL);
+		}
+
+	if (iOwnedFileArray)
+		{
+		count = iOwnedFileArray->MdcaCount();
+		aWriteStream.WriteUint32L(count);
+		for (i = 0; i < count; ++i)
+			{
+			aWriteStream << (*iOwnedFileArray)[i];
+			}
+		}
+	else
+		{
+		aWriteStream.WriteUint32L(0);
+		}
+	}
+
+TInt CApaAppList::IdleUpdateCallbackL(TAny* aObject)
+	{
+	CApaAppList* self=REINTERPRET_CAST(CApaAppList*,aObject);
+	const TBool moreToCome=self->IdleUpdateL();
+	if (moreToCome==EFalse)
+		{
+		//Reset language change flag if scanning is over.
+		if (self->IsLanguageChangePending())
+			{
+			self->iFlags &= ~ELangChangePending;
+			}
+		self->StopIdler();
+		if (self->iLoadMbmIconsOnDemand)
+			{
+			self->InitiateStoringOfAppList();
+			}
+		else
+			{
+			self->StartIconLoadingL();
+			}
+		}
+	return moreToCome;
+	}
+
+void CApaAppList::StoreL()
+	{
+	iAppListStorer = CApaAppListStorer::NewL(iAppData, iFs, *this);
+	iAppListStorer->StartL(KAppListToFileStartDelay);
+	}
+
+void CApaAppList::NotifyObserver()
+	{
+	if (iObserver)
+		{
+		if (iFlags & EAppListHasChanged || iFlags & ENotifyUpdateOnFirstScanComplete)
+			{
+			// NotifyUpdate will notify clients for both list update and scan complete.
+			iObserver->NotifyUpdate(MApaAppListServObserver::EAppListChanged);
+			}
+		else
+			{
+			// NotifyScanComplete will notify clients for scan complete.
+			iObserver->NotifyScanComplete();
+			}
+		iObserver=NULL;
+		}
+	}
+
+void CApaAppList::StopIdler()
+	{
+ 	delete iAppIdler;
+	iAppIdler=NULL;
+	}
+
+TInt CApaAppList::IdleUpdateL()
+// returns ETrue if there is more scanning to be done.
+	{
+	TBool more=EFalse;
+	TApaAppEntry currentApp = TApaAppEntry();
+	TRAPD(err,more=iAppRegFinder->NextL(currentApp, iForcedRegistrations));
+	if (err!=KErrNone)
+		{
+		if (iFlags & ENotifyUpdateOnFirstScanComplete)
+			{
+			User::Leave(err);
+			}
+		return more;
+		}
+	TBool hasChanged=EFalse;
+	if (more)
+		{
+		TRAPD(err,UpdateNextAppL(currentApp,hasChanged));
+		if (err!=KErrNone)
+			{
+			SetNotFound(iAppData,hasChanged);
+			if (iFlags & ENotifyUpdateOnFirstScanComplete)
+				{
+				User::Leave(err);
+				}	
+			more=EFalse; // abandon ship
+			}
+		}
+	else
+		{
+		SetNotFound(iAppData,hasChanged);
+		PurgeL();
+		}
+
+	if (hasChanged)
+		{
+		iFlags |= EAppListHasChanged;
+		}
+	return more;
+	}
+
+EXPORT_C TBool CApaAppList::IsIdleUpdateComplete() const
+/** Tests whether an asynchronous update of the list is currently in progress.
+
+@return True if no asynchronous update of the list is currently in progress, 
+otherwise false. */
+	{
+	return iAppIdler == NULL;
+	}
+
+void CApaAppList::SetPending(CApaAppData* aAppData)
+	// set all apps to pending update - we'll find them again as we scan
+	{
+  	for (; aAppData; aAppData = aAppData->iNext)
+		{
+		aAppData->SetAppPending();
+		}
+	}
+
+void CApaAppList::SetNotFound(CApaAppData* aAppData, TBool& aHasChanged)
+	// mark any unfound apps not present
+	{
+	while (aAppData)
+		{
+		if (aAppData->IsPending())
+			{
+			aAppData->iIsPresent = CApaAppData::ENotPresent;
+			aHasChanged = ETrue;
+			}
+		aAppData = aAppData->iNext;
+		}
+	}
+
+void CApaAppList::AddToList( CApaAppData* aAppData )
+{
+	__ASSERT_DEBUG(aAppData, Panic(EPanicNullPointer));
+	aAppData->iNext=iAppData;
+	iAppData=aAppData;
+}
+
+void CApaAppList::UpdateNextAppL(const TApaAppEntry& aAppEntry,TBool& aHasChanged)
+	{
+	CApaAppData* appData=AppDataByUid(aAppEntry.iUidType[2]);
+	if (appData==NULL)
+		{// not in list, so add it at the start
+		TRAPD(err,appData=CApaAppData::NewL(aAppEntry, iFs));
+		if (err==KErrNone)
+			{
+			AddToList( appData );
+			aHasChanged=ETrue;
+			}
+		}
+	else if (appData->IsPending())
+		{ // not found yet during current scan - we may need to override this one
+		
+		// On a system which scans for registration .RSC files (V2 apps) first, followed by
+		// .APP files (V1 apps), it's valid for a V1 app to override a V2 app (if the V2 app
+		// has just been removed). If this is the case, assume it's ok to compare the V1 .APP filename,
+		// with the V2 .RSC filename as their filenames will never match (which is what we want in this case).
+		TPtrC currentFileName;
+		if (appData->RegistrationFileUsed())
+			{
+			currentFileName.Set(*appData->iRegistrationFile);
+			}
+		else
+			{
+			currentFileName.Set(*appData->iFullName);
+			}
+		if (aAppEntry.iFullName.CompareF(currentFileName)!=0)
+			{
+			delete appData->iSuccessor;
+			appData->iSuccessor = NULL;
+			appData->iSuccessor = CApaAppEntry::NewL(aAppEntry);
+
+
+			appData->iIsPresent = CApaAppData::ESuperseded;
+			aHasChanged=ETrue;
+			}
+		else
+			{
+			if (appData->Update()
+				|| appData->iIsPresent==CApaAppData::ENotPresentPendingUpdate) 
+				{
+				aHasChanged=ETrue; 
+				}
+			appData->iIsPresent = CApaAppData::EIsPresent;
+			}
+		}
+	}
+
+/**
+@internalComponent
+*/
+EXPORT_C CApaAppData* CApaAppList::FindAndAddSpecificAppL(CApaAppRegFinder* aFinder, TUid aAppUid)
+	{
+//Scans and adds the specified application to the app list if found
+	__ASSERT_DEBUG(aFinder, Panic(EPanicNullPointer));
+	TBool found = EFalse;
+	TApaAppEntry appEntry;
+	aFinder->FindAllAppsL();
+	while (aFinder->NextL(appEntry, iForcedRegistrations))
+		{
+		if (appEntry.iUidType[2] == aAppUid)
+			{
+			found = ETrue;
+			break;
+			}
+		}
+	
+	CApaAppData* app = NULL;
+	if (found)
+		{
+		// add the app to the list
+		TBool hasChanged = EFalse;
+		CApaAppData* prevFirstAppInList = iAppData;
+		UpdateNextAppL(appEntry, hasChanged);
+		if (iAppData != prevFirstAppInList)
+			{
+			// assume the new app was added to the list
+			app = iAppData;
+			}
+		if (hasChanged)
+			{
+			iFlags |= EAppListHasChanged;
+			}
+		}
+	return app;
+	}
+
+EXPORT_C void CApaAppList::PurgeL()
+/** Removes any applications from the list if they are no longer present 
+on the phone. It updates applications that have been 
+superceded. */
+	{
+	CApaAppData* appData=iAppData;
+	CApaAppData* prev=NULL;
+	while (appData)
+		{
+		CApaAppData* next=appData->iNext;
+		if (appData->iIsPresent==CApaAppData::ENotPresent)
+			{
+			if (prev)
+				prev->iNext=next;
+			else
+				iAppData=next;
+ 
+			//Add uninstalled application UID to a list
+            if(iUninstalledApps==NULL)
+                iUninstalledApps=new(ELeave) CArrayFixFlat<TUid>(1);
+            
+            iUninstalledApps->AppendL(appData->AppEntry().iUidType[2]);
+ 			
+			delete appData;
+			}
+		else if (appData->iIsPresent==CApaAppData::ESuperseded)
+			{
+			CApaAppData* newApp=NULL;
+			TApaAppEntry appEntry;
+			appData->iSuccessor->Get(appEntry);
+			TRAPD(err,newApp=CApaAppData::NewL(appEntry, iFs));
+			if (err==KErrNone)
+				{
+				// remove the old one and add the new one in its place
+				if (prev)
+					prev->iNext=newApp;
+				else
+					iAppData=newApp;
+				newApp->iNext = appData->iNext;
+				delete appData;
+				// increment the iterator
+				prev = newApp;
+				}
+			}
+		else
+			prev=appData;
+		appData=next;
+		}
+	}
+
+EXPORT_C TInt CApaAppList::Count() const
+/** Gets the count of applications present in the app list.
+
+@return The number of applications in the list. */
+
+	{
+	TInt count=0;
+	CApaAppData* appData=iAppData;
+	while (appData)
+		{
+		count++;
+		appData=appData->iNext;
+		}
+	return count;
+	}
+
+EXPORT_C CApaAppData* CApaAppList::FirstApp() const
+/** Gets a pointer to the first application in the list 
+that can use the default screen mode.
+
+@return A pointer to the first application. */
+	{
+	return FirstApp(0);
+	}
+
+EXPORT_C CApaAppData* CApaAppList::FirstApp(TInt aScreenMode) const
+/** Gets a pointer to the first application in the list 
+that can use the specified screen mode.
+
+@param aScreenMode The index of the screen mode. Specifying 
+KIgnoreScreenMode returns the first application in the list, 
+regardless of screen mode.
+@return A pointer to the first application that can use the 
+specified screen mode. */
+	{
+
+	CApaAppData* appData=iValidFirstAppData;
+
+	if(aScreenMode!=KIgnoreScreenMode)
+		{
+		while (appData && !appData->CanUseScreenMode(aScreenMode))
+			appData = appData->iNext;
+		}
+
+	return appData;
+	}
+
+EXPORT_C CApaAppData* CApaAppList::NextApp(const CApaAppData* aApp) const
+/** Gets a pointer to the next application after aApp in the list 
+that can use the default screen mode.
+
+@param aApp A pointer to an application in the list.
+@return A pointer to the next application after aApp in the list 
+that can use the default screen mode.
+@panic APGRFX 12 aApp is NULL. */
+	{
+	return NextApp(aApp,0);
+	}
+
+EXPORT_C CApaAppData* CApaAppList::NextApp(const CApaAppData* aApp, TInt aScreenMode) const
+/** Gets a pointer to the next application after aApp in the list 
+that can use the specified screen mode.
+
+@param aApp A pointer to an application in the list. 
+@param aScreenMode The index of the screen mode. Specifying 
+KIgnoreScreenMode returns the next application in the list, 
+regardless of screen mode.
+@return A pointer to the next application after aApp in the list 
+that can use the specified screen mode.
+@panic APGRFX 12 aApp is NULL. */
+
+	{
+	__ASSERT_ALWAYS(aApp,Panic(EPanicNoAppDataSupplied));
+	//
+	CApaAppData* iApp=aApp->iNext; //lint !e613 Suppress possible use of null pointer - asserted above
+
+	if(aScreenMode!=KIgnoreScreenMode)
+		while (iApp && !iApp->CanUseScreenMode(aScreenMode))
+			iApp = iApp->iNext;
+
+	return iApp;
+	}
+
+EXPORT_C CApaAppData* CApaAppList::AppDataByUid(TUid aAppUid) const
+/** Gets a pointer to the application in the list whose third 
+UID matches the specified UID.
+
+@param aAppUid An application's third UID. 
+@return A pointer to the application, if successful. Null, 
+if no match is found or if KNullUid was specified. */
+	{
+	if (aAppUid==KNullUid)
+		return NULL; // never match null UID as it represents an un-UIDed file
+	CApaAppData* appData=iAppData;
+	while (appData)
+		{
+		if (appData->AppEntry().iUidType[2]==aAppUid)
+			return appData;
+		appData=appData->iNext;
+		}
+	return NULL;
+	}
+
+EXPORT_C CApaAppData* CApaAppList::AppDataByFileName(const TDesC& aFullFileName) const
+/** Gets a pointer to the application in the list whose application
+file name matches the one specified
+
+@param aFullFileName a file name. 
+@return A pointer to the application, if successful. Null, 
+if no match is found or if KNullDesC was specified.
+@internalTechnology
+*/
+	{
+	if (aFullFileName.Length()==0)
+		{
+		return NULL; // never match null UID as it represents an un-UIDed file
+		}
+	CApaAppData* appData=iAppData;
+	while (appData)
+		{
+		if (appData->AppEntry().iFullName.CompareF(aFullFileName)==0)
+			{
+			return appData;
+			}
+		appData=appData->iNext;
+		}
+	return NULL;
+	}
+	
+/**
+Adds a registration file to the iForcedRegistrations array.
+
+@param aRegistrationFile The function takes ownership of the HBufC.
+@internalComponent
+*/
+EXPORT_C void CApaAppList::AddForcedRegistrationL(HBufC* aRegistrationFile)
+	{
+	TInt err = iForcedRegistrations.InsertInOrder(aRegistrationFile, TLinearOrder<HBufC>(CompareStrings));
+	if (err == KErrAlreadyExists) // We silently ignore attempts to insert duplicates
+		{
+		delete aRegistrationFile;
+		}
+	else
+		{
+		User::LeaveIfError(err);
+		}
+	} //lint !e818 Suppress pointer parameter 'aRegistrationFile' could be declared as pointing to const
+	
+EXPORT_C void CApaAppList::ResetForcedRegistrations()
+	{
+	iForcedRegistrations.ResetAndDestroy();
+	}
+
+EXPORT_C TUid CApaAppList::PreferredDataHandlerL(const TDataType& aDataType) const
+/** Finds the preferred application to handle the specified data type.
+
+@param aDataType The data type of interest.
+@return The third UID of the application in the list which has the 
+highest priority for handling the specified data type. A null UID is 
+returned if no application in the list can handle the specified data type. */
+	{
+	TInt dummy;
+	return PreferredDataHandlerL(aDataType, NULL, dummy);
+	}
+	
+EXPORT_C TUid CApaAppList::PreferredDataHandlerL(const TDataType& aDataType, const TUid* aServiceUid, TInt& aPriority) const
+/** Finds the preferred application to handle the specified data type.
+
+@param aDataType The data type of interest.
+@param aServiceUid The optional service UID.
+@param aPriority The priority associated with the returned app.
+@return The third UID of the application in the list which has the 
+highest priority for handling a combination of the specified data type
+and service. A null UID is returned if no application in the list can
+handle the combination of specified data type and service.
+@internalComponent
+*/
+	{
+	// If there is a service uid we first try to use the service specific list
+	// of datatypes
+	if (aServiceUid)
+		{
+		CApaAppData* appData=iAppData;
+		aPriority=KDataTypePriorityNotSupported;
+		TUid uid={0};
+		while (appData)
+			{
+			TInt priority = appData->ImplementsServiceWithDataType(*aServiceUid, aDataType);
+			if (priority > aPriority)
+				{
+				aPriority=priority;
+				uid=appData->AppEntry().iUidType[2];
+				}
+			appData=appData->iNext;
+			}
+		if (aPriority != KDataTypePriorityNotSupported)
+			{
+			return uid;
+			}
+		}
+	
+	CApaAppData* appData=iAppData;
+	aPriority=KDataTypePriorityNotSupported;
+	TUid uid={0};
+	while (appData)
+		{
+		TInt priority=appData->DataType(aDataType);
+		if ((priority > aPriority) &&
+			(!aServiceUid || (aServiceUid && appData->ImplementsService(*aServiceUid))))
+			{
+			aPriority=priority;
+			uid=appData->AppEntry().iUidType[2];
+			}
+		appData=appData->iNext;
+		}
+	return uid;
+	}
+  
+void CApaAppList::DeleteAppData()
+	{
+	iValidFirstAppData = NULL;
+	iFlags &= ~EFirstScanComplete;
+	iFlags &= ~EAppListHasChanged;
+	iFlags &= ~ELangChangePending;
+	
+	CApaAppData* next = NULL;
+	for (CApaAppData* appData=iAppData; appData; appData = next)
+		{
+		next = appData->iNext;
+		delete appData;
+		}
+	iAppData = NULL;
+	}
+
+void CApaAppList::ScanComplete()
+	{
+	if (!(iFlags & EFirstScanComplete) && iObserver)
+		iObserver->InitialListPopulationComplete();
+	iValidFirstAppData = iAppData;
+	iFlags|=EFirstScanComplete;
+	iNNAInstallation = EFalse;
+	}
+
+/**
+ *
+ * Tests whether the first scan for list of Apps has completed.
+ *
+ * @return   "TBool"
+ *            True, if the first scan for list of Apps has completed; false, otherwise.
+ * @internalComponent
+ */
+EXPORT_C TBool CApaAppList::IsFirstScanComplete() const
+	{
+	return iFlags&EFirstScanComplete;
+	}
+
+EXPORT_C TBool CApaAppList::AppScanInProgress() const
+/** @internalComponent */
+	{
+	return (iAppIdler!=NULL) && iAppIdler->IsActive();
+	}
+
+/**
+@internalComponent
+*/
+EXPORT_C CBufFlat* CApaAppList::ServiceArrayBufferL(TUid aAppUid) const
+	{
+	CApaAppData* app = FirstApp(KIgnoreScreenMode);
+	while (app && app->AppEntry().iUidType[2] != aAppUid)
+		{
+		app = NextApp(app, KIgnoreScreenMode);
+		}
+
+	if (app)
+		{
+		if (!app->RegistrationFileUsed())
+			{
+			User::Leave(KErrNotSupported);
+			}
+		if (app->iServiceArray)
+			{
+			CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
+			CleanupStack::PushL(buf);
+			RBufWriteStream writeStream(*buf);
+			writeStream << *(app->iServiceArray);
+			writeStream.CommitL();
+			writeStream.Release();
+			CleanupStack::Pop(buf);
+			return buf;
+			}
+		}
+	User::Leave(KErrNotFound);
+	return NULL; // to keep compiler happy
+	}
+
+/**
+@internalComponent
+*/
+EXPORT_C CBufFlat* CApaAppList::ServiceUidBufferL(TUid aAppUid) const
+	{
+	CApaAppData* app = FirstApp(KIgnoreScreenMode);
+	while (app && app->AppEntry().iUidType[2] != aAppUid)
+		{
+		app = NextApp(app, KIgnoreScreenMode);
+		}
+
+	if (app)
+		{
+		if (!app->RegistrationFileUsed())
+			{
+			User::Leave(KErrNotSupported);
+			}
+		if (app->iServiceArray)
+			{
+			CArrayFixFlat<TApaAppServiceInfo>& serviceArray = *(app->iServiceArray);
+			CArrayFixFlat<TUid>* uidArray = new(ELeave) CArrayFixFlat<TUid>(4);
+			CleanupStack::PushL(uidArray);
+			for (TInt i = serviceArray.Count()-1; i >= 0; i--)
+				{
+				uidArray->AppendL(serviceArray[i].Uid());
+				}
+			CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
+			CleanupStack::PushL(buf);
+			RBufWriteStream writeStream(*buf);
+			writeStream << *uidArray;
+			writeStream.CommitL();
+			writeStream.Release();
+			CleanupStack::Pop(buf);
+			CleanupStack::PopAndDestroy(uidArray);
+			return buf;
+			}
+		}
+	User::Leave(KErrNotFound);
+	return NULL; // to keep compiler happy
+	}
+
+/**
+@internalComponent
+*/
+EXPORT_C CBufFlat* CApaAppList::ServiceOpaqueDataBufferL(TUid aAppUid, TUid aServiceUid) const
+	{
+	CApaAppData* app = FirstApp(KIgnoreScreenMode);
+	while (app && app->AppEntry().iUidType[2] != aAppUid)
+		{
+		app = NextApp(app, KIgnoreScreenMode);
+		}
+
+	if (app)
+		{
+		if (!app->RegistrationFileUsed())
+			{
+			User::Leave(KErrNotSupported);
+			}
+		if (app->iServiceArray)
+			{
+			CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
+			CArrayFixFlat<TApaAppServiceInfo>& serviceArray = *(app->iServiceArray);
+			for (TInt i = serviceArray.Count()-1; i >= 0; i--)
+				{
+				const TApaAppServiceInfo& infoRef = serviceArray[i];
+				if (infoRef.Uid() == aServiceUid)
+					{
+					if (!implArray)
+						{
+						implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
+						CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
+						}
+					CArrayFixFlat<TDataTypeWithPriority>* dummy =
+						new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
+					CleanupStack::PushL(dummy);					
+					TApaAppServiceInfo info(aServiceUid, dummy, infoRef.OpaqueData().AllocLC());
+					implArray->AppendL(info);
+					CleanupStack::Pop(CONST_CAST(TDesC8*,&info.OpaqueData()));
+					CleanupStack::Pop(dummy);
+					}
+				}
+			if (implArray)
+				{
+				CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
+				CleanupStack::PushL(buf);
+				RBufWriteStream writeStream(*buf);
+				writeStream << *implArray;
+				writeStream.CommitL();
+				writeStream.Release();
+				CleanupStack::Pop(buf);
+				CleanupStack::PopAndDestroy(implArray);
+				return buf;
+				}
+			}
+		}
+	User::Leave(KErrNotFound);
+	return NULL; // to keep compiler happy
+	}
+
+/**
+@internalComponent
+*/
+EXPORT_C CBufFlat* CApaAppList::ServiceImplArrayBufferL(TUid aServiceUid) const
+	{
+	CApaAppData* app = FirstApp(KIgnoreScreenMode);
+	// build an array containing all implementations of the service identified by aServiceUid
+	CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
+	while (app)
+		{
+		if (app->iServiceArray)
+			{
+			for (TInt i = app->iServiceArray->Count()-1; i >= 0; i--)
+				{
+				const TApaAppServiceInfo& infoRef = (*app->iServiceArray)[i];
+				if (infoRef.Uid() == aServiceUid)
+					{
+					if (!implArray)
+						{
+						implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
+						CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
+						}
+					CArrayFixFlat<TDataTypeWithPriority>* datatypes = DataTypeArrayDeepCopyLC(infoRef.DataTypes());
+					HBufC8* data = infoRef.OpaqueData().AllocLC();
+					TApaAppServiceInfo info(app->AppEntry().iUidType[2], datatypes, data);
+					implArray->AppendL(info);
+					CleanupStack::Pop(data);
+					CleanupStack::Pop(datatypes);
+					}
+				}
+			}
+		app = NextApp(app, KIgnoreScreenMode);
+		}
+
+	if (implArray)
+		{
+		CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
+		CleanupStack::PushL(buf);
+		RBufWriteStream writeStream(*buf);
+		writeStream << *(implArray);
+		writeStream.CommitL();
+		writeStream.Release();
+		CleanupStack::Pop(buf);
+		CleanupStack::PopAndDestroy(implArray);
+		return buf;
+		}
+	User::Leave(KErrNotFound);
+	return NULL; // to keep compiler happy
+	}
+
+EXPORT_C CBufFlat* CApaAppList::ServiceImplArrayBufferL(TUid aServiceUid, const TDataType& aDataType) const
+	{
+	CApaAppData* app = FirstApp(KIgnoreScreenMode);
+	// build an array containing all implementations of the service identified by aServiceUid
+	CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
+	while (app)
+		{
+		if (app->iServiceArray)
+			{
+			for (TInt i = app->iServiceArray->Count()-1; i >= 0; i--)
+				{
+				const TApaAppServiceInfo& infoRef = (*app->iServiceArray)[i];
+				if (infoRef.Uid() == aServiceUid)
+					{
+				 	if (KDataTypePriorityNotSupported != app->DataType(aDataType, infoRef.DataTypes()))
+						{
+						if (!implArray)
+							{
+							implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
+							CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
+							}
+						CArrayFixFlat<TDataTypeWithPriority>* datatypes = DataTypeArrayDeepCopyLC(infoRef.DataTypes());
+						HBufC8* data = infoRef.OpaqueData().AllocLC();
+						TApaAppServiceInfo info(app->AppEntry().iUidType[2], datatypes, data);
+						implArray->AppendL(info);
+						CleanupStack::Pop(data);
+						CleanupStack::Pop(datatypes);
+						}
+					}
+				}
+			}
+		app = NextApp(app, KIgnoreScreenMode);
+		}
+
+	if (implArray)
+		{
+		CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
+		CleanupStack::PushL(buf);
+		RBufWriteStream writeStream(*buf);
+		writeStream << *(implArray);
+		writeStream.CommitL();
+		writeStream.Release();
+		CleanupStack::Pop(buf);
+		CleanupStack::PopAndDestroy(implArray);
+		return buf;
+		}
+	User::Leave(KErrNotFound);
+	return NULL; // to keep compiler happy
+	}
+	
+CArrayFixFlat<TDataTypeWithPriority>* CApaAppList::DataTypeArrayDeepCopyLC(const CArrayFixFlat<TDataTypeWithPriority>& aOriginal) const
+	{
+	CArrayFixFlat<TDataTypeWithPriority>* result = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
+	CleanupStack::PushL(result);
+	TInt ii = 0;
+	TInt end = aOriginal.Count();
+	while (ii < end)
+		{
+		result->AppendL(aOriginal[ii]);
+		ii++;
+		}
+	return result;
+	}
+	
+EXPORT_C TInt CApaAppList::CompareStrings(const HBufC& aFirst, const HBufC& aSecond)
+	{
+	return aFirst.CompareF(aSecond);
+	}
+
+EXPORT_C CApaAppList* CApaAppList::Self()
+	{ // static
+	return STATIC_CAST(CApaAppList*,Dll::Tls());
+	}
+	
+/*EXPORT_C*/ RFs& CApaAppList::ShareProtectedFileServer()
+	{
+	return iFsShareProtected; //lint !e1536 Exposing low access member - need to consider a redesign or design clarification here(iFsShareProtected should be owned be the one that needs it) but postpone for now as that may require large changes
+	}
+	
+CApaAppIconArray* CApaAppList::LoadDefaultIconsL() const
+	{
+	CApaIconLoader* iconLoader = CApaIconLoader::NewLC(iFs);
+	CApaAppIconArray* icons = CApaAppIconArray::NewRealDefaultIconsLC(KNumberOfIconsInDefaultMbm,*iDefaultAppIconMbmFileName, *iconLoader);
+	const TBool badMbmEntryInfo = !icons->LoadIconsL();
+	if(badMbmEntryInfo)
+		{
+		CleanupStack::PopAndDestroy(2,iconLoader);
+		return CApaAppIconArray::NewL();
+		}
+	else
+		{
+		CleanupStack::Pop(icons);
+		CleanupStack::PopAndDestroy(iconLoader);
+		}
+	return icons;
+	}
+
+void CApaAppList::AcquireDefaultIconArrayL() const
+	{
+	ASSERT(iDefaultIconUsageCount >= 0);
+	if (iDefaultIconUsageCount == 0)
+		{
+		iDefaultIconArray = LoadDefaultIconsL();
+		}
+	++iDefaultIconUsageCount;
+	}
+
+// Should NEVER be called by an object that does not call AcquireDefaultIconArrayL and
+// ReleaseDefaultIconArray at the beginning and end of its lifetime respectively
+const CApaAppIconArray& CApaAppList::DefaultIconArray() const
+	{
+	__ASSERT_ALWAYS(iDefaultIconArray, Panic(EPanicNullPointer));
+	return *iDefaultIconArray;
+	}
+
+void CApaAppList::ReleaseDefaultIconArray() const
+	{
+	ASSERT(iDefaultIconUsageCount > 0);
+	if(0 == --iDefaultIconUsageCount)
+		{
+		delete iDefaultIconArray;
+		iDefaultIconArray = NULL;		
+		}
+	}
+	
+// DEF077478 - Required to update the default icons that the app list holds.
+void CApaAppList::UpdateDefaultIconsL()
+	{
+	CApaAppIconArray* iconArray = LoadDefaultIconsL();
+	if (iconArray)
+		{
+		delete iDefaultIconArray;
+		iDefaultIconArray = iconArray;
+		}
+	}
+
+void CApaAppList::DeleteAppListStorer()
+	{
+	delete iAppListStorer;
+	iAppListStorer = NULL;
+	}
+
+void CApaAppList::DeleteAppIconLoader()
+	{
+	delete iAppIconLoader;
+	iAppIconLoader = NULL;
+	}
+
+void CApaAppList::InitiateStoringOfAppList()
+	{
+	ScanComplete();	
+	NotifyObserver();
+	iFlags &= ~ENotifyUpdateOnFirstScanComplete;
+	// now that the scan is finished, iDefaultAppIconMbmFileName is deleted
+	delete iDefaultAppIconMbmFileName;
+	iDefaultAppIconMbmFileName=NULL;
+	// if applist has not changed and AppsList_Backup.bin file exists then it is replaced back to AppsList.bin
+	if (!(iFlags & EAppListHasChanged) && BaflUtils::FileExists(iFs, iAppsListCacheBackUpFileName))
+		{
+		TInt replaceError = iFs.Replace(iAppsListCacheBackUpFileName, iAppsListCacheFileName);
+		if (replaceError == KErrNone)
+			{
+			return;
+			}
+		}
+    iFlags &= ~EAppListHasChanged;
+	iFs.Delete(iAppsListCacheBackUpFileName);
+	TInt err = iFs.MkDir(iAppsListCachePath);
+	if (err == KErrNone || err == KErrAlreadyExists)
+		{
+		TRAP(err, StoreL());
+		if (err)
+			{
+			DeleteAppListStorer();
+			}
+		}
+	}
+//
+// Class CApaAppListStorer
+//
+
+CApaAppList::CApaAppListStorer::CApaAppListStorer(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList) : CActive(EPriorityIdle), iCurrentAppData(aFirstAppData), iFs(aFs), iAppList(aAppList)
+	{
+	}
+
+CApaAppList::CApaAppListStorer::~CApaAppListStorer()
+	{
+	Cancel();
+	iWriteStream.Close();
+	iFs.Delete(iTempFilename);
+	iTimer.Close();
+	iCurrentAppData = NULL;
+	}
+
+CApaAppList::CApaAppListStorer* CApaAppList::CApaAppListStorer::NewL(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList)
+	{
+	CApaAppListStorer* self = new(ELeave) CApaAppListStorer(aFirstAppData, aFs, aAppList);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CApaAppList::CApaAppListStorer::ConstructL()
+	{
+	User::LeaveIfError(iTimer.CreateLocal());
+	CActiveScheduler::Add(this);
+	}
+
+void CApaAppList::CApaAppListStorer::StartL(const TTimeIntervalMicroSeconds32& aDelay)
+	{
+	User::LeaveIfError(iWriteStream.Temp(iFs, iAppList.iAppsListCachePath, iTempFilename, EFileWrite));
+	iWriteStream.WriteInt32L(User::Language());
+
+#if defined (SYMBIAN_BAFL_SYSUTIL)
+	//Write a cache of the ROM version to a separate stream
+	//Build the filename for the cache file
+	TInt maxSizeofFileName = iAppList.iAppsListCachePath.Length() + KROMVersionStringCacheFileName().Length();
+	RBuf romVersionCacheFileName;
+	romVersionCacheFileName.CreateL(maxSizeofFileName);
+	romVersionCacheFileName.CleanupClosePushL();
+	romVersionCacheFileName.Append(iAppList.iAppsListCachePath);
+	romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
+	
+	RFileWriteStream romVerStream;
+	User::LeaveIfError(romVerStream.Replace(iFs,romVersionCacheFileName,EFileWrite));
+	CleanupClosePushL(romVerStream);
+	
+	// Write the file version that apparc can handle.
+	romVerStream.WriteInt8L(KROMVersionCacheFileMajorVersion);
+	romVerStream.WriteInt8L(KROMVersionCacheFileMinorVersion);
+	romVerStream.WriteInt16L(KROMVersionCacheFileBuildVersion);
+		
+	TBuf<KInfoBufLength> version;
+	SysUtil::GetSWVersion(version);
+	
+	// Write the software version even if SysUtil returns err since all conditions are taken care during restore.
+	romVerStream.WriteUint32L(version.Length());
+	romVerStream.WriteL(version, version.Length());
+	CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
+#endif //(SYMBIAN_BAFL_SYSUTIL)
+	
+	iTimer.After(iStatus, aDelay);
+	SetActive();
+	}
+
+void CApaAppList::CApaAppListStorer::RunL()
+	{ 
+	// iStatus could be KErrNone or negative when timer completes, irrespective of its status we need to re-queue the request.
+	if (iCurrentAppData)
+		{
+		StoreEntryL(iWriteStream, *iCurrentAppData);
+		iCurrentAppData = iCurrentAppData->Next();
+		SetActive();
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, KErrNone);
+		}
+	else
+		{
+		iWriteStream.CommitL();
+		iWriteStream.Close();
+
+		TInt err = iFs.Replace(iTempFilename, iAppList.iAppsListCacheFileName);
+		if (err != KErrNone)
+			{
+			iFs.Delete(iTempFilename);
+			}
+		iAppList.DeleteAppListStorer();
+		}
+	}
+
+void CApaAppList::CApaAppListStorer::StoreEntryL(RWriteStream& aWriteStream, const CApaAppData& aApp)
+	{
+	aWriteStream << aApp;
+	}
+
+void CApaAppList::CApaAppListStorer::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+TInt CApaAppList::CApaAppListStorer::RunError(TInt /*aError*/)
+	{
+	iAppList.DeleteAppListStorer();
+	return KErrNone;
+	}
+
+//
+// Class CApaIdleIconLoader
+//
+
+CApaAppList::CApaIdleIconLoader::CApaIdleIconLoader(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList) : CActive(EPriorityLow), iCurrentAppData(aFirstAppData), iFs(aFs), iAppList(aAppList)
+	{ // Priority is less than KAppListServerPriority, to maintain server responsiveness.
+	CActiveScheduler::Add(this);
+	}
+
+CApaAppList::CApaIdleIconLoader::~CApaIdleIconLoader()
+	{
+	Cancel();
+	iCurrentAppData = NULL;
+	}
+
+void CApaAppList::CApaIdleIconLoader::Start()
+	{
+	SetActive();
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+void CApaAppList::CApaIdleIconLoader::RunL()
+/** if the icons are not already loaded on demand then it would be loaded here. */
+	{
+	while (iCurrentAppData && !iCurrentAppData->MbmIconsRequireLoading())
+		{
+		iCurrentAppData = iCurrentAppData->Next();
+		}
+
+	if(iCurrentAppData)
+		{
+		Start();
+		CApaAppData* const appData = iCurrentAppData;
+		iCurrentAppData = iCurrentAppData->Next();
+		appData->LoadIconsL();
+		}
+	else
+		{
+		iAppList.InitiateStoringOfAppList();
+		iAppList.DeleteAppIconLoader();
+		}
+	}
+
+void CApaAppList::CApaIdleIconLoader::DoCancel()
+	{
+	}
+
+TInt CApaAppList::CApaIdleIconLoader::RunError(TInt /*aError*/)
+	{
+	return KErrNone;
+	}
+
+// ApaUtils
+
+EXPORT_C TBool ApaUtils::HandleAsRegistrationFile(const TUidType& aUidType)
+	{ // static
+	return (aUidType[1].iUid==KUidAppRegistrationFile.iUid ||
+		   aUidType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile);
+	}
+	
+
+//
+// Class CApaLangChangeMonitor
+//
+
+CApaAppList::CApaLangChangeMonitor::~CApaLangChangeMonitor()
+	{	
+	Cancel();
+	iLangNotifier.Close();
+	}
+
+CApaAppList::CApaLangChangeMonitor* CApaAppList::CApaLangChangeMonitor::NewL(CApaAppList& aAppList)
+	{ // static	
+	CApaLangChangeMonitor* self=new(ELeave) CApaLangChangeMonitor(aAppList);
+	self->ConstructL();
+	return self;
+	}
+
+CApaAppList::CApaLangChangeMonitor::CApaLangChangeMonitor(CApaAppList& aAppList)
+	: CActive(EPriorityNormal),
+	iAppList(aAppList)
+	{	
+	iPrevLanguage = User::Language();
+	CActiveScheduler::Add(this);
+	}
+
+void CApaAppList::CApaLangChangeMonitor::ConstructL()
+	{
+	User::LeaveIfError(iLangNotifier.Create());
+	Start();
+	}
+ 
+void CApaAppList::CApaLangChangeMonitor::Start()
+	{
+	iLangNotifier.Logon(iStatus);
+	SetActive();
+	}
+
+void CApaAppList::CApaLangChangeMonitor::DoCancel()
+	{
+	iLangNotifier.LogonCancel();
+	}
+
+void CApaAppList::CApaLangChangeMonitor::RunL()
+	{
+	// Logon to get further events before handling current request.
+	TRequestStatus status = iStatus;
+	Start();
+	
+	// if it is a language change event, start a rescan on app-list.
+	if (status.Int() == EChangesLocale && iPrevLanguage != User::Language())
+		{		
+		iPrevLanguage = User::Language();
+		iAppList.iFlags |= CApaAppList::ELangChangePending;
+		iAppList.StartIdleUpdateL(iAppList.iObserver);
+		}
+	}
+
+TInt CApaAppList::CApaLangChangeMonitor::RunError(TInt /*aError*/)
+	{
+	// Reset ELangChangePending flag if RunL leaves.
+	iAppList.iFlags &= ~CApaAppList::ELangChangePending;
+	// Reset iPrevLanguage to ELangNone if RunL leaves.
+	iPrevLanguage = ELangNone;
+	return KErrNone;
+	}
+
+void CApaAppList::GetAppsListCachePathL()
+	{
+	_LIT(KAppsListCacheFileName, ":\\private\\10003a3f\\AppsListCache\\AppsList.bin");
+	_LIT(KAppsListCacheBackUpFileName, ":\\private\\10003a3f\\AppsListCache\\AppsList_Backup.bin");
+	_LIT(KAppsListCachePath, ":\\private\\10003a3f\\AppsListCache\\");
+	TChar sysDrive = RFs::GetSystemDriveChar();
+	TInt maxSizeofFileName = KAppsListCacheFileName().Length() + 1;
+	iAppsListCacheFileName.CreateL(maxSizeofFileName);
+	iAppsListCacheFileName.Append(sysDrive);
+	iAppsListCacheFileName.Append(KAppsListCacheFileName());
+	maxSizeofFileName = KAppsListCacheBackUpFileName().Length() + 1;
+	iAppsListCacheBackUpFileName.CreateL(maxSizeofFileName);
+	iAppsListCacheBackUpFileName.Append(sysDrive);
+	iAppsListCacheBackUpFileName.Append(KAppsListCacheBackUpFileName());
+	maxSizeofFileName = KAppsListCachePath().Length() + 1;
+	iAppsListCachePath.CreateL(maxSizeofFileName);
+	iAppsListCachePath.Append(sysDrive);
+	iAppsListCachePath.Append(KAppsListCachePath());
+	}
+
+
+// The function transfers ownership of the pointer owned by a CApaAppList to the caller
+// to avoid copying the array.
+
+EXPORT_C CArrayFixFlat<TUid>* CApaAppList::UninstalledAppArray()
+    {
+    CArrayFixFlat<TUid>* uninstalledApps=iUninstalledApps;
+    iUninstalledApps=NULL;
+    return uninstalledApps;
+    }