meetingrequest/mrservices/src/cesmrconflictchecker.cpp
branchRCL_3
changeset 64 3533d4323edc
child 80 726fba06891a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrservices/src/cesmrconflictchecker.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,891 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+*  Description : ESMR conflict checker implementation
+*  Version     : %version: e002sa33#9 %
+*
+*/
+
+#include "emailtrace.h"
+#include "cesmrconflictchecker.h"
+#include "cesmrcaldbmgr.h"
+#include "esmrhelper.h"
+#include "esmrentryhelper.h"
+#include "esmrinternaluid.h"
+
+#include <calcommon.h>
+#include <calinstance.h>
+#include <calentryview.h>
+#include <calinstanceview.h>
+#include <calinstanceiterator.h>
+#include <ct/rcpointerarray.h>
+#include <calrrule.h>
+
+/// Unnamed namespace for local definitions
+namespace { // codescanner::namespace
+
+// Definition for zero
+const TInt KZero(0);
+
+/** Defines instace filter type */
+enum TInstanceFilter
+    {
+    EIncludeSameUID,
+    ERemoveSameUID
+    };
+
+#ifdef _DEBUG
+
+// Literal for panic texts
+_LIT( KESMRConflictCheckerTxt, "ESMRConflictChecker" );
+
+/** Enumeration for panic codes */
+enum TESMRConflictCheckerPanic
+    {
+    // Input entry is not appointment
+    EESMRConflictCheckerInvalidEntryType
+    };
+
+/**
+ * Thows system wide panic.
+ * @param aPanic Panic code.
+ */
+void Panic( TESMRConflictCheckerPanic aPanic )
+    {
+
+    User::Panic( KESMRConflictCheckerTxt, aPanic );
+    }
+
+#else
+
+/**
+ * Thows system wide leave.
+ * @param aError Leave code.
+ */
+void Leave( TInt aError )
+    {
+
+    User::Leave( aError );
+    }
+
+#endif
+
+/**
+ * Resolves time range for possible conflicting entries. Instance view
+ * is used for resolving the time range.
+ *
+ * @param aStart Start time
+ * @param aEnd End time
+ * @param aInstanceView Pointer to calendar db instance view
+ * @return Time range for possible conflicting entries
+ */
+CalCommon::TCalTimeRange ResolveFetchTimeRangeL(
+        TTime aStart,
+        TTime aEnd,
+        CCalInstanceView* aInstanceView )
+    {
+    FUNC_LOG;
+    const CalCommon::TCalViewFilter instanceFilter =
+            CalCommon::EIncludeAppts;
+
+    TDateTime start = aStart.DateTime();
+    TDateTime end   = aEnd.DateTime();
+
+    start.SetHour( KZero );
+    start.SetMinute( KZero );
+    start.SetSecond( KZero );
+    start.SetMicroSecond( KZero );
+
+    end.SetHour( KZero );
+    end.SetMinute( KZero );
+    end.SetSecond( KZero );
+    end.SetMicroSecond( KZero );
+    TTime endTime = end;
+
+    if ( TTime(start) == endTime ||
+         endTime < aEnd )
+        {
+
+        endTime += TTimeIntervalDays(1);
+        end = endTime.DateTime();
+        }
+
+    TCalTime rangeStart;
+    rangeStart.SetTimeLocalL( start );
+
+    TCalTime instanceTime = aInstanceView->PreviousInstanceL(
+            instanceFilter,
+            rangeStart );
+
+    if (  Time::NullTTime() != instanceTime.TimeUtcL()  )
+        {
+        rangeStart = instanceTime;
+        }
+
+    TCalTime rangeEnd;
+    rangeEnd.SetTimeLocalL( end );
+
+    instanceTime = aInstanceView->NextInstanceL(
+            instanceFilter,
+            rangeEnd );
+
+    if ( instanceTime.TimeLocalL() != Time::NullTTime() )
+        {
+        rangeEnd = instanceTime;
+        }
+
+    return CalCommon::TCalTimeRange( rangeStart, rangeEnd );
+    }
+
+/**
+ * Removes and deletes the entries, which do not conflict with
+ * entry. Entry is considered to be conflicting entry if starts or
+ * ends between aEntry's start and end time.
+ *
+ * @param aEntries Reference to entries, which may conflict
+ * @param aEntry Reference to entry, which confilcts are resolved.
+ */
+void RemoveAndDeleteNonConflictingInstancesL(
+    RPointerArray<CCalInstance>& instanceArray,
+    TCalTime aStartTime,
+    TCalTime aEndTime,
+    const TDesC8& aUid,
+    TInstanceFilter aFilterType )
+    {
+    FUNC_LOG;
+    TInt index(0);
+
+    TTime startTimeLocal = aStartTime.TimeLocalL();
+    TTime endTimeLocal = aEndTime.TimeLocalL();
+
+    while( index < instanceArray.Count() )
+        {
+        TBool conflictingInstance( ETrue );
+        CCalInstance* instance = instanceArray[index];
+
+        TTime entryStartTimeLocal = instance->StartTimeL().TimeLocalL();
+        TTime entryEndTimeLocal = instance->EndTimeL().TimeLocalL();
+
+        TPtrC8 uid( instance->Entry().UidL() );
+        if ( ERemoveSameUID == aFilterType &&
+             0 == aUid.CompareF(uid) )
+            {
+            conflictingInstance = EFalse;
+            }
+        else if ( entryStartTimeLocal >= startTimeLocal &&
+                  entryStartTimeLocal < endTimeLocal )
+            {
+            // Entry starts during another entry
+            index++;
+            }
+        else if ( entryEndTimeLocal > startTimeLocal &&
+                entryEndTimeLocal <= endTimeLocal )
+            {
+            // Entry ends during another entry
+            index++;
+            }
+        else if ( entryStartTimeLocal < startTimeLocal &&
+                  entryEndTimeLocal > endTimeLocal )
+            {
+            // Antry starts and ends during another entry
+            index++;
+            }
+        else
+            {
+            conflictingInstance = EFalse;
+            }
+
+        // Remove non-conflicting instance from instance array
+        if ( !conflictingInstance )
+            {
+            instanceArray.Remove(index);
+            delete instance;
+            instance = NULL;
+            }
+        }
+    }
+
+/**
+ * Creates calendar entries from the conflicting instances
+ * and stores the created entries into entry array.
+ * Ownership of the created entries is transferred to caller.
+ * @param aInstanceArray Reference to instance array
+ * @param aConflictingEntries Reference to entry array.
+ */
+void CreateEntriesFromInstancesL(
+        RPointerArray<CCalInstance>& instanceArray,
+        RPointerArray<CCalEntry>& aConflictingEntries )
+    {
+    FUNC_LOG;
+    TInt instanceCount( instanceArray.Count() );
+    for ( TInt i(0); i < instanceCount; ++i )
+        {
+        CCalEntry& parent( instanceArray[i]->Entry() );
+        CCalEntry* entry = ESMRHelper::CopyEntryLC( parent,
+                                                    parent.MethodL(),
+                                                    ESMRHelper::ECopyFull );
+
+        entry->SetStartAndEndTimeL( instanceArray[i]->StartTimeL(),
+                                    instanceArray[i]->EndTimeL() );
+
+        aConflictingEntries.AppendL( entry );
+        CleanupStack::Pop( entry );
+        }
+    }
+
+/**
+ * Checks if entry is repeating.
+ * @return ETrue if entry is repeating
+ */
+TBool IsRepeatingMeetingL( const CCalEntry& aEntry,
+                           MESMRCalDbMgr& aDb )
+    {
+    FUNC_LOG;
+
+    TBool recurrent( EFalse );
+
+    CCalInstance* instance = aDb.FindInstanceL( aEntry );
+
+    if ( instance )
+        {
+        CleanupStack::PushL( instance );
+        recurrent = ESMREntryHelper::IsRepeatingMeetingL( instance->Entry() );
+        CleanupStack::PopAndDestroy( instance );
+        }
+    else
+        {
+        recurrent = ESMREntryHelper::IsRepeatingMeetingL( aEntry );
+        }
+
+    return recurrent;
+    }
+
+/**
+ * Finds conflicts for entry
+ */
+void FindConflictsForEntryL(
+        const CCalEntry& aEntry,
+        RPointerArray< CCalInstance >& aInstances,
+        MESMRCalDbMgr& aDb )
+    {
+    FUNC_LOG;
+
+    // Get instance views of all calendar
+    RPointerArray<CCalInstanceView> allCalenInstanceView =
+            aDb.NormalDbAllCalenInstanceView();
+
+    // Check if there is any conflict in each calendar
+    for( TInt i = 0; i < allCalenInstanceView.Count(); i++ )
+        {
+        CalCommon::TCalTimeRange timeRange =
+                    ResolveFetchTimeRangeL(
+                                    aEntry.StartTimeL().TimeUtcL(),
+                                    aEntry.EndTimeL().TimeUtcL(),
+                                    allCalenInstanceView[i] );
+
+        allCalenInstanceView[i]->FindInstanceL(
+                aInstances,
+                CalCommon::EIncludeAppts,
+                timeRange );
+        }
+
+    RemoveAndDeleteNonConflictingInstancesL(
+            aInstances,
+            aEntry.StartTimeL(),
+            aEntry.EndTimeL(),
+            aEntry.UidL(),
+            ERemoveSameUID );
+    }
+
+/**
+ * Moves instances from an array to another.
+ */
+void MoveInstancesL(
+        RPointerArray< CCalInstance >& aFrom,
+        RPointerArray< CCalInstance >& aTo )
+    {
+    FUNC_LOG;
+
+    aTo.ReserveL( aTo.Count() + aFrom.Count() );
+    while ( aFrom.Count() )
+        {
+        aTo.AppendL( aFrom[ 0 ] );
+        aFrom.Remove( 0 );
+        }
+    }
+
+/**
+ * Finds conflicts based on Daily recurrence.
+ *
+ */
+void FindConflictsForDailyRRuleL(
+        CCalEntry& aEntry,
+        RPointerArray< CCalInstance >& aInstances,
+        MESMRCalDbMgr& aDb,
+        TBool aFindAllConflicts )
+    {
+    FUNC_LOG;
+
+    TCalRRule rRule;
+    aEntry.GetRRuleL( rRule );
+    RCPointerArray< CCalInstance > tmpInstanceArray;
+    CleanupClosePushL( tmpInstanceArray );
+
+    // Entry start and end time
+    TTime start( aEntry.StartTimeL().TimeUtcL() );
+    TTime end( aEntry.EndTimeL().TimeUtcL() );
+
+    if ( rRule.Count() )
+        {
+        for ( TInt i = 0; i < rRule.Count(); ++i )
+            {
+            // Set each occurence start and end time on entry
+            TTimeIntervalDays interval( i * rRule.Interval() );
+            TCalTime startTime;
+            startTime.SetTimeUtcL( start + interval );
+            TCalTime endTime;
+            endTime.SetTimeUtcL( end + interval );
+            aEntry.SetStartAndEndTimeL(
+                    startTime,
+                    endTime );
+
+            // Find conflicts for this occurence
+            FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
+
+            if ( tmpInstanceArray.Count() )
+                {
+                MoveInstancesL( tmpInstanceArray, aInstances );
+                if ( !aFindAllConflicts )
+                    {
+                    break;
+                    }
+                }
+            }
+        }
+    else if ( rRule.Until().TimeUtcL() != Time::NullTTime() )
+        {
+        TTime until( rRule.Until().TimeUtcL() );
+        TTime start( aEntry.StartTimeL().TimeUtcL() );
+        TTime end( aEntry.EndTimeL().TimeUtcL() );
+        TTimeIntervalDays interval( rRule.Interval() );
+
+        // Loop while start time is before until time
+        while ( start <= until )
+            {
+            // Set start and end time for occurence
+            TCalTime startTime;
+            startTime.SetTimeUtcL( start );
+            TCalTime endTime;
+            endTime.SetTimeUtcL( end );
+            aEntry.SetStartAndEndTimeL(
+                    startTime,
+                    endTime );
+
+            // Find conflicts
+            FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
+
+            if ( tmpInstanceArray.Count() )
+                {
+                MoveInstancesL( tmpInstanceArray, aInstances );
+                if ( !aFindAllConflicts )
+                    {
+                    break;
+                    }
+                }
+
+            // Move to next occurence
+            start += interval;
+            end += interval;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &tmpInstanceArray );
+    }
+
+/**
+ * Finds conflicts based on Weekly recurrence.
+ */
+void FindConflictsForWeeklyRRuleL(
+        CCalEntry& aEntry,
+        RPointerArray< CCalInstance >& aInstances,
+        MESMRCalDbMgr& aDb,
+        TBool aFindAllConflicts )
+    {
+    FUNC_LOG;
+
+    TCalRRule rRule;
+    aEntry.GetRRuleL( rRule );
+
+    // Tmp array for conflic instances
+    RCPointerArray< CCalInstance > tmpInstanceArray;
+    CleanupClosePushL( tmpInstanceArray );
+
+    // Array of recurrence days
+    RArray< TDay > days;
+    CleanupClosePushL( days );
+    rRule.GetByDayL( days );
+
+    // Recurrence start time
+    TTime start( aEntry.StartTimeL().TimeUtcL() );
+    // Recurrence end time
+    TTime end( aEntry.EndTimeL().TimeUtcL() );
+    const TTimeIntervalDays KWeek( 7 );
+    TDay startDayOfWeek( start.DayNoInWeek() );
+
+    // Instance duration
+    TTimeIntervalMinutes duration;
+    end.MinutesFrom( start, duration );
+
+    if ( rRule.Count() )
+        {
+        for ( TInt i = 0; i < rRule.Count(); ++i )
+            {
+            // Calculate weekly start time
+            TTimeIntervalDays interval( i* KWeek.Int() );
+            TDateTime date( TTime( start + interval ).DateTime() );
+            date.SetDay( date.Day() - startDayOfWeek );
+            TTime weekStartTime( date );
+
+            for ( TInt j = 0; j < days.Count(); ++j )
+                {
+                // Iterate through days of week
+                TTime entryStartTime( weekStartTime + TTimeIntervalDays( days[ j ] ) );
+
+                if ( start <= entryStartTime )
+                    {
+                    // Start time is in recurrence range
+                    // Calcualte end time
+                    TCalTime startCalTime;
+                    startCalTime.SetTimeUtcL( entryStartTime );
+                    TCalTime endCalTime;
+                    endCalTime.SetTimeUtcL( entryStartTime + duration );
+                    aEntry.SetStartAndEndTimeL( startCalTime, endCalTime );
+
+                    // Find conflicts of for entry and move them to result array
+                    FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
+
+                    if ( tmpInstanceArray.Count() )
+                        {
+                        MoveInstancesL( tmpInstanceArray, aInstances );
+                        if ( !aFindAllConflicts )
+                            {
+                            break;
+                            }
+                        }
+                    }
+                }
+
+            if ( !aFindAllConflicts && aInstances.Count() )
+                {
+                break;
+                }
+            }
+        }
+    else if ( rRule.Until().TimeUtcL() != Time::NullTTime() )
+        {
+        TDateTime date( start.DateTime() );
+        date.SetDay( date.Day() - startDayOfWeek );
+        TTime weekStartTime( date );
+        TTime until( rRule.Until().TimeUtcL() );
+
+        while ( weekStartTime < until )
+            {
+            for ( TInt j = 0; j < days.Count(); ++j )
+                {
+                // Iterate through days of week
+                TTime entryStartTime( weekStartTime + TTimeIntervalDays( days[ j ] ) );
+
+                if ( start <= entryStartTime )
+                    {
+                    // Start time is in recurrence range
+                    // Calculate end time
+                    TCalTime startCalTime;
+                    startCalTime.SetTimeUtcL( entryStartTime );
+                    TCalTime endCalTime;
+                    endCalTime.SetTimeUtcL( entryStartTime + duration );
+                    aEntry.SetStartAndEndTimeL( startCalTime, endCalTime );
+
+                    // Find conflicts of for entry and move them to result array
+                    FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
+
+                    if ( tmpInstanceArray.Count() )
+                        {
+                        MoveInstancesL( tmpInstanceArray, aInstances );
+                        if ( !aFindAllConflicts )
+                            {
+                            break;
+                            }
+                        }
+                    }
+                }
+
+            if ( !aFindAllConflicts && aInstances.Count() )
+                {
+                break;
+                }
+            else
+                {
+                weekStartTime += KWeek;
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &days );
+    CleanupStack::PopAndDestroy( &tmpInstanceArray );
+    }
+
+/**
+ * Finds conflict for recurrent entry
+ */
+void FindConflictsForRepeatingMeetingL(
+        const CCalEntry& aEntry,
+        RPointerArray< CCalInstance >& aInstances,
+        MESMRCalDbMgr& aDb,
+        TBool aFindAllConflicts )
+    {
+    FUNC_LOG;
+
+    CCalInstance* instance = aDb.FindInstanceL( aEntry );
+
+    if ( instance ) // Instance is stored
+        {
+        CleanupStack::PushL( instance );
+        RCPointerArray< CCalInstance > tmpInstanceArray;
+        CleanupClosePushL( tmpInstanceArray );
+
+        CCalEntry& parent = instance->Entry();
+        CCalInstanceView* instanceView = aDb.InstanceViewL( parent );
+        CCalInstanceIterator* iterator = instanceView->FindInstanceByUidL(
+                        parent.UidL(),
+                        parent.StartTimeL() );
+        CleanupStack::PushL( iterator );
+        CCalEntry* entry = ESMRHelper::CopyEntryLC(
+                            parent,
+                            parent.MethodL(),
+                            ESMRHelper::ECopyFull );
+
+        while ( iterator->HasMore() )
+            {
+            CCalInstance* next = iterator->NextL();
+            CleanupStack::PushL( next );
+            entry->SetStartAndEndTimeL( next->StartTimeL(), next->EndTimeL() );
+            CleanupStack::PopAndDestroy( next );
+            FindConflictsForEntryL( *entry,
+                                    tmpInstanceArray,
+                                    aDb );
+
+            if ( tmpInstanceArray.Count() )
+                {
+                MoveInstancesL( tmpInstanceArray, aInstances );
+
+                if ( !aFindAllConflicts )
+                    {
+                    break;
+                    }
+                }
+            }
+
+        CleanupStack::PopAndDestroy( entry );
+
+        CleanupStack::PopAndDestroy( iterator );
+
+        if ( aFindAllConflicts
+             || !aInstances.Count() )
+            {
+            // Find conflicts also for parent entry
+            FindConflictsForEntryL( parent, tmpInstanceArray, aDb );
+            MoveInstancesL( tmpInstanceArray, aInstances );
+            }
+
+        CleanupStack::PopAndDestroy( &tmpInstanceArray );
+        CleanupStack::PopAndDestroy( instance );
+        }
+    else // Entry is not stored yet
+        {
+        CCalEntry* entry = ESMRHelper::CopyEntryLC(
+                aEntry,
+                aEntry.MethodL(),
+                ESMRHelper::ECopyFull );
+
+        TCalRRule rRule;
+        if ( aEntry.GetRRuleL( rRule ) )
+            {
+            switch ( rRule.Type() )
+                {
+                case TCalRRule::EDaily:
+                    {
+                    FindConflictsForDailyRRuleL(
+                            *entry,
+                            aInstances,
+                            aDb,
+                            aFindAllConflicts );
+                    break;
+                    }
+                case TCalRRule::EWeekly:
+                    {
+                    FindConflictsForWeeklyRRuleL(
+                            *entry,
+                            aInstances,
+                            aDb,
+                            aFindAllConflicts );
+                    break;
+                    }
+                default:
+                    break;
+                }
+            }
+        else
+            {
+            // Entry has RDates set
+            RCPointerArray< CCalInstance > tmpInstanceArray;
+            CleanupClosePushL( tmpInstanceArray );
+
+            RArray< TCalTime > rDates;
+            CleanupClosePushL( rDates );
+            aEntry.GetRDatesL( rDates );
+
+            // Get entry start time, end time and duration
+            TTime start( aEntry.StartTimeL().TimeUtcL() );
+            TTime end( aEntry.EndTimeL().TimeUtcL() );
+            TTimeIntervalMinutes duration(0);
+            end.MinutesFrom(
+                    start,
+                    duration );
+
+            for ( TInt i = 0; i < rDates.Count(); ++i )
+                {
+                // Set start and end times for entry
+                TCalTime startTime( rDates[ i ] );
+                TCalTime endTime;
+                endTime.SetTimeUtcL( startTime.TimeUtcL() + duration );
+                entry->SetStartAndEndTimeL( startTime, endTime );
+
+                // Find conflicts
+                FindConflictsForEntryL( *entry, tmpInstanceArray, aDb );
+
+                if ( tmpInstanceArray.Count() )
+                    {
+                    MoveInstancesL( tmpInstanceArray, aInstances );
+                    if ( !aFindAllConflicts )
+                        {
+                        break;
+                        }
+                    }
+                }
+
+            CleanupStack::PopAndDestroy( &rDates );
+
+            if ( aFindAllConflicts
+                 || aInstances.Count() == 0 )
+                {
+                // Find conflicts for parent entry
+                FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
+                MoveInstancesL( tmpInstanceArray, aInstances );
+                }
+
+            CleanupStack::PopAndDestroy( &tmpInstanceArray );
+            }
+
+        CleanupStack::PopAndDestroy( entry );
+        }
+    }
+
+}  // namespace
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::CESMRConflictChecker
+// ---------------------------------------------------------------------------
+//
+inline CESMRConflictChecker::CESMRConflictChecker(
+        MESMRCalDbMgr& aDbMgr ) :
+        iDbMgr( aDbMgr )
+    {
+    FUNC_LOG;
+    // Not implementation yet
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::~CESMRConflictChecker
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRConflictChecker::~CESMRConflictChecker()
+    {
+    FUNC_LOG;
+    // Not implementation yet
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRConflictChecker* CESMRConflictChecker::NewL(
+        MESMRCalDbMgr& aDbMgr )
+    {
+    FUNC_LOG;
+    CESMRConflictChecker* self =
+            new (ELeave) CESMRConflictChecker(aDbMgr);
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::FindConflictsL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRConflictChecker::FindConflictsL(
+            const CCalEntry& aEntry,
+            RPointerArray<CCalEntry>& aConflicts )
+    {
+    FUNC_LOG;
+
+    // Checking input parameters
+#ifdef _DEBUG
+
+    __ASSERT_DEBUG(
+            CCalEntry::EAppt == aEntry.EntryTypeL(),
+            Panic(EESMRConflictCheckerInvalidEntryType) );
+
+#else
+
+    if ( CCalEntry::EAppt != aEntry.EntryTypeL() )
+        {
+        Leave( KErrArgument );
+        }
+
+#endif
+
+    RCPointerArray<CCalInstance> instanceArray;
+    CleanupClosePushL( instanceArray );
+
+    if ( IsRepeatingMeetingL( aEntry, iDbMgr ) )
+        {
+        FindConflictsForRepeatingMeetingL(
+                aEntry,
+                instanceArray,
+                iDbMgr,
+                EFalse );
+        }
+    else
+        {
+        FindConflictsForEntryL(
+                aEntry,
+                instanceArray,
+                iDbMgr );
+        }
+
+    CreateEntriesFromInstancesL( instanceArray, aConflicts );
+    CleanupStack::PopAndDestroy( &instanceArray);
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::FindInstancesForEntry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRConflictChecker::FindInstancesForEntryL(
+        TTime aStart,
+        TTime aEnd,
+        const CCalEntry& aEntry,
+        TCalCollectionId aColId,
+        RPointerArray<CCalEntry>& aInstances )
+    {
+    FUNC_LOG;
+    CCalInstanceView* instanceView = iDbMgr.InstanceViewL( aEntry );
+
+    RCPointerArray<CCalInstance> instanceArray;
+    CleanupClosePushL( instanceArray );
+
+    // First we need the parent entry of the series ...
+    CCalInstance* entryInstance = instanceView->FindInstanceL(
+    		aEntry.LocalUidL(),
+    		aEntry.StartTimeL() ); //Ownership gained
+    CleanupStack::PushL( entryInstance );
+
+    CCalInstance* parentEntryInstance = instanceView->FindInstanceL(
+    		aEntry.LocalUidL(),
+    		entryInstance->Entry().StartTimeL() );
+    CleanupStack::PopAndDestroy( entryInstance );
+    CleanupStack::PushL( parentEntryInstance );
+
+    // ... And the parent entry instances start time
+    TCalTime firstIntanceStartTime( parentEntryInstance->StartTimeL() );
+
+    CleanupStack::Pop( parentEntryInstance ); // ownership given to instanceArray
+    instanceArray.Append( parentEntryInstance );
+
+    // Let's get all instances which have same uid and collection id
+    // as the aEntry to an iterator.
+    CCalInstanceIterator* instanceIterator = instanceView->FindInstanceByUidL(
+    		aColId,
+    		aEntry.UidL(),
+    		firstIntanceStartTime );
+    CleanupStack::PushL( instanceIterator );
+
+    TInt count( instanceIterator->Count() );
+
+    for( TInt i = 0; i < count; ++i )
+    	{
+		CCalInstance* instance = NULL;
+		TRAPD( err, instance = instanceIterator->NextL() ); //Ownership gained
+		if( !err && instance )
+			{
+			instanceArray.Append( instance );
+			}
+    	}
+
+    CleanupStack::PopAndDestroy( instanceIterator );
+
+    // Now the instanceArray has all instances of the aEntry,
+    // let's remove this instance == instance of aEntry, from the array
+	TInt i( 0 );
+    while( i < instanceArray.Count() )
+    	{
+		CCalInstance* instance = instanceArray[i];
+
+        TBool thisInstance(
+                instance->StartTimeL().TimeLocalL() ==
+                aEntry.StartTimeL().TimeLocalL() &&
+                instance->EndTimeL().TimeLocalL() ==
+                aEntry.EndTimeL().TimeLocalL() );
+
+        if( thisInstance )
+        	{
+			delete instance;
+			instanceArray.Remove( i );
+        	}
+        else
+        	{
+			++i;
+        	}
+    	}
+
+    TCalTime start;
+    start.SetTimeLocalL( aStart );
+
+    TCalTime end;
+    end.SetTimeLocalL( aEnd );
+
+    RemoveAndDeleteNonConflictingInstancesL(
+            instanceArray,
+            start,
+            end,
+            aEntry.UidL(),
+            EIncludeSameUID );
+
+    CreateEntriesFromInstancesL( instanceArray, aInstances );
+
+    CleanupStack::PopAndDestroy(); // instanceArray
+    }
+
+// EOF
+