pimappservices/calendar/client/src/calentryimpl.cpp
changeset 0 f979ecb2b13e
child 18 d68a4b5d5885
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/client/src/calentryimpl.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,1812 @@
+// Copyright (c) 2005-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:
+//
+
+#include "calentryimpl.h"
+
+#include "calclient.h"
+#include "agsalarm.h"
+#include "agmattachment.h"
+#include "agmdate.h"
+#include "agmentry.h"
+#include "agmpanic.h"
+#include "agmcategory.h"
+#include "agmattendee.h"
+#include "agmcontent.h"
+#include <calalarm.h>
+#include "calcategoryimpl.h"
+#include <calcontent.h>
+#include <calrrule.h>
+#include <calsession.h>
+#include "calsessionimpl.h"
+#include "caluserimpl.h"
+
+const TInt KAttendeeGranularity = 2;
+const TInt KCategoryGranularity = 1;
+const TInt KAttachmentGranularity = 1;
+
+
+CCalEntryImpl::~CCalEntryImpl()
+	{
+	if(iSessionImpl)
+		{
+		iSessionImpl->DecrementReferenceCount();
+		}
+
+	if (iLiteEntry)
+ 		{
+		iLiteEntry->DecrementRefCount();
+ 		}
+	if(iCalAttachmentList)
+		{
+		iCalAttachmentList->ResetAndDestroy();
+		delete iCalAttachmentList; 	
+		}
+	if(iCalAttendeeList)
+		{
+		iCalAttendeeList->ResetAndDestroy();
+		delete iCalAttendeeList;
+		}
+	if(iCalCategoryList)
+		{
+		iCalCategoryList->ResetAndDestroy();
+		delete iCalCategoryList;
+		}
+	delete iCalOrganizer;
+	delete iFullEntry;
+	}
+
+CCalEntryImpl::CCalEntryImpl()
+	{
+	}
+
+CCalEntryImpl::CCalEntryImpl(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl)
+	: iFullEntry(&aEntry), iSessionImpl(&aSessionImpl)
+	{
+	iSessionImpl->IncrementReferenceCount();
+	}
+
+
+CCalEntryImpl::CCalEntryImpl(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl)
+	: iLiteEntry(&aEntry), iSessionImpl(&aSessionImpl)
+ 	{
+ 	iSessionImpl->IncrementReferenceCount();
+	iLiteEntry->IncrementRefCount();
+ 	}
+
+void CCalEntryImpl::ClearSimpleEntry()
+	{
+	if (iSessionImpl && iLiteEntry)
+		{
+		iLiteEntry->DecrementRefCount();
+		iLiteEntry = NULL;
+		}
+	}
+	
+CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
+	{
+	__ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument));
+
+	CCalEntryImpl* self = new (ELeave) CCalEntryImpl();
+	CleanupStack::PushL(self);
+	self->ConstructL(aType, aUid, aMethod, aSeqNum); // takes ownership of aUid
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod,
+			TUint aSeqNum, const TCalTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
+	{
+	__ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument));
+
+	CCalEntryImpl* self = new (ELeave) CCalEntryImpl();
+	CleanupStack::PushL(self);
+	self->ConstructL(aType, aUid, aMethod, aSeqNum, CalUtils::TCalTimeToTAgnCalendarTimeL(aRecurrenceId), aRange);
+	   // takes ownership of aUid
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CCalEntryImpl* CCalEntryImpl::NewL(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl)
+	{
+	CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl);
+	return self;
+	}
+
+CCalEntryImpl* CCalEntryImpl::NewL(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl)
+	{
+	CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl);
+	return self;
+	}
+
+void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
+	{
+	// Create appropriate CAgnEntry type child entry.
+	iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod, aSeqNum, aRecurrenceId, aRange); // takes ownership of aUid
+	}
+
+
+void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
+	{
+	// Create appropriate CAgnEntry type parent entry.
+	iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod,aSeqNum);
+	}
+
+void CCalEntryImpl::LoadFullEntryL()
+	{
+	if (iLiteEntry)
+		{
+		// iFullEntry should be NULL at this point
+		__ASSERT_DEBUG(iFullEntry == NULL, User::Leave(KErrCorrupt));
+		
+		// extract full CAgnEntry from TAgnLiteEntry and store it in iFullEntry
+		TCalLocalUid id = iLiteEntry->LiteEntry().LocalUid();
+		iFullEntry = iSessionImpl->Server().FetchEntryL(id, iSessionImpl->FileId());
+		__ASSERT_ALWAYS(iFullEntry, User::Leave(KErrNotFound));
+		iFullEntry->SetCollectionId(iLiteEntry->LiteEntry().CollectionId());
+		ClearSimpleEntry();
+		}
+	}
+
+// return the CAgnEntry associated with this entry, loading it from the server if necessary
+CAgnEntry* CCalEntryImpl::GetFullEntryL()
+	{
+	LoadFullEntryL();
+	return iFullEntry;
+	}
+
+void CCalEntryImpl::PopulateCategoryListL()
+	{
+	if (!iCalCategoryList)
+		{
+		LoadFullEntryL();
+		iCalCategoryList = new (ELeave) RPointerArray<CCalCategory>(KCategoryGranularity);
+
+		const TInt KCategoryCount = iFullEntry->CategoryCount();
+		for (TInt i = 0; i < KCategoryCount; ++i)
+			{
+			CAgnCategory& agnCategory = iFullEntry->FetchCategory(i); // ownership not taken
+			CCalCategoryImpl* impl = CCalCategoryImpl::NewL(&agnCategory); // doesn't take ownership of agnCategory
+			CleanupStack::PushL(impl);
+			CCalCategory* category = CCalCategory::NewL(impl); // takes ownership of impl
+			CleanupStack::Pop(impl);
+			CleanupStack::PushL(category);
+			iCalCategoryList->AppendL(category); // takes ownership of category
+			CleanupStack::Pop(category);
+			}
+		}
+	}
+
+void CCalEntryImpl::PopulateAttendeeListL()
+	{
+	if(!iCalAttendeeList)
+		{
+		LoadFullEntryL();
+
+		iCalAttendeeList = new(ELeave) RPointerArray<CCalAttendee>(KAttendeeGranularity);
+
+		const TInt KAttendeeCount = iFullEntry->AttendeeCount();
+		for(TInt i = 0; i < KAttendeeCount; ++i)
+			{
+			CAgnAttendee& agnAttendee = iFullEntry->FetchAttendee(i);
+			
+			CCalUserImpl* impl = CCalUserImpl::NewL(&agnAttendee);	// doesn't take ownership of agnAttendee
+			CleanupStack::PushL(impl);
+			CCalAttendee* calAttendee = CCalAttendee::NewL(impl);	// takes ownership of impl
+			CleanupStack::Pop(impl);
+			
+			CleanupStack::PushL(calAttendee);
+			iCalAttendeeList->AppendL(calAttendee);
+			CleanupStack::Pop(calAttendee);
+			}
+		}
+	}
+
+
+void CCalEntryImpl::AddAttendeeL(CCalAttendee* aAttendee)
+	{
+    if (!aAttendee)
+        {
+        User::Leave( KErrArgument );
+        }
+
+	CleanupStack::PushL(aAttendee);
+	__ASSERT_ALWAYS(aAttendee != NULL, User::Leave(KErrArgument));
+	PopulateAttendeeListL();
+
+	CCalUserImpl* userImpl = aAttendee->Impl();
+	CAgnAttendee* attendee = userImpl->Attendee();
+	
+	// add attendee to CAgnEntry (no longer owned by CCalAttendee)
+	userImpl->SetOwnsCAgnAttendee(EFalse);		
+	iFullEntry->AddAttendeeL(attendee);		
+	
+	// store attendee in attendee array too
+	iCalAttendeeList->AppendL(aAttendee);
+	CleanupStack::Pop(aAttendee);
+	}
+
+RPointerArray<CCalAttendee>& CCalEntryImpl::AttendeesL()
+	{
+	PopulateAttendeeListL();
+	return *iCalAttendeeList;
+	}
+
+void CCalEntryImpl::DeleteAttendeeL(TInt aIndex)
+	{
+	LoadFullEntryL();
+
+	if(iCalAttendeeList)
+		{
+		if (aIndex < 0 || aIndex >= iCalAttendeeList->Count())
+			{
+			User::Leave(KErrArgument);
+			}
+		delete (*iCalAttendeeList)[aIndex];
+		iCalAttendeeList->Remove(aIndex);
+		}
+
+	iFullEntry->DeleteAttendee(aIndex);
+	}
+
+void CCalEntryImpl::SetOrganizerL(CCalUser* aUser)
+	{
+	CleanupStack::PushL(aUser);
+	__ASSERT_ALWAYS(aUser != NULL, User::Leave(KErrArgument));
+	LoadFullEntryL();
+	
+	aUser->Impl()->SetOwnsCAgnAttendee(EFalse);
+	iFullEntry->SetOrganizerL(aUser->Impl()->Attendee());	//	takes ownership of user immediately
+
+	delete iCalOrganizer;
+	iCalOrganizer = aUser;
+	CleanupStack::Pop(aUser);
+	}
+
+void CCalEntryImpl::SetPhoneOwnerL(const CCalUser* aOwner)
+	{
+	__ASSERT_ALWAYS(aOwner != NULL, User::Leave(KErrArgument));
+	LoadFullEntryL();
+	CCalUserImpl* userImpl = aOwner->Impl();
+	iFullEntry->SetPhoneOwnerL(userImpl->Attendee());
+	}
+
+CCalUser* CCalEntryImpl::PhoneOwnerL()
+	{
+	LoadFullEntryL();
+
+	CAgnAttendee* agnPhoneOwner = iFullEntry->PhoneOwner();
+
+	if(agnPhoneOwner)
+		{	
+		//check to see if phone owner is the organizer
+		if(OrganizerL())
+			{
+			if(agnPhoneOwner == iCalOrganizer->Impl()->Attendee())
+				{
+				return iCalOrganizer;
+				}
+			}
+
+		PopulateAttendeeListL();
+		
+		// see if the phone owner is one of the other attendees
+		const TInt KAttendeeCount = iCalAttendeeList->Count();
+		for(TInt i = 0; i < KAttendeeCount; ++i)
+			{
+			CCalAttendee* calAttendee = (*iCalAttendeeList)[i];
+			if(agnPhoneOwner == calAttendee->Impl()->Attendee())
+				{
+				return calAttendee;
+				}
+			}
+		}
+	return NULL;
+	}
+
+
+CCalUser* CCalEntryImpl::OrganizerL()
+	{
+	LoadFullEntryL();
+	if( ! iCalOrganizer)
+		{
+		CAgnAttendee* organizer = iFullEntry->Organizer();
+		
+		if(organizer)
+			{
+			CCalUserImpl* impl = CCalUserImpl::NewL(organizer);
+			CleanupStack::PushL(impl);
+			impl->SetOwnsCAgnAttendee(EFalse);
+			iCalOrganizer = CCalUser::NewL(impl);
+			CleanupStack::Pop(impl);
+			}
+		}
+
+	return iCalOrganizer;
+	}
+
+CTzRules* CCalEntryImpl::GetTzRulesL()
+	{
+	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
+	
+	if (rptDef == NULL)
+		{
+		return NULL;
+		}
+	return rptDef->CloneTzRulesL();
+	}
+
+void CCalEntryImpl::SetTzRulesL(const CTzRules& aTzRules)
+	{
+	LoadFullEntryL();
+	
+	if (TimeMode() == MAgnCalendarTimeMode::EFloating)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CAgnRptDef* rptDef = SimpleEntry()->RptDef(); // doesn't take ownership
+	
+	if (!rptDef)
+		{
+		User::Leave(KErrNotFound);
+		}
+   
+	rptDef->SetTimeZoneL(aTzRules); // rptDef doesn't take ownership of aTzRules
+	}
+
+void CCalEntryImpl::SetTzRulesL()
+	{
+	LoadFullEntryL();
+	
+	if (TimeMode() == MAgnCalendarTimeMode::EFloating)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
+	if (rptDef == NULL)
+		{
+		User::Leave(KErrNotFound);
+		}
+	rptDef->SetTimeZoneL();
+	}
+
+void CCalEntryImpl::SetRDatesL(const RArray<TCalTime>& aRDates)
+	{
+	LoadFullEntryL();
+	SetDatesL(ETrue, aRDates);
+	}
+
+void CCalEntryImpl::SetExceptionDatesL(const RArray<TCalTime>& aExDates)
+	{
+	LoadFullEntryL();
+	
+	if (iFullEntry->RptDef() == NULL)
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	SetDatesL(EFalse, aExDates);
+	}
+	
+//if aDateType is ETrue, add dates to sporadic date list
+//if aDateType is EFalse, add dates to exception list
+void CCalEntryImpl::SetDatesL(TBool aDateType, const RArray<TCalTime>& aDates)
+	{
+	const TCalTime::TTimeMode KEntryTimeMode = static_cast<TCalTime::TTimeMode>(TimeMode());
+	const TInt KDateCount = aDates.Count();
+	TInt i = 0;
+	for (i = 0; i < KDateCount; i++)
+		{
+		if (aDates[i].TimeMode() != KEntryTimeMode)
+			{
+			User::Leave(KErrArgument);
+			}
+		}
+
+	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
+
+	TBool entryHasNoRptDef(rptDef == NULL);
+	if (entryHasNoRptDef)
+		{
+		rptDef = CAgnRptDef::NewL(*SimpleEntry());
+		CleanupStack::PushL(rptDef);
+		}
+	else
+		{
+		if (aDateType)
+			{
+			rptDef->RemoveAllSporadicDates();
+			}
+		else
+			{
+			rptDef->RemoveAllExceptions();
+			}
+		}
+
+	// store the dates
+	for (i = 0; i < KDateCount; ++i)
+		{
+		TAgnCalendarTime agnTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aDates[i]);
+		if (aDateType)
+			{
+			rptDef->AddSporadicDateL(agnTime);
+			}
+		else
+			{
+			rptDef->AddExceptionL(agnTime);
+			}
+		}
+
+	// if the rptDef didn't exist in the entry already, add it
+	if (entryHasNoRptDef)
+		{
+		iFullEntry->SetRptDefL(*rptDef); // makes a copy of rptDef
+		CleanupStack::PopAndDestroy(rptDef);
+		}
+	}
+
+void CCalEntryImpl::GetRDatesL(RArray<TCalTime>& aRDates)
+	{
+	aRDates.Reset();
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	if (KRptDef)
+		{
+		FetchDatesL(KRptDef->SporadicDateList(), aRDates);
+		}
+	}
+
+void CCalEntryImpl::GetExceptionDatesL(RArray<TCalTime>& aExDates)
+	{
+	aExDates.Reset();
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	if (KRptDef)
+		{
+		FetchDatesL(KRptDef->Exceptions(), aExDates);
+		}
+	}
+	
+void CCalEntryImpl::FetchDatesL(const RArray<TAgnCalendarTime>* aDateList, RArray<TCalTime>& aRDates)
+	{
+	// aDateList may be NULL
+	if (aDateList)
+		{
+		const TInt KDateCount = aDateList->Count();
+		for (TInt i = 0; i < KDateCount; ++i)
+			{
+			TCalTime calTime = CalUtils::TAgnCalendarTimeToTCalTimeL((*aDateList)[i]);
+			aRDates.AppendL(calTime);
+			}
+		}
+	}
+
+CCalEntry::TMethod CCalEntryImpl::MethodL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->Method();
+	}
+	
+TCalTime CCalEntryImpl::RecurrenceIdL()
+	{
+	// If this entry has been committed to store, the Rec-Id can be retrieved from the
+	// CAgnEntryModel by passing the appropraite CAgnEntry.
+	// Else try to retrieve it from CAgnEntry's temporary GS data.
+
+	LoadFullEntryL();
+	return CalUtils::TAgnCalendarTimeToTCalTimeL(iFullEntry->RecurrenceId());
+	}
+	
+CalCommon::TRecurrenceRange CCalEntryImpl::RecurrenceRangeL()
+   	{
+   	LoadFullEntryL();
+	return iFullEntry->RecurrenceRange();
+   	}
+	
+const TDesC8& CCalEntryImpl::UidL()
+	{
+	LoadFullEntryL();
+	// Does not transfer ownership
+	if(iFullEntry->Guid() == KNullDesC8)
+		{
+		// this entry must be a child entry whose GUID has not been loaded
+		__ASSERT_ALWAYS(iFullEntry->GsDataType() == CGsData::EChild, User::Leave(KErrCorrupt)); 
+		
+		// get parent entry
+		TCalLocalUid parentId = iFullEntry->ParentId();
+		CAgnEntry* parentEntry = iSessionImpl->Server().FetchEntryL(parentId, iSessionImpl->FileId());
+		__ASSERT_ALWAYS(parentEntry, User::Leave(KErrNotFound));
+		CleanupStack::PushL(parentEntry);
+		HBufC8* guidHbuf = parentEntry->Guid().AllocL();
+		CleanupStack::PopAndDestroy(parentEntry);	
+
+		iFullEntry->SetGuid(guidHbuf);
+		}
+		
+	return iFullEntry->Guid();
+	}
+
+
+TInt CCalEntryImpl::SequenceNumberL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->SequenceNumber();
+	}
+
+
+void CCalEntryImpl::SetMethodL(CCalEntry::TMethod aMethod)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetMethod(aMethod);
+	}
+
+const RPointerArray<CCalCategory>& CCalEntryImpl::CategoryListL()
+	{
+	PopulateCategoryListL();
+
+	return *iCalCategoryList;
+	}
+
+void CCalEntryImpl::AddCategoryL(CCalCategory* aCategory)
+	{
+	CleanupStack::PushL(aCategory);
+	__ASSERT_ALWAYS(aCategory != NULL, User::Leave(KErrArgument));
+	
+ 	PopulateCategoryListL();
+
+	// add the category to the list
+ 	iCalCategoryList->AppendL(aCategory);
+	CleanupStack::Pop(aCategory);
+
+	TInt err(KErrNone);
+
+	// add category to CAgnEntry
+	TRAP(err , iFullEntry->AddCategoryL( aCategory->Impl()->AgnCategory() ) ); // this can leave before taking ownership
+
+ 	if (err != KErrNone)
+ 		{
+ 		delete (*iCalCategoryList)[iCalCategoryList->Count() - 1];
+ 		iCalCategoryList->Remove(iCalCategoryList->Count() - 1);
+ 		User::Leave(err);
+ 		}
+
+ 	aCategory->Impl()->SetOwnAgnCategory(EFalse);
+	}
+
+void CCalEntryImpl::DeleteCategoryL(TInt aIndex)
+	{
+	LoadFullEntryL();
+	
+	if (aIndex < 0 || aIndex >= iFullEntry->CategoryCount())
+		{
+		User::Leave(KErrArgument);
+		}
+			
+	iFullEntry->DeleteCategory(aIndex);
+	if(iCalCategoryList)
+		{
+		delete (*iCalCategoryList)[aIndex];
+		iCalCategoryList->Remove(aIndex);
+		
+		// check count of CAgnCategory and CCalCategory is the same
+		__ASSERT_DEBUG(iCalCategoryList->Count() == iFullEntry->CategoryCount(), Panic(EAgmErrCategoryCountCorrupt)); 
+		}
+	}
+
+TBool CCalEntryImpl::GetRRuleL(TCalRRule& aRule)
+	{
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	if (KRptDef == NULL || KRptDef->RRule() == NULL)
+		{
+		return EFalse;
+		}
+
+	const TAgnRpt* KRpt = KRptDef->RRule();
+
+	// get the DTSTART property
+	if (SimpleEntry()->Type() == CCalEntry::ETodo)
+		{
+		aRule.SetDtStart(EndTimeL());
+		}
+	else
+		{
+		aRule.SetDtStart(StartTimeL());
+		}
+
+	TInt repCount = 0;
+	TCalTime untilCaltime = CalUtils::TAgnCalendarTimeToTCalTimeL(KRpt->UntilTimeL());
+		
+	if (untilCaltime.TimeLocalL() == TCalTime::MaxTime())
+		{
+		//Idealy, only UTC maximum time should be used to indicate the repeating forever. However, for a behaviour compatible reason,
+		//when the client sets local or UTC repeating until time to be maximum time, it is treated as repeating forever. 
+		untilCaltime.SetTimeUtcL(TCalTime::MaxTime());
+		}
+	else
+		{
+		repCount = KRpt->InstanceCountL();
+		}
+
+	aRule.SetUntilAndCount(untilCaltime, repCount);	
+	
+	// get the INTERVAL property
+	aRule.SetInterval(KRpt->Interval());
+
+	// get the TCalRRule's type, and type-specific data
+	switch (KRpt->Type())
+		{
+		case TAgnRpt::EDaily:
+			aRule.SetType(TCalRRule::EDaily);
+			break;
+		case TAgnRpt::EYearlyByDate:
+			aRule.SetType(TCalRRule::EYearly);
+			break;
+		case TAgnRpt::EYearlyByDay:
+			{
+			aRule.SetType(TCalRRule::EYearly);
+
+			TDay day;
+			TAgnRpt::TWeekInMonth weekInMonth;
+			TMonth month;
+			TInt year;
+
+			const TAgnYearlyByDayRpt* KYearlyRpt = static_cast<const TAgnYearlyByDayRpt*>(KRpt);
+			KYearlyRpt->GetStartDayL(day, weekInMonth, month, year);
+			TInt8 week = CalUtils::AgnWeekInMonthToWeekNumberL(weekInMonth);
+			TCalRRule::TDayOfMonth dayOfMonth(day, week);
+
+			RArray<TCalRRule::TDayOfMonth> dayOfMonthArray;
+			CleanupClosePushL(dayOfMonthArray);
+			dayOfMonthArray.AppendL(dayOfMonth);
+			aRule.SetByDay(dayOfMonthArray);
+			CleanupStack::PopAndDestroy(&dayOfMonthArray);
+
+			RArray<TMonth> monthArray;
+			CleanupClosePushL(monthArray);
+			monthArray.AppendL(month);
+			aRule.SetByMonth(monthArray);
+			CleanupStack::PopAndDestroy(&monthArray);
+			}
+			break;
+		case TAgnRpt::EWeekly:
+			{
+			aRule.SetType(TCalRRule::EWeekly);
+			const TAgnWeeklyRpt* KWeeklyRpt = static_cast<const TAgnWeeklyRpt*>(KRpt);
+			aRule.SetWkSt(KWeeklyRpt->FirstDayOfWeek());
+
+			RArray<TDay> array;
+			CleanupClosePushL(array);
+			TDay day = EMonday;
+			while (day <= ESunday)
+				{
+				if (KWeeklyRpt->IsDaySet(day))
+					{
+					array.AppendL(day);
+					}
+				day = static_cast<TDay>(static_cast<TInt>(day) + 1);
+				}
+			aRule.SetByDay(array);
+			CleanupStack::PopAndDestroy(&array);
+			}
+			break;
+		case TAgnRpt::EMonthlyByDays:
+			{
+			aRule.SetType(TCalRRule::EMonthly);
+			const TAgnMonthlyByDaysRpt* KMonthlyByDayRpt = static_cast<const TAgnMonthlyByDaysRpt*>(KRpt);
+
+			RArray<TCalRRule::TDayOfMonth> dayArray;
+			CleanupClosePushL(dayArray);
+			
+			TAgnRpt::TWeekInMonth week = TAgnRpt::EFirst;
+			while (week <= TAgnRpt::ELast)
+				{
+				TDay day = EMonday;
+				while (day <= ESunday)
+					{
+					if (KMonthlyByDayRpt->IsDaySet(day, week))
+						{
+						TInt8 weekInt = CalUtils::AgnWeekInMonthToWeekNumberL(week);
+						TCalRRule::TDayOfMonth dayOfMonth(day, weekInt);
+						dayArray.AppendL(dayOfMonth);
+						}
+					day = static_cast<TDay>(static_cast<TInt>(day) + 1);
+					}
+			
+				week = static_cast<TAgnRpt::TWeekInMonth>(static_cast<TInt>(week) + 1);
+				}
+			//coverity [dead_error_begin]
+			aRule.SetByDay(dayArray);
+
+			CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close()
+			}
+			break;
+		case TAgnRpt::EMonthlyByDates:
+			{
+			aRule.SetType(TCalRRule::EMonthly);
+			const TAgnMonthlyByDatesRpt* KMonthlyByDateRpt = static_cast<const TAgnMonthlyByDatesRpt*>(KRpt);
+
+			RArray<TInt> array;
+			CleanupClosePushL(array);
+			for (TInt i = 0; i < 31; ++i) // dates run from 0 to 30
+				{
+				if (KMonthlyByDateRpt->IsDateSet(i))
+					{
+					array.AppendL(i);
+					}
+				}
+			aRule.SetByMonthDay(array);
+			CleanupStack::PopAndDestroy(&array);
+			}
+			break;
+		default:
+			CalUtils::Panic(EInvalidRepeatRuleType);
+			break;
+		}
+
+	return ETrue;
+	}
+
+TBool CCalEntryImpl::CompareL(const CCalEntry& aEntry)
+	{
+	// load full CAgnEntries before comparison
+	LoadFullEntryL();
+	aEntry.Impl()->LoadFullEntryL();
+	
+	// Load both entry's summary, description and alarm action data before comparing - these properties
+	// are stored in separate streams so may not be loaded at this point
+	SummaryL();
+	aEntry.SummaryL();
+	DescriptionL();
+	aEntry.DescriptionL();
+	delete AlarmL();
+	delete aEntry.AlarmL();
+	
+	return (iFullEntry->CompareL(*aEntry.Impl()->GetFullEntryL()));
+	}
+
+void CCalEntryImpl::CopyFromL(CCalEntryImpl& aOther, CCalEntry::TCopyType aCopyType)
+	{
+	TCalCollectionId collectionId = 0;
+	if (iLiteEntry)
+		{
+		TUint8 collectionId = aOther.SimpleEntry()->CollectionId();
+		}
+	aOther.LoadFullEntryL();
+	// Delete old state.
+	ClearSimpleEntry();
+
+	if(iCalAttendeeList)
+		{
+		iCalAttendeeList->ResetAndDestroy();
+		delete iCalAttendeeList; 	
+		iCalAttendeeList = NULL;
+		}
+
+	if(iCalCategoryList)
+		{
+		iCalCategoryList->ResetAndDestroy();
+		delete iCalCategoryList; 
+		iCalCategoryList = NULL;
+		}
+
+	delete iCalOrganizer;
+	iCalOrganizer = NULL;
+
+	if(iSessionImpl)
+		{
+        // Use this entry's existing uid.
+		iSessionImpl->DecrementReferenceCount();
+		}
+	iSessionImpl = aOther.iSessionImpl;
+	if (iSessionImpl)
+		{
+		iSessionImpl->IncrementReferenceCount();
+		}
+
+	// ensure other entry has a full CAgnEntry
+	aOther.LoadFullEntryL();
+	
+	// ensure other entry has summary, description and alarm action properties loaded - these
+	// are stored in separate streams
+	aOther.SummaryL();
+	aOther.DescriptionL();
+	delete aOther.AlarmL();
+	
+	iFullEntry->CopyFromL(*aOther.iFullEntry, aCopyType);
+	iFullEntry->SetLastModifiedDate();
+	iFullEntry->SetCollectionId(collectionId);
+	}
+
+void CCalEntryImpl::SetAlarmL(CCalAlarm* aAlarm)
+	{
+	LoadFullEntryL();
+	
+	if ( aAlarm == NULL ) 
+		{
+		// if aAlarm is NULL, clear the alarm data
+		iFullEntry->ClearAlarm();
+		}
+	else
+		{
+		// This method does not take ownership of aAlarm, so need to copy the alarm details
+		// before adding to the entry.
+		
+		// the alarm must be on the same day in local time as the event
+		TDateTime dt = iFullEntry->EntryTime().LocalL().DateTime();
+		TInt minutes = dt.Hour()*60 + dt.Minute();
+		__ASSERT_ALWAYS(minutes - aAlarm->TimeOffset().Int() <= KAgnMinutesInADay, User::Leave(KErrNotSupported));
+
+		iFullEntry->SetAlarmOffset(aAlarm->TimeOffset());
+	 	iFullEntry->SetAlarmSoundNameL(aAlarm->AlarmSoundNameL());
+
+		CCalContent* alarmAction = aAlarm->AlarmAction(); // doesn't take ownership
+		
+		if ( alarmAction )
+			{
+			CAgnContent* agnAlarmAction = static_cast<CAgnContent*>(alarmAction->Impl());
+			
+			if ( agnAlarmAction )
+				{
+				CAgnContent* alarmActionCopy = agnAlarmAction->CloneL();
+				iFullEntry->SetAlarmAction(alarmActionCopy); // entry takes ownership of alarmActionCopy
+				}					
+			}
+		else
+		    {
+		    iFullEntry->SetAlarmAction(NULL); 
+		    }
+		}
+	}
+
+CCalAlarm* CCalEntryImpl::AlarmL()
+	{
+	LoadFullEntryL();
+	
+	if (!iFullEntry->HasAlarm())
+		{
+		return NULL;
+		}
+        
+	TTime time = iFullEntry->EntryTime().LocalL();
+	
+	// Invalid or non-existant entries are set on import to NULL time
+	// That being the case, we return NULL for the Alarm.
+	TDateTime timeOfEvent;
+	if(time == Time::NullTTime())
+		{
+		return NULL;
+		}
+	else
+		{
+		timeOfEvent = time.DateTime();
+		}
+
+	CCalAlarm* alarm = CCalAlarm::NewL();
+	CleanupStack::PushL(alarm);
+	
+	alarm->SetTimeOffset(iFullEntry->AlarmOffset().Int());
+	alarm->SetAlarmSoundNameL(iFullEntry->AlarmSoundName());
+	
+	if(!iFullEntry->AlarmActionIsLoaded())
+		{
+		CAgnContent* agnAlarmaction = iSessionImpl->Server().RestoreAlarmActionL(iFullEntry->AlarmActionStreamId(), iSessionImpl->FileId());
+		// Restore should always return something, even if it's only a Null Descriptor
+		iFullEntry->SetAlarmAction(agnAlarmaction);
+		}
+
+	if (iFullEntry->AlarmAction())
+		{
+		CCalContent* alarmAction = CCalContent::NewL();
+		CleanupStack::PushL(alarmAction);
+		CAgnContent* agnAlarmActionCopy = iFullEntry->AlarmAction()->CloneL();
+		alarmAction->SetImpl(agnAlarmActionCopy); // Takes ownership of agnAlarmAction.
+		alarm->SetAlarmAction(alarmAction); // Takes ownership of alarmAction.
+		CleanupStack::Pop(alarmAction);
+		}
+
+	CleanupStack::Pop(alarm);
+	return alarm;
+	}
+
+void CCalEntryImpl::SetCommonRptDataL(const TCalRRule& aRpt, CAgnRptDef& aRptRule)
+	{
+	// set repeat rule data which is not specific to the rule type
+	// Both repeating count and until time could be set. If so, the one come earlist will be set as repeating until time.
+	// Note that the repeating until time will be adjusted in TAgnRpt::UntilTimeL() when the entry is stored (CCalEntryViewImpl::DoStore and 
+	// CAgnSimpleEntry::AdjustStartUntilTimeForRepEntryL)By then, the TZ rule has been set to a repeating entry.
+	aRptRule.SetInterval(aRpt.Interval());
+	const_cast<TAgnRpt*> (aRptRule.RRule())->SetCount(aRpt.Count());
+
+    TTime untilTime = aRpt.Until().TimeLocalL();
+    if (untilTime != Time::NullTTime())
+    	{
+		TAgnCalendarTime untilTimeTAgn = CalUtils::TCalTimeToTAgnCalendarTimeL(aRpt.Until());
+		aRptRule.SetUntilTime(untilTimeTAgn);
+    	}
+	}
+
+void CCalEntryImpl::SetRRuleL(const TCalRRule& aRpt)
+	{
+	if (aRpt.Until().TimeLocalL() != Time::NullTTime() && aRpt.DtStart().TimeLocalL() >= aRpt.Until().TimeLocalL())
+		{
+		// if Until time is set to earlier than the start time and is non-NULL, leave
+		User::Leave(KErrArgument);
+		}
+	LoadFullEntryL();
+
+	//Leaves if this is a todo entry and its end date has not been set or this is a non-todo entry and its start date has not been set
+	//since repeating pattern is based on those time attributes.
+	if ( ! iFullEntry->EntryTime().IsSet())
+		{
+		User::Leave(KErrArgument);
+		}
+
+	TBool createdNewRptDef = EFalse;
+	CAgnRptDef* rptDef = iFullEntry->RptDef();
+	if(rptDef == NULL)
+		{
+		rptDef = CAgnRptDef::NewL(*iFullEntry);
+		CleanupStack::PushL(rptDef);
+		createdNewRptDef = ETrue;
+		}
+
+	switch (aRpt.Type())
+		{
+		case TCalRRule::EDaily:
+			{
+			TAgnDailyRpt daily(*rptDef);
+			rptDef->SetRRuleL(daily);
+			}
+			break;
+		case TCalRRule::EWeekly:
+			{
+			TAgnWeeklyRpt weekly(*rptDef);
+			weekly.SetFirstDayOfWeek(aRpt.WkSt());
+			RArray<TDay> array;
+			CleanupClosePushL(array);
+			aRpt.GetByDayL(array);
+			const TInt KWeeklyDayCount = array.Count();
+			for (TInt i = 0; i < KWeeklyDayCount; ++i)
+				{
+				weekly.SetDay(array[i]);
+				}
+			CleanupStack::PopAndDestroy(&array);
+			
+			rptDef->SetRRuleL(weekly);
+			}
+			break;
+		case TCalRRule::EMonthly:
+			{
+			RArray<TInt> array;
+			CleanupClosePushL(array);
+			aRpt.GetByMonthDayL(array);
+			if (array.Count() <= 0)
+				{
+				// may be monthly by week
+				RArray<TCalRRule::TDayOfMonth> dayArray;
+				CleanupClosePushL(dayArray);
+				aRpt.GetByDayL(dayArray);
+				const TInt KMonthlyDayCount = dayArray.Count();
+				if (KMonthlyDayCount > 0)
+					{
+					TAgnMonthlyByDaysRpt monthlyByDayAndWeek(*rptDef);
+					for (TInt i = 0; i < KMonthlyDayCount; ++i)
+						{
+						TCalRRule::TDayOfMonth dayOfMonth = dayArray[i];
+						TAgnRpt::TWeekInMonth weekNum = CalUtils::WeekNumberToAgnWeekInMonthL(dayOfMonth.WeekInMonth());
+						monthlyByDayAndWeek.SetDay(dayOfMonth.Day(), weekNum);
+						}
+					
+					rptDef->SetRRuleL(monthlyByDayAndWeek);
+					}
+				CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close()
+				}
+			else
+				{
+				TAgnMonthlyByDatesRpt monthlyByDate(*rptDef);
+				const TInt KMonthlyDateCount = array.Count();
+				for (TInt i = 0; i < KMonthlyDateCount; ++i)
+					{
+					monthlyByDate.SetDate(array[i]);
+					}
+				
+				rptDef->SetRRuleL(monthlyByDate);
+				}
+			CleanupStack::PopAndDestroy(&array); // array.Reset();
+			}
+			break;
+		case TCalRRule::EYearly:
+			{
+			RArray<TCalRRule::TDayOfMonth> dayArray;
+			CleanupClosePushL(dayArray);
+			aRpt.GetByDayL(dayArray);
+			if (dayArray.Count() > 0)
+				{
+				RArray<TMonth> monthArray;
+				CleanupClosePushL(monthArray);
+				aRpt.GetByMonthL(monthArray);
+				if (monthArray.Count() > 0)
+					{
+					TDay day = dayArray[0].Day();
+					TAgnRpt::TWeekInMonth week = CalUtils::WeekNumberToAgnWeekInMonthL(dayArray[0].WeekInMonth());
+					TMonth month = monthArray[0];
+
+					TAgnYearlyByDayRpt yearlyByDay(*rptDef);
+
+					// Check that the first month to repeat on is earlier than the repeat dtstart date...
+					TDateTime rptStartTime = aRpt.DtStart().TimeUtcL().DateTime();
+					TInt year = rptStartTime.Year();
+					if (month < rptStartTime.Month())
+						{
+						// ...if not, start the following year
+						year++;
+						}
+						
+					TTime newStartDay = yearlyByDay.FindStartDayL(day, week, month, year);
+					TCalTime newStartDaycal;
+					newStartDaycal.SetTimeLocalL(newStartDay);
+					const_cast<TCalRRule&>(aRpt).SetDtStart(newStartDaycal);
+					TTime untilTimeLocal = yearlyByDay.UntilTimeL().LocalL();
+					TDateTime rptUntilTime = untilTimeLocal.DateTime();
+					if (aRpt.Count() != 0 || year < rptUntilTime.Year() ||
+						(year == rptUntilTime.Year() && month < rptUntilTime.Month())
+						)
+						{
+                        // The count has been set
+                        // or the first month to repeat on is not later than the repeat until date
+						rptDef->SetRRuleL(yearlyByDay);
+						}
+					}
+				else
+					{
+					User::Leave(KErrArgument);	
+					}	
+				CleanupStack::PopAndDestroy(&monthArray);
+				}
+			else
+				{
+				TAgnYearlyByDateRpt yearlyByDate(*rptDef);
+				rptDef->SetRRuleL(yearlyByDate);
+				}
+			CleanupStack::PopAndDestroy(&dayArray);
+			}
+			break;
+		default:
+			User::Leave(KErrNotSupported);
+			break;
+		}
+	
+	if (rptDef->RRule())
+		{
+		SetCommonRptDataL(aRpt, *rptDef);
+		}
+	
+	if (createdNewRptDef)
+		{
+		if (rptDef->RRule())
+			{
+			iFullEntry->SetRptDefL(*rptDef);
+			}
+		CleanupStack::PopAndDestroy(rptDef);
+		}
+	
+	//Move the entry start date is same as repeating date
+	
+	TDateTime newEntryDateTime;
+	if(EntryTypeL() == CCalEntry::ETodo)
+		{
+		newEntryDateTime = EndTimeL().TimeLocalL().DateTime();	
+		}
+	else
+		{
+		newEntryDateTime = StartTimeL().TimeLocalL().DateTime();		
+		}
+
+	newEntryDateTime.SetYear(aRpt.DtStart().TimeLocalL().DateTime().Year());
+	newEntryDateTime.SetMonth(aRpt.DtStart().TimeLocalL().DateTime().Month());
+	newEntryDateTime.SetDay(aRpt.DtStart().TimeLocalL().DateTime().Day());
+	
+	//adjust the entrytime (it the entry start time for non-todos and end time for todos) 
+	iFullEntry->MoveStartTimeLocalL(newEntryDateTime);
+	}
+
+void CCalEntryImpl::ClearRepeatingPropertiesL()
+	{
+	SimpleEntry()->ClearRepeat();
+	}
+
+TCalTime CCalEntryImpl::NextInstanceForLocalUIDL(const TCalTime& aTime)
+	{
+	const TTime KTimeUtc = aTime.TimeUtcL() + TTimeIntervalMicroSeconds(1);
+	TTime nextTimeUtc = Time::NullTTime();
+	
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	if (KRptDef)
+		{
+		if (KRptDef->NudgeNextInstanceUtcL(KTimeUtc, nextTimeUtc) == EFalse)
+			{
+			nextTimeUtc = Time::NullTTime();
+			}
+		}
+	else
+		{
+		TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL();
+		if (KTimeUtc < entryTimeUtc)
+			{
+			nextTimeUtc = entryTimeUtc;
+			}
+		}
+	
+	TCalTime calTime;
+	calTime.SetTimeUtcL(nextTimeUtc);
+	return calTime;
+	}
+
+TCalTime CCalEntryImpl::PreviousInstanceForLocalUIDL(const TCalTime& aTime)
+	{
+	const TTime KTimeUtc = aTime.TimeUtcL() - TTimeIntervalMicroSeconds(1);
+	TTime prevTimeUtc = Time::NullTTime();
+	
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	if (KRptDef)
+		{
+		if (KRptDef->NudgePreviousInstanceUtcL(KTimeUtc, prevTimeUtc) == EFalse)
+			{
+			prevTimeUtc = Time::NullTTime();
+			}
+		}
+	else
+		{
+		TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL();
+		if (KTimeUtc > entryTimeUtc)
+			{
+			prevTimeUtc = entryTimeUtc;
+			}
+		}
+	
+	TCalTime calTime;
+	calTime.SetTimeUtcL(prevTimeUtc);
+	return calTime;
+	}
+	
+TCalTime CCalEntryImpl::LastModifiedDateL()
+	{
+	TTime lastModifiedEntry = SimpleEntry()->LastModifiedDateUtc();
+	if(iSessionImpl && SimpleEntry()->RptDef() && SimpleEntry()->TimeMode()!= MAgnCalendarTimeMode::EFloating)
+		{
+		TTime lastModifiedTzChange = iSessionImpl->TzRulesLastModifiedDateL();
+		if(lastModifiedTzChange>lastModifiedEntry)
+			{
+			lastModifiedEntry = lastModifiedTzChange;
+			}
+		}
+	TCalTime lastModifiedTime;
+	lastModifiedTime.SetTimeUtcL(lastModifiedEntry);
+	return lastModifiedTime;
+	}
+
+TCalTime CCalEntryImpl::DTStampL()
+	{
+	LoadFullEntryL();
+	TCalTime dTStampTime;
+	dTStampTime.SetTimeUtcL(iFullEntry->DTStampUtcL());
+	return dTStampTime;
+	}
+
+void CCalEntryImpl::SetLocationL(const TDesC& aLocation)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetLocationL(aLocation);
+	}
+
+const TDesC& CCalEntryImpl::LocationL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->Location();
+	}
+
+void CCalEntryImpl::SetPriorityL(TUint aPriority)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetPriority(aPriority);
+	}
+
+TUint CCalEntryImpl::PriorityL()
+	{
+	return SimpleEntry()->Priority();
+	}
+
+TCalTime CCalEntryImpl::StartTimeL()
+	{
+	return CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->StartTime());
+	}
+
+TCalTime CCalEntryImpl::EndTimeL()
+	{
+	TCalTime calEndTime; // initialised to Null time on construction
+	if (SimpleEntry()->Type() != CCalEntry::EReminder)
+		{
+		calEndTime = CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->EndTime());
+		}
+	return calEndTime;
+	}
+
+void CCalEntryImpl::SetStartAndEndTimeL(const TCalTime& aStartTime, const TCalTime& aEndTime)
+	{
+	LoadFullEntryL();
+	TCalTime::TTimeMode mode = aStartTime.TimeMode();
+	if (aEndTime.TimeUtcL() != Time::NullTTime())
+		{
+		if (aStartTime.TimeUtcL() != Time::NullTTime())
+			{
+			// both times are non-null so check the modes
+			__ASSERT_ALWAYS(aStartTime.TimeMode() == aEndTime.TimeMode(), User::Leave(KErrArgument));
+
+			// both times are non-null so check that end time is not earlier than start time
+			__ASSERT_ALWAYS(aStartTime.TimeUtcL() <= aEndTime.TimeUtcL(), User::Leave(KErrArgument));
+			}
+		else
+			{
+			// start time non-null so fetch mode from end time
+			mode = aEndTime.TimeMode();
+			}
+		}
+	__ASSERT_ALWAYS(mode == TCalTime::EFixedUtc || mode == TCalTime::EFloating, User::Leave(KErrArgument));
+
+	// either this is a parent entry, or time mode should match recurrence ID
+	__ASSERT_ALWAYS(RecurrenceIdL().TimeUtcL() == Time::NullTTime() ||
+					mode == RecurrenceIdL().TimeMode(),
+					User::Leave(KErrArgument));		
+
+	TAgnCalendarTime agnStartTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aStartTime);
+	TAgnCalendarTime agnEndTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aEndTime);
+
+	const CCalEntry::TType KType = SimpleEntry()->Type();
+		
+	switch (KType)
+		{
+		case CCalEntry::ETodo:
+			// for todos, if end time is not set, set start time to null as well - this is an undated entry
+			if ( ! agnEndTime.IsSet())
+				{
+				agnStartTime = agnEndTime;
+				}
+			break;
+		case CCalEntry::EReminder:
+			// for reminders, end time is the same as start time
+			agnEndTime = agnStartTime;
+			break;
+		case CCalEntry::EAppt:
+		case CCalEntry::EAnniv:
+		case CCalEntry::EEvent:
+			// for other entries, if end time is not set, make it the same as the start time
+			if ( ! agnEndTime.IsSet())
+				{
+				agnEndTime = agnStartTime;
+				}
+			break;
+		default:
+			// bad entry type
+			User::Leave(KErrArgument);
+			break;
+		}
+		
+	iFullEntry->SetStartAndEndTimeL(agnStartTime, agnEndTime);
+	}
+
+MAgnCalendarTimeMode::TTimeMode CCalEntryImpl::TimeMode() const
+	{
+	return SimpleEntry()->TimeMode();
+	}
+
+TCalTime CCalEntryImpl::CompletedTimeL()
+	{
+	TTime completedDateUtc(Time::NullTTime());
+	if (SimpleEntry()->Type() == CCalEntry::ETodo)
+		{
+		completedDateUtc = SimpleEntry()->CompletedDateUtc();
+		}
+	TCalTime calCompletedDate;
+	calCompletedDate.SetTimeUtcL(completedDateUtc);
+	return calCompletedDate;
+	}
+
+void CCalEntryImpl::SetCompletedL(TBool aCompleted, const TCalTime& aDate)
+	{
+	LoadFullEntryL();
+	if (SimpleEntry()->Type() == CCalEntry::ETodo)
+		{
+		if (aCompleted)
+			{
+			SimpleEntry()->SetCompletedDateUtcL(aDate.TimeUtcL());
+			SetStatusL(CCalEntry::ETodoCompleted);
+			}
+		else
+			{
+			SimpleEntry()->SetIncomplete(); // resets completed date to null time
+			SetStatusL(CCalEntry::ETodoNeedsAction);
+			}
+		}
+	else
+		{
+		User::Leave(KErrNotSupported);
+		}
+	}
+
+void CCalEntryImpl::SetSummaryL(const TDesC& aSummary)
+	{
+	LoadFullEntryL();
+	HBufC* summ = aSummary.AllocL();
+	iFullEntry->SetSummary(summ); // takes ownership of aSummary
+	}
+
+const TDesC& CCalEntryImpl::SummaryL()
+	{
+	LoadFullEntryL();
+
+	if(!iFullEntry->SummaryIsLoaded())
+		{
+		__ASSERT_DEBUG(iFullEntry->SummaryStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId));
+		HBufC* summary = iSessionImpl->Server().RestoreTextL(iFullEntry->SummaryStreamId(), iSessionImpl->FileId());
+		// Restore should always return something, even if it's only a Null Descriptor
+		iFullEntry->SetSummary(summary);
+		}
+
+	return iFullEntry->Summary();
+	}
+
+void CCalEntryImpl::SetDescriptionL(const TDesC& aDescription)
+	{
+	LoadFullEntryL();
+	HBufC* desc = aDescription.AllocL();
+	iFullEntry->SetDescription(desc); // takes ownership of aDescription
+	}
+
+const TDesC& CCalEntryImpl::DescriptionL()
+	{
+	LoadFullEntryL();
+	
+	if(!iFullEntry->DescriptionIsLoaded())
+		{
+		__ASSERT_DEBUG(iFullEntry->DescriptionStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId));
+		HBufC* description = iSessionImpl->Server().RestoreTextL(iFullEntry->DescriptionStreamId(), iSessionImpl->FileId());
+		// Restore should always return something, even if it's only a Null Descriptor
+		iFullEntry->SetDescription(description);
+		}
+
+	return iFullEntry->Description();
+	}
+
+CCalEntry::TType CCalEntryImpl::EntryTypeL()
+	{
+	return SimpleEntry()->Type();
+	}
+
+void CCalEntryImpl::SetStatusL(CCalEntry::TStatus aStatus)
+	{
+	LoadFullEntryL();
+	switch (aStatus)
+		{
+		case CCalEntry::ETentative:
+		case CCalEntry::EConfirmed:
+			__ASSERT_ALWAYS(EntryTypeL() != CCalEntry::ETodo, User::Leave(KErrNotSupported));
+			break;
+		case CCalEntry::ECancelled:
+			SimpleEntry()->SetIncomplete();
+			break;
+		
+		case CCalEntry::ETodoCompleted:
+		case CCalEntry::ETodoNeedsAction:
+		case CCalEntry::ETodoInProcess:
+			__ASSERT_ALWAYS(EntryTypeL() == CCalEntry::ETodo, User::Leave(KErrNotSupported));
+			break;
+		default:
+			// do nothing
+			break;
+		}
+	if (aStatus == CCalEntry::ETodoCompleted)
+		{
+		if (iFullEntry->CompletedDateUtc() == Time::NullTTime())
+			{
+			TTime time;
+			time.UniversalTime();
+			iFullEntry->SetCompletedDateUtcL(time);
+			}
+		}
+	
+	iFullEntry->SetStatus(aStatus);
+	}
+
+void CCalEntryImpl::SetReplicationStatusL(CCalEntry::TReplicationStatus aReplicationStatus)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetReplicationStatusL(aReplicationStatus);
+	}
+
+CCalEntry::TReplicationStatus CCalEntryImpl::ReplicationStatusL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->ReplicationStatus();
+	}
+
+CCalEntry::TStatus CCalEntryImpl::StatusL()
+	{
+	return SimpleEntry()->Status();
+	}
+
+void CCalEntryImpl::SetSequenceNumberL(TInt aSeqNum)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetSequenceNumber(aSeqNum);
+	}
+
+void CCalEntryImpl::SetLastModifiedDateL()
+	{
+	LoadFullEntryL();
+	iFullEntry->SetLastModifiedDate();
+	}
+	
+void CCalEntryImpl::SetLastModifiedDateL(const TCalTime& aModifiedTime)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetLastModifiedDateUtc(aModifiedTime.TimeUtcL());
+	}
+	
+void CCalEntryImpl::SetDTStampL(const TCalTime& aDTStampTime)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetDTStampUtcL(aDTStampTime.TimeUtcL());
+	}
+
+TAgnEntryId CCalEntryImpl::AgnEntryIdL()
+	{
+	return SimpleEntry()->EntryId();
+	}
+
+void CCalEntryImpl::SetLocalUidL(TCalLocalUid aLocalId)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetLocalUid(aLocalId);
+	}
+
+TCalLocalUid CCalEntryImpl::LocalUidL()
+	{
+	if(iLiteEntry)
+		{
+		return iLiteEntry->LiteEntry().LocalUid();
+		}
+	else
+		{
+		return iFullEntry->LocalUid();
+		}
+	}
+
+TUint8 CCalEntryImpl::ShortFileIdL()
+	{
+	if(iLiteEntry)
+		{
+		return iLiteEntry->LiteEntry().CollectionId();
+		}
+	else
+		{
+		return iFullEntry->CollectionId();
+		}	
+	}
+
+CCalEntry::TTransp CCalEntryImpl::BusyStatusL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->BusyStatus();
+	}
+
+void CCalEntryImpl::SetBusyStatusL(CCalEntry::TTransp aBusyStatus)
+	{
+	LoadFullEntryL();
+	iFullEntry->SetBusyStatusL(aBusyStatus);
+	}
+
+CCalGeoValue* CCalEntryImpl::GeoValueL()
+	{
+	LoadFullEntryL();
+	TReal geoLatitude;
+	TReal geoLongitude;
+	iFullEntry->GeoValue(geoLatitude,geoLongitude);
+	if(geoLatitude != KGEODefaultValue && geoLongitude != KGEODefaultValue)
+		{
+		CCalGeoValue* geoValue = CCalGeoValue::NewL();
+		CleanupStack::PushL(geoValue);
+		geoValue->SetLatLongL(geoLatitude,geoLongitude);
+		CleanupStack::Pop(geoValue);
+		return geoValue;
+		}
+	return NULL;		
+	}
+
+void CCalEntryImpl::SetGeoValueL(const CCalGeoValue& aGeoValue)
+	{
+	LoadFullEntryL();
+	TReal geoLatitude;
+	TReal geoLongitude;
+	aGeoValue.GetLatLong(geoLatitude,geoLongitude);
+	iFullEntry->SetGeoValueL(geoLatitude,geoLongitude);
+	}
+
+void CCalEntryImpl::ClearGeoValueL()
+	{
+	LoadFullEntryL();
+	iFullEntry->SetGeoValueL(KGEODefaultValue,KGEODefaultValue);
+	}
+	
+TCalTime CCalEntryImpl::FindRptUntilTimeL(TInt aCount)
+	{
+	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
+	
+	TTime untilTime = Time::NullTTime();
+	
+	if (KRptDef)
+		{
+		untilTime = KRptDef->RRule()->FindRptUntilTimeLocalL(aCount);
+		}
+	
+	TCalTime calUntilTime;
+	calUntilTime.SetTimeLocalL(untilTime);
+	
+	return calUntilTime;
+	}
+
+
+  void CCalEntryImpl::AddAttachmentL(CCalAttachment* aAttachment)
+   	{
+   	__ASSERT_ALWAYS(aAttachment, User::Leave(KErrArgument));
+   	
+	PopulateAttachmentListL();
+	iCalAttachmentList->AppendL(aAttachment);
+	
+	TRAPD(err , iFullEntry->AddAttachmentL(&aAttachment->Impl()));
+ 
+	if (err != KErrNone)
+ 		{
+		TInt count = iCalAttachmentList->Count();
+ 		iCalAttachmentList->Remove(count - 1);
+ 		User::Leave(err);
+ 		}
+ 		
+   	aAttachment->Impl().ClearFlag(CAgnAttachment::EOwnedByCalAttachment);
+
+   	}
+
+void CCalEntryImpl::PopulateAttachmentListL()
+	{
+   	if (!iCalAttachmentList)
+   		{
+
+		LoadFullEntryL();
+		iCalAttachmentList = new (ELeave) RPointerArray<CCalAttachment>(KAttachmentGranularity);
+
+		const TInt KAttachmentCount = iFullEntry->AttachmentCount();
+		for (TInt i = 0; i < KAttachmentCount; ++i)
+			{
+			CAgnAttachment& agnAttachment = iFullEntry->Attachment(i);
+			CCalAttachment* calAttachment = CCalAttachment::NewL(agnAttachment, *iSessionImpl);
+			CleanupStack::PushL(calAttachment);
+			agnAttachment.ClearFlag(CAgnAttachment::EOwnedByCalAttachment);
+			iCalAttachmentList->AppendL(calAttachment);
+			CleanupStack::Pop(calAttachment);
+			}
+   		}
+
+   	}	
+	
+void CCalEntryImpl::DeleteAttachmentL(const CCalAttachment& aAttachment)
+	{
+	LoadFullEntryL();
+	TInt index = iFullEntry->DeleteAttachmentL(aAttachment.Impl());
+	if(iCalAttachmentList && index >= 0 && index < iCalAttachmentList->Count())
+		{
+		delete (*iCalAttachmentList)[index];
+		iCalAttachmentList->Remove(index);
+		__ASSERT_DEBUG(iCalAttachmentList->Count() == iFullEntry->AttachmentCount(), Panic(EAgmErrAttachmentCountCorrupt)); 
+		}
+	}
+	
+CCalAttachment* CCalEntryImpl::AttachmentL(TInt aIndex)
+	{
+	PopulateAttachmentListL();
+
+	if (aIndex < 0 || aIndex >= iCalAttachmentList->Count() )
+		{
+		return NULL;
+		}
+		
+	return (*iCalAttachmentList)[aIndex];
+	}
+
+TInt CCalEntryImpl::AttachmentCountL()
+	{
+	LoadFullEntryL();
+	return iFullEntry->AttachmentCount();
+	}
+	
+CAgnSimpleEntry* CCalEntryImpl::SimpleEntry()
+	{
+	if (!iFullEntry)
+		{
+		return &iLiteEntry->LiteEntry();
+		}
+	return iFullEntry;
+	}
+
+const CAgnSimpleEntry* CCalEntryImpl::SimpleEntry() const
+	{
+	if (!iFullEntry)
+		{
+		return &iLiteEntry->LiteEntry();
+		}
+	return iFullEntry;
+	}
+
+void CCalEntryImpl::SetUserIntL( TUint32 aUserInt )
+    {
+    SimpleEntry()->SetUserInt(aUserInt);
+    }
+
+TUint32 CCalEntryImpl::UserIntL()
+    {
+    return SimpleEntry()->UserInt();
+    }
+
+
+//  CCalEntryIdImpl //
+
+CCalEntryIdImpl* CCalEntryIdImpl::NewL(TDesC8* aFlatData)
+	{
+	CCalEntryIdImpl* self = new(ELeave) CCalEntryIdImpl();
+	CleanupStack::PushL(self);
+	self->ConstructL(aFlatData);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CCalEntryIdImpl::CCalEntryIdImpl()
+	{
+	}
+
+CCalEntryIdImpl::~CCalEntryIdImpl()
+	{
+	delete iFlatData;
+	}
+
+void CCalEntryIdImpl::ConstructL(TDesC8* aFlatData)
+	{
+	__ASSERT_ALWAYS(aFlatData != NULL, User::Leave(KErrArgument));
+	
+	iFlatData = aFlatData;
+	iUniqueId = reinterpret_cast<const TAgnAlarmInfo*>(aFlatData->Ptr());
+	}
+
+TPtrC8 CCalEntryIdImpl::IdL()
+	{
+	return iUniqueId->iGlobalIdentifier;
+	}
+
+TPtrC CCalEntryIdImpl::StoreFileNameL()
+	{
+	return iUniqueId->iFileName;
+	}
+
+TCalTime CCalEntryIdImpl::RecurrenceIdL()
+	{
+	TCalTime time;
+	
+	if(iUniqueId->iTimeMode ==MAgnCalendarTimeMode::EFloating)
+ 		{
+ 		time.SetTimeLocalFloatingL(iUniqueId->iRecurrenceId);
+ 		}
+ 	else
+ 		{
+ 		time.SetTimeUtcL(iUniqueId->iRecurrenceId);
+ 		}
+ 	
+ 	return time;
+	}
+
+TCalTime CCalEntryIdImpl::InstanceTimeL()
+	{
+	TCalTime time;
+
+	if(iUniqueId->iTimeMode == MAgnCalendarTimeMode::EFloating)
+		{
+		time.SetTimeLocalL(iUniqueId->iInstanceTime);
+		}
+	else
+		{
+		time.SetTimeUtcL(iUniqueId->iInstanceTime);		
+		}
+		
+	return time;
+	}
+
+TCalLocalUid CCalEntryIdImpl::LocalUidL()
+	{
+	return iUniqueId->iAgnUniqueId;
+	}
+	
+
+/** Construct a new CCalLiteEntry 
+
+@param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects.
+@param aSession A reference to the CCalSession
+@internalComponent
+*/
+CCalLiteEntry* CCalLiteEntry::NewL(CAgnSimpleEntry& aSimpleEntry, RAgendaServ& aAgendaServ)
+	{
+	CCalLiteEntry* self = new(ELeave) CCalLiteEntry(aSimpleEntry, aAgendaServ);
+	return self;
+	}
+
+/** Constructor
+
+@param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects.
+@param aSession A reference to the CCalSession
+@internalComponent
+*/	
+CCalLiteEntry::CCalLiteEntry(CAgnSimpleEntry& aLiteEntry, RAgendaServ& aAgendaServ)
+	: iAgendaServ(aAgendaServ), iLiteEntry(aLiteEntry)
+	{
+	iAgendaServ.IncreaseRef();
+	}
+
+/** Deletes the TAgnLiteEntry that is contained 
+
+@internalComponent
+*/	
+CCalLiteEntry::~CCalLiteEntry()
+	{
+	iAgendaServ.DeleteSimpleEntry(&iLiteEntry);
+	iAgendaServ.DecreaseRef();
+	}
+	
+/** Get a reference to the TAgnLiteEntry
+
+@return A reference to the TAgnLiteEntry
+@internalComponent
+*/
+CAgnSimpleEntry& CCalLiteEntry::LiteEntry() const
+	{
+	return iLiteEntry;
+	}
+
+/** Increments the reference count
+
+This should only be called by a CCalEntry object that is being created from a CCalLiteEntry 
+@internalComponent
+*/	
+void CCalLiteEntry::IncrementRefCount()
+	{
+	++iRefCount;
+	}
+
+/** Decrements the reference count and deletes this CCalLiteEntry if there are no more entries refering to it
+
+This should only be called by a CCalEntry object
+@internalComponent
+*/	
+void CCalLiteEntry::DecrementRefCount()
+	{
+	__ASSERT_ALWAYS(iRefCount > 0, User::Invariant());
+	if (--iRefCount == 0)
+		{
+		delete this;
+		}
+	}