pimappservices/calendar/server/src/agsextractor.cpp
changeset 0 f979ecb2b13e
child 83 5aadd1120515
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "agsextractor.h"
       
    17 
       
    18 #include "agmsimpleentry.h"
       
    19 #include "agsentrymodel.h"
       
    20 #include "agmrptdef.h"
       
    21 #include "agmutil.h"
       
    22 #include "agssortinstance.h"
       
    23 #include "agsindex.h"
       
    24 #include "agssort.h"
       
    25 
       
    26 // This represents the number of instances that have been found by a next or previous instance
       
    27 // call that could, when sorted into order, appear before the search from instance
       
    28 TInt gPossibleInstancesOutsideRange(0);
       
    29 
       
    30 // ----------------------------CAgnInstanceExtractor------------------------
       
    31 CAgnInstanceExtractor::CAgnInstanceExtractor(TAgnIterator* aIterator, CAgnEntryModel& aEntryModel)
       
    32 	:iEntryModel(aEntryModel), iIterator(aIterator)
       
    33 	{
       
    34 	__ASSERT_ALWAYS(aIterator, Panic(EAgmErrNullPointer));
       
    35 	}
       
    36 
       
    37 CAgnInstanceExtractor::~CAgnInstanceExtractor()
       
    38 	{
       
    39 	delete iIterator;
       
    40 	}
       
    41 
       
    42 #ifdef SYMBIAN_SKIPPED_CALENDAR_ALARMS
       
    43 /** Determines whether to continue the Find Instances search.
       
    44 @param aAlarmedInstanceSearch Whether this is an alarmed instance search
       
    45 @param aSearchRangeEndLocal The local time of the end of the search range
       
    46 @internalComponent
       
    47 */
       
    48 TBool CAgnInstanceExtractor::ContinueSearchL(const TBool aAlarmInstanceSearch, const TTime& aSearchRangeEndLocal) const
       
    49 	{
       
    50 	TBool ret(ETrue);
       
    51 	if (aAlarmInstanceSearch)
       
    52 		{
       
    53 		ret = !iIterator->AtEnd();
       
    54 		}
       
    55 	else
       
    56 		{
       
    57 		ret = !iIterator->AtEnd() 
       
    58 			&& ( (iIterator->CurrentElement().ValidFromTimeLocalL() == Time::NullTTime()) 
       
    59 					|| iIterator->CurrentElement().ValidFromTimeLocalL() <= aSearchRangeEndLocal);
       
    60 		}
       
    61 	return ret;
       
    62 	}
       
    63 
       
    64 /** Inserts an instance into an instance list.
       
    65 @param aAlarmInstanceSearch Whether this is an alarmed instance search
       
    66 @param aInstances The instance is inserted into this list
       
    67 @param aInstance The instance to insert
       
    68 @param aFindInstanceParams Defines the search range
       
    69 @internalComponent
       
    70 */
       
    71 void CAgnInstanceExtractor::InsertInstanceL(const TBool aAlarmInstanceSearch, 
       
    72 											CArrayFix<TAgnSortInstance>& aInstances, 
       
    73 											TAgnSortInstance& aInstance,
       
    74 											const TFindInstanceParams& aFindInstanceParams) const
       
    75 	{
       
    76 	if (aAlarmInstanceSearch)
       
    77 		{	
       
    78 		 if (aInstance.CheckAlarmTimeWithinL(aFindInstanceParams))
       
    79 			 {
       
    80 			 TAgnAlarmSortKey sortKey;	// Only needed for function call below
       
    81 			 aInstances.InsertIsqAllowDuplicatesL(aInstance, sortKey);
       
    82 			 }
       
    83 		}
       
    84 	else
       
    85 		{
       
    86 		if (aInstance.CheckStartAndEndDateOverlap(aFindInstanceParams))
       
    87 			{
       
    88 			aInstances.AppendL(aInstance);
       
    89 			}
       
    90 		}
       
    91 	}
       
    92 #endif
       
    93 
       
    94 /** Finds all instances in a time range that match the filter requirements
       
    95 
       
    96 @param aInstances The instance list to append instances to
       
    97 @param aSearchParams The filter requirements for the instance search
       
    98 
       
    99 @internalComponent
       
   100 */
       
   101 void CAgnInstanceExtractor::FindInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   102 	{		  	
       
   103 	TTime searchRangeStartLocal(aSearchParams.iRangeStart.LocalL());
       
   104 	TTime searchRangeEndLocal(aSearchParams.iRangeEnd.LocalL());
       
   105 	
       
   106 	TTime startTime(searchRangeStartLocal);	
       
   107 	
       
   108 #ifdef SYMBIAN_SKIPPED_CALENDAR_ALARMS
       
   109 	TBool alarmInstanceSearch(EFalse);		
       
   110 	alarmInstanceSearch = aSearchParams.iFilter.IsAlarmedInstanceSearch();
       
   111 	if (alarmInstanceSearch)
       
   112 		{
       
   113 		iIterator->StartL();
       
   114 		}
       
   115 	else
       
   116 		{
       
   117 		TTime startTime(searchRangeStartLocal);
       
   118 		iIterator->GotoL(startTime);
       
   119 		}
       
   120 
       
   121 	TFindInstanceParams findInstanceParams(aSearchParams);
       
   122 	
       
   123 	for (; ContinueSearchL(alarmInstanceSearch, searchRangeEndLocal); iIterator->NextL())
       
   124 		{
       
   125 		const CAgnSimpleEntry& KSimpleEntry(iIterator->CurrentElement());
       
   126 		 
       
   127 		if (alarmInstanceSearch)
       
   128 			{
       
   129 			searchRangeStartLocal = aSearchParams.iRangeStart.LocalL() + KSimpleEntry.AlarmOffset();
       
   130 			searchRangeEndLocal = aSearchParams.iRangeEnd.LocalL() + KSimpleEntry.AlarmOffset();
       
   131 			findInstanceParams.iRangeStart.SetLocalL(searchRangeStartLocal);
       
   132 			findInstanceParams.iRangeEnd.SetLocalL(searchRangeEndLocal);
       
   133 			}
       
   134 				
       
   135 		if(iEntryModel.MatchFullEntryL(KSimpleEntry.EntryId(), aSearchParams))
       
   136    			{
       
   137    			const CAgnRptDef* KRptDef(KSimpleEntry.RptDef());
       
   138    			if (KRptDef)
       
   139    				{	
       
   140    				TTime instanceTime;   				
       
   141    				if (Filter()->RptNextInstanceOnly())
       
   142    					{
       
   143    					// if this flag is set we only want the next instance after the start time
       
   144  					if (KRptDef->NudgeNextInstanceL(searchRangeStartLocal, instanceTime, ETrue) && instanceTime <= searchRangeEndLocal)
       
   145    						 {
       
   146 	   					 TAgnSortInstance instance(KSimpleEntry);
       
   147 	   					 instance.SetL(instanceTime, UndatedTodoTime());
       
   148 	   					 InsertInstanceL(alarmInstanceSearch, aInstances, instance, findInstanceParams);
       
   149 	   					 }
       
   150 	   				}
       
   151    				else
       
   152    					{
       
   153    					// nudge backwards from the end of the search range
       
   154  					TTime fromTime(AgnDateTime::ConvertToLocalTimeL(KSimpleEntry.DurationPlusL(AgnDateTime::ConvertToUtcTimeL(searchRangeEndLocal)) + TTimeIntervalMicroSeconds(1)));
       
   155    					while (KRptDef->NudgePreviousUnexceptedInstanceL(fromTime, instanceTime)
       
   156  							&& (KSimpleEntry.DurationPlusL(instanceTime) >= searchRangeStartLocal) )
       
   157    						{
       
   158    						TAgnSortInstance instance(KSimpleEntry);
       
   159    						instance.SetL(instanceTime, UndatedTodoTime());
       
   160    						InsertInstanceL(alarmInstanceSearch, aInstances, instance, findInstanceParams);
       
   161    						fromTime = instanceTime;
       
   162    						}
       
   163    					}
       
   164    				}
       
   165    			else
       
   166    				{
       
   167    				// It is a non-repeating entry
       
   168    			    TAgnSortInstance instance(KSimpleEntry);
       
   169    			    instance.SetL(KSimpleEntry.EntryTime().LocalL(), UndatedTodoTime());
       
   170    			    InsertInstanceL(alarmInstanceSearch, aInstances, instance, findInstanceParams);
       
   171    				}
       
   172    			}
       
   173 		}
       
   174 	
       
   175 #else	
       
   176 	for (iIterator->GotoL(startTime); !iIterator->AtEnd() && ( (iIterator->CurrentElement().ValidFromTimeLocalL() == Time::NullTTime()) || iIterator->CurrentElement().ValidFromTimeLocalL() <= searchRangeEndLocal) ; iIterator->NextL())
       
   177 		{
       
   178 		const CAgnSimpleEntry& KSimpleEntry(iIterator->CurrentElement());
       
   179 		if(iEntryModel.MatchFullEntryL(KSimpleEntry.EntryId(), aSearchParams))
       
   180    			{
       
   181    			const CAgnRptDef* KRptDef(KSimpleEntry.RptDef());
       
   182    			if (KRptDef)
       
   183    				{	
       
   184    				TTime instanceTime;   				
       
   185    				if (Filter()->RptNextInstanceOnly())
       
   186    					{
       
   187    					// if this flag is set we only want the next instance after the start time
       
   188  					if (KRptDef->NudgeNextInstanceL(searchRangeStartLocal, instanceTime, ETrue) && instanceTime <= searchRangeEndLocal)
       
   189    						 {
       
   190    						 TAgnSortInstance instance(KSimpleEntry);
       
   191    						 instance.SetL(instanceTime, UndatedTodoTime());
       
   192    						 if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   193    							{
       
   194    						  	aInstances.AppendL(instance);
       
   195    						  	}	
       
   196    						 }
       
   197    					}
       
   198    				else
       
   199    					{
       
   200    					// nudge backwards from the end of the search range
       
   201  					TTime fromTime(AgnDateTime::ConvertToLocalTimeL(KSimpleEntry.DurationPlusL(AgnDateTime::ConvertToUtcTimeL(searchRangeEndLocal)) + TTimeIntervalMicroSeconds(1)));
       
   202    					while (KRptDef->NudgePreviousUnexceptedInstanceL(fromTime, instanceTime)
       
   203  							&& (KSimpleEntry.DurationPlusL(instanceTime) >= searchRangeStartLocal) )
       
   204    						{
       
   205    						TAgnSortInstance instance(KSimpleEntry);
       
   206    						instance.SetL(instanceTime, UndatedTodoTime());
       
   207    						if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   208    							{
       
   209    						  	aInstances.AppendL(instance);
       
   210    						  	}	
       
   211    						fromTime = instanceTime;
       
   212    						}
       
   213    					}
       
   214    				}
       
   215    			else
       
   216    				{
       
   217    				// It is a non-repeating entry
       
   218    			    TAgnSortInstance instance(KSimpleEntry);
       
   219    			    instance.SetL(KSimpleEntry.EntryTime().LocalL(), UndatedTodoTime());
       
   220    			    if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   221    			    	{
       
   222    			 	   	aInstances.AppendL(instance);
       
   223    			 	   	}	
       
   224    				}
       
   225    			}
       
   226 		}
       
   227 #endif
       
   228 	}	
       
   229 
       
   230 		
       
   231 // ----------------------------TAgnInstanceExtractor----------------------------
       
   232 
       
   233 /** Instance extractor for all entry types
       
   234 
       
   235 @internalComponent
       
   236 */
       
   237 TAgnInstanceExtractor::TAgnInstanceExtractor(CAgnSimpleEntryTable& aEntryInfoTable)
       
   238 	:iSimpleEntryTable(&aEntryInfoTable)
       
   239 	{
       
   240 	}
       
   241 
       
   242 /** Instances are obtained from each index selected by the filter by mean of an extractor.
       
   243 
       
   244 The instances are returned in the order defined by TAgnDaySortKey
       
   245 
       
   246 @internalComponent
       
   247 */ 
       
   248 void TAgnInstanceExtractor::FindInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   249     {
       
   250 
       
   251 	RArray<TInt> indexList;
       
   252 	CleanupClosePushL(indexList);
       
   253 
       
   254 	// Get the indexes of interest as per filter
       
   255 	//
       
   256 	iSimpleEntryTable->GetFilteredIndexListL(indexList, aSearchParams.iFilter);
       
   257 	
       
   258    	// Extract instances from each index (both floating and fixed time modes).
       
   259    	// Instances are extracted from each index of interest using a "extractor".
       
   260    	// The extractor is initialized with the particular index when "GetExtractor" is called.
       
   261    	//
       
   262    	const TInt KIndexCount = indexList.Count();
       
   263 	for (TInt i = 0; i < KIndexCount; ++i)
       
   264    		{
       
   265 		iSimpleEntryTable->GetExtractor(indexList[i], MAgnCalendarTimeMode::EFloating, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->FindInstancesL(aInstances, aSearchParams);
       
   266 		iSimpleEntryTable->GetExtractor(indexList[i], MAgnCalendarTimeMode::EFixedUtc, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->FindInstancesL(aInstances, aSearchParams);
       
   267    		}
       
   268 
       
   269 	CleanupStack::PopAndDestroy(&indexList); // Close()
       
   270 	}
       
   271 
       
   272 void TAgnInstanceExtractor::NextPossibleInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   273 	{
       
   274 	RArray<TInt> indexList;
       
   275 	CleanupClosePushL(indexList);
       
   276 	
       
   277 	// Get the indices of interest as per filter
       
   278 	iSimpleEntryTable->GetFilteredIndexListL(indexList, aSearchParams.iFilter);
       
   279 	
       
   280 	gPossibleInstancesOutsideRange = 0;
       
   281 
       
   282 	const TInt KIndexCount = indexList.Count();
       
   283 	for (TInt ii = 0; ii < KIndexCount; ++ii)
       
   284 		{
       
   285 		iSimpleEntryTable->GetExtractor(indexList[ii], MAgnCalendarTimeMode::EFloating, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->NextInstancesL(aInstances, aSearchParams);
       
   286 		iSimpleEntryTable->GetExtractor(indexList[ii], MAgnCalendarTimeMode::EFixedUtc, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->NextInstancesL(aInstances, aSearchParams);
       
   287 		}
       
   288 	CleanupStack::PopAndDestroy(&indexList); // Close()
       
   289 	}
       
   290 
       
   291 void TAgnInstanceExtractor::PreviousPossibleInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   292 	{
       
   293 	RArray<TInt> indexList;
       
   294 	CleanupClosePushL(indexList);
       
   295 	
       
   296 	// Get the indices of interest as per filter
       
   297 	iSimpleEntryTable->GetFilteredIndexListL(indexList, aSearchParams.iFilter);
       
   298 	
       
   299 	gPossibleInstancesOutsideRange = 0;
       
   300 	
       
   301    	const TInt KIndexCount = indexList.Count();
       
   302 	for (TInt ii = 0 ; ii < KIndexCount ; ++ii) 
       
   303 		{
       
   304 		iSimpleEntryTable->GetExtractor(indexList[ii], MAgnCalendarTimeMode::EFloating, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->PreviousInstancesL(aInstances, aSearchParams);
       
   305 		iSimpleEntryTable->GetExtractor(indexList[ii], MAgnCalendarTimeMode::EFixedUtc, aSearchParams.iFilter, aSearchParams.iUndatedTodoTimeLocal)->PreviousInstancesL(aInstances, aSearchParams);
       
   306 		}
       
   307 	CleanupStack::PopAndDestroy(&indexList); // Close()
       
   308 	}
       
   309 void CAgnInstanceExtractor::NextInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   310 	{
       
   311 	const TTime KSearchFromTimeLocal(aSearchParams.iInstance.iId.Date().IsSet() ? aSearchParams.iInstance.iId.Date().LocalL() : aSearchParams.iUndatedTodoTimeLocal);
       
   312 	const TTime KSearchRangeEndLocal(aSearchParams.iRangeEnd.LocalL());
       
   313 	
       
   314 	TTime searchFromTimeLocal(KSearchFromTimeLocal);
       
   315 	TTime lastMatchedTimeLocal(KSearchFromTimeLocal);
       
   316 	
       
   317 	TAgnDaySortKey sortKey(AgnDateTime::MaxDate(), UndatedTodoTime());
       
   318 	
       
   319 	// This time is used so that we do not add instances to the list that are after
       
   320 	// the Nth one that has been found because we know that we will not need them
       
   321 	TTime NthInstanceTimeLocal(AgnDateTime::MaxDate());
       
   322 
       
   323 	TInt numInstancesFound(0);
       
   324 
       
   325 	for (iIterator->GotoL(searchFromTimeLocal) ; !iIterator->AtEnd() && (iIterator->CurrentElement().ValidFromTimeLocalL() <= KSearchRangeEndLocal) && (iIterator->CurrentElement().ValidFromTimeLocalL() <= NthInstanceTimeLocal) ; iIterator->NextL())
       
   326 		{
       
   327 		if ( aInstances.Count() > (aSearchParams.iNumInstances + gPossibleInstancesOutsideRange) )
       
   328 			{
       
   329 			// We don't need instances after aSearchParams.iNumInstances
       
   330 			NthInstanceTimeLocal = aInstances.At(aSearchParams.iNumInstances + gPossibleInstancesOutsideRange).InstanceDate();
       
   331 			}
       
   332 
       
   333 		const CAgnSimpleEntry& KSimpleEntry(iIterator->CurrentElement());
       
   334 		
       
   335 		if (iEntryModel.MatchFullEntryL(KSimpleEntry.EntryId(), aSearchParams))
       
   336 		    {
       
   337 		    // find out where this instance is in the list
       
   338 		        	    		    
       
   339 		    if (KSimpleEntry.RptDef())
       
   340 		    	{
       
   341     			// nudge backwards to find instances that over lap into the start of the range
       
   342     			// add a microsecond to the search from time so that we find instances that start exactly on the start range
       
   343 		    	TTime fromTime = AgnDateTime::ConvertToLocalTimeL(AgnDateTime::ConvertToUtcTimeL(KSearchFromTimeLocal) + TTimeIntervalMicroSeconds(1));
       
   344     			TTime instanceTime;
       
   345     			
       
   346     			while (KSimpleEntry.RptDef()->NudgePreviousUnexceptedInstanceL(fromTime, instanceTime))
       
   347     				{
       
   348     				TAgnSortInstance instance(KSimpleEntry);
       
   349     				instance.SetL(instanceTime, UndatedTodoTime());
       
   350     				
       
   351     	    		if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   352     	    			{
       
   353     	    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   354     	    			
       
   355     	    			// it is possible that this instance appears before
       
   356 		    			// the starting instance when sorted into order
       
   357     	    			++gPossibleInstancesOutsideRange;
       
   358     	    			
       
   359     	    			if (!aSearchParams.iInstance.iId.IsNullId())
       
   360 	    			    	{
       
   361 	    			    	// We are searching from a particular instance
       
   362 	    			    	// so one nudge backwards is good enough to get the search from instance
       
   363 	    			    	break;
       
   364 	    			    	}
       
   365     	    			}
       
   366     	    		else
       
   367     	    			{
       
   368     	    			// There are no more instances in the repeat that overlap into the start of the search range
       
   369     	    			break;
       
   370     	    			}
       
   371     	    		
       
   372     				fromTime = instanceTime;
       
   373     				}
       
   374     			
       
   375     			// Try to get the next n number of instances from the repeat rule
       
   376     			numInstancesFound = 0;
       
   377     			fromTime = KSearchFromTimeLocal;
       
   378     			while ( KSimpleEntry.RptDef()->NudgeNextInstanceL(fromTime, instanceTime, ETrue)
       
   379     					&& aSearchParams.iNumInstances >= ++numInstancesFound
       
   380     					&& KSimpleEntry.DurationMinusL(instanceTime) <= KSearchRangeEndLocal
       
   381     					&& KSimpleEntry.DurationMinusL(instanceTime) <= NthInstanceTimeLocal )
       
   382     				{
       
   383     				TAgnSortInstance instance(KSimpleEntry);
       
   384     				instance.SetL(instanceTime, UndatedTodoTime());
       
   385     				
       
   386     	    		if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   387     	    			{
       
   388     	    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   389     	    			}
       
   390     	    		
       
   391     				fromTime = instanceTime;
       
   392     				}
       
   393 		    	}
       
   394 		    else
       
   395 		    	{
       
   396 		    	// It is a non-repeating entry
       
   397 		    	
       
   398 				TAgnSortInstance instance(KSimpleEntry);
       
   399 				instance.SetL(KSimpleEntry.EntryTime().LocalL(), UndatedTodoTime());
       
   400 				
       
   401 			    if ( lastMatchedTimeLocal > KSearchFromTimeLocal )
       
   402 					{
       
   403 					// We now have any instances that are the same as the search from time
       
   404 					
       
   405 					if (++numInstancesFound > aSearchParams.iNumInstances)
       
   406 						{
       
   407 						// We now have the number of requested instances
       
   408 						
       
   409 						if (iIterator->CurrentKey() > lastMatchedTimeLocal)
       
   410 							{
       
   411 							// Break when all the instances that are at
       
   412 							// the same time as the last instance have been found  
       
   413 							break;
       
   414 							}
       
   415 						}
       
   416 					}
       
   417 			    
       
   418 				// Add the instance to the list
       
   419 			    if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   420 			    	{
       
   421 	    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   422 	    			lastMatchedTimeLocal = instance.InstanceDate();
       
   423 	    			
       
   424 	    			if (lastMatchedTimeLocal == KSearchFromTimeLocal)
       
   425 		    			{
       
   426 		    			// it is possible that this instance appears before
       
   427 		    			// the starting instance when sorted into order
       
   428 		    			++gPossibleInstancesOutsideRange;
       
   429 		    			}
       
   430 			    	}
       
   431 		    	}
       
   432 		    }
       
   433 		}
       
   434 	}
       
   435 
       
   436 /** Finds the previous n number of instance that match the filter requirements
       
   437 
       
   438 The filter includes the time to search from and the search time range.
       
   439 
       
   440 @param aInstances The instance list to append instances to
       
   441 @param aSearchParams The filter requirements for the instance search.  This includes how many instances to find.
       
   442 
       
   443 @internalComponent
       
   444 */
       
   445 void CAgnInstanceExtractor::PreviousInstancesL(CArrayFix<TAgnSortInstance>& aInstances, const TFindInstanceParams& aSearchParams)
       
   446 	{
       
   447 	const TTime KSearchFromTimeLocal(aSearchParams.iInstance.iId.Date().IsSet() ? aSearchParams.iInstance.iId.Date().LocalL() : aSearchParams.iUndatedTodoTimeLocal);
       
   448 	const TTime KSearchRangeStartLocal(aSearchParams.iRangeStart.LocalL());
       
   449 	
       
   450 	TTime searchFromTime(KSearchFromTimeLocal);
       
   451 	TTime lastMatchedTime(KSearchFromTimeLocal);
       
   452 	
       
   453 	TAgnDaySortKey sortKey(AgnDateTime::MaxDate(), UndatedTodoTime());
       
   454 	
       
   455 	// This time is used so that we do not add instances to the list that are after
       
   456 	// the Nth one that has been found because we know that we will not need them
       
   457 	TTime NthInstanceTime(AgnDateTime::MinDate());
       
   458 	
       
   459 	TInt numInstancesFound(0);
       
   460 	
       
   461 	for (iIterator->GotoLessOrEqualL(searchFromTime) ; !iIterator->AtStart() ; iIterator->PreviousL())
       
   462 		{
       
   463 		if ( aInstances.Count() > (aSearchParams.iNumInstances + gPossibleInstancesOutsideRange) )
       
   464 			{
       
   465 			// We don't need instances after aSearchParams.iNumInstances
       
   466 			NthInstanceTime = aInstances.At( aInstances.Count() - 1 - (aSearchParams.iNumInstances + gPossibleInstancesOutsideRange) ).InstanceDate();
       
   467 			}
       
   468 
       
   469 		const CAgnSimpleEntry& KSimpleEntry(iIterator->CurrentElement());
       
   470 		
       
   471 		if(iEntryModel.MatchFullEntryL(KSimpleEntry.EntryId(), aSearchParams))
       
   472 		    {
       
   473 		    if (KSimpleEntry.RptDef())
       
   474 		    	{
       
   475 				// find instances that overlap into the end of the range
       
   476 				TTime fromTime = AgnDateTime::ConvertToLocalTimeL(AgnDateTime::ConvertToUtcTimeL(KSearchFromTimeLocal) - TTimeIntervalMicroSeconds(1));
       
   477 				TTime instanceTime;
       
   478 				
       
   479 				while (KSimpleEntry.RptDef()->NudgeNextInstanceL(fromTime, instanceTime, ETrue))
       
   480 					{
       
   481 					// get instances that are the same as the start time
       
   482 					TAgnSortInstance instance(KSimpleEntry);
       
   483 					instance.SetL(instanceTime, UndatedTodoTime());
       
   484 					if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   485 		    			{
       
   486 		    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   487 		    			
       
   488 		    			++gPossibleInstancesOutsideRange;
       
   489 		    			
       
   490     	    			if (!aSearchParams.iInstance.iId.IsNullId())
       
   491     			    		{
       
   492     			    		// We are searching from a particular instance
       
   493     			    		// so one nudge forwards is good enough to get the search from instance
       
   494     			    		break;
       
   495     			    		}
       
   496 		    			}
       
   497 					else
       
   498 						{
       
   499 						break;
       
   500 						}
       
   501 					
       
   502 					fromTime = instanceTime;
       
   503 					}
       
   504 				
       
   505 				// find n number of instances in the past
       
   506 				numInstancesFound = 0;
       
   507 				fromTime = KSearchFromTimeLocal;
       
   508 					
       
   509 				while (KSimpleEntry.RptDef()->NudgePreviousUnexceptedInstanceL(fromTime, instanceTime)
       
   510 						&& ++numInstancesFound <= aSearchParams.iNumInstances
       
   511 						&&  iIterator->CurrentElement().DurationPlusL(instanceTime) >= KSearchRangeStartLocal
       
   512 						&&  iIterator->CurrentElement().DurationPlusL(instanceTime) >= NthInstanceTime)
       
   513 					{
       
   514 					// get previous n number of instances before the start time
       
   515 					TAgnSortInstance instance(KSimpleEntry);
       
   516 					instance.SetL(instanceTime, UndatedTodoTime());
       
   517 					
       
   518 					if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   519 		    			{
       
   520 		    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   521 		    			}
       
   522 								
       
   523 					fromTime = instanceTime;
       
   524 					}
       
   525 			    }
       
   526 		    else
       
   527 		    	{
       
   528 		    	// This is a non-repeating entry
       
   529 
       
   530 	    		TAgnSortInstance instance(KSimpleEntry);
       
   531 	    		instance.SetL(KSimpleEntry.EntryTime().LocalL(), UndatedTodoTime());	
       
   532 	    		
       
   533 	    		if (lastMatchedTime > KSearchFromTimeLocal)
       
   534 	    			{
       
   535 	    			// We now have all instances that are the same as the end time
       
   536 	    			if (++numInstancesFound > aSearchParams.iNumInstances)
       
   537 	    				{
       
   538 	    				if (lastMatchedTime > instance.InstanceDate())
       
   539 	    					{
       
   540 	    					// We now have all instances that are the same as
       
   541 	    					// the nth instances before the end time
       
   542 	    					break;
       
   543 	    					}
       
   544 	    				}
       
   545 	    			}
       
   546 	    			
       
   547 	    		// Add the instance to the list
       
   548 	    		if (instance.CheckStartAndEndDateOverlap(aSearchParams))
       
   549 	    			{
       
   550 	    			aInstances.InsertIsqAllowDuplicatesL(instance, sortKey);
       
   551 	    			lastMatchedTime = instance.InstanceDate();
       
   552 	    			
       
   553 	    			if (lastMatchedTime == KSearchFromTimeLocal)
       
   554 	    				{
       
   555 	    				++gPossibleInstancesOutsideRange;
       
   556 	    				}
       
   557 	    			}
       
   558 	    		}
       
   559 		    }
       
   560 		}
       
   561 	}
       
   562