searchfw/plugins/contactsplugin/src/contactssearcher.cpp
changeset 0 f979ecb2b13e
child 5 42814f902fe6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/searchfw/plugins/contactsplugin/src/contactssearcher.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,1292 @@
+/*
+* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Plugin for contactsplugin information search.
+*
+*/
+
+
+//SYSTEM INCLUDES
+#include <utf.h>
+#include <e32std.h>
+#include <searchcondition.h>
+#include <searchtextsearcher.h>
+#include <searchdocumentid.h>
+#include <searchlightresult.h>
+#include <searchresult.h>
+#include <searchcommon.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <CVPbkContactFieldIterator.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <CVPbkContactLinkArray.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkContactStoreList.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkContactFieldDateTimeData.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactLink.h>
+#include <VPbkEng.rsg>
+#include <VPbkContactStoreUris.h>
+#include <TVPbkWordParserCallbackParam.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <searchpluginobserver.h>
+
+#include <MVPbkContactViewBase.h>
+#include <MVPbkContactStoreInfo.h>
+#include <CVPbkContactViewDefinition.h>
+#include <CVPbkSortOrder.h>
+#include <MVPbkContactViewFiltering.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <contactssearchresource.rsg>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+//USER INCLUDES
+#include "contactssearcher.h"
+#include "contactssearchplugindefines.h"
+#include <featmgr.h>
+//FORWARD DECLARATION
+TInt VPbkParseDataL( TAny* aParam );
+
+
+// ---------------------------------------------------------------------------------
+// 1st phase constructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher* CContactsSearcher::NewL( const RArray<TUid>& aContentIdArray, 
+                                const CSearchCondition& aCondition, 
+                                const TUid& aPluginId,
+                                MSearchPluginObserver& aObserver )
+    {
+	CContactsSearcher* self = new ( ELeave ) CContactsSearcher( aPluginId );
+	CleanupStack::PushL( self );
+	self->ConstructL( aContentIdArray, aCondition,aObserver );
+	CleanupStack::Pop( self );
+	return self;
+    }
+
+
+// ---------------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher::~CContactsSearcher() 
+    {
+    delete iFilterView;
+    delete iContactViewBase;
+	
+	ifSession.Close();
+	if( iCurrentlyOpenStores)
+        {	
+        // Close all the stores opened
+        if(iContactManager)
+        {
+            TRAP_IGNORE(iContactManager->ContactStoresL().CloseAll( *this ));
+        }
+        if(iCurrentlyOpenStores)
+        {
+            const TInt count = iCurrentlyOpenStores->Count();
+            for ( TInt i = count - 1; i >= 0; --i )
+                {
+                iCurrentlyOpenStores->Remove( (*iCurrentlyOpenStores)[i] );
+                }
+           delete iCurrentlyOpenStores;
+		       iCurrentlyOpenStores = NULL;
+        	
+        }
+        }
+    if ( iContactManager )
+        {
+ 		delete iContactManager;
+		iContactManager = NULL;	
+        }
+
+    if ( iTextSearcher )
+        {
+ 		delete iTextSearcher;
+		iTextSearcher = NULL;	
+        }
+        
+   
+    
+   
+    if(iAllContactItemsFromDb)
+    {
+        iAllContactItemsFromDb->ResetAndDestroy();   	
+    	delete iAllContactItemsFromDb;
+    	iAllContactItemsFromDb = NULL;
+    }
+    iContactArrayMapper.Reset();
+    iCotnactDeletedList.Reset();
+   	iHeavyResultsArray.ResetAndDestroy();
+	
+    FeatureManager::UnInitializeLib();
+	
+}
+
+
+// ---------------------------------------------------------------------------
+// A function that returns the contact link at given index of the iContactLinkArray
+// ---------------------------------------------------------------------------
+// 
+//
+MVPbkContactLink* CContactsSearcher::GetContactLinkAtIndexLC(TInt aIndex)
+    {
+    if(aIndex < iContactArrayMapper.Count()  && (EFalse == iCotnactDeletedList[aIndex] ))
+        {
+        if ( iAllContactItemsFromDb ) 
+        	{
+        	return iAllContactItemsFromDb->At(iContactArrayMapper[aIndex]).CloneLC();
+        	}
+        }
+    else
+        {
+  	    return NULL;
+        }
+
+return NULL;
+}
+
+// ---------------------------------------------------------------------------------
+// Releases the resources
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::Destroy() 
+    {
+	if( IsActive() ) 
+	    {
+		CActive::Cancel();
+	    }
+	 else
+	    {
+	    CleanUp(); 	
+	    }   
+	    delete this; 
+}
+
+// ---------------------------------------------------------------------------------
+// Starts the search
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::SearchL()
+    { 
+    iSearchCancelled = EFalse;
+
+    
+   	iHeavyResultsArray.ResetAndDestroy();
+   //	iContactLinkIndexArray.Reset();
+   
+    if(iAllContactItemsFromDb)
+    {
+     
+	   iAllContactItemsFromDb->ResetAndDestroy();   
+    }
+    iContactManager->ContactStoresL().OpenAllL( *this );
+   
+    }
+
+// ---------------------------------------------------------------------------------
+// Returns true,f search is in progress
+// ---------------------------------------------------------------------------------
+//
+TBool CContactsSearcher::IsSearching() 
+    {
+	return IsActive();
+    }
+
+// ---------------------------------------------------------------------------------
+// Cancels the search
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CancelSearch() 
+    {
+    iSearchCancelled = ETrue;
+	CActive::Cancel();
+	
+    }
+
+// ---------------------------------------------------------------------------------
+// Gets the results 
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::GetResultsL( 
+	const RPointerArray<CSearchDocumentId>& aDocumentIdArray )
+    {
+	
+    //Check the aDocumentIdArray
+    // For all the matching documentIds, fetch the corresponding
+    // Heavy Result from iHeavyResultsArray and append it to heavyResultResponse
+	
+	RPointerArray<CSearchResult> heavyResultResponse; 
+	//Search through the aDocumentIdArray, and select those heavy results
+	// which belong to this plugin with the corresponding document id
+	for( TInt j = 0; j < aDocumentIdArray.Count(); j++ ) 
+	    {
+	    TUid pluginId;
+	    pluginId.iUid = aDocumentIdArray[j]->PluginId().iUid;
+	    if ( (  pluginId.iUid == iPluginId.iUid ) &&
+	         (aDocumentIdArray[j]->RepositoryId() == KSearchCClassContactsUid.iUid)
+	       )  
+	        {
+	        
+            TInt myArrayIndex =aDocumentIdArray[j]->DocumentId()  ;
+
+	        heavyResultResponse.AppendL(iHeavyResultsArray[myArrayIndex]);        
+
+	        }             
+	    }
+		
+	iObserver->ResultsRetrieveCompleteL( heavyResultResponse );
+	heavyResultResponse.Reset();
+    }
+
+// ---------------------------------------------------------------------------------
+// Cancels the result retrieval
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CancelResultsRetrieve() 
+    {
+	
+    }
+
+
+//---------------------------------------------------------------------------------
+// Returns the search progress
+//---------------------------------------------------------------------------------
+//
+void CContactsSearcher::GetSearchProgressL( TUid& /*aContentClassId*/, TInt& /*aCurrentDocument*/, TInt& /*aTotalDocuments*/ )
+    {
+	
+    }
+
+
+
+// ---------------------------------------------------------------------------------
+// Called when a result is found matching the search criteria
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::HitL( TInt /*aResult*/ ) 
+    {
+	// If search is still in progress, then process the search result
+	if( !iSearchCancelled ) 
+	    {
+		CSearchDocumentId* searchDocId = NULL;
+		
+		TBuf8<KBufferLength> tempDes; 
+		
+	    
+	    // Set the repository id
+		searchDocId = CSearchDocumentId::NewL( iTotalHits,iPluginId );
+		searchDocId->SetRepositoryIdL( KSearchCClassContactsUid.iUid );
+		CSearchLightResult* searchLightResult = CSearchLightResult::NewL( searchDocId );
+        CleanupStack::PushL(searchLightResult);		
+		searchLightResult->SetContentClassId( KSearchCClassContactsUid );
+		searchLightResult->SetServiceId( KNullUid );
+		
+		 //HBufC8 *repositoryId = HBufC8::NewL( KBufferLength ) ;
+         //repositoryId->Des().Append(KSpace);
+	     searchDocId->SetRepositoryIdL( KSearchCClassContactsUid.iUid );
+         //delete repositoryId; 
+         //repositoryId = NULL;
+	
+		iContactArrayMapper.Append(iCurrentDatatBaseItemIndex - 1);
+		
+	    // Form the heavy result and append it to the iHeavyResultsArray
+	    CSearchResult* tmpHeavyRes = NULL;
+	    tmpHeavyRes = CSearchResult::NewL(searchLightResult);
+	    CleanupStack::PushL(tmpHeavyRes);
+	    //Set the Title for the heavy result
+	    if ( iCurrentTitle )
+	        {
+		    tmpHeavyRes->SetTitleL( *iCurrentTitle );
+	        delete iCurrentTitle; iCurrentTitle = NULL;
+	        }
+	    
+	    //Set the snippet for the heavy result
+	    if ( iCurrentSnippet )
+	        {
+		    tmpHeavyRes->SetSnippetL(*iCurrentSnippet);
+	        delete iCurrentSnippet;iCurrentSnippet = NULL;
+	        }
+	    
+	    // Check if the contact is a phone contact or a sim contact
+	    // Accordingly set the folder id
+	    
+	    TInt tempIndex = iContactArrayMapper[iTotalHits];
+	    TVPbkContactStoreUriPtr uri = iAllContactItemsFromDb->At(tempIndex).ContactStore().StoreProperties().Uri();       
+	    TVPbkContactStoreUriPtr phoneMemoryUri( VPbkContactStoreUris::DefaultCntDbUri() );
+ 
+        if ( uri.Compare( phoneMemoryUri,TVPbkContactStoreUriPtr::EContactStoreUriStoreType) == 0 )
+            {
+             searchLightResult->SetContentFolderId( KSearchCFolderPhoneUid );  
+            }
+        else
+            {
+         
+			searchLightResult->SetContentFolderId( KSearchCFolderSIMUid );         	
+            }
+	    //Set the SetSnippetFormatL
+	    HBufC8 *snippetFormat = HBufC8::NewL( KBufferLength ) ;
+	    snippetFormat->Des().Append(KSpace);
+		tmpHeavyRes->SetSnippetFormatL( snippetFormat->Des() );
+		delete snippetFormat; 
+		snippetFormat = NULL;
+	    
+	    //Append the heavy result to the iHeavyResultsArray
+	    iHeavyResultsArray.AppendL(tmpHeavyRes);
+				
+		// Increment the iTotalHits and call ResultFoundL()
+		iTotalHits++;              
+	    iObserver->ResultFoundL( searchLightResult, iTotalHits, iTotalNumOfContactsSearched );
+
+
+	   CleanupStack::Pop(tmpHeavyRes); 
+	   CleanupStack::Pop(searchLightResult); 
+	   
+
+	   }
+	
+}
+
+HBufC8* CContactsSearcher::LaunchInfoL( const CSearchDocumentId& aDocumentID )
+{
+     if((aDocumentID.PluginId() == iPluginId) &&
+       (aDocumentID.RepositoryId() == KSearchCClassContactsUid.iUid))
+         {
+           //HBufC *temp = HBufC::NewL(KMaxFileName) ;
+           //TPtr docIdPtr = temp->Des();
+								
+           TInt myArrayIndex = aDocumentID.DocumentId();
+		   //CnvUtfConverter::ConvertToUnicodeFromUtf8( docIdPtr,aDocumentID.DocumentId() );
+		   //TLex16 myDocId(docIdPtr);
+	       if(myArrayIndex < iContactArrayMapper.Count()  && (EFalse == iCotnactDeletedList[myArrayIndex] ))
+	    	   {
+                 if ( iAllContactItemsFromDb ) 
+                	 {
+	        	     MVPbkContactLink* launchContact = iAllContactItemsFromDb->At(iContactArrayMapper[myArrayIndex]).CloneLC();
+	                 
+	                 HBufC8 *launchInfo = launchContact->PackLC();
+	                 CleanupStack::Pop();
+	                 CleanupStack::Pop(); 
+	                 delete launchContact;
+	                 launchContact= NULL;
+	                 return launchInfo;
+	                 }
+	    	   }
+	       
+           else
+        	   {
+               User::Leave( KErrNotFound );
+        	   }
+         
+         }
+     
+     return NULL;
+     
+	
+}
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreListObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::OpenComplete()
+    {
+     // If atleast one store is ready, 
+     //       set iStoreReadyForAccessing = ETrue so that we can start the serach    
+     // else
+     //       Finish the search as no stores are available 
+     if(iAtLeastOneStoreReady)
+        {
+        iStoreReadyForAccessing = ETrue;
+        TRequestStatus* status = &iStatus;
+    	User::RequestComplete( status, KErrNone );
+    	SetActive();
+    
+        }
+    else
+        {
+        //No stores available, so set the appropriate flag
+        iNoContactStoreAvailable = ETrue;	
+        }
+
+  
+    }
+    
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::StoreReady(MVPbkContactStore& aStore)
+    {
+    // This function is called every time a store is ready to be 
+    // accessed.
+    const TDesC& uri = aStore.StoreProperties().Uri().UriDes();
+    if ( !iCurrentlyOpenStores->IsIncluded( uri ) )
+        {
+        TRAP_IGNORE(iCurrentlyOpenStores->AppendL( uri ));
+        }
+    // We know that atleast one store is ready, so we can set this flag to ETrue
+    iAtLeastOneStoreReady = ETrue;
+     
+    
+    }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::StoreUnavailable(
+        MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/)
+    {
+        //The store is not availble..so do notthing....
+        //TRequestStatus* status = &iStatus;
+        //User::RequestComplete( status, KErrNone );
+     	//SetActive();
+    }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::HandleStoreEventL(MVPbkContactStore& aContactStore, 
+                TVPbkContactStoreEvent aStoreEvent)
+    {
+    
+    //if there is deletetion of contact, then we need to update
+    MVPbkContactStore* storeInList = iContactManager->ContactStoresL().Find(aContactStore.StoreProperties().Uri());
+	  TInt contactLocation = 0;
+	if (storeInList !=NULL)
+	{
+		switch(aStoreEvent.iEventType)
+		{
+			case TVPbkContactStoreEvent::EContactDeleted:
+			contactLocation =  iAllContactItemsFromDb->Find(*aStoreEvent.iContactLink);	
+			if( KErrNotFound != contactLocation)
+			{
+				TInt tempLoc = iContactArrayMapper.Find(contactLocation);
+				if( KErrNotFound != tempLoc)
+				{
+					iCotnactDeletedList[tempLoc] = ETrue;
+				}
+			}
+			break;
+			
+			default:
+				break;
+		}
+			
+	}
+      // Dont't show store events
+     TRequestStatus* status = &iStatus;
+     User::RequestComplete( status, KErrNone );
+     SetActive();
+    }
+
+// ---------------------------------------------------------------------------
+//  Callback Method.Called when one Retrieve operation is complete
+// ---------------------------------------------------------------------------
+//   
+void CContactsSearcher::VPbkSingleContactOperationComplete(
+        MVPbkContactOperationBase& /*aOperation*/, MVPbkStoreContact* aContact)
+    {
+
+    delete iVPbkOperation;
+    iVPbkOperation = NULL;
+    
+    // Delete the retrieved link
+    //iAllContactItemsFromDb->Delete( iCurrentDatatBaseItemIndex );
+    
+    // Handle the fetched contact....
+    TRAPD( res, HandleRetrievedContactL( aContact ) );
+    if ( res != KErrNone )
+        {
+    
+        }
+    
+    if(iAllContactsSearched)
+        {
+        TRequestStatus* status = &iStatus;
+	    User::RequestComplete( status, KErrNone );
+	    SetActive();
+	   
+        }
+        
+    }
+    
+// ---------------------------------------------------------------------------
+//  Callback Method.Called when one Retrieve operation fails.
+// ---------------------------------------------------------------------------
+//   
+void CContactsSearcher::VPbkSingleContactOperationFailed(
+        MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
+    {
+    //delete the operation, since its completed
+    delete iVPbkOperation;
+    iVPbkOperation = NULL;
+    
+    }
+
+
+
+// ---------------------------------------------------------------------------------
+// Implements cancellation of an outstanding request.
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::DoCancel() 
+    {
+	
+    }
+
+
+// ---------------------------------------------------------------------------------
+// The function is called by the active scheduler 
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::RunL() 
+    {
+    
+	if(  !DoActualSearchL() )
+	    {      
+	    ReportFinishedL();   
+    	
+	    }
+	
+    }
+
+// ---------------------------------------------------------------------------------
+// Called in case of any errros 
+// ---------------------------------------------------------------------------------
+//
+TInt CContactsSearcher::RunError(TInt /*aError*/) 
+    {
+	return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------------
+// CContactsSearcher::CContactsSearcher() 
+// Constructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher::CContactsSearcher( const TUid& aPluginId ) :
+	CActive( CActive::EPriorityStandard ), 
+	iPluginId( aPluginId ),
+	iTotalNumOfContactsSearched(0),
+	iTotalHits(0),
+	iStoreReadyForAccessing(EFalse),
+    iAtLeastOneStoreReady(EFalse),
+    iAllContactsSearched (EFalse),
+    iNoContactStoreAvailable (EFalse),
+    iSearchStarted (EFalse),
+    iSearchCancelled(EFalse)
+    {
+	CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------------
+// CContactsSearcher::ConstructL() 
+// 2nd phase constructor
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::ConstructL( const RArray<TUid>& /*aContentIdArray*/, 
+		                             const CSearchCondition& aCondition,
+		                             MSearchPluginObserver& aObserver ) 
+    {
+
+    iObserver = &aObserver;
+	User::LeaveIfError( ifSession.Connect() );
+
+	// initialize virtual phonebook with phonebook and sim contact uris.
+	CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC();
+	uriArray->AppendL( TVPbkContactStoreUriPtr(VPbkContactStoreUris::DefaultCntDbUri()));
+    uriArray->AppendL( TVPbkContactStoreUriPtr( VPbkContactStoreUris::SimGlobalAdnUri() ) );
+    
+    
+    iContactManager = CVPbkContactManager::NewL(*uriArray);
+    CleanupStack::PopAndDestroy(uriArray); 
+    
+    // Create the container for currently open stores
+    iCurrentlyOpenStores = CVPbkContactStoreUriArray::NewL();
+     
+    // create containers for holding the contacts data      
+    iAllContactItemsFromDb = CVPbkContactLinkArray::NewL();
+   
+    
+    //Create the text searcher
+ 	SetPriority( EPriorityStandard );
+	iTextSearcher = CSearchTextSearcher::NewL( *this );
+    iTextSearcher->SetParametersL( aCondition );
+	
+    iIsFilterView = EFalse;
+    FeatureManager::InitializeLibL();
+    }
+
+// ---------------------------------------------------------------------------------
+// Called when search is finished
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::ReportFinishedL()
+    {
+        //Search is completed, call the appropriate function
+        for( TInt j = 0; j < iHeavyResultsArray.Count(); j++ ) 
+        {
+        	
+           iCotnactDeletedList.Append(EFalse);  
+        }
+		iObserver->SearchCompletedL( iTotalHits, iTotalNumOfContactsSearched );
+       
+    }
+
+// ---------------------------------------------------------------------------------
+// Will be called when the CActive::Cancel() is called.. by DoCancel()
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CleanUp() 
+    {	
+    //Cleanup the resources
+    // delete all the data members owned.
+    
+    delete iCurrentTitle;
+	iCurrentTitle = NULL;	
+    
+    delete iCurrentSnippet;
+	iCurrentSnippet = NULL;	
+    
+    delete iContactsDataTobeSearched ;
+	iContactsDataTobeSearched  = NULL;	
+    
+    delete iCurrentContactDataString;
+	iCurrentContactDataString = NULL;	
+    
+     
+    if( iAllContactItemsFromDb)
+        {
+    	delete iAllContactItemsFromDb;
+    	iAllContactItemsFromDb = NULL ;
+        }
+    
+    
+    if(iFieldTypeRefList )
+        {    
+        iFieldTypeRefList->Reset();
+    	delete iFieldTypeRefList;
+		iFieldTypeRefList = NULL;	
+        }
+     delete iVPbkOperation;
+	 iVPbkOperation = NULL;
+	   
+	 delete iSearchStrings;
+	 iSearchStrings = NULL;
+	   
+	 delete iBufferForQuery;
+	 iBufferForQuery = NULL;
+    
+   
+    
+    }
+
+
+// ---------------------------------------------------------------------------------
+// Does the search for the file.  Called from RunL. 
+// Return:  ETrue: if more note items need to be searched. 
+//          EFalse: otherwise (i.e if iAllContactsSearched is set to true)
+// ---------------------------------------------------------------------------------
+//
+TBool CContactsSearcher::DoActualSearchL()
+	{
+	
+	    if (iNoContactStoreAvailable || iAllContactsSearched )
+	        { 
+	        // Either store is not available, or all data has been searched
+	        // so retrun EFalse
+		    return EFalse; 
+	        }
+	
+    	if(iStoreReadyForAccessing ) 
+	        {   
+            // Start the search if not yet started 	
+	        if(!iSearchStarted)
+	           {
+	   	       iSearchStarted = ETrue;
+		       FetchContactItemsFromDbAndSearchL();
+	 	       }
+	       
+	        }
+	    
+	    return ETrue;
+
+	}
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactFindObserver.
+// When using the FindL, check that the field type of the find result is correct
+// since the underlying db find isnt perfect, ex. uses SQL to optimize the find.
+// Test application doesn't check the contact fields, it might be possible
+// the a field whose type was not given in Find has been matched.
+// ---------------------------------------------------------------------------
+//
+
+// ---------------------------------------------------------------------------
+//  Fetches the contact items from the database.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::FetchContactItemsFromDbAndSearchL(void)
+    {
+    // We just fire a find function with null value to get all the links
+    // in the contact store. Once we get the links, we extract data from them 
+    // to be searched, and then pass the same to the text searcher
+    
+    CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL( iContactManager->FieldTypes() );
+    CleanupStack::PushL( sortOrder );
+        
+    CVPbkContactViewDefinition* viewDef = CVPbkContactViewDefinition::NewL();
+    CleanupStack::PushL( viewDef );
+    viewDef->SetType( EVPbkCompositeView );
+         
+    MVPbkContactStoreList& stores = iContactManager->ContactStoresL();
+    TInt totalNumberOfContacts = 0;
+    for ( TInt i(0); i < iCurrentlyOpenStores->Count(); ++i)
+        {
+   
+        TInt numberOfContacts = stores.Find((*iCurrentlyOpenStores)[i])->StoreInfo().NumberOfContactsL();
+        totalNumberOfContacts += numberOfContacts;
+        if ( numberOfContacts != 0)
+            {
+            CVPbkContactViewDefinition* subViewDef = CVPbkContactViewDefinition::NewL();
+            CleanupStack::PushL( subViewDef );
+            subViewDef->SetUriL( (*iCurrentlyOpenStores)[i].UriDes() );
+            viewDef->AddSubViewL( subViewDef );
+            CleanupStack::Pop( subViewDef ); // Ownership changed.
+            }
+        }
+    if (totalNumberOfContacts == 0)
+        {
+        iAllContactsSearched = ETrue;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    iContactViewBase = iContactManager->CreateContactViewLC( 
+                   *this, *viewDef, *sortOrder );
+                
+    CleanupStack::Pop(); // CreateContactViewLC
+    CleanupStack::PopAndDestroy( viewDef );
+    CleanupStack::PopAndDestroy( sortOrder );
+    }
+    
+
+    
+// ---------------------------------------------------------------------------
+// Handles the operations for a single contact after it is fetched
+// ---------------------------------------------------------------------------
+//   
+void CContactsSearcher::HandleRetrievedContactL( 
+        MVPbkStoreContact* aContact )
+    {
+    
+    // Take the ownership
+    aContact->PushL();
+    
+    MVPbkContactGroup* myContactGroup= aContact->Group();
+    //The retrieved contact can be a contact item or a contact group, Handle accordingly
+    if(NULL == myContactGroup)
+        {
+        // The fetched contact item (and not a contact group.)
+        //Fetch all the editable data of the fetched contact
+        // and pass it to the iTextSearcher for searching	
+        GetDataForSingleContactL( *aContact );
+        iTotalNumOfContactsSearched++;
+        if(!iSearchCancelled)
+            {
+            iTextSearcher->SearchL( *iCurrentContactDataString );	
+            }
+         
+        }
+    else
+        {
+    
+        }
+    
+    CleanupStack::PopAndDestroy(); // aContact
+    if(iCurrentContactDataString)
+       {
+       delete iCurrentContactDataString;
+       iCurrentContactDataString = NULL;
+       }
+   
+   
+    // Start reading next contact
+    if ( iAllContactItemsFromDb)  
+    	{	
+    	if ( !iSearchCancelled && (iAllContactItemsFromDb->Count() > iCurrentDatatBaseItemIndex ))
+	        {
+	        const MVPbkContactLink& link = iAllContactItemsFromDb->At( iCurrentDatatBaseItemIndex );
+	        iCurrentDatatBaseItemIndex++;
+	        
+	        iVPbkOperation = iContactManager->RetrieveContactL( link, *this );
+	        
+	        }
+	   		else
+	        {
+	        // All the contacts have been read so set the iAllContactsSearched flag
+	        iAllContactsSearched = ETrue;
+	       
+		    } 
+    	}
+      
+     
+    }
+   
+    
+// ---------------------------------------------------------------------------
+// Fetches the data from a particular contact 
+// ---------------------------------------------------------------------------
+//     
+void CContactsSearcher::GetDataForSingleContactL( MVPbkBaseContact& aContact )
+    {
+     // Fetches all the editable fields for a particular contact. The AddContactFieldsL() 
+     // function fetches the data for a particular entry of the contact.
+     //  iCurrentContactDataString will contain the final space separated string 
+    if(iCurrentContactDataString)
+        {
+      	delete iCurrentContactDataString;
+      	iCurrentContactDataString = NULL;
+        }
+    delete iCurrentSnippet;
+   	iCurrentSnippet = NULL;
+    
+    // First fetch the last name and first name
+    AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAME);
+    AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAME);
+    AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_COMPANYNAME);
+    
+    // Now the iCurrentContactDataString contains last name and first name. 
+    // This forms  the title for our contact.
+    if(iCurrentContactDataString)
+        {
+        if(iCurrentTitle)
+            {
+        	delete iCurrentTitle;
+        	iCurrentTitle = NULL;
+            }
+        iCurrentTitle = HBufC::NewL(iCurrentContactDataString->Des().Length()); 
+        TPtr ptr( iCurrentTitle->Des() );
+        ptr.Append(iCurrentContactDataString->Des());
+        //delete iCurrentContactDataString; iCurrentContactDataString = NULL;
+        }
+    else
+        {
+        iCurrentTitle = HBufC::NewL(KBufferLength);
+      	TPtr ptr( iCurrentTitle->Des() );
+      	ptr.Append( KUnnamedContact );
+        }
+        
+    if(iCurrentSnippet)
+            {
+        	delete iCurrentSnippet;
+        	iCurrentSnippet = NULL;
+            }
+    
+     // Add the Phone number
+    AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEGEN); 
+          
+	//AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAMEREADING);
+	//AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAMEREADING);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_PREFIX);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SUFFIX);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SECONDNAME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERHOME);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPHOME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLHOME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOHOME  );
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTHOME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETHOME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALHOME);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONHOME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEHOME );
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYHOME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_JOBTITLE); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_COMPANYNAME);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEWORK); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEWORK);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERWORK);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERWORK);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPWORK); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILWORK);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLWORK);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELWORK);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOWORK);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTWORK); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETWORK); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALWORK);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONWORK); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEWORK );
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYWORK);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEGEN);
+	//AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEGEN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERGEN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPGEN);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_POC);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SWIS );
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SIP);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILGEN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTGEN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETGEN);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONGEN);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEGEN);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYGEN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_PAGERNUMBER);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DTMFSTRING);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_WVADDRESS);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DATE);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_NOTE);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_THUMBNAILPIC);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_RINGTONE); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CALLEROBJIMG);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CALLEROBJTEXT);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MIDDLENAME);  
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DEPARTMENT ); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ASSTNAME); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SPOUSE);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CHILDREN); 
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ASSTPHONE);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CARPHONE); 
+    AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ANNIVERSARY);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SYNCCLASS);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LOCPRIVACY);
+	AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_GENLABEL);
+    
+    //Set the snippet if not set yet
+    if(!iCurrentSnippet) 
+        {
+        iCurrentSnippet =HBufC8::NewL(KSpace().Length()); 
+        iCurrentSnippet->Des().Append( KSpace );
+        }        
+   
+}
+
+
+// ---------------------------------------------------------------------------
+// Add the data from contact fields
+// ---------------------------------------------------------------------------
+//     
+void CContactsSearcher::AddContactFieldsL(MVPbkBaseContact& aContact,TInt afieldtype)
+    {
+	 
+	 const MVPbkFieldType*  myContactDataField = 
+        iContactManager->FieldTypes().Find( afieldtype );
+
+    CVPbkBaseContactFieldTypeIterator* itr = 
+        CVPbkBaseContactFieldTypeIterator::NewLC( *myContactDataField, 
+            aContact.Fields() );
+    while ( itr->HasNext() )
+        {
+        
+        const MVPbkBaseContactField* field = itr->Next();
+        // last name field is text data
+        HBufC* fieldToAdd = NULL;
+        
+       //Check if the contact filed is a date field or a text field
+        if( (field->FieldData()).DataType() == EVPbkFieldStorageTypeDateTime)
+            {
+        
+            const MVPbkContactFieldDateTimeData& myDate = MVPbkContactFieldDateTimeData::Cast( field->FieldData() );
+            TTime dateValue = myDate.DateTime();
+            TDateTime  xyz = dateValue.DateTime();
+            TInt yearDate = xyz.Year();
+            TInt monthDate = xyz.Month() + 1; //Add 1,since month starts from 0
+            TInt dayDate = xyz.Day() + 1;//Add 1,since day starts from 0
+                
+            //Form the date filed .. DD/MM/YYYY
+            fieldToAdd = HBufC::NewLC( KMaxFileName );
+		    TPtr fieldToAddPtr( fieldToAdd->Des() );
+		    fieldToAddPtr.AppendNum( dayDate );
+		    fieldToAddPtr.Append( KForwardSlash );
+	    	fieldToAddPtr.AppendNum( monthDate );
+		    fieldToAddPtr.Append( KForwardSlash );
+		
+	    	//The year is shown as YYYY. So append appropriate 
+		   // number of zeros in the year
+		   if(yearDate < 10)
+		       {
+			   fieldToAddPtr.AppendNum(0);
+			   fieldToAddPtr.AppendNum(0);
+			   fieldToAddPtr.AppendNum(0);
+		       }
+		  else if(yearDate < 100)
+		      {
+			  fieldToAddPtr.AppendNum(0);
+			  fieldToAddPtr.AppendNum(0);
+		      }
+		 else if(yearDate < 1000)
+		      {
+		      fieldToAddPtr.AppendNum(0);
+		
+		      }
+		
+		fieldToAddPtr.AppendNum( yearDate );
+		
+			
+		}
+        else if( (field->FieldData()).DataType() == EVPbkFieldStorageTypeText)
+            {
+        	
+            const MVPbkContactFieldTextData& data = 
+            MVPbkContactFieldTextData::Cast( field->FieldData() );
+        
+            fieldToAdd = data.Text().AllocLC();
+            }
+       else
+           {
+           CleanupStack::PopAndDestroy( itr );
+            return;	
+           }
+
+      if(!iCurrentSnippet)
+         {
+        
+         switch(afieldtype)
+		     {
+			
+			 case R_VPBK_FIELD_TYPE_LANDPHONEGEN:
+			 case R_VPBK_FIELD_TYPE_LANDPHONEWORK:
+             case R_VPBK_FIELD_TYPE_LANDPHONEHOME:	
+             case R_VPBK_FIELD_TYPE_MOBILEPHONEWORK:
+             case R_VPBK_FIELD_TYPE_MOBILEPHONEGEN:
+             case R_VPBK_FIELD_TYPE_MOBILEPHONEHOME:		
+		 
+		     if(fieldToAdd->Des().Length())
+                 {
+                 iCurrentSnippet = HBufC8::NewL(KSpace().Length() + fieldToAdd->Des().Length() ) ;
+                 TPtr8 ptr8(iCurrentSnippet->Des()) ;
+                 TPtr16 ptr16(fieldToAdd->Des()) ;
+	             CnvUtfConverter::ConvertFromUnicodeToUtf8( ptr8,ptr16 );
+                 }
+                 break;
+			default:
+	    	     break;
+	     	}
+            
+         	
+        }
+        if(iCurrentContactDataString)
+            {
+            iCurrentContactDataString = iCurrentContactDataString->ReAllocL( 
+                                        iCurrentContactDataString->Length() + 
+                                        KSpace().Length() + fieldToAdd->Des().Length() );	
+                                
+            }
+        else
+            {
+    	    iCurrentContactDataString =HBufC::NewL(KSpace().Length() + fieldToAdd->Des().Length() ) ;
+    
+            }
+   	
+        iCurrentContactDataString->Des().Append( fieldToAdd->Des() );
+        iCurrentContactDataString->Des().Append( KSpace );
+        CleanupStack::PopAndDestroy( fieldToAdd );
+        }
+    
+    CleanupStack::PopAndDestroy( itr );
+
+    }
+
+void CContactsSearcher::ContactViewReadyL(
+                MVPbkContactViewBase& aView )
+    {
+    aView.RemoveObserver( *this );
+    if ( !iIsFilterView )
+        {    
+        iSearchStrings = new( ELeave ) CDesCArrayFlat( 2 );
+        for ( TInt i = 0; i < iTextSearcher->SearchKeyword()->MdcaCount(); ++i )
+            {
+            TPtrC searchWord = iTextSearcher->SearchKeyword()->MdcaPoint( i );
+            TVPbkWordParserCallbackParam param( &searchWord, iSearchStrings );
+            VPbkParseDataL( &param );
+            }
+    
+        if (iSearchStrings->MdcaCount() == 0)
+    	    {
+    	    iSearchStrings->AppendL(KNullDesC);
+    	    }
+		 
+        iFilterView = iContactViewBase->ViewFiltering()->CreateFilteredViewLC(*this, *iSearchStrings, NULL );
+        CleanupStack::Pop();
+        iIsFilterView = ETrue;
+        return;
+        }
+    delete iVPbkOperation;
+    iVPbkOperation = NULL;
+	   
+    delete iSearchStrings;
+    iSearchStrings = NULL;
+	   
+    delete iBufferForQuery;
+    iBufferForQuery = NULL;
+	
+    TInt cnt = aView.ContactCountL();
+    for ( TInt i = 0; i < cnt; ++i )
+        {
+        if ( iAllContactItemsFromDb ) 
+            {
+            iAllContactItemsFromDb->AppendL( aView.CreateLinkLC(i) );	
+            CleanupStack::Pop();
+            }
+        }
+		
+    if ( iAllContactItemsFromDb ) 
+        {
+        if ( iAllContactItemsFromDb->Count() >0)
+            {
+            // If there are still contacts available, then retrieve them one by one
+            const MVPbkContactLink& link = iAllContactItemsFromDb->At( iCurrentDatatBaseItemIndex );
+            iCurrentDatatBaseItemIndex++;
+		        //Retrieve the contact 
+            TRAP_IGNORE( iVPbkOperation = iContactManager->RetrieveContactL( link, *this ) ); 
+            }
+        else
+            {
+            // All contacts searched, set the appropriate flag
+            iAllContactsSearched = ETrue;
+            
+            // Active object needs to be activated.
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone );
+            SetActive();
+            }
+        }
+    }
+// --------------------------------------------------------------------
+//Called when a view is ready for use.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewReady(
+                MVPbkContactViewBase& aView )
+    {
+    TRAP_IGNORE(ContactViewReadyL(aView));
+    }
+
+// --------------------------------------------------------------------
+// Called when a view is unavailable for a while. 
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewUnavailable(
+                MVPbkContactViewBase& aView )
+    {
+	TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+	SetActive();
+	return;
+    }
+
+// --------------------------------------------------------------------
+// Called when a contact has been added to the view. 
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactAddedToView(
+                MVPbkContactViewBase& aView, 
+                TInt aIndex, 
+                const MVPbkContactLink& aContactLink )
+    {
+    }
+
+// --------------------------------------------------------------------
+// Called when an error occurs in the view.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactRemovedFromView(
+                MVPbkContactViewBase& aView, 
+                TInt aIndex, 
+                const MVPbkContactLink& aContactLink )
+    {
+    }
+
+// --------------------------------------------------------------------
+// Called when a contact has been removed from a view.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewError(
+                MVPbkContactViewBase& aView, 
+                TInt aError, 
+                TBool aErrorNotified )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// A function that parser field data into words
+// This function is used as a callback in the iContactManager->FindL()
+// ---------------------------------------------------------------------------
+// 
+TInt VPbkParseDataL( TAny* aParam )
+    {
+    TVPbkWordParserCallbackParam* param = 
+    static_cast<TVPbkWordParserCallbackParam*>( aParam );
+    const TText* ptr = param->iStringToParse->Ptr();
+	const TText* end = ptr + param->iStringToParse->Length();
+	const TText* startOfWord = NULL;
+	
+	if ( FeatureManager::FeatureSupported( KFeatureIdJapanese ) ||
+	     FeatureManager::FeatureSupported( KFeatureIdChinese )  ||
+	     FeatureManager::FeatureSupported( KFeatureIdThai ) )
+	    {
+	    while(ptr != end)
+	        {
+	        if (*ptr >= 0x4e00)
+	            {
+	            TPtrC addWord(ptr, 1);
+	            param->iWordArray->AppendL(addWord);	
+	            }
+		    ptr++;
+	        }
+	    }
+	else
+		{
+	    FOREVER
+		    {
+		    // Other than alpha digit are separators
+		    if (ptr==end || !TChar(*ptr).IsAlphaDigit())
+			    {
+			    if (startOfWord)
+				    {
+				    TPtrC addWord(startOfWord,ptr-startOfWord);
+				    param->iWordArray->AppendL(addWord);
+				    startOfWord=NULL;
+				    }
+			    if (ptr==end)
+				    break;
+			    }
+		    else if (!startOfWord)
+			    startOfWord=ptr;
+		    ptr++;
+		    }
+		}
+	return KErrNone;
+    }    
+
+