predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp
branchRCL_3
changeset 85 38bb213f60ba
parent 74 6b5524b4f673
--- a/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp	Wed Sep 15 11:56:55 2010 +0300
+++ b/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp	Wed Oct 13 14:15:33 2010 +0300
@@ -23,7 +23,26 @@
 #include <collate.h>
 #include <biditext.h>
 
+// Compare functions
+TBool Compare2(const HBufC& aFirst, const HBufC& aSecond)
+    {
+    TPtrC t1(aFirst);
+    TPtrC t2(aSecond);
+    return (t1.Length() > t2.Length());
+    }
 
+TBool Compare3(const TDesC& aFirst, const TDesC& aSecond)
+    {
+    return aFirst == aSecond;
+    }
+
+TBool Compare4(const CPsQuery& aFirst, const CPsQuery& aSecond)
+    {
+    CPsQuery& first = const_cast<CPsQuery&> (aFirst);
+    CPsQuery& second = const_cast<CPsQuery&> (aSecond);
+    
+    return (first.Count() > second.Count());
+    }
 // ============================== MEMBER FUNCTIONS ============================
 
 // ----------------------------------------------------------------------------
@@ -63,14 +82,13 @@
     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
 
     iAlgorithm = aAlgorithm;
-    iKeyMap = iAlgorithm->GetKeyMap();
-    iMaxCount = 0;
-    
+    keyMap = iAlgorithm->GetKeyMap();
+
     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
     }
 
 // ----------------------------------------------------------------------------
-// CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper
+// CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper
 // Destructor
 // ----------------------------------------------------------------------------
 CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
@@ -98,105 +116,90 @@
 // ----------------------------------------------------------------------------
 void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, 
                                                    RPointerArray<CPsQuery>& aPsQuery,
-                                                   TBool aIsSearchInGroup, 
-                                                   const RArray<TInt>& aContactsInGroup, 
-                                                   RPointerArray<CPsData>& aSearchResults,
-                                                   RPointerArray<CPsPattern>& aSearchSeqs)
+                                                   TBool isSearchInGroup, 
+                                                   RArray<TInt>& aContactsInGroup, 
+                                                   RPointerArray<CPsData>& searchResults,
+                                                   RPointerArray<CPsPattern>& searchSeqs,
+                                                   TInt keyboardMode)
     {
+    __LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
 
-    //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
-
-    PRINTQUERYLIST ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL: "), aPsQuery );
-
-    iMaxCount = aSettings.MaxResults();
     // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results
     TSortType sortType = aSettings.GetSortType();
     CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
-    CleanupStack::PushL( filterHelper );
     RPointerArray<CPcsPoolElement> elements;
-    CleanupClosePushL( elements );
 
     iMultiSearchResultsArr.ResetAndDestroy();
 
     // Get the data stores  
-    RPointerArray<TDesC> dataStores;
-    CleanupResetAndDestroyPushL( dataStores );
-    aSettings.SearchUrisL(dataStores);
+    RPointerArray<TDesC> aDataStores;
+    aSettings.SearchUrisL(aDataStores);
 
     // Get the required display fields from the client
     RArray<TInt> requiredDataFields;
-    CleanupClosePushL( requiredDataFields );
     aSettings.DisplayFieldsL(requiredDataFields);
 
-    // Search from cache based on first character of 1st item in query list
+    // Search from cache based on first character
     const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
-    TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
-
+    TInt numValue  = keyMap->PoolIdForCharacter( firstCharItem.Character() );
+    
     // Get the elements from all the databases
-    const TInt dataStoresCount = dataStores.Count(); 
-    for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
+    for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
         {
         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
         iMultiSearchResultsArr.Append(temp);
 
         // Get the contents for this data store
-        TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
+        TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
         if (arrayIndex < 0)
             {
             continue;
             }
         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
-        cache->GetContactsForKeyL(cachePoolId, elements);
+        cache->GetContactsForKeyL(numValue, elements);
 
         // Get the supported data fields for this data store
         RArray<TInt> supportedDataFields;
-        CleanupClosePushL( supportedDataFields );
         cache->GetDataFields(supportedDataFields);
 
-        // Get the filtered data fields for this data store
-        TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL(
-                requiredDataFields, supportedDataFields);
+        // Get the filtered data fields for this data store    		
+        TUint8 filteredDataMatch = FilterDataFieldsL(requiredDataFields, supportedDataFields);
 
         // Filter the results now
-        FilterResultsMultiL(filterHelper, 
-                            elements, 
-                            aPsQuery, 
-                            filteredDataMatch, 
-                            aIsSearchInGroup, 
-                            aContactsInGroup);
+        FilterResultsMultiL(filterHelper, elements, aPsQuery, filteredDataMatch, 
+                            isSearchInGroup, aContactsInGroup, keyboardMode);
 
-        // If alphabetical sorting, get the results for this datastore
+        // If alphabetical sorting, get the results for this datastore               
         if (sortType == EAlphabetical)
             {
             filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
             }
 
         elements.Reset();
-        CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
+        supportedDataFields.Reset();
         }
-    CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
-    CleanupStack::PopAndDestroy( &dataStores );         // ResetAndDestroy
+    aDataStores.ResetAndDestroy();
+    requiredDataFields.Reset();
 
     // If alphabetical sorting, merge the result sets of all datastores
     if (sortType == EAlphabetical)
         {
         // Form the complete searchResults array
-        CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, 
-                                                        aSearchResults);
+        CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, searchResults);
         }
     else
         {
         // Results are already sorted patternbased
-        filterHelper->GetResults(aSearchResults);
+        filterHelper->GetResults(searchResults);
         }
 
     // Get the sorted match sequence list
-    filterHelper->GetPatternsL(aSearchSeqs);
+    filterHelper->GetPatternsL(searchSeqs);
 
-    PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() );
+    PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
 
-    // Cleanup
+    // Cleanup             
     for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
         {
         iMultiSearchResultsArr[i]->Reset();
@@ -205,197 +208,214 @@
         }
 
     iMultiSearchResultsArr.Reset();
-    CleanupStack::PopAndDestroy( &elements ); // Close
-    CleanupStack::PopAndDestroy( filterHelper );
-
-    //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
+    delete filterHelper;
 
     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
+    __LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
     }
 
 // ----------------------------------------------------------------------------
-// CPcsAlgorithm1MultiSearchHelper::SearchMatchSeqMultiL
-// Function adds matches, and locations based on multi query, and data
-// Duplicate locations are allowed (as they are removed later anyway)
-// Post condition locations in index order
+// CPcsAlgorithm2MultiSearchHelper::SearchInputMultiL
+// Function to search match sequences for multi query
 // ----------------------------------------------------------------------------
-void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL( RPointerArray<CPsQuery>& aPsQuery,
-                                                            const TDesC& aData,
-                                                            RPointerArray<TDesC>& aMatchSeq,
-                                                            RArray<TPsMatchLocation>& aMatchLocation )
+void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL(RPointerArray<CPsQuery>& aPsQuery, 
+                                                           TDesC& aData, 
+                                                           RPointerArray<TDesC>& aMatchSet,
+                                                           RArray<TPsMatchLocation>& aMatchLocation)
     {
     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
-
-    TLex lex(aData);
-    while ( !lex.Eos() ) // Search thru all words
-        {
-        TPtrC currentWord = lex.NextToken(); // next word
-
-        const TInt psQueryCount = aPsQuery.Count(); 
-        for ( TInt queryIndex = 0; queryIndex < psQueryCount; ++queryIndex )
-            {
-            CPsQuery* currentQuery = aPsQuery[queryIndex];
-
-            RArray<TInt> matchPos;
-            CleanupClosePushL( matchPos );
-            RArray<TInt> matchLen;
-            CleanupClosePushL( matchLen );
-            
-            if ( iAlgorithm->FindUtilECE()->MatchRefineL( currentWord, *currentQuery, matchPos, matchLen, ETrue ) )
-                {
-                // Some matches found. Add all of them to result array.
-                ASSERT( matchPos.Count() == matchLen.Count() );
-                
-                TInt wordStartPos = lex.Offset() - currentWord.Length();
-                const TInt matchPosCount =  matchPos.Count(); 
-                for ( TInt i = 0 ; i < matchPosCount; ++i )
-                    {
-                    TPsMatchLocation newLocation = { wordStartPos + matchPos[i], matchLen[i], 
-                            TBidiText::TextDirectionality(currentWord) };
-                    aMatchLocation.AppendL( newLocation );
+    CleanupResetAndDestroyPushL( aMatchSet );
+    CleanupClosePushL( aMatchLocation );
+    
+    RPointerArray<HBufC> queryList;
+    ConvertQueryToListL(aPsQuery, queryList);
 
-                    TPtrC matchPart = currentWord.Mid( matchPos[i], matchLen[i] );
-                    CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSeq, matchPart );
-                    }
-                }
-                
-            CleanupStack::PopAndDestroy( &matchLen );
-            CleanupStack::PopAndDestroy( &matchPos );
-            }
+    RPointerArray<HBufC> tempqueryList;
+    // Remember a temporary copy of query list
+    // since we sort the queries
+    for (TInt i = 0; i < queryList.Count(); i++)
+        {
+        tempqueryList.Append(queryList[i]);
         }
-
-    PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
-    }
-
-// ----------------------------------------------------------------------------
-// CPcsAlgorithm2MultiSearchHelper::LookupMatchL
-// ----------------------------------------------------------------------------
-void CPcsAlgorithm2MultiSearchHelper::LookupMatchL( CPsQuery& aSearchQuery,
-    const TDesC& aData, TDes& aMatchedData )
-    {
-    _LIT( KSpace, " " );
-    aMatchedData.Zero();
-    RPointerArray<CPsQuery> queryList = MultiQueryL( aSearchQuery );
-    CleanupResetAndDestroyPushL( queryList );
-    // Convert the individual queries to string form
-    RPointerArray<CPsQuery> mySearchQuery;
-    CleanupResetAndDestroyPushL( mySearchQuery );
-
-    // Remember a temporary copy of query list
-    // Copy the content of searchQuery
-    const TInt searchQueryCount = queryList.Count();
-    for (TInt i = 0; i < searchQueryCount; i++ )
-        {
-        CPsQuery* tempQuery = CPsQuery::NewL();
-        CleanupStack::PushL( tempQuery );
-        iAlgorithm->FindUtilECE()->GetPartOfQueryL( *(queryList[i]), 0,
-            queryList[i]->Count() - 1, *tempQuery );
-        mySearchQuery.AppendL( tempQuery );
-        CleanupStack::Pop( tempQuery ); // ownership transferred
-        }
-
-    // Sort the query items according to the length of each query 
-    TLinearOrder<CPsQuery> rule( CPcsAlgorithm2Utils::CompareLength );
-    mySearchQuery.Sort( rule );
-
     // To hold the match results
     RPointerArray<TDesC> tmpMatchSet;
-    CleanupResetAndDestroyPushL( tmpMatchSet );
+    TBool isMatch = ETrue;
+    TUint32 wordMatches = 0;
 
-    TBool isMatch = ETrue;
-    TInt wordMatches = 0;
-
-    // Reset iWordMatches to zero 
-    ClearWordMatches();
+    // Sort the query items before we search them
+    TLinearOrder<HBufC> rule(Compare2);
+    queryList.Sort(rule);
 
     // Check for each query atleast one data element matches
     // Loop from the last query so that longest match is seen first
-    for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex-- )
+    for (TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex--)
         {
         TBool queryMatch = EFalse;
-        CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
+        HBufC* tmpQuery = queryList[queryIndex];
+        // Get the original query mode corresponding to this query
+        TInt modeIndex = tempqueryList.Find(tmpQuery);
 
-        TInt wordIndex = -1;
-        TLex lex( aData );
+        TLex lex(aData);
 
         // First word
         TPtrC tmpData = lex.NextToken();
 
+        TInt beg = lex.Offset() - tmpData.Length(); // start index of match sequence
+
+        TInt wordIndex = -1;
         // Search thru multiple words
-        while (tmpData.Length() != 0 )
+        while ((tmpData.Length() != 0) && (!queryMatch))
             {
             wordIndex++;
 
-            // Compare the data against query
-            TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL( tmpData,
-                *tmpPsQuery );
+            TPtr ptr = tmpQuery->Des();
 
-            if ( matched )
+            // Perform two checks.
+            // 1. Ensure that the word is not matched against any previous query
+            // 2. If it is the first match to the query
+            TBool isWordMatch = EFalse;
+            TReal val;
+            Math::Pow(val, 2, wordIndex);
+            isWordMatch = wordMatches & (TUint) val;
+
+            if (!isWordMatch)
                 {
-                // Perform two checks.
-                // 1. Ensure that the word is not matched against any previous query
-                // 2. If it is the first match to the query
-                TBool isWordMatch = IsWordMatch( 0, wordIndex );
-
-                // Check if the current word is not matched to any query
-                // For example, there is a contact named "abc a" and query is key2
-                // The key2 could match the first and second 'a'. So it is required to 
-                // check if the current word has aready been matched before.
-
-                if ( !isWordMatch )
+                // Check if no word is matched till now for this query
+                if (!queryMatch)
                     {
-                    // Check if no word is matched for this query till now
-                    if ( !queryMatch )
-                        {
-                        wordMatches++;
-                        queryMatch = ETrue;
-                        SetWordMap( 0, wordIndex );
-                        // Extract matched character sequence and fill in temp array
-                        TInt len = tmpPsQuery->Count();
-                        if ( iAlgorithm->FindUtilECE()->IsChineseWordIncluded(
-                            tmpData ) )
-                            {
-                            // A Chinese word could be matched by serveral keys
-                            // It is hard to know the matched query length. So set it to 1
-                            // as a trick result
-                            len = 1;
-                            }
+                    queryMatch = ETrue;
+                    //set the word match bit
+                    TReal val;
+                    Math::Pow(val, 2, wordIndex);
+                    wordMatches |= (TUint) val;
+                    }
+
+                TPsMatchLocation tempLocation;
+                // check for directionality of the text
+                TBool found(EFalse);
+                TBidiText::TDirectionality dir = TBidiText::TextDirectionality(tmpData, &found);
 
-                        TPtrC seq = tmpData.Left( len );
-                        CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet,
-                            seq );
-                        }
-                    }
+                tempLocation.index = beg;
+                tempLocation.length = 0;
+                tempLocation.direction = dir;
+
+                // Add the match location to the data structure array
+                aMatchLocation.Append(tempLocation);
                 }
+            }
+        // Next word
+        tmpData.Set(lex.NextToken());
+        beg = lex.Offset() - tmpData.Length(); // start index of next word  
 
-            // Next word
-            tmpData.Set( lex.NextToken() );
-            }
 
         // No data element matches the query. Ignore this result.
-        if ( queryMatch == EFalse )
+        if (queryMatch == EFalse)
             {
             isMatch = EFalse;
             break;
             }
         }
 
+    // Count the number of bits set
+    TInt matchCount = 0;
+    matchCount = BitsSet32(wordMatches);
+
     // If match add the element to the result set
-    //  And before adding to the result set, check if there is atleast one match per query
-    if ( isMatch && wordMatches >= mySearchQuery.Count() )
+    // Before adding to the result set, check if there is atleast one match per query
+    // Number of bits set in word matches is atleast equal to total number of queries.
+    if ((isMatch) && (matchCount >= queryList.Count()))
         {
-        const TInt matchCount = tmpMatchSet.Count();
-        for (TInt i = 0; i < matchCount; i++ )
+
+        // Include the match sequences in the final results
+        for (int i = 0; i < tmpMatchSet.Count(); i++)
             {
-            aMatchedData.Append( *tmpMatchSet[i] );
-            aMatchedData.Append( KSpace );
+            TIdentityRelation<TDesC> rule(Compare3);
+            CleanupStack::PushL(tmpMatchSet[i]);
+            if (aMatchSet.Find(tmpMatchSet[i], rule) == KErrNotFound)
+                {
+                aMatchSet.Append(tmpMatchSet[i]);
+                CleanupStack::Pop();
+                }
+            else
+                {
+                CleanupStack::PopAndDestroy();
+                }
             }
-        aMatchedData.TrimRight();
+
+        // Reset tmp match set
+        tmpMatchSet.Reset();
+        }
+    else
+        {
+        tmpMatchSet.ResetAndDestroy();
         }
 
-    CleanupStack::PopAndDestroy( &tmpMatchSet ); // ResetAndDestroy
-    CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
-    CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy
+    // Free the query list
+    queryList.ResetAndDestroy();
+    tempqueryList.Reset();
+    
+    CleanupStack::Pop();
+    CleanupStack::Pop( &aMatchSet );
+
+    PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
+    }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2MultiSearchHelper::ConvertQueryToList
+// Converts the multiple search queries to a list
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2MultiSearchHelper::ConvertQueryToListL(RPointerArray<CPsQuery>& aSearchQuery, 
+                                                          RPointerArray<HBufC>& aQueryList)
+    {
+    for (int queryIndex = 0; queryIndex < aSearchQuery.Count(); queryIndex++)
+        {
+        CPsQuery* query = aSearchQuery[queryIndex];
+
+        HBufC* tmpSearchQuery = HBufC::NewL(KPsQueryMaxLen);
+        TPtr ptr = tmpSearchQuery->Des();
+
+        if (query->KeyboardModeL() == EItut) // ITU
+            {
+            keyMap->GetNumericKeyString(query->QueryAsStringLC(), ptr);
+            CleanupStack::PopAndDestroy();
+            }
+        else if (query->KeyboardModeL() == EQwerty) // QWERTY
+            {
+            ptr = query->QueryAsStringLC();
+            ptr.LowerCase();
+            CleanupStack::PopAndDestroy();
+            }
+        else // UNDEFINED
+            {
+            ExtractQueryL(*query, ptr);
+            ptr.LowerCase();
+            }
+        aQueryList.Append(tmpSearchQuery);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL
+// Converts the input data to the key board mode specified by the query
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL(CPsQuery* aQuery, 
+                                                                  TPtrC aInputData, 
+                                                                  TBuf<KPsQueryMaxLen>& aOutputData)
+    {
+    if (aQuery->KeyboardModeL() == EItut)
+        {
+        keyMap->GetNumericKeyString(aInputData, aOutputData);
+        }
+    else if (aQuery->KeyboardModeL() == EQwerty)
+        {
+        aOutputData = aInputData;
+        aOutputData.LowerCase();
+        }
+    else
+        {
+        ExtractQueryL(aInputData, *aQuery, aOutputData);
+        aOutputData.LowerCase();
+        }
     }
 
 // ----------------------------------------------------------------------------
@@ -403,81 +423,63 @@
 // Subset search function. Refer the above function for more description.
 // ----------------------------------------------------------------------------
 void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
-                                                          RPointerArray<CPcsPoolElement>& aSearchSet,
-                                                          RPointerArray<CPsQuery>& aSearchQuery, 
+                                                          RPointerArray<CPcsPoolElement>& searchSet,
+                                                          RPointerArray<CPsQuery>& searchQuery, 
                                                           TUint8 aFilteredDataMatch,
-                                                          TBool aIsSearchInGroup, 
-                                                          const RArray<TInt>& aContactsInGroup)
+                                                          TBool isSearchInGroup, 
+                                                          RArray<TInt>& aContactsInGroup,
+                                                          TInt keyboardMode)
     {
     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
 
-    //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
-
-    TInt maxcount = 0;
-    
     // Convert the individual queries to string form
     RPointerArray<CPsQuery> mySearchQuery;
-    CleanupResetAndDestroyPushL( mySearchQuery );
 
     // Remember a temporary copy of query list
     // Copy the content of searchQuery
-    const TInt searchQueryCount = aSearchQuery.Count(); 
-    for (TInt i=0; i < searchQueryCount; i++)
+    for (TInt i=0; i<searchQuery.Count(); i++)
         {
         CPsQuery* tempQuery = CPsQuery::NewL();
-        CleanupStack::PushL( tempQuery );
-        iAlgorithm->FindUtilECE()->GetPartOfQueryL(
-                *(aSearchQuery[i]), 0, aSearchQuery[i]->Count()-1, *tempQuery );
-        mySearchQuery.AppendL(tempQuery);
-        CleanupStack::Pop(tempQuery); // ownership transferred
+        iAlgorithm->FindUtilECE()->GetPartOfQueryL(*(searchQuery[i]), 0, 
+                                                   searchQuery[i]->Count()-1, *tempQuery);
+        mySearchQuery.Append(tempQuery);
         }
 
     // Sort the query items according to the length of each query 
-    TLinearOrder<CPsQuery> rule(CPcsAlgorithm2Utils::CompareLength);
+    TLinearOrder<CPsQuery> rule(Compare4);
     mySearchQuery.Sort(rule);
 
     // To hold the match results
     RPointerArray<TDesC> tmpMatchSet;
-    CleanupResetAndDestroyPushL( tmpMatchSet );
 
-    // Parse thru each search set elements and filter the results
-    const TInt searchSetCount = aSearchSet.Count(); 
-    for (TInt index = 0; index < searchSetCount; index++)
+    // Parse thru each search set elements and filter the results    
+    for (int index = 0; index < searchSet.Count(); index++)
         {
-        CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (aSearchSet[index]);
+        CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
         CPsData* psData = poolElement->GetPsData();
         psData->ClearDataMatches();
 
-        // Skip the contact if we are doing a group search and contact doesn't belong to the group
-        if ( aIsSearchInGroup && 
-             aContactsInGroup.Find( psData->Id() ) == KErrNotFound )
-            {
-            continue;
-            }
-        
         TBool isMatch = ETrue;
-        TInt wordMatches = 0;
+        TUint8 wordMatches = 0;
 
         // Reset iWordMatches to zero 
         ClearWordMatches();
 
         // Check for each query atleast one data element matches
         // Loop from the last query so that longest match is seen first
-        for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)
+        for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)            
             {
             TBool queryMatch = EFalse;
             CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
 
-            const TInt dataElementCount = psData->DataElementCount();
-            for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++)
+            for (TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++)
                 {
                 // Filter off data fields not required in search
-                TUint8 bitIndex = 1 << dataIndex;
-                TUint8 filter = bitIndex & aFilteredDataMatch;
-                
-                // Omit the data fields which is not required in search
-                // or not matched with the pool element
-                if ( filter == 0x0 ) 
+                TReal bitIndex;
+                Math::Pow(bitIndex, 2, dataIndex);
+
+                TUint8 filter = (TUint8) bitIndex & aFilteredDataMatch;
+                if (filter == 0x0)
                     {
                     // Move to next data
                     continue;
@@ -495,9 +497,27 @@
                     {
                     wordIndex++;
                     
+                    TPtrC queryPtr = tmpPsQuery->QueryAsStringLC();
+                    TBool matched = EFalse;
+                    
+                    if (keyboardMode == EModeUndefined)
+                        {
+                        matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
+                        }
+                    else if (keyboardMode == EItut)
+                        {
+                        matched = iAlgorithm->FindUtil()->Interface()->
+                                  MatchRefineL(tmpData, queryPtr, ECustomConverter, iAlgorithm);
+                        }
+                    else // Qwerty
+                        {
+                        matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(tmpData, queryPtr);
+                        
+                        }
+                    
+                    CleanupStack::PopAndDestroy(); // queryPtr
+                    
                     // Compare the data against query
-                    TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
-                    
                     if (matched)
                         {
                         psData->SetDataMatch(dataIndex);
@@ -520,18 +540,25 @@
 
                             // Extract matched character sequence and fill in temp array
                             TInt len = tmpPsQuery->Count();
-                            if (iAlgorithm->FindUtilECE()->IsChineseWordIncluded(tmpData))
+                            if (iAlgorithm->FindUtilECE()->IsChineseWord(tmpData))
                                 {
                                 len = 1;
                                 }
 
-                            TPtrC seq = tmpData.Left(len);
-                            CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, seq );
-                            
-                            // TODO: Match seqs could be extracted from actual
-                            //       match locations by using the other overload of
-                            //       CFindUtilChineseECE::MatchRefineL().
-                            //       Currently, match seq data is not used by clients.
+                            HBufC* seq = HBufC::NewL(len);
+                            *seq = tmpData.Mid(0, len);
+
+                            seq->Des().UpperCase();
+                            TIdentityRelation<TDesC> searchRule(Compare3);
+                            if (tmpMatchSet.Find(seq, searchRule) == KErrNotFound)
+                                {
+                                tmpMatchSet.Append(seq);
+                                }
+                            else
+                                {
+                                delete seq;
+                                seq = NULL;
+                                }
                             }
                         }
 
@@ -547,50 +574,112 @@
                 break;
                 }
             }
-        
 
         // If match add the element to the result set
         //  And before adding to the result set, check if there is atleast one match per query
-        if ( isMatch && wordMatches >= mySearchQuery.Count() )
+        if ((isMatch) && (wordMatches >= mySearchQuery.Count()))
             {
-            aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
-            maxcount++;
+            if (isSearchInGroup)
+                {
+                if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
+                    {
+                    aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
+                    }
+                }
+            else
+                {
+                aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
+                }
             }
-        
-        if ( iMaxCount != -1 && maxcount > iMaxCount )
-            {
-            break;
-            }
-        
+
         // Cleanup the match sequence array as 
         // they are stored in pattern details structure
         tmpMatchSet.ResetAndDestroy();
         }
 
-    CleanupStack::PopAndDestroy( &tmpMatchSet );   // ResetAndDestroy
-    CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
-
-    //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
+    mySearchQuery.Reset();
 
     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
     }
 
 // ----------------------------------------------------------------------------
-// CPcsAlgorithm2MultiSearchHelper::SetWordMap
+// CPcsAlgorithm2MultiSearchHelper::SetWordMap()
 // ----------------------------------------------------------------------------
 void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
     {
-    TUint8 val = 1 << aPosition;
-    iWordMatches[aIndex] |= val;
+    TReal val;
+    Math::Pow(val, 2, aPosition);
+
+    iWordMatches[aIndex] |= (TUint8) val;
+    }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2MultiSearchHelper::IsWordMatch()
+// ----------------------------------------------------------------------------
+TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
+    {
+    TReal val;
+    Math::Pow(val, 2, aWordIndex);
+
+    return (iWordMatches[aDataIndex] & (TUint8) val);
     }
 
 // ----------------------------------------------------------------------------
-// CPcsAlgorithm2MultiSearchHelper::IsWordMatch
+// CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
+// Extracts the query as a string. If the mode of query item is ITU numeric
+// character is used. Else the character is used.
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
+    {
+    for (int i = 0; i < aQuery.Count(); i++)
+        {
+        if (aQuery.GetItemAtL(i).Mode() == EItut)
+            {
+            TBuf<KPsQueryMaxLen> outBuf;
+            keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
+            aOutput.Append(outBuf[i]);
+            CleanupStack::PopAndDestroy();
+            }
+        else
+            {
+            aOutput.Append(aQuery.GetItemAtL(i).Character());
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
+// Converts the input data refering the modes in the query.
+// If the mode of query item is ITU numeric character is used. Else the character
+// is used.
 // ----------------------------------------------------------------------------
-TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
+void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
     {
-    TUint8 val = 1 << aWordIndex;
-    return (iWordMatches[aDataIndex] & val);
+    TInt len = -1;
+
+    // Always loop thru the lowest length
+    if (aInput.Length() > aQuery.Count())
+        {
+        len = aQuery.Count();
+        }
+    else
+        {
+        len = aInput.Length();
+        }
+
+    for (int i = 0; i < len; i++)
+        {
+        if (aQuery.GetItemAtL(i).Mode() == EItut)
+            {
+            TBuf<KPsQueryMaxLen> outBuf;
+            keyMap->GetNumericKeyString(aInput, outBuf);
+            aOutput.Append(outBuf[i]);
+            }
+        else
+            {
+            aOutput.Append(aInput[i]);
+            }
+        }
     }
 
 // ----------------------------------------------------------------------------
@@ -610,7 +699,7 @@
     }
 
 // ----------------------------------------------------------------------------
-// CPcsAlgorithm2MultiSearchHelper::ClearWordMatches
+// CPcsAlgorithm2MultiSearchHelper::BitsSet32
 // Function to reset the iWordMatches
 // ----------------------------------------------------------------------------
 void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
@@ -640,14 +729,13 @@
             {
             // Scan the end of the word
             TInt end = beg;
-            while ( end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace() )
+            for (; end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace(); ++end)
                 {
-                end++;
                 }
 
             // Create a new query object and append
             CPsQuery* newQuery = CPsQuery::NewL();
-            for (TInt i = beg; i < end; i++)
+            for (int i = beg; i < end; i++)
                 {
                 CPsQueryItem* item = CPsQueryItem::NewL();
                 item->SetCharacter(aQuery.GetItemAtL(i).Character());
@@ -664,6 +752,35 @@
     return query;
     }
 
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL()
+// Constructs a bit pattern using the required/supported data fields
+// For example, 6, 4 and 27 are supported fields <-- 00000111
+//              6 and 4 are required fields      <-- 00000011
+// Bit pattern returned is 00000011.
+// ----------------------------------------------------------------------------
+TUint8 CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL(RArray<TInt>& aRequiredDataFields, 
+                                                          RArray<TInt>& aSupportedDataFields)
+    {
+    TUint8 filteredMatch = 0x0;
+
+    for (int i = 0; i < aSupportedDataFields.Count(); i++)
+        {
+        for (int j = 0; j < aRequiredDataFields.Count(); j++)
+            {
+            if (aSupportedDataFields[i] == aRequiredDataFields[j])
+                {
+                TReal val;
+                Math::Pow(val, 2, i);
+
+                filteredMatch |= (TUint8) val;
+                }
+            }
+        }
+
+    return filteredMatch;
+    }
+
 // End of file