pimappservices/calendar/server/src/agssess.cpp
changeset 0 f979ecb2b13e
child 20 9c5b1510919f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/server/src/agssess.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,4310 @@
+// Copyright (c) 1997-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 "agssess.h"
+
+#include "agmattachment.h"
+#include "agscategoryindex.h"
+#include "agscategorylist.h"
+#include "agmentry.h"
+#include "agsiterator.h"
+#include "agsentrymodel.h"
+#include "agmpanic.h"
+#include "agmcategory.h"
+#include "agmcontent.h"
+#include "agmserv.h"
+#include "agsfilemanager.h"
+#include "agsmain.h"
+#include "calcommonimpl.h"
+#include "agmdebug.h"
+#include "agmtzrules.h"
+#include "agssortinstance.h"
+#include "agsinstanceiterator.h"
+#include "agmsortcriteria.h"
+#include "agmdate.h"
+#include "agssort.h"
+#include "agmcalendarinfo.h"
+#include "calsessionimpl.h"
+#include "agmfilechangenotification.h"
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+#include "agssystemstateobserver.h"
+#endif
+
+#include <apparc.h>
+#include <s32file.h>
+
+//
+// CAgnServerSession
+//
+
+const TInt KGranFilteredEntries = 20;
+const TInt KMaxNumberOfBufferedNotifications = 50;
+const TInt KGranNotificationBuffer = 64;
+
+const TInt KSlot0 = 0;
+const TInt KSlot1 = 1;
+const TInt KSlot2 = 2;
+const TInt KSlot3 = 3;
+
+void CleanupCloseAgendaImmediately(TAny* aRef)
+    {
+    if (aRef)
+        {
+        static_cast<CAgnServFile*>(aRef)->CloseAgenda(ETrue);
+        }
+    }
+
+TAgnChangeFilter::TAgnChangeFilter(CAgnServerSession& aSession) :
+	iChangeBroadcastEnabled(ETrue),
+	iSession(aSession),
+	iStartTimeUtc(Time::NullTTime()),
+	iEndTimeUtc(Time::NullTTime()),
+	iPubSubChangeMadeDuringDisable(ENoChange),
+	iPubSubEnabled(ETrue)
+	{
+	}
+
+TBool TAgnChangeFilter::ChangeBroadcastEnabled() const
+	{
+	return iChangeBroadcastEnabled;
+	}
+	
+const CAgnServerSession& TAgnChangeFilter::Session() const
+	{
+	return iSession;
+	}
+
+void TAgnChangeFilter::SetEnableChangeBroadcast(TBool aBool)
+	{
+	iChangeBroadcastEnabled = aBool;
+	}
+
+TBool TAgnChangeFilter::ChangeMadeWhileDisabled() const
+	{
+	return iChangeMadeWhileDisabled;
+	}
+	
+void TAgnChangeFilter::SetChangeMadeWhileDisabled(TBool aBool)
+	{
+	iChangeMadeWhileDisabled = aBool;	
+	}
+
+void TAgnChangeFilter::SetChangeParameter(const TTime& aStartTime, const TTime& aEndTime, MCalChangeCallBack2::TChangeEntryType aChangeType)
+	{
+	iStartTimeUtc = aStartTime;
+	iEndTimeUtc = aEndTime;
+	iEntryType = aChangeType;
+	}
+
+TBool TAgnChangeFilter::CheckChangeWithinRangeL(const CAgnRptDef* aRptDef, const TTime& aStartTime, const TTime& aEndTime) const
+	{
+	TBool entryInTimeRange = ETrue;
+	if (aRptDef)
+		{
+		TTime nudgedNextTimeUtc;
+		TBool nextDateExists = aRptDef->NudgeNextInstanceUtcL(iStartTimeUtc, nudgedNextTimeUtc);
+		if ( ! nextDateExists || nudgedNextTimeUtc > iEndTimeUtc)
+			{
+			entryInTimeRange = EFalse;
+			}
+		}
+	else
+		{
+		if (iStartTimeUtc > aEndTime || iEndTimeUtc < aStartTime)
+			{
+			entryInTimeRange = EFalse;
+			}
+		}
+	return entryInTimeRange;
+	}
+			
+TBool TAgnChangeFilter::IsValidChangeL(const TAgnChange& aChange) const
+	{
+	if (aChange.iOperationType != MCalChangeCallBack2::EChangeUndefined)
+		{
+		if (iEntryType == MCalChangeCallBack2::EChangeEntryTodo && aChange.iEntryType != CCalEntry::ETodo)
+			{
+			return EFalse;
+			}
+		if (iEntryType == MCalChangeCallBack2::EChangeEntryEvent && aChange.iEntryType == CCalEntry::ETodo)
+			{
+			return EFalse;
+			}
+		
+		// Check the entry is within the time range specified by the filter
+		// aChange.iRepeatRule gives the repeat data for the newly stored entry. If this operation is an update,
+		// then aChange.iOriginalRepeatRule gives the repeat data for the old entry.
+		TBool entryInTimeRange = CheckChangeWithinRangeL(aChange.iRepeatRule, aChange.iStartTimeOfEntryUtc, aChange.iEndTimeOfEntryUtc);
+		TBool originalEntryInTimeRange = CheckChangeWithinRangeL(aChange.iOriginalRepeatRule, aChange.iOriginalStartTimeUtc, aChange.iOriginalEndTimeUtc);
+			
+		if (iEntryType != MCalChangeCallBack2::EChangeEntryEvent)
+			{
+			if (aChange.iEntryType == CCalEntry::ETodo && aChange.iStartTimeOfEntryUtc == Time::NullTTime() &&  aChange.iEndTimeOfEntryUtc == Time::NullTTime())
+				{
+				return ETrue;
+				}
+			}
+		
+		if ( ! entryInTimeRange && ! originalEntryInTimeRange)
+			{
+			return EFalse;
+			}
+		}
+	return ETrue;
+	}
+	
+TBool TAgnChangeFilter::PubSubEnabled() const
+	{
+	return iPubSubEnabled;
+	}
+
+void TAgnChangeFilter::SetPubSubChange(TPubSubChange aChange)
+	{
+	if(aChange==ENoChange)
+		{//clear all bits
+		iPubSubChangeMadeDuringDisable = ENoChange; // = 0
+		}
+	else
+		{
+		iPubSubChangeMadeDuringDisable = iPubSubChangeMadeDuringDisable | aChange;
+		}
+	}
+	
+TBool TAgnChangeFilter::TodoChanged() const
+	{
+	return iPubSubChangeMadeDuringDisable & ETodoChanged;
+	}
+
+void TAgnChangeFilter::SetEnablePubSubNotification(TBool aEnablePubSubNotification)
+	{
+	iPubSubEnabled = aEnablePubSubNotification;
+	}
+	
+CAgnServerSession::CAgnServerSession(CAgnServer& aServer)
+    :iAgnServer(aServer), iSessionReady(ETrue)
+	{
+	iAgnServer.SessionAdded();
+	}
+
+CAgnServerSession* CAgnServerSession::NewL(CAgnServer& aServer)
+    {
+    CAgnServerSession* self = new (ELeave) CAgnServerSession(aServer);
+    CleanupStack::PushL(self);
+    self->ConstrucL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CAgnServerSession::ConstrucL()
+    {
+    iAgnSessionFileManager = CAgnSessionFileManager::NewL(*this, *(iAgnServer.FileMgr()));
+    }
+
+void CAgnServerSession::ServiceL(const RMessage2 &aMessage)
+	{
+	TBool complete = ETrue;
+	TInt err = KErrNone;
+	iMessage = aMessage;
+	
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+	if (iAgnServer.SystemStateObserver().IsShutdownInProgress())
+		{
+		//Shutdown in progress
+		err = IsReadOnlyOperation();
+		complete = ETrue;
+		}
+#endif
+	if (err == KErrNone)
+		{
+	    TRAP(err,complete = DispatchMessageL());
+	    _DBGLOG_IPC(AgmDebug::DebugLogIPCL(aMessage.Function(), TInt(this), err);)
+
+	    if ( err != KErrNone )
+	    	{
+	    	if (err == KErrNotReady && 
+	    			aMessage.Function() != ETransferAttachmentFileToServer &&
+	    			aMessage.Function() != ETransferFileToClientToWrite &&
+	    			aMessage.Function() != ETransferAttachmentFileToClient&&
+	    			aMessage.Function() != EMoveFileToServer)
+	    		{
+	    		// If a function has failed with Not ready, then a drive must not be ready
+	    		// If it is not an attachment failure, then it must have happened on the drive containing
+	    		// the Calendar file. In this case, ensure the session always leaves with KErrNotReady
+	    		// until the session is closed and re-opened.
+	    		iSessionReady = EFalse;
+	    		}
+	    	delete iBuffer;
+	    	iBuffer = NULL;
+	    	}
+		}
+		
+	if (complete && err != KClientHasBeenPanicked)
+		{
+		aMessage.Complete(err);
+		}
+	}
+
+CAgnServerSession::~CAgnServerSession()
+	{
+	//This is required for robustness. Clients which are incorrectly
+	//written can make requests with MCalProgressCallBack callbacks could
+	//subsequently panic and cause the session to be destructed. 
+	//The task which the client had initiated will be cancelled so it does not
+	//attempt to use the session again with further progress information.
+	
+	CancelAllTask();
+ 
+	// Cleanup any resources that have been allocated
+	delete iBuffer;
+	// Close the calendar file after a delay
+	CloseAgendas();
+	iAgnServer.SessionClosed();
+	delete iAgnSessionFileManager;
+	delete iInstanceIteratorMgr;
+	}
+
+/** 
+* Check to see if an operation can be performed due to backup\restore process
+* @return ETrue, if the operation can not be performed, EFalse otherwise. 
+*/
+TBool CAgnServerSession::CheckBackupRestore()
+    {
+    if(iBackupRestoreLock  
+    //All opeerations apart from the following ones are not allowed when Backup\Restore is in progress. 
+    && iMessage.Function() != ECloseAgenda
+    && iMessage.Function() != ECancelChangeNotification
+    && iMessage.Function() != EDisableChangeBroadcast
+    && iMessage.Function() != ETransmitBuffer
+    && iMessage.Function() != ERequestChangeNotificationParameters
+    && iMessage.Function() != ERequestChangeNotification
+    && iMessage.Function() != EEnableChangeBroadcast
+    && iMessage.Function() != EGetChangesSinceLastNotification
+    && iMessage.Function() != ERequestProgress)
+        {
+        return ETrue;
+        }
+        
+  // Return false, if iBackupRestoreLock is false or operations are those above, CAgnServFile::IsLocked()
+  // will determine whether or not an operation can be performed.
+    return EFalse;
+    }
+
+TBool CAgnServerSession::DispatchMessageL()
+	{
+    TBool operationRequiresFileLock = EFalse;
+    TBool callIsAsynchronous = ETrue;
+ 	if(CheckBackupRestore())
+	    {
+	    User::Leave(KErrLocked);
+	    }
+
+	switch (iMessage.Function())
+		{
+		case EOpenAgenda:
+			{
+			OpenAgendaL();
+			iSessionReady = ETrue;
+			}
+			break;
+			
+		case ECloseAgenda:
+			{
+			// Close the calendar file after a delay
+			CloseAgendaL();
+			iSessionReady = ETrue;
+			}
+			break;
+	
+		case ERequestChangeNotificationParameters:
+			{
+			RequestChangeNotificationParametersL();
+			}			
+			break;
+			
+		case ERequestChangeNotification:
+			{
+			RequestChangeNotification();
+			callIsAsynchronous = EFalse;
+			}
+			break;
+
+		case ECancelChangeNotification:
+			{
+			CancelChangeNotification();
+			}
+			break;
+
+		case EDisableChangeBroadcast:
+			{
+			DisableChangeBroadcastL();
+			}
+			break;
+
+		case EEnableChangeBroadcast:
+			{
+			EnableChangeBroadcastL();
+			}
+			break;
+
+		case EAgnHeapSizeCount:
+			{
+			TInt allocSize;
+			User::Heap().AllocSize(allocSize);
+			TPckg<TInt> HeapSize(allocSize);
+			iMessage.WriteL(KSlot0, HeapSize);			
+			}
+			break;
+
+		case EAgnResourceCount:
+			{
+			TPckg<TInt> HeapCells(User::Heap().Count());
+			iMessage.WriteL(KSlot0, HeapCells);			
+			}
+			break;
+			
+		case EAgnSetHeapFailure:
+			{
+			User::__DbgSetAllocFail(RHeap::EUser,(RHeap::TAllocFail)iMessage.Int0(),iMessage.Int1());		
+			}
+			break;
+
+		case ECreateAgendaFile:
+			{
+			CreateAgendaFileL();			
+			}
+  			break;
+ 
+		case EGetListFileNames:
+			{
+			ListAgendaFilesL();
+			}
+			break;
+
+		case EDeleteAgendaFile:
+			{
+	  		DeleteAgendaFileL();
+			}
+	  		break;
+
+		case ECancelTask:
+			{
+			CancelTaskL();
+			}
+			break;
+
+		case EAgendaFileExists:
+			{
+			AgendaFileExistsL();
+			}
+			break;
+
+		case ETransmitBuffer:
+			{
+			TransmitBufferL();
+			}
+			break;
+
+		case ESetUpdateAlarm:
+			{
+			SetUpdateAlarmL();
+			}
+			break;
+
+		case ESetEnablePubSubNotification:
+			{
+			SetEnablePubSubNotificationL();
+			}
+			break;
+
+		case ERequestProgress:
+			{
+			RequestProgressL();
+			callIsAsynchronous = EFalse; 
+			}
+			break;
+			
+		case EGetChangesSinceLastNotification:
+			{
+			GetChangesSinceLastNotificationL();
+			}
+			break;
+			
+		case EStartBuildIndex:
+			{
+			//Asynchronous call
+			StartBuildIndex();
+			callIsAsynchronous = EFalse; 
+			}
+			break;
+		case ETzDbChangedTime:
+			{
+			TzRulesLastModifiedDateTimeL();
+			}
+			break;
+		case ERollback:
+			{
+			RollbackL();
+			}
+			break;
+		case EGetFileChangesSinceLastNotification:
+		    {
+		    GetFileChangesSinceLastNotificationL();
+		    }
+		    break;
+		default:
+			{
+			operationRequiresFileLock = ETrue;
+			}
+			break;
+		}
+		
+	// Most commands are not permitted while the file is locked
+    
+    if ( operationRequiresFileLock )
+	    {
+    	if ( ! iSessionReady)
+			{
+			User::Leave(KErrNotReady);
+			}
+		else
+			{
+			switch ( iMessage.Function() )
+				{
+				case EFetchEntry:
+					{
+					FetchEntryL();
+					}
+					break;
+				case EFetchEntryByUID:
+					{
+					FetchEntryByUIDL();
+					}
+					break;
+				case EFetchSimpleEntry:
+					{
+					FetchSimpleEntryL();
+					}
+					break;
+				case EFetchSimpleEntries:
+					{
+					FetchSimpleEntriesL();
+					}
+					break;
+				case EUpdateEntry:
+					{
+					UpdateEntryL();
+					}
+					break;
+				case EAddEntry:
+					{
+					AddEntryL();
+					}
+					break;
+				case EDeleteEntry:
+					{
+					DeleteEntryL();
+					}
+					break;
+				case EPreviousInstances:
+					{
+					PreviousInstancesL();
+					}
+					break;
+				case ENextInstances:
+					{
+					NextInstancesL();
+					}
+					break;
+				case ECreateEntryIterator:
+					{
+					CreateEntryIteratorL();
+					}
+					break;
+				case EEntryIteratorNext:
+					{
+					EntryIteratorNextL();
+					}
+					break;
+				case EEntryIteratorPosition:
+					{
+					EntryIteratorPositionL();
+					}
+					break;
+				case ECommit:
+					{
+					CommitL();
+					}
+					break;
+				case EGetEntryUidsSinceDate:
+					{
+					GetEntryUidsSinceDateL();
+					}
+					break;
+				case ERestoreText:
+					{
+					RestoreTextL();
+					}
+					break;
+				case ERestoreAlarmAction:
+					{
+					RestoreAlarmActionL();
+					}
+					break;
+				case EGetCategoryListCount:
+					{
+					GetCategoryListCountL();
+					}
+					break;
+				case EGetCategoryListItem:
+					{
+					GetCategoryListItemL();
+					}
+					break;
+				case EAddCategoryToList:
+					{
+					AddCategoryToListL();
+					}
+					break;
+				case ECategoryFilter:
+					{
+					FilterCategoryL();
+					}
+					break;
+				case ETidyByDateReadParams:
+					{
+					TidyByDateReadParamsL();
+					}
+					break;
+				case ETidyByDateStart:
+					{
+					TidyByDateStartL();
+					callIsAsynchronous = EFalse; 
+					}
+					break;
+				case ECategoryStart:
+					{
+					CategoryTaskStartL();
+					}
+					break;
+				case ECategoryStartAsyn:
+					{
+					AsynchCategoryTaskStartL();
+					callIsAsynchronous = EFalse;
+					}
+					break;
+				case EInstanceIteratorCreate:
+					{
+					CreateInstanceIteratorL();
+					}
+					break;
+				case EInstanceIteratorDestroy:
+					{
+					DestroyInstanceIteratorL();
+					}
+					break;
+				case EInstanceIteratorNext:
+					{
+					InstanceIteratorNextL();
+					}
+					break;
+				case EInstanceIteratorPrevious:
+					{
+					InstanceIteratorPreviousL();
+					}
+					break;
+				case EInstanceIteratorCount:
+					{
+					InstanceIteratorCountL();
+					}
+					break;
+				case EInstanceIteratorLocateIndex:
+					{
+					InstanceIteratorLocateIndexL();
+					}
+					break;
+				
+			// Group Scheduling
+				case EGetChangesSinceLastNotification:
+					{
+					GetChangesSinceLastNotificationL();
+					}
+					break;
+				case EFetchEntryByGuid:
+					{
+					FetchEntryByGuidL();
+					}
+					break;
+				case EFetchSimpleEntriesByGuid:
+					{
+					FetchSimpleEntriesByGuidL();
+					}
+					break;
+				case EDeleteEntriesByLocalUid:
+					{
+					DeleteEntriesByLocalUidL();
+					}
+					break;
+				case EDeleteEntryByGuid:
+					{
+					DeleteEntryByGuidL();
+					}
+					break;
+				case EFindInstances:
+					{
+					FindInstancesL();
+					}
+					break;
+				case ETransferAttachmentFileToServer:
+					{
+					TransferAttachmentFileToServerL();
+					}
+					break;
+				case ETransferAttachmentFileToClient:
+					{
+					TransferAttachmentFileToClientL();
+					callIsAsynchronous = EFalse;
+					}
+					break;
+				case ETransferFileToClientToWrite:
+					{
+					TransferFileToClientToWriteL();
+					callIsAsynchronous = EFalse;
+					}
+					break;
+				case EFetchSortedAttachments:
+					{
+					FetchSortedAttachmentsL();
+					}
+					break;
+				case EEntriesWithAttachment:
+					{
+					EntriesWithAttachmentL();
+					}
+					break;
+				case EFetchAttachmentById:
+					{
+					FetchAttachmentByIdL();
+					}
+					break;
+				case EMoveFileToServer:
+					{
+					MoveFileToServerL();
+					}
+					break;
+				case EFetchSimpleEntryByUID:
+					{
+					FetchSimpleEntryByUIDL();
+					}
+					break;
+               case ESetCalendarInfo:
+                    {
+                    SetCalendarInfoL();
+                    }
+                    break;
+               case EGetCalendarInfo:
+                    {
+                    GetCalendarInfoL();
+                    }
+                    break;
+               case EGetPropertyValue:
+                    {
+                    GetPropertyValueL();
+                    }
+                    break;
+				default:
+					PanicClientL(EBadRequest);
+					return ETrue;
+				}
+			}
+		}
+	
+	// If the buffer size is greater than KInitialBufferSize, then the buffer cannot be 
+	// transmitted now. A large enough buffer must first be created on the client side to 
+	// hold this.
+	if ( iBuffer && iBuffer->Size() <= KInitialBufferSize && 
+		 iBuffer->Size() > 0 )
+		{
+		TransmitBufferL();
+		}
+
+	return callIsAsynchronous;	// complete normally
+	}
+
+void CAgnServerSession::SetUpdateAlarmL()
+	{
+	TBool updateAlarm = iMessage.Int0();
+	CAgnServFile* file = GetFileL(KSlot1);
+	file->Model()->SetUpdateAlarmL(updateAlarm);
+	}
+
+void CAgnServerSession::SetEnablePubSubNotificationL()
+	{
+	TBool enablePubsub = iMessage.Int0();
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot1, fileId);
+	
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile* client = NULL;
+		TRAPD(err, client = &(iAgnSessionFileManager->GetSessionFileL(fileId())));
+		if(err == KErrNone && client)
+		    {
+		    client->SetEnablePubSubNotificationL(enablePubsub);
+		    }
+		else if (err != KErrNotFound)
+		    {
+		    User::Leave(err);
+		    }		    
+		}
+	}
+
+void CAgnServerSession::PanicClientL(TInt aPanic) const
+	{
+	_LIT(KAgendaServerPanic,"AgnServer");
+  	iMessage.Panic(KAgendaServerPanic,aPanic);
+	User::Leave(KClientHasBeenPanicked);
+	}
+
+//
+// Utility Functions:
+
+HBufC* CAgnServerSession::ReadClientDesLC(TInt aDesNum)
+	{
+	const TInt KDesLength = iMessage.GetDesLength(aDesNum);
+	if (KDesLength == KErrArgument)
+		{
+        PanicClientL(EIndexError);
+		}
+	else if (KDesLength == KErrBadDescriptor)
+		{
+        PanicClientL(EBadDescriptor);
+		}
+	User::LeaveIfError(KDesLength);
+
+	HBufC* readBuffer = HBufC::NewLC(KDesLength);
+	TPtr readPtr(readBuffer->Des());
+
+	TRAPD(ret, iMessage.ReadL(aDesNum, readPtr));
+	if (ret != KErrNone)
+		{
+		PanicClientL(EBadDescriptor);
+		}
+
+	return readBuffer;
+	}
+
+
+HBufC8* CAgnServerSession::ReadClientDes8LC(TInt aDesNum)
+	{
+	const TInt KDesLength = iMessage.GetDesLength(aDesNum);
+	if (KDesLength == KErrArgument)
+		{
+        PanicClientL(EIndexError);
+		}
+	else if (KDesLength == KErrBadDescriptor)
+		{
+        PanicClientL(EBadDescriptor);
+		}
+	User::LeaveIfError(KDesLength);
+	
+	HBufC8* readBuffer = HBufC8::NewLC(KDesLength);
+	TPtr8 readPtr(readBuffer->Des());
+
+	TRAPD(ret, iMessage.ReadL(aDesNum, readPtr));
+	if (ret != KErrNone)
+		{
+		PanicClientL(EBadDescriptor);
+		}
+
+	return readBuffer;
+	}	
+
+//
+//Server Functions:
+void CAgnServerSession::OpenAgendaL()
+	{
+	// Open a new file for this session
+	// Arguments:   0: Input - buffer contains name of file and session ID
+	//              1: Output - status
+	//              2: Output - file ID
+	//              3: Output - collection ID
+	//
+
+	// Get descriptor for filename to open
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot0);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0, des);
+	RDesReadStream readStream(des);
+	HBufC* fileName = HBufC::NewLC(readStream, KMaxTInt);
+	TInt sessionId = readStream.ReadInt32L();	
+	CalCommon::TCalFileVersionSupport status;
+
+	HBufC* nameWithPath = iAgnServer.FileMgr()->ParseFilenameLC(*fileName);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFile(*nameWithPath);
+	TInt err = KErrNone;
+	if(file)
+		{
+		if(IsOwnFileL(sessionId, *file))
+			{//If this file has been opened by same CCalSession object
+			User::Leave(KErrAlreadyExists);
+			}
+		else if (FileHasBeenOpenedL(*file))
+			{//If this file has been opened by a different CCalSession object
+			User::Leave(KErrArgument);
+			} 
+		}
+	CleanupStack::PopAndDestroy(nameWithPath);
+	CloseAgendaL(sessionId);//Check if this CCalSession object has had opened a different file, if so, close it.      
+	TRAP(err, file = &iAgnServer.FileMgr()->OpenAgendaL(*fileName, iAgnServer, status));
+	CleanupStack::PopAndDestroy(fileName);
+	CleanupStack::PopAndDestroy(buffer);
+	User::LeaveIfError(err);
+	CleanupStack::PushL(TCleanupItem(CleanupCloseAgendaImmediately, file));
+	TPckg<TInt> theStatus(status);
+	iMessage.WriteL(KSlot1, theStatus);
+
+	__ASSERT_ALWAYS(file, User::Leave(KErrCorrupt));
+	TInt64 fileId = file->Model()->GetFileIdL();
+	TCalCollectionId shortFileId = file->CollectionId();
+	TPckg<TInt64> fileIdPackage(fileId);
+	iMessage.WriteL(KSlot2, fileIdPackage);
+	TPckg<TUint8> shortFileIdPackage(shortFileId);
+	iMessage.WriteL(KSlot3, shortFileIdPackage);
+	file->Model()->CategoryIndex().SetCategoryList(&(file->CategoryList()));
+	if(iAgnSessionFileManager->AddClientL(fileId, sessionId))
+		{
+		file->Model()->CheckTzDbModificationL();
+		}
+
+	// This is the cleanup item to close agenda if anything fails
+	CleanupStack::Pop(); 
+	}
+
+void CAgnServerSession::BackupReStoreChangedL(TInt64 aOldFileId, const CAgnServFile& aServFile, MCalChangeCallBack2::TChangeType aChangeType)
+	{
+	if(iAgnSessionFileManager)
+		{
+		TAgnChange change;
+		change.iOperationType = aChangeType;
+		
+		//reset model and file id if restore ends
+		if(aChangeType == MCalChangeCallBack2::ERestoreEnd)
+			{
+			iAgnSessionFileManager->ReSetModel(aOldFileId, aServFile);
+			change.iFileId = aServFile.Model()->GetFileIdL();
+			}
+		else
+			{
+			change.iFileId = aOldFileId;        
+			}
+		
+		iAgnSessionFileManager->AddChangeL(change);
+		}
+
+	if(aChangeType == MCalChangeCallBack2::EBackupStart || aChangeType == MCalChangeCallBack2::ERestoreStart)
+	   {
+	   LockClient(ETrue);
+	   }
+	else
+	   {
+	   LockClient(EFalse);
+	   }
+	}
+
+void CAgnServerSession::LockClient(TBool aLock)
+	{
+	iBackupRestoreLock = aLock;
+	}
+
+/** 
+* Closes the calendar file in the current agenda server session immediately or after a delay.
+* The delay is triggered using a timer owned by the calendar file. If a session then tries to access the same calendar file, the delay is cancelled and the file is not closed
+* @param aCloseImmediately EFalse if a delay is required before the closure of the calendar file, ETrue if the calendar file is to be closed immediately
+*/
+void CAgnServerSession::CloseAgendaL()
+	{
+	TInt sessionId = iMessage.Int0();
+	CloseAgendaL(sessionId);
+	}
+
+void CAgnServerSession::CloseAgendaL(TInt aSessionId)
+	{
+	if(iAgnSessionFileManager)
+		{
+		TInt index = iAgnSessionFileManager->GetSessionFile(aSessionId);
+		CAgnServFile* file = NULL;
+		if(index >= 0)
+			{
+			TRAPD(err, file = iAgnServer.FileMgr()->GetFileL(iAgnSessionFileManager->GetSessionFileByIndex(index).FileId()));           
+			if(file && err == KErrNone)
+				{
+				User::LeaveIfError(iAgnServer.FileMgr()->CloseAgenda(*file, EFalse));
+				}       
+			iAgnSessionFileManager->DeleteSessionFile(aSessionId);           
+			}
+		}
+	}
+void CAgnServerSession::FetchEntryL()
+	{
+	// Fetch an entry from the agenda file
+	// Arguments: 0 : Output - Data Buffer
+	//			  1 : Input  - Entry Id to fetch
+	//			  2 : Output - Size of buffer
+	//			  3 : Input  - File Id
+	TPckgBuf<TAgnEntryId> entryId;
+	iMessage.ReadL(KSlot1, entryId);
+	
+	CAgnServFile* file = GetFileL(KSlot3);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnEntry* entry = file->Model()->FetchEntryL(entryId());
+	
+	if ( entry )
+		{
+		CleanupStack::PushL(entry);
+	
+		ExternalizeEntryToClientL(*entry, KSlot2);
+	
+		CleanupStack::PopAndDestroy(entry);
+		}
+	else
+		{
+		TPckg<TInt> size(0);
+		iMessage.WriteL(KSlot2, size);
+		}	
+	}
+
+
+void CAgnServerSession::FetchEntryByUIDL()
+	{
+	// Fetch an entry from the agenda file
+	// Arguments: 0 : Output - Data Buffer
+	//			  1 : Input  - Unique Id to fetch
+	//			  2 : Output - Size of buffer
+	//			  3 : Input  - File ID
+
+	TPckgBuf<TCalLocalUid> uniqueId;
+	iMessage.ReadL(KSlot1, uniqueId);
+	
+	CAgnServFile* file = GetFileL(KSlot3);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnEntry* entry = file->Model()->FetchEntryL(uniqueId());
+	
+	if ( entry )
+		{
+		CleanupStack::PushL(entry);
+	
+		ExternalizeEntryToClientL(*entry, KSlot2);
+	
+		CleanupStack::PopAndDestroy(entry);
+		}
+	else
+		{
+		TPckg<TInt> size(0);
+		iMessage.WriteL(KSlot2, size);
+		}	
+	}
+
+
+void CAgnServerSession::ExternalizeEntryToClientL(const CAgnEntry& aEntry, TInt aSlot)
+	{
+	delete iBuffer;
+	iBuffer = NULL;
+		
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	bufStream.WriteUint32L( aEntry.Type() );
+	aEntry.ExternalizeToBufferL(bufStream);
+
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(aSlot, size);	
+	}
+
+
+void CAgnServerSession::TransmitBufferL()
+	{
+	// Transmit the contents of the buffer stream to the client,
+	// then delete it
+	// Arguments: 0 : Output - Data Buffer
+
+	if (!iBuffer)
+		{
+		PanicClientL(EBadRequest);	
+		}
+	iMessage.WriteL(KSlot0, iBuffer->Ptr(0));
+
+	delete iBuffer;
+	iBuffer = NULL;
+	}
+
+
+void CAgnServerSession::FetchSimpleEntryL()
+	{
+	// Fetch a lite-entry from the server
+	// (A lite entry consists of time information without any text)
+	// Arguments: 0 : Output - Data buffer
+	//			  1 : Input  - TAgnInstace
+	//			  2 : Output - Size of buffer
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot1);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+	RDesReadStream readStream(des);
+	TAgnEntryId entryId;
+	readStream >> entryId;
+	CleanupStack::PopAndDestroy(buffer);
+
+	// Make sure this entry hasn't been deleted or updated		TAgnInstanceId entryId = (*entryIds)[ii].iId;
+	TCalCollectionId collectionId = iMessage.Int3();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(collectionId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	const CAgnSimpleEntry* KEntry = file->Model()->GetSimpleEntryFromIndexes(entryId);
+
+	if ( KEntry )
+		{
+		delete iBuffer;
+		iBuffer = NULL;
+
+		iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+		// Create a write stream for this buffer
+		RBufWriteStream bufStream;
+		bufStream.Open(*iBuffer);
+		CleanupClosePushL(bufStream);	
+
+		// Write a bool to indicate if entry is available
+		bufStream.WriteUint8L(KEntry != NULL);
+
+		bufStream.WriteUint32L(KEntry->Type());
+		KEntry->ExternalizeL(bufStream, ETrue);
+
+		bufStream.CommitL();
+
+		CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+		// Send it back to the client
+		TPckg<TInt> size(iBuffer->Size());
+		iMessage.WriteL(KSlot2, size);
+		}
+	else
+		{
+		TPckg<TInt> emptyBuffer(0);
+		iMessage.WriteL(KSlot2, emptyBuffer);
+		}
+	}
+
+void CAgnServerSession::FetchSimpleEntryByUIDL()
+	{
+	// Fetch a lite-entry from the server
+	// (A lite entry is consists of time information without any text)
+	// Arguments: 0 : Output - Data buffer
+	//			  1 : Input  - TAgnInstace
+	//			  2 : Output - Size of buffer
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot1);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+	RDesReadStream readStream(des);	
+	TUint32 entryId = readStream.ReadUint32L();
+	CleanupStack::PopAndDestroy(buffer);
+
+	TCalCollectionId collectionId = iMessage.Int3();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(collectionId );
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	// Make sure this entry hasn't been deleted or updated
+	const CAgnSimpleEntry* KEntry = file->Model()->GetSimpleEntryFromIndexes(entryId);
+
+	if ( KEntry )
+		{
+		delete iBuffer;
+		iBuffer = NULL;
+
+		iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+		// Create a write stream for this buffer
+		RBufWriteStream bufStream;
+		bufStream.Open(*iBuffer);
+		CleanupClosePushL(bufStream);	
+
+		// Write a bool to indicate if entry is available
+		bufStream.WriteUint8L(KEntry != NULL);
+
+		bufStream.WriteUint32L(KEntry->Type());
+		KEntry->ExternalizeL(bufStream, ETrue);
+		bufStream.CommitL();
+
+		CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+		// Send it back to the client
+		TPckg<TInt> size(iBuffer->Size());
+		iMessage.WriteL(KSlot2, size);
+		}
+	else
+		{
+		TPckg<TInt> emptyBuffer(0);
+		iMessage.WriteL(KSlot2, emptyBuffer);
+		}
+	}
+
+void CAgnServerSession::EnsureStringsLoadedL(CAgnEntry& aEntry, TUint8 aShortFileId)
+	{
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(aShortFileId);
+	if (!aEntry.SummaryIsLoaded())
+		{
+		HBufC* summary = file->Model()->RestoreTextL(aEntry.SummaryStreamId());
+		aEntry.SetSummary(summary);
+		}
+
+	if (!aEntry.DescriptionIsLoaded())
+		{
+		HBufC* description = file->Model()->RestoreTextL(aEntry.DescriptionStreamId());
+		aEntry.SetDescription(description);
+		}
+	}
+		
+void CAgnServerSession::FetchSimpleEntriesL()
+	{
+	// Fetch an array of lite-entries from the server
+	// (A lite entry consists of time information without any text)
+	// Arguments: 0 : Output - Data buffer
+	//			  1 : Input  - TArray<TAgnEntryId> to fetch
+	//			  2 : Output - Size of buffer
+
+	CArrayFixSeg<TAgnInstance>* instanceIds = new (ELeave) CArrayFixSeg<TAgnInstance>(8);
+	CleanupStack::PushL(instanceIds);
+	
+	const TInt KDesLength = iMessage.GetDesLength(KSlot1);
+	if(KDesLength<0)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CBufFlat* buffer = CBufFlat::NewL(KDesLength);
+	CleanupStack::PushL(buffer);
+	
+	buffer->ExpandL(0, KDesLength);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+
+	RBufReadStream readStream;
+	readStream.Open(*buffer);
+	CleanupClosePushL(readStream);
+	
+	const TInt KIdCount1 = readStream.ReadUint32L();
+	
+	for ( TInt i = 0; i < KIdCount1; ++i )
+		{
+		TAgnInstance instance;
+		instance.InternalizeL(readStream);
+		instanceIds->AppendL(instance);
+		}
+		
+	CleanupStack::PopAndDestroy(&readStream);	// readStream.Close();
+
+	CleanupStack::PopAndDestroy(buffer);		// buffer
+	
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+	
+	const TInt KIdCount2 = instanceIds->Count();
+	
+	bufStream.WriteUint8L(KIdCount2);
+	
+	for ( TInt ii = 0; ii < KIdCount2 ; ++ii )
+		{
+#if defined (__CAL_VERBOSE_LOGGING__) || defined (__CAL_ENTRY_LOGGING__)
+		CAgnServFile* agnFile = iAgnServer.FileMgr()->GetFile((*instanceIds)[ii].iCollectionId);
+		CAgnEntry* fullEntry = agnFile->Model()->FetchEntryL((*instanceIds)[ii]);
+		CleanupStack::PushL(fullEntry);
+		AgmDebug::DebugLog("FetchSimpleEntriesL - Fetch entry with Id %d", (*instanceIds)[ii].Value());
+		EnsureStringsLoadedL(*fullEntry, *entryIds[ii].iCollectionId);
+		AgmDebug::DebugLogEntryL(*fullEntry, EDumpEntryAll);
+		CleanupStack::PopAndDestroy(fullEntry);
+#endif
+		TAgnInstanceId entryId = (*instanceIds)[ii].iId;
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL((*instanceIds)[ii].iCollectionId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		const CAgnSimpleEntry* KEntry = file->Model()->GetSimpleEntryFromIndexes(entryId);
+		
+		// Write a bool to indicate if entry is available
+		bufStream.WriteUint8L(KEntry != NULL);
+		
+		if ( KEntry )
+			{
+			bufStream.WriteUint32L(KEntry->Type());
+			KEntry->ExternalizeL(bufStream, ETrue);
+			bufStream.WriteUint8L((*instanceIds)[ii].iCollectionId);
+			}
+		}
+
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	
+	CleanupStack::PopAndDestroy(instanceIds);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot2, size);
+	}
+
+void CAgnServerSession::UpdateEntryL()
+	{
+	// Updates an entry on the server
+	// Arguments: 0 : Input  - Size of buffer
+	//            1 : Input  - Data Buffer (containing entry data)
+	//		      2 : Output - Entry Id of updated entry
+	//			  3 : File ID	
+	
+	// Restore length
+	const TInt KBufferSize = iMessage.Int0();
+	
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+
+	// Internalize the data from the stream
+	RBufReadStream readStream;
+	readStream.Open(*buffer);
+	CleanupClosePushL(readStream);
+
+	const CCalEntry::TType KEntryType = static_cast<CCalEntry::TType>(readStream.ReadUint32L());
+
+	TBool deleteChildren = readStream.ReadUint8L();
+
+	CAgnEntry* entry = CAgnEntry::NewL(KEntryType);
+	CleanupStack::PushL(entry);
+
+	entry->InternalizeFromBufferL(readStream);
+
+	_DBGLOG_ENTRY(AgmDebug::DebugLog("Updating calendar file with entry");)
+	_DBGLOG_ENTRY(AgmDebug::DebugLogEntryL(*entry, EDumpEntryAll);)
+
+	TCalCollectionId collectionId = iMessage.Int3();
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(collectionId);
+	client.UpdateEntryL(*entry, deleteChildren);
+	_DBGLOG_ENTRY(AgmDebug::DebugLog("Entry: Updated entry on file. Entry ID: %d",entry->EntryId().Value());)
+
+	// Return entry id
+	TPckg<TAgnEntryId> entryPckg(entry->EntryId());
+	iMessage.WriteL(KSlot2, entryPckg);
+
+	CleanupStack::PopAndDestroy(entry);
+	CleanupStack::PopAndDestroy(&readStream); // readStream.Close();	
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+void CAgnServerSession::AddChangeL(const TAgnChange& aChange)
+    {
+    if(iAgnSessionFileManager)
+        {
+        iAgnSessionFileManager->AddChangeL(aChange);
+        }
+ 	}
+
+void CAgnServerSession::AddEntryL()
+	{
+	// Adds an entry to the server
+	// Arguments: 0 : Input  - Size of buffer
+	//            1 : Input  - Data Buffer (containing entry data)
+	//		      2 : Output - Ids of updated entry
+	//            3 : Input  - File Id
+		
+
+	// Restore length
+	const TInt KBufferSize = iMessage.Int0();
+	
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+
+	// Internalize the data from the stream
+	RBufReadStream readStream;
+	readStream.Open(*buffer);
+	CleanupClosePushL(readStream);
+
+	const CCalEntry::TType KEntryType = (CCalEntry::TType) readStream.ReadUint32L();
+	CAgnEntry* entry = CAgnEntry::NewL(KEntryType);
+	CleanupStack::PushL(entry);
+
+	entry->InternalizeFromBufferL(readStream);
+
+	TAgnEntryParameters params;
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId());
+	params.iEntryId = client.StoreEntryL(*entry);
+	params.iLocalId = entry->LocalUid();
+	params.iRecurrenceId = entry->RecurrenceId().LocalL();
+	params.iLastModifiedDateUtc = entry->LastModifiedDateUtc();
+	params.iRecurrenceRange = entry->RecurrenceRange();
+
+	if (entry->TimeMode() != MAgnCalendarTimeMode::EFloating &&	entry->RptDef() != NULL )
+		{
+		CAgnTzRules* tzRules = entry->RptDef()->AgnTzRules();
+		if(tzRules != NULL)
+			{
+			params.iTzStreamId = (tzRules->TzZoneStreamId());
+			params.iSystemTzRule = (tzRules->SystemTzRule());
+			}
+		}
+	
+	// Set entry Id and unique Id
+	TPckg<TAgnEntryParameters> paramsPckg(params);
+ 	iMessage.WriteL(KSlot2, paramsPckg);
+
+	CleanupStack::PopAndDestroy(entry);			// entry
+	CleanupStack::PopAndDestroy(&readStream);	// readStream.Close();
+	CleanupStack::PopAndDestroy(buffer);		// buffer
+	}
+
+/**
+Called when a new attachment is stored with a file handle.
+The file handle is transferred to the server side and the file is moved to the Calendar store.
+*/
+void CAgnServerSession::TransferAttachmentFileToServerL()
+	{
+	// Arguments: 0 - Output	: Attachment Data - local UID of entry and index of attachment on that entry
+	//			  1 - Input		: Attachment UID of new attachment
+	//			  2,3 - FS		: Used by file server to transfer file from client to agenda server
+	
+	RFile file;
+	CleanupClosePushL(file);
+	
+	User::LeaveIfError(file.AdoptFromClient(iMessage, KTransferAttachmentToSrvFsArgIndex, KTransferAttachmentToSrvFileArgIndex));
+	
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot0);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0, des);
+	
+	RDesReadStream readStream(des);
+	TCalLocalUid localUid = readStream.ReadUint32L();
+	TInt attachmentIndex = readStream.ReadInt16L();
+	TInt64 fileId;
+	readStream >> fileId;	
+	
+	CAgnServFile* agnFile = iAgnServer.FileMgr()->GetFileL(fileId);
+	TPckg<TCalAttachmentUid> attachUid = agnFile->Model()->TransferAttachmentFileToServerL(file, localUid, attachmentIndex);
+	iMessage.WriteL(1, attachUid);
+	CleanupStack::PopAndDestroy();
+	CleanupStack::PopAndDestroy(&file); // file.Close()
+	}
+	
+void CAgnServerSession::MoveFileToServerL()
+	{
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot0);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0, des);
+	
+	RDesReadStream readStream(des);
+	TCalLocalUid localUid = readStream.ReadUint32L();
+	TInt attachmentIndex = readStream.ReadInt16L();
+	TInt64 fileId;
+	readStream >> fileId;	
+	
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	TPckg<TCalAttachmentUid> attachUid = file->Model()->MoveFileToServerL(localUid, attachmentIndex);
+	iMessage.WriteL(1, attachUid);
+	CleanupStack::PopAndDestroy();
+	}
+/**
+Called when a file attachment is fetched from the client.
+The file handle is opened on the server side then transferred to the client.
+*/
+void CAgnServerSession::TransferAttachmentFileToClientL()
+	{
+	// Arguments: 0 - Output	: Attachment UID of file attachment to send to client
+	//			  1 - FS		: Used by file server to transfer file from agenda server to client
+	//			  2 - File Id   : Long file id of the calendar file
+	TCalAttachmentUid attachmentUid = iMessage.Int0();
+
+	RFile file;
+	CleanupClosePushL(file);
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot2, fileId);
+	CAgnServFile* agnServfile = iAgnServer.FileMgr()->GetFileL(fileId());
+	agnServfile->Model()->OpenAttachmentFileL(file, attachmentUid);
+	
+	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle()); 
+	iMessage.WriteL(KTransferAttachmentToCliFileArgIndex, pckgSubSessionHandle);
+	
+	User::LeaveIfError(file.TransferToClient(iMessage, KTransferAttachmentToCliFileArgIndex));
+	
+	CleanupStack::PopAndDestroy(&file); // file.Close()
+	}
+
+/**
+Called when a new attachment is stored with binary data.
+The new file handle is opened on the server side, then transferred to the client side where the data is written directly onto the file.
+This means that the binary data is not passed directly over IPC.
+*/
+void CAgnServerSession::TransferFileToClientToWriteL()
+	{
+	// Arguments: 0 - Output	: Attachment data of new file attachment to be created
+	//			  1 - FS		: Used by file server to transfer new file from agenda server to client
+	//			  2 - Input     : File Id
+	// 			  3 - Output	: Size of attachment data that will be written to file handle on client side
+	TAttachmentData data;
+	TPckg<TAttachmentData> pckgData(data);
+	iMessage.ReadL(0, pckgData);
+	TInt dataSize = iMessage.Int3();
+	
+	RFile file;
+	CleanupClosePushL(file);
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot2, fileId);
+	CAgnServFile* agnServFile = iAgnServer.FileMgr()->GetFileL(fileId());
+	HBufC* fileName = agnServFile->Model()->GenerateRandomFilenameLC(data.iDrive);
+	agnServFile->Model()->CreateNewFileL(file, *fileName);
+	agnServFile->Model()->UpdateAttachmentDetailsL(data.iLocalUid, data.iAttachmentIndex, *fileName, dataSize);
+	CleanupStack::PopAndDestroy(fileName);
+	
+	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle()); 
+	iMessage.WriteL(KTransferAttachmentToCliFileArgIndex, pckgSubSessionHandle);
+	User::LeaveIfError(file.TransferToClient(iMessage, KTransferAttachmentToCliFileArgIndex));
+	
+	CleanupStack::PopAndDestroy(&file); // file.Close()
+	}
+
+/**
+Fetches attachment UIDs of all file attachments in the order specified in CCalAttachmentManager::FetchAttachmentsL.
+*/
+void CAgnServerSession::FetchSortedAttachmentsL()
+	{
+	// Arguments: 0 - Output	: Data buffer (containing list of TCalLocalUid's of entries)
+	//			  1 - Output	: Size of data buffer
+	//			  2 - Input		: Sort order
+	//			  3 - Input     : File Id
+	
+	TUint32 sortOrder = iMessage.Int2();
+
+	RArray<TCalAttachmentUid> attachmentIds;
+	CleanupClosePushL(attachmentIds);
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	file->Model()->GetSortedAttachmentsL(attachmentIds, static_cast<CCalAttachmentManager::TSortOrder>(sortOrder));
+	
+	WriteIntArrayToBufferL(attachmentIds);
+
+	CleanupStack::PopAndDestroy(&attachmentIds); // attachmentIds->Close()
+
+	// Send it back to the client
+	TPckg<TInt> listsize(iBuffer->Size());
+	iMessage.WriteL(KSlot1, listsize);
+	}
+
+void CAgnServerSession::WriteIntArrayToBufferL(const RArray<TUint32>& aArray)
+	{
+	// Create a write stream for this buffer
+	const TInt KCount = aArray.Count();
+	
+	// Buffer contains enough space for KCount integers and a count
+	const TInt KSizeOfBuffer = (KCount + 1) * sizeof(TUint32);
+	
+	delete iBuffer;
+	iBuffer = NULL;
+	
+	iBuffer = CBufFlat::NewL(KSizeOfBuffer);
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	// Externalize the list 
+	bufStream.WriteUint32L(KCount);
+
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		bufStream << aArray[ii];
+		}
+
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	}
+
+/**
+Fetches all file attachments with the attachment specified by the UID. 
+This is called from CCalAttachmentManager::EntriesReferencingFileAttachmentL.
+*/
+void CAgnServerSession::EntriesWithAttachmentL()
+	{
+	// Arguments: 0 - Output	: Data buffer (containing list of TCalLocalUid's of entries)
+	//			  1 - Output	: Size of data buffer
+	//			  2 - Input		: attachment Uid
+	//			  3 - Input     : File Id
+	TCalAttachmentUid attachUid = iMessage.Int2();
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	const RArray<TCalLocalUid>* KUniqueIdList = file->Model()->GetEntriesWithAttachment(attachUid);
+
+	WriteIntArrayToBufferL(*KUniqueIdList);
+	
+	// Send it back to the client
+	TPckg<TInt> listsize(iBuffer->Size());
+	iMessage.WriteL(KSlot1, listsize);
+	}
+
+/**
+Fetches a file attachment by its UID.
+Attachment UIDs are not exposed to the user. This function is used in the CCalAttachmentIterator.
+*/
+void CAgnServerSession::FetchAttachmentByIdL()
+	{
+	// Get a list of file names held by the server 
+	// currently setup extractor
+	// Arguments: 0 : Output - Data buffer 
+	//			   1 : Output - Size of buffer
+	//			   2 : Input - attachment uid
+	//			   3 : Input - File Id
+
+	TCalAttachmentUid attachUid = iMessage.Int2();
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	CAgnAttachment* attachmentToWrite = file->Model()->FetchAttachmentByIdL(attachUid);
+
+	if ( attachmentToWrite )
+		{
+		CleanupStack::PushL(attachmentToWrite);
+
+		delete iBuffer;
+		iBuffer = NULL;
+
+		iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+		// Create a write stream for this buffer
+		RBufWriteStream bufStream;
+		bufStream.Open(*iBuffer);
+		CleanupClosePushL(bufStream);
+	
+		attachmentToWrite->ExternalizeL(bufStream);
+			
+		bufStream.CommitL();
+
+		CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+		CleanupStack::PopAndDestroy(attachmentToWrite);
+
+		// Send it back to the client
+		TPckg<TInt> size(iBuffer->Size());
+		iMessage.WriteL(KSlot1, size);
+		}
+	else
+		{
+		TPckg<TInt> emptyBuffer(0);
+		iMessage.WriteL(KSlot1, emptyBuffer);
+		}
+	}
+
+void CAgnServerSession::PreviousInstancesL()
+	{
+	// Gets the time of the previous instance to today
+	// Arguments: 0 : output data buffer
+	//			  1 : size of output data buffer
+	//			  2 : input data buffer
+	//			  3 : size of input data buffer
+
+	// Restore length
+	const TInt KBufferSize = iMessage.Int3();
+	
+	const TInt KInstanceArrayGranularity = 16;
+	CArrayFixSeg<TAgnSortInstance>* instances = new (ELeave) CArrayFixSeg<TAgnSortInstance>(KInstanceArrayGranularity);
+	CleanupStack::PushL(instances);
+
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot2, des);
+	
+	TFindInstanceParams parameters;
+	
+	RDesReadStream readStream(des);
+	
+	parameters.InternalizeL(readStream);
+
+	TInt filecount = readStream.ReadInt16L();
+	for(TInt ii=0;ii<filecount;++ii)
+		{
+		TInt64 fileId;
+		readStream >> fileId;
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		CAgnEntryModel* model = file->Model();
+		model->PreviousPossibleInstancesL(*instances, parameters);
+		}
+
+	CleanupStack::PopAndDestroy(buffer);
+
+	const CAgnSimpleEntry* searchFromEntry = NULL;
+	if(parameters.iInstance.iCollectionId > 0)
+		{//If the iInstance.iFileId ==0, instances should be found from the start date of the searching range so there is no searchFromEntry
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(parameters.iInstance.iCollectionId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		searchFromEntry = file->Model()->GetSimpleEntryFromIndexes(parameters.iInstance.iId);
+		}
+	
+	TAgnSortInstance searchFromInstance(*searchFromEntry);
+	
+	if (searchFromEntry)
+		{
+		TAgnDaySortKey sortKey(AgnDateTime::MaxDate(), parameters.iUndatedTodoTimeLocal);
+		searchFromInstance.SetL(parameters.iInstance.iId.Date().LocalL(), parameters.iUndatedTodoTimeLocal);
+		const_cast<CAgnSimpleEntry&>(searchFromInstance.SimpleEntry()).SetCollectionId(parameters.iInstance.iCollectionId);
+		//the search from instance must match the filter settings
+		__ASSERT_ALWAYS(searchFromInstance.CheckStartAndEndDateOverlap(parameters), User::Leave(KErrNotFound));
+		
+		// remove all instances before and including the searched from instance
+		TInt thisPosition(0);
+		User::LeaveIfError(instances->FindIsq(searchFromInstance, sortKey, thisPosition));
+		instances->Delete(thisPosition, instances->Count() - thisPosition);
+		}
+	else if (!parameters.iInstance.iId.IsNullId())
+		{
+		// The entry searched has been deleted or the entry id is wrong
+		User::Leave(KErrNotFound);
+		}
+	else
+		{
+		// we did not search from a specified instance
+		// so remove all instances that are after and including the start time
+		for (TInt i(instances->Count() - 1) ; i >= 0 && instances->At(i).InstanceDate() >= parameters.iInstance.iId.Date().LocalL() ; --i)
+			{
+			instances->Delete(i);
+			}
+		}
+	
+	// Truncate the list to the length of aSearchParams.iNumInstances by removeing instances from the end
+	if (instances->Count() > parameters.iNumInstances)
+		{
+		instances->Delete(0, instances->Count() - parameters.iNumInstances);
+		}
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);
+
+	const TInt KInstanceCount(instances->Count());
+
+	bufStream.WriteUint32L(KInstanceCount);
+
+	for (TInt i(0) ; i < KInstanceCount ; ++i)
+		{
+		TAgnInstance instance;
+		instance.iId = instances->At(i).InstanceIdL();
+		instance.iCollectionId = (*instances)[i].SimpleEntry().CollectionId();
+		bufStream << instance;
+		}
+
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(instances);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::NextInstancesL()
+	{
+	// Gets the time of the next instance to today
+	// Arguments: 0 : output data buffer
+	//			  1 : size of the output data buffer
+	//			  2 : input data buffer
+
+	// Restore length
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot2);
+	
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot2, des);
+	
+	TFindInstanceParams parameters;
+	
+	RDesReadStream readStream(des);
+	
+	parameters.InternalizeL(readStream);
+	TInt filecount = readStream.ReadInt16L();
+	const TInt KInstanceArrayGranularity = 16;
+	CArrayFixSeg<TAgnSortInstance>* instances = new (ELeave) CArrayFixSeg<TAgnSortInstance>(KInstanceArrayGranularity);
+	CleanupStack::PushL(instances);
+
+	for(TInt ii=0;ii<filecount;++ii)
+		{
+		TInt64 fileId;
+		readStream >> fileId;
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		CAgnEntryModel* model = file->Model();
+		model->NextPossibleInstancesL(*instances, parameters);
+		}
+	
+	const CAgnSimpleEntry* searchFromEntry = NULL;
+	if(parameters.iInstance.iCollectionId > 0)
+		{
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(parameters.iInstance.iCollectionId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		searchFromEntry = file->Model()->GetSimpleEntryFromIndexes(parameters.iInstance.iId);
+		}
+
+	TAgnSortInstance searchFromInstance(*searchFromEntry);
+	if (searchFromEntry)
+		{
+		TAgnDaySortKey sortKey(AgnDateTime::MaxDate(), parameters.iUndatedTodoTimeLocal);
+		searchFromInstance.SetL(parameters.iInstance.iId.Date().LocalL(), parameters.iUndatedTodoTimeLocal);
+		const_cast<CAgnSimpleEntry&>(searchFromInstance.SimpleEntry()).SetCollectionId(parameters.iInstance.iCollectionId);
+		//the search from instance must match the filter settings
+		__ASSERT_ALWAYS(searchFromInstance.CheckStartAndEndDateOverlap(parameters), User::Leave(KErrNotFound));
+		TInt thisPosition(0);
+		User::LeaveIfError(instances->FindIsq(searchFromInstance, sortKey, thisPosition));
+		instances->Delete(0, thisPosition + 1);
+		}
+	else if (!parameters.iInstance.iId.IsNullId())
+		{
+		// The entry searched has been deleted or the entry id is wrong
+		User::Leave(KErrNotFound);
+		}
+	
+	// Truncate the list to the length of aSearchParams.iNumInstances by removeing instances from the end
+	if (instances->Count() > parameters.iNumInstances)
+		{
+		instances->Delete(parameters.iNumInstances, instances->Count() - parameters.iNumInstances);
+		}
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);
+
+	const TInt KInstanceCount(instances->Count());
+
+	bufStream.WriteUint32L(KInstanceCount);
+
+	for (TInt i(0) ; i < KInstanceCount ; ++i)
+		{
+		TAgnInstance instance;
+		instance.iId = instances->At(i).InstanceIdL();
+		instance.iCollectionId = (*instances)[i].SimpleEntry().CollectionId();
+		bufStream << instance;
+		}
+
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(instances);
+	CleanupStack::PopAndDestroy(buffer);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::CreateEntryIteratorL()
+	{
+	// Creates a server side entry iterator
+	// Used to iterate through all entries in the model e.g. for saving
+	// Arguments: 1 : Output - True if an entry is available
+	//			  0 : Input  - File Id
+
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot0, fileId);
+
+	TBool isEntry = EFalse;
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId());
+		isEntry = client.CreateEntryIterL();
+		}
+	TPckg<TBool> entryBuffer(isEntry);
+	iMessage.WriteL(KSlot1, entryBuffer);
+	}
+
+void CAgnServerSession::EntryIteratorNextL()
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot0, fileId);
+
+	// Iterates to the next entry
+	// Arguments: 0 : Output - True if an entry is available
+	TBool isEntry = EFalse;
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId());
+		isEntry = client.IsEntryAvailableAtIteratorL();
+		}
+
+	TPckg<TBool> boolBuffer(isEntry);
+	iMessage.WriteL(KSlot1, boolBuffer);
+	}
+
+void CAgnServerSession::EntryIteratorPositionL()
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot2, fileId);
+
+	// Returns the entry ID of the current entry
+	// Arguments: 0 : Output - Entry ID
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnEntry* entry = NULL;
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId());
+		entry = client.FetchEntryAtIteratorL();
+		}
+	
+	if ( entry )
+		{
+		CleanupStack::PushL(entry);
+	
+		ExternalizeEntryToClientL(*entry, KSlot1);
+	
+		CleanupStack::PopAndDestroy(entry);
+		}
+	else
+		{
+		TPckg<TInt> size(0);
+		iMessage.WriteL(KSlot1, size);
+		}	
+	}
+
+void CAgnServerSession::GetEntryUidsSinceDateL()
+	{
+	// Selects entries with a last changed date greater than specified and that match filter
+	// Arguments: 0 - Output	: Data buffer (containing list of TCalLocalUid's of entries)
+	//			  1 - Output	: Size of data buffer
+	//			  2 - Input		: Time
+
+	TPckgBuf<TTime> time;
+	iMessage.ReadL(KSlot2,time);
+
+ 	RArray<TCalLocalUid> uniqueIdList;
+ 	CleanupClosePushL(uniqueIdList);
+
+ 	CAgnServFile* file = GetFileL(KSlot3);
+ 	if(file->IsLocked())
+ 		{
+ 		User::Leave(KErrLocked);
+ 		}
+	file->Model()->GetEntryUidsSinceDateL(time(), uniqueIdList);
+
+	WriteIntArrayToBufferL(uniqueIdList);
+
+	CleanupStack::PopAndDestroy(&uniqueIdList); //uniqueIdList.Close();
+
+	// Send it back to the client
+	TPckg<TInt> listsize(iBuffer->Size());
+	iMessage.WriteL(KSlot1, listsize);
+	}
+	
+void CAgnServerSession::RequestChangeNotification()
+	{	
+	if(iAgnSessionFileManager)
+		{
+		iAgnSessionFileManager->RequestChangeNotification(iMessage);
+		}
+	}
+
+void CAgnSessionFileManager::RequestChangeNotification(const RMessage2 aMessage)
+    {
+    TInt sessionId = aMessage.Int0();
+    TUint8 whichNotification = aMessage.Int1();
+
+    TInt index = GetSessionFile(sessionId);
+    if (index == KErrNotFound && whichNotification &EFileChange)
+        {
+        CAgnSessionFile* sessionFile = CAgnSessionFile::NewL(sessionId, iAgnServerSession);
+        CleanupStack::PushL(sessionFile);
+        iSessionFiles.AppendL(sessionFile);
+        CleanupStack::Pop(sessionFile);
+        sessionFile->RequestChangeNotification(aMessage);
+        }
+    else if(index >= 0)
+        {
+        iSessionFiles[index]->RequestChangeNotification(aMessage);
+        }
+    }
+
+void CAgnServerSession::CancelChangeNotification()
+	{
+	//get fileid
+	TInt sessionId = iMessage.Int0();
+	TUint8 aNotificationType = iMessage.Int1();
+	if(iAgnSessionFileManager)
+		{
+		TInt index = iAgnSessionFileManager->GetSessionFile(sessionId);	
+		if (index >= 0)
+			{
+			iAgnSessionFileManager->GetSessionFileByIndex(index).CancelChangeNotification(aNotificationType);
+			}
+		}
+	}
+
+void CAgnServerSession::RequestChangeNotificationParametersL()
+	{
+	TPckgBuf<TTime> start;
+	iMessage.ReadL(KSlot0, start);
+
+	TPckgBuf<TTime> end;
+	iMessage.ReadL(KSlot1, end);
+	
+	// Restore length
+	const TInt KBufferSize = iMessage.GetDesLength(KSlot2);
+	
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot2, des);
+	RDesReadStream readStream(des);
+	TInt16 type = readStream.ReadInt16L();
+	TBool includeUndatedTodos = readStream.ReadInt16L(); 
+	TInt64 fileid;
+	readStream >> fileid;
+	CleanupStack::PopAndDestroy(buffer);
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileid);
+		client.SetChangeNotificationParametersL(start(), end(), MCalChangeCallBack2::TChangeEntryType(type));
+		}
+	}
+
+/**
+ * Gets the Notes Text writes it to a stream buffer and returns the size.
+ * Arguments:
+ *		0.  Output  - Buffer
+ *		1.  Input  - Stream Id
+ *		2.	Output - Size of Notes Field
+ */
+void CAgnServerSession::RestoreTextL()
+	{
+	delete iBuffer;
+	iBuffer = NULL;
+	
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);	
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	TPckgBuf<TStreamId> textId;
+	iMessage.ReadL(KSlot1,textId);
+	
+	CAgnServFile* file = GetFileL(KSlot3);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	HBufC* text = file->Model()->RestoreTextL(textId());
+	CleanupStack::PushL(text);
+	
+	bufStream.WriteUint32L(text->Length());
+	bufStream << *text;
+	CleanupStack::PopAndDestroy(text);
+	
+	bufStream.CommitL();
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	// Send the size back to the client
+	TPckg<TInt> sizeBuf(iBuffer->Size());
+	iMessage.WriteL(KSlot2, sizeBuf); 
+	}
+
+/**
+Gets the Alarm Action writes it to a stream buffer and returns the size.
+Arguments:
+	0.  Output - Buffer
+	1.  Input  - Stream Id
+	2.	Output - Size of alarm action
+	3.  Input  - File Id  
+*/
+void CAgnServerSession::RestoreAlarmActionL()
+	{
+	delete iBuffer;
+	iBuffer = NULL;
+	
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);	
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);
+	
+	TPckgBuf<TStreamId> id;
+
+	iMessage.ReadL(KSlot1, id);
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnContent* alarmAction = file->Model()->RestoreAlarmActionL(id());
+	CleanupStack::PushL(alarmAction);
+	alarmAction->ExternalizeL(bufStream);
+	CleanupStack::PopAndDestroy(alarmAction);	
+	
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close(); 
+
+	// Send the size back to the client
+	TPckg<TInt> sizeBuf(iBuffer->Size());
+	iMessage.WriteL(KSlot2, sizeBuf);
+	}
+
+void CAgnServerSession::StartBuildIndex()
+	{
+	// if the calendar file is not opened, leave
+	TBool reportProgress = iMessage.Int0();
+	TAgnMessageToComplete message(iMessage, reportProgress, *this);
+	
+	TUint8 fileId = iMessage.Int1();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	file->StartBuildIndex(message);
+	}
+
+void CAgnServerSession::TidyByDateStartL()
+	{
+	TBool reportProgress = iMessage.Int0();
+	TAgnMessageToComplete message(iMessage, reportProgress, *this);
+	TUint8 fileId = iMessage.Int1();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId);
+	client.TidyByDateStartL(message, *file);
+	}
+
+void CAgnServerSession::RequestProgressL()
+	{
+	TAgnMessageToComplete message(iMessage, ETrue, *this);
+	TUint8 fileId = iMessage.Int0();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	file->RequestProgressL(message);
+	}
+
+void CAgnServerSession::AsynchCategoryTaskStartL()
+	{
+	TBool reportProgress = iMessage.Int0();
+	TAgnMessageToComplete message(iMessage, reportProgress, *this);
+	CCalAsyncTaskManager::TAsyncAction task = (CCalAsyncTaskManager::TAsyncAction)iMessage.Int1();
+	TUint8 fileId = iMessage.Int2();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	file->CategoryTaskStartL(message, task);
+	}
+
+void CAgnServerSession::GetCategoryListCountL()
+// gets the number of categories in the list
+// arguments:
+//	0 - output, count
+//  1 - input, file id
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot1, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	TInt count = file->CategoryList().CategoryCount();
+	TPckg<TInt> buf(count);
+	iMessage.WriteL(KSlot0, buf);
+	}
+
+void CAgnServerSession::GetCategoryListItemL()
+// gets the category in the list at index passed in from the client
+// arguments:
+//	0 - output,	data buffer
+//	1 - input, index
+//  2 - output, size of buffer
+//  3 - input, file id
+	{
+	TInt index = iMessage.Int1();
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot3, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	if( index >= file->CategoryList().CategoryCount() )
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	// Buffer contains one byte for category type and the string for the extended category name
+	file->CategoryList().Category(index).ExternalizeL(bufStream);
+
+	bufStream.CommitL();
+
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot2, size);
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close()
+	}
+
+void CAgnServerSession::AddCategoryToListL()
+// adds a new category to the list; 
+// arguments:
+//	0 - input,	category name
+//  1 - input,  file id
+	{
+
+	HBufC* bufptr = ReadClientDesLC(KSlot0);
+	TPtr categoryName = bufptr->Des();
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot1, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	file->CategoryList().AddCategoryL(categoryName);
+	
+	CleanupStack::PopAndDestroy(bufptr);
+	}
+
+void CAgnServerSession::CategoryTaskStartL()
+	{
+	// Arguments: 0 - Input	: Data buffer (category and step size)
+	//			  1 - Input	: Size of data buffer
+	//			  2 - Input : step of the task
+	//			  3 - Input	: File Id
+	const TInt KBufferSize = iMessage.Int1();
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 buf(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0,buf);
+	// Internalize the data from the stream
+	TInt categoryIndex;
+	TUint8 shortFileId = iMessage.Int3();
+	GetCategoryInfoL(*buffer,categoryIndex, shortFileId);
+	CleanupStack::PopAndDestroy(buffer);
+	
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(shortFileId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	TInt task = iMessage.Int2();
+	file->Model()->CategoryIndex().PrepareStepTaskL(task,categoryIndex);
+	}
+
+void CAgnServerSession::FilterCategoryL()
+	{
+	//	Arguments:0 - Input		: Data Buffer (category and step size)
+	//			  1 - Input		: Size of data buffer
+	CArrayFixSeg<TAgnEntryId>* entryList = new (ELeave) CArrayFixSeg<TAgnEntryId>(KGranFilteredEntries);
+	CleanupStack::PushL(entryList);
+	
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot2, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	file->Model()->CategoryIndex().GetArrayFilterCategoryL(*entryList);
+	
+	delete iBuffer;
+	iBuffer = NULL;
+	
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = entryList->Count();
+
+	bufStream.WriteInt16L(KCount);
+	
+	for(  TInt ii = 0; ii < KCount; ++ii )
+		{
+		entryList->At(ii).ExternalizeL(bufStream);
+		}
+		
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	CleanupStack::PopAndDestroy(entryList);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::CancelTaskL()
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot0, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	if(file)
+		{
+		file->DoTaskCompleteL(KErrCancel, this);
+		}
+	}
+
+void CAgnServerSession::CancelAllTask()
+	{
+	const TInt count = FileIdCount();
+	for(TInt ii=0; ii<count; ++ii)
+		{
+		CAgnServFile* file = NULL;
+		TRAPD(err, file = iAgnServer.FileMgr()->GetFileL(FileId(ii)));
+		if(err == KErrNone)
+			{
+			TRAP_IGNORE(file->DoTaskCompleteL(KErrCancel, this));
+			}
+		}
+	}
+
+void CAgnServerSession::BackupRestoreCancelTask()
+    {
+    const TInt count = FileIdCount();
+    for(TInt ii=0; ii<count; ++ii)
+        {
+        CAgnServFile* file = NULL;
+        TRAPD(err, file = iAgnServer.FileMgr()->GetFileL(FileId(ii)));
+        if(err == KErrNone)
+            {
+            TRAP_IGNORE(file->CancelTaskL(this));
+            }
+        }
+    }
+
+void CAgnServerSession::GetCategoryInfoL(const CBufFlat& aBufFlat,TInt& aCategoryIndex, TCalCollectionId aCollectionId)
+	{
+	RBufReadStream readStream;
+	readStream.Open(aBufFlat);
+	CleanupClosePushL(readStream);
+		
+	CAgnCategory* category = CAgnCategory::NewL(readStream);
+
+	CleanupStack::PopAndDestroy(&readStream); // readStream.Close();
+
+	CleanupStack::PushL(category);
+	
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(aCollectionId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	aCategoryIndex = file->CategoryList().FindCategoryIndex(*category);
+	User::LeaveIfError(aCategoryIndex);
+
+	CleanupStack::PopAndDestroy(category);
+	}
+
+/** Create a store with Agenda file */
+void CAgnServerSession::CreateAgendaFileL()
+	{
+	// Arguments: 0 : Input - size fo buffer
+	//			  1 : Input - Data Buffer
+	//			  2 : Input - file name
+	//			  3 : Input - todo list name
+
+	//Create a store
+	HBufC* filenameBuf = ReadClientDesLC(KSlot0);
+	CFileStore* store=iAgnServer.FileMgr()->CreateAgendaFileLC(*filenameBuf);//PUSH: store
+	store->SetTypeL(TUidType(KPermanentFileStoreLayoutUid, KUidAppDllDoc, KUidAgnApp));
+
+	CAgnEntryModel* model = CAgnEntryModel::NewL(NULL);
+	CleanupStack::PushL(model); //PUSH: model
+	TStreamId headstreamId = model->CreateL(*store); 
+
+	//Write dummy app id to the store
+	//Create the streamdictionary (effectively the root stream)
+	CStreamDictionary* streamDic=CStreamDictionary::NewLC();//PUSH: streamDic
+	if (streamDic->At(KUidAgnModel)!=headstreamId)
+		{
+		streamDic->AssignL(KUidAgnModel, headstreamId);
+		}
+
+	// Stream dictionary (root)
+	TApaAppIdentifier dummyApp(KUidAgnModel, KNullDesC());
+	CApaProcess::WriteRootStreamL(*store,*streamDic, dummyApp);
+	store->CommitL();
+	CleanupStack::PopAndDestroy(3, store);
+	
+	//Convert the file name into standard format "c:filename
+	HBufC* parsedFilename = iAgnServer.FileMgr()->ParseFilenameLC(*filenameBuf);//full name include the parth	
+    parsedFilename->Des().Fold();   
+    TParsePtrC parse(*parsedFilename);
+    HBufC* shortFileName = HBufC::NewLC(parsedFilename->Length());
+    shortFileName->Des().Append(parse.Drive());
+    shortFileName->Des().Append(parse.NameAndExt());   
+    CAgnFileChangeInfo* changeInfo = NULL;
+    changeInfo = CAgnFileChangeInfo::NewL(shortFileName, MCalFileChangeObserver::ECalendarFileCreated);
+    CleanupStack::Pop(shortFileName);
+    CleanupStack::PushL(changeInfo);
+    CalendarFileChangedL(*changeInfo);//add the change to the buffer  
+    CleanupStack::PopAndDestroy(3, filenameBuf);//changeInfo, parsedFilename, filenameBuf
+	}
+
+TBool CAgnServerSession::IsOwnFileL(TInt aSessionId, const CAgnServFile& file)
+    {
+    TBool isOwnFile = EFalse;    
+    //Check whether it is its own file
+    if(iAgnSessionFileManager)
+       {
+       TInt index = iAgnSessionFileManager->GetSessionFile(aSessionId);
+       if(index >= 0)
+           {
+           TCalFileId fileId = iAgnSessionFileManager->GetSessionFileByIndex(index).FileId();
+           if(fileId == file.Model()->GetFileIdL())
+               {
+               isOwnFile = ETrue;
+               }
+           }
+       }
+    return isOwnFile;
+    }
+
+TBool CAgnServerSession::FileCanBeDeletedL(TInt aSessionId, const CAgnServFile& file)
+    {
+    TBool fileCanBeDeleted = EFalse;
+    TBool isOwnFile = IsOwnFileL(aSessionId, file);    
+    if(file.ReferenceCount() == 0 || (isOwnFile && file.ReferenceCount() == 1))
+        {
+        fileCanBeDeleted = ETrue;
+        }
+    return fileCanBeDeleted;       
+    }
+
+TBool CAgnServerSession::FileHasBeenOpenedL(const CAgnServFile& file)
+    {
+    TBool fileHasBeenOpened = EFalse;
+    if(iAgnSessionFileManager)
+        {
+        if(iAgnSessionFileManager->FindL(file.Model()->GetFileIdL()) != KErrNotFound)
+            {
+            fileHasBeenOpened = ETrue;
+            }      
+        }
+    return fileHasBeenOpened;
+    }
+
+void CAgnServerSession::DeleteAgendaFileL()
+    {
+    // Delete a file held by the server
+    //              1: Input - Agenda file name
+    
+    // Get descriptor for filename to delete
+    HBufC* bufptr = ReadClientDesLC(KSlot0);
+    TPtr filename = bufptr->Des();
+    
+    HBufC* fullFilename = iAgnServer.FileMgr()->ParseFilenameLC(filename);
+    TInt sessionId = iMessage.Int1();
+  
+    CAgnServFile* file = NULL;
+    file = iAgnServer.FileMgr()->GetFile(*fullFilename);
+    if(file && !FileCanBeDeletedL(sessionId, *file))
+        {
+        User::Leave(KErrInUse);
+        }
+    
+    TBool closeFile(EFalse);
+    TInt err = KErrNone;
+    if (!file)
+        {
+        // the file is not open so we must open it now
+        CalCommon::TCalFileVersionSupport status;
+        TRAP(err, file = &iAgnServer.FileMgr()->OpenAgendaL(filename, iAgnServer, status));       
+        if (err == KErrNone)
+            {
+            // Everything was fine when opening the file
+            closeFile = ETrue;
+            CleanupStack::PushL(TCleanupItem(CleanupCloseAgendaImmediately, file));        
+            }
+        }
+    if(!file)
+        {
+        iAgnServer.FileMgr()->DeleteAgendaFileL(filename);
+        }
+    else
+        {
+        TBool calInfoExist = file->IsCalendarInfoExistL();
+        TBool deleteSessionFile = EFalse;     
+        if (closeFile)
+            {
+            // This will call CloseAgenda(ETrue)
+            CleanupStack::PopAndDestroy();
+            }
+        else if( IsOwnFileL(sessionId, *file) )
+            {
+            // The client has requested to delete it's own calendar file
+            // so try to close it immediately
+            User::LeaveIfError(iAgnServer.FileMgr()->CloseAgenda(*file, ETrue));
+            deleteSessionFile = ETrue;
+            iSessionReady = ETrue;
+            }
+        iAgnServer.FileMgr()->DeleteAgendaFileL(filename);
+        
+        TParsePtrC parse(*fullFilename);
+        HBufC* shortFileName = HBufC::NewLC(fullFilename->Length());
+        shortFileName->Des().Append(parse.Drive());
+        shortFileName->Des().Append(parse.NameAndExt());
+		iAgnServer.AlarmServer().AlarmDeleteByCalendarFile(*shortFileName, EAllAlarms);
+        CAgnFileChangeInfo* changeInfo = NULL;
+    
+        if(calInfoExist)
+            {
+            HBufC* shortFileNameCopy = shortFileName->AllocLC();
+            changeInfo = CAgnFileChangeInfo::NewL(shortFileNameCopy, MCalFileChangeObserver::ECalendarInfoDeleted);
+            CleanupStack::Pop(shortFileNameCopy);         
+            CleanupStack::PushL(changeInfo);
+            CalendarFileChangedL(*changeInfo);//add the change to the buffer
+            CleanupStack::PopAndDestroy(changeInfo);
+            }       
+        changeInfo = CAgnFileChangeInfo::NewL(shortFileName, MCalFileChangeObserver::ECalendarFileDeleted);
+        CleanupStack::Pop(shortFileName);
+        CleanupStack::PushL(changeInfo);
+        CalendarFileChangedL(*changeInfo);
+        CleanupStack::PopAndDestroy(changeInfo);
+        if(deleteSessionFile)
+            {
+            iAgnSessionFileManager->DeleteSessionFileIfFileNotificationNotRequired(sessionId); 
+            }
+        }  
+    
+    CleanupStack::PopAndDestroy(fullFilename);
+    CleanupStack::PopAndDestroy(bufptr);    // buffer
+    }
+
+void CAgnServerSession::CalendarFileChangedL(CAgnFileChangeInfo& aFileChangeInfo)
+    {
+    RPointerArray<CAgnServerSession> sessions;
+    CleanupClosePushL(sessions);
+    iAgnServer.FetchSessionsL(sessions);
+    const TInt count = sessions.Count();
+    for ( TInt i = 0; i < count; ++i )
+        {       
+        sessions[i]->AddFileChangeL(aFileChangeInfo, this);
+        }
+    CleanupStack::PopAndDestroy(&sessions); // sessions.Close()   
+    }
+
+void CAgnServerSession::AddFileChangeL(CAgnFileChangeInfo& aFileChangeInfo, CAgnServerSession* aSession)
+    {
+    if(iAgnSessionFileManager && this != aSession)
+        {
+        iAgnSessionFileManager->AddFileChangeL(aFileChangeInfo);
+        }
+    }
+
+void CAgnSessionFileManager::AddFileChangeL(CAgnFileChangeInfo& aFileChangeInfo)
+    {
+    const TInt count = iSessionFiles.Count();
+    for(TInt ii = 0; ii < count; ++ii)
+        {
+        iSessionFiles[ii]->AddFileChangeToBufferL(aFileChangeInfo);
+        }
+    }
+
+void CAgnServerSession::ListAgendaFilesL()
+	{
+	// Get a list of file names held by the server 
+	// currently setup extractor
+	// Arguments: 0 : Output - Data buffer 
+	//			   1 : Output - Size of buffer
+
+	//create the buffer
+
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	CDesCArray* fileNames = iAgnServer.FileMgr()->ListAgendaFilesL();
+	if( fileNames )
+		{
+		CleanupStack::PushL(fileNames);
+
+		const TInt KCount = fileNames->Count();
+
+		bufStream.WriteUint8L(KCount);
+
+		for ( TInt ii = 0; ii < KCount; ++ii )
+			{
+			const TInt KLength = (fileNames->MdcaPoint(ii)).Length();
+			bufStream.WriteUint8L(KLength);
+			bufStream.WriteL(fileNames->MdcaPoint(ii), KLength);
+			}
+
+		CleanupStack::PopAndDestroy(fileNames);			
+		}
+	else
+		{
+		bufStream.WriteUint8L(0);
+		}
+		
+	bufStream.CommitL();
+
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::TidyByDateReadParamsL()
+	{
+	// Set up a tidy by date operation 
+	// Arguments: 0 : Input -  Buffer containing packaged tidy by date operation data
+	//			  1 : Input - File Id	 
+	TUint8 fileId = iMessage.Int1();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	__ASSERT_ALWAYS( file, Panic(EAgmErrTidyByDateNoFileOpen));
+	// If the file already has a session associated with it, then it's busy
+	// for this delete operation.
+	if (file->IsLocked())
+	    {
+	    return;
+	    }
+	
+	const TInt KDesLength = iMessage.GetDesLength(KSlot0);
+	if(KDesLength<0)
+		{
+		User::Leave(KErrArgument);
+		}
+	CBufFlat* buffer = CBufFlat::NewL(KDesLength);
+	CleanupStack::PushL(buffer);
+
+	buffer->ExpandL(0, KDesLength);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0, des);
+
+	RBufReadStream readStream;
+	readStream.Open(*buffer);
+	CleanupClosePushL(readStream);
+
+	TAgnFilter filter;
+	filter.InternalizeL(readStream);
+	TPckgBuf<TTime> undatedTodosDatePckgBuf;
+	readStream.ReadL(undatedTodosDatePckgBuf);
+	TPckgBuf<TTime> startDatePckgBuf;
+	readStream.ReadL(startDatePckgBuf);
+	TPckgBuf<TTime> endDatePckgBuf;
+	readStream.ReadL(endDatePckgBuf);
+	
+	CleanupStack::PopAndDestroy(&readStream); // readStream.Close();
+
+	file->TidyByDateSetup(*this,
+							  filter,
+							  undatedTodosDatePckgBuf(),
+							  startDatePckgBuf(),
+							  endDatePckgBuf());
+
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+void CAgnServerSession::AgendaFileExistsL()
+	{
+	// Check if a Calendar file exists 
+	// Arguments: 0 : Output -  True if the file exists, otherwise False
+	//			  1 : Input  -  Buffer containing calendar file name
+	HBufC* bufptr = ReadClientDesLC(KSlot1);
+
+	TPckg<TBool> isExists(iAgnServer.FileMgr()->AgendaFileExistsL(*bufptr));
+	
+	CleanupStack::PopAndDestroy(bufptr);	// bufptr
+
+	iMessage.WriteL(KSlot0, isExists);
+	}
+
+void CAgnServerSession::BulkChangeCompletedL(TInt64 aFileId, TInt aErr)
+	{
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(aFileId);
+	client.BulkChangeCompletedL(*this, aErr);
+	}
+
+void CAgnServerSession::EnableChangeBroadcastL()
+	{
+	//get fileid
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot0, fileId);
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile* client = NULL;
+		TRAPD(err, client = &(iAgnSessionFileManager->GetSessionFileL(fileId())));
+		if(err == KErrNone && client)
+			{
+			client->EnableChangeBroadcastL(*this);
+			}
+		else if (err != KErrNotFound)
+			{
+			User::Leave(err);
+			}           
+		}    
+	}
+
+void CAgnServerSession::DisableChangeBroadcastL()
+	{
+	//get fileid
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot0, fileId);
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile* client = NULL;
+		TRAPD(err, client = &(iAgnSessionFileManager->GetSessionFileL(fileId())));
+		if(err == KErrNone && client)
+			{
+			client->DisableChangeBroadcast();
+			}
+		else if (err != KErrNotFound)
+			{
+			User::Leave(err);
+			}           
+		}    
+	}
+
+void CAgnServerSession::GetFileChangesSinceLastNotificationL()
+	{
+	// Get calendar change info
+	// Arguments: 0 : Output - Data buffer 
+	//            1 : Output - Size of buffer
+	//            2 : Input - Session Id
+
+	TInt sessionId = iMessage.Int2();;
+	delete iBuffer;
+	iBuffer = NULL;
+	TInt buffersize = 0;
+	if(iAgnSessionFileManager)
+		{
+		TInt index = iAgnSessionFileManager->GetSessionFile(sessionId);
+		if(index >= 0)
+			{
+			buffersize = iAgnSessionFileManager->GetSessionFileByIndex(index).GetFileChangesSinceLastNotificationL(iBuffer);       
+			}
+		}
+
+	TPckg<TInt> size(buffersize);
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::GetChangesSinceLastNotificationL()
+	{
+	// Get changed entries from the log kept in the model
+	// Arguments: 0 : Output - Data buffer 
+	//			   1 : Input  - Size of buffer
+	
+	TCalCollectionId collectionId = iMessage.Int2();;
+	delete iBuffer;
+	iBuffer = NULL;
+	TInt buffersize = 0;
+	TInt64 fileId = 0;
+	if(iAgnSessionFileManager)
+		{
+		CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(collectionId);
+		buffersize = client.GetChangesSinceLastNotificationL(iBuffer);
+		fileId = client.FileId();
+		}
+	
+	TPckg<TInt> size(buffersize);
+	iMessage.WriteL(KSlot1, size);
+	TPckg<TInt64> fileIdPackage(fileId);
+	iMessage.WriteL(KSlot3, fileIdPackage);
+	}
+
+void CAgnServerSession::FindInstancesL()
+	{
+	// Restore length
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot2);
+	
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot2, des);
+	
+	TFindInstanceParams parameters;
+	
+	RDesReadStream readStream(des);
+	
+	parameters.InternalizeL(readStream);
+	TInt filecount = readStream.ReadInt16L();
+	const TInt KInstanceArrayGranularity = 16;
+	CArrayFixSeg<TAgnSortInstance>* instances = new (ELeave) CArrayFixSeg<TAgnSortInstance>(KInstanceArrayGranularity);
+	CleanupStack::PushL(instances);
+	for(TInt ii=0;ii<filecount;++ii)
+		{
+		TInt64 fileId;
+		readStream >> fileId;
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		CAgnEntryModel* model = file->Model();
+		model->FindInstancesL(*instances, parameters);
+		}
+	
+	TAgnDaySortKey sortKey(AgnDateTime::MaxDate(), parameters.iUndatedTodoTimeLocal);
+	instances->Sort(sortKey);
+	
+	// Now put the relevant info into a buffer
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = instances->Count();
+
+	bufStream.WriteUint32L(KCount);
+	
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		TAgnInstance instance;
+		instance.iId = (*instances)[ii].InstanceIdL();
+		instance.iCollectionId = (*instances)[ii].SimpleEntry().CollectionId();
+		bufStream << instance;
+		}
+
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	CleanupStack::PopAndDestroy(instances);
+	CleanupStack::PopAndDestroy(buffer);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+// CAgnInstanceInfo //	
+	
+CAgnInstanceInfo* CAgnInstanceInfo::NewL(const CAgnSimpleEntry& aSimpleEntry)
+	{
+	CAgnInstanceInfo* self = CAgnInstanceInfo::NewLC(aSimpleEntry);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+CAgnInstanceInfo* CAgnInstanceInfo::NewLC(const CAgnSimpleEntry& aSimpleEntry)
+	{
+	CAgnInstanceInfo* self = new (ELeave) CAgnInstanceInfo();
+	CleanupStack::PushL(self);
+	self->ConstructL(aSimpleEntry);
+	return self;
+	}
+
+void CAgnInstanceInfo::ConstructL(const CAgnSimpleEntry& aSimpleEntry)
+	{
+	iType = aSimpleEntry.Type();
+	if ( aSimpleEntry.RptDef() )
+		{
+		iRptDef = CAgnRptDef::NewL(aSimpleEntry);
+		iRptDef->CopyL(*aSimpleEntry.RptDef());
+		}
+	else
+		{
+		iStartTimeUtc = aSimpleEntry.StartTime().UtcL();
+		iEndTimeUtc = aSimpleEntry.EndTime().UtcL();
+		}
+	}
+
+CAgnInstanceInfo::CAgnInstanceInfo()
+	{
+	}
+
+CCalEntry::TType CAgnInstanceInfo::Type() const
+	{
+	return iType;
+	}
+	
+CAgnInstanceInfo::~CAgnInstanceInfo()
+	{
+	delete iRptDef;
+	}
+
+const CAgnRptDef* CAgnInstanceInfo::RptDef() const
+	{
+	return iRptDef;
+	}
+
+const TTime& CAgnInstanceInfo::StartTimeUtc() const
+	{
+	return iStartTimeUtc;
+	}
+
+const TTime& CAgnInstanceInfo::EndTimeUtc() const
+	{
+	return iEndTimeUtc;
+	}
+	
+// TAgnMessageToComplete //
+	
+TAgnMessageToComplete::TAgnMessageToComplete(RMessage2& aMessage, TBool aReportProgress, CAgnServerSession& aSession)
+	:iMessage(aMessage), iReportProgress(aReportProgress), iSession(aSession)		
+	{
+	}
+
+RMessage2 TAgnMessageToComplete::Message() const
+	{
+	return iMessage;
+	}
+
+TBool TAgnMessageToComplete::ReportProgress() const
+	{
+	return iReportProgress;
+	}
+
+CAgnServerSession& TAgnMessageToComplete::Session() const
+	{
+	return iSession;
+	}
+       
+/*
+@capability WriteUserData
+@capability ReadUserData
+*/
+void CAgnServerSession::DeleteEntryByUIdL(TCalLocalUid aUniqueId, TCalCollectionId aCollectionId)
+	{
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(aCollectionId); 
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	CAgnEntry* entry = file->Model()->FetchEntryL(aUniqueId);
+	if (entry)
+		{
+		CleanupStack::PushL(entry);
+		DeleteEntryL(*entry, aCollectionId);
+		CleanupStack::PopAndDestroy(entry);
+		}
+	}
+	
+void CAgnServerSession::DeleteEntryByIdL(TAgnEntryId aEntryId, TCalCollectionId aCollectionId)
+	{
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(aCollectionId);
+	__ASSERT_ALWAYS(file, User::Leave(KErrCorrupt));
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	CAgnEntry* entry = file->Model()->FetchEntryL(aEntryId);
+	if (entry)
+		{
+		CleanupStack::PushL(entry);
+		DeleteEntryL(*entry, aCollectionId);
+		CleanupStack::PopAndDestroy(entry);
+		}
+	}
+	
+void CAgnServerSession::DeleteEntryL()
+	{
+	TPckgBuf<TAgnEntryId> entryId;
+	iMessage.ReadL(KSlot0,entryId);
+	TUint8 fileId = iMessage.Int1();
+	DeleteEntryByIdL(entryId(), fileId);
+	}
+	
+void CAgnServerSession::DeleteEntryL(CAgnEntry& aEntry, TCalCollectionId aCollectionId)
+	{
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(aCollectionId);
+	client.DeleteEntryL(aEntry);
+	}
+
+void CAgnServerSession::FetchEntryByGuidL()
+	{
+	// Get a list of entries from the server with this GUID
+	// currently setup extractor
+	// Arguments:  0 : Output - Data buffer 
+	//			   1 : Output - Size of buffer
+	//			   2 : Input - Guid
+	//create the buffer
+
+	HBufC8* bufptr = ReadClientDes8LC(KSlot2);
+	TPtr8 guid = bufptr->Des();
+
+	RPointerArray<CAgnEntry> list;
+	CleanupResetAndDestroyPushL(list);
+	CAgnServFile* file = GetFileL(KSlot3);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	file->Model()->FetchEntriesL(guid, list);
+
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = list.Count();
+
+	bufStream.WriteUint32L(KCount);
+
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		CAgnEntry* entry = list[ii];
+
+ 		bufStream.WriteUint32L( entry->Type() );
+ 		entry->ExternalizeToBufferL(bufStream);
+		}
+		
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(&list); // list.Close()
+	CleanupStack::PopAndDestroy(bufptr);
+
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::FetchSimpleEntriesByGuidL()
+	{
+	// Get a list of entries from the server with this GUID
+	// currently setup extractor
+	// Arguments:  0 : Output - Data buffer 
+	//			   1 : Output - Size of buffer
+	//			   2 : Input - Guid
+	//create the buffer
+
+	RPointerArray<CAgnEntry> list;
+	CleanupResetAndDestroyPushL(list);
+
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot2);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot2, des);
+
+	RDesReadStream readStream(des);
+	TInt uidLen = readStream.ReadInt16L();
+	HBufC8* uid = HBufC8::NewLC(uidLen);
+	TPtr8 guid = uid->Des();
+	readStream.ReadL(guid, uidLen);
+	TInt filecount = readStream.ReadInt16L();
+	TInt preEntryCount = 0;;
+	TInt entryCount = 0;
+	for(TInt ii=0;ii<filecount;++ii)
+		{
+		TUint8 fileId = readStream.ReadUint8L();
+		CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+		if(file->IsLocked())
+			{
+			User::Leave(KErrLocked);
+			}
+		file->Model()->FetchEntriesL(*uid, list);
+		entryCount = list.Count();
+		for(TInt jj = preEntryCount; jj<entryCount; ++jj)
+			{
+			list[jj]->SetCollectionId(fileId);
+			}
+		preEntryCount = entryCount;
+		}
+	CleanupStack::PopAndDestroy(uid);
+	CleanupStack::PopAndDestroy(buffer);
+
+	delete iBuffer;
+	iBuffer = NULL;
+
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	// Create a write stream for this buffer
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = list.Count();
+
+	bufStream.WriteUint32L(KCount);
+
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		CAgnEntry* entry = list[ii];
+		
+		bufStream.WriteUint32L(entry->Type());
+		// explictly use the simple entriy's ExternalizeL
+ 		entry->CAgnSimpleEntry::ExternalizeL(bufStream, ETrue);
+ 		bufStream.WriteUint8L(entry->CollectionId());
+		}
+		
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(&list); // list.Close()
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::DeleteEntriesByLocalUidL()
+	{
+	
+	// Delete entries by their local uids
+	// Arguments: 0 : Input  - Size of data buffer
+	//			  1 : Input  - Data Buffer (containing filter)
+	const TInt KBufferSize = iMessage.Int0();
+
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+
+	buffer->ExpandL(0, KBufferSize);
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+
+	// Internalize the data from the stream
+	RBufReadStream readStream;
+	readStream.Open(*buffer);
+	CleanupClosePushL(readStream);
+	
+	const TInt KCount = readStream.ReadUint32L();
+	TUint8 fileId = iMessage.Int2();
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		const TCalLocalUid KUniqueId = readStream.ReadUint32L();
+		DeleteEntryByUIdL(KUniqueId, fileId);
+		}
+
+	CleanupStack::PopAndDestroy(&readStream);	// readStream.Close();
+
+	CleanupStack::PopAndDestroy(buffer);		// buffer
+	}
+
+void CAgnServerSession::DeleteEntryByGuidL()
+	{
+
+	HBufC8* guid = ReadClientDes8LC(KSlot0);
+	TBool commitAndNotify = iMessage.Int1();
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot2, fileId);
+	CAgnSessionFile& client = iAgnSessionFileManager->GetSessionFileL(fileId());
+	client.DeleteEntryByGuidL(*guid, commitAndNotify);
+	CleanupStack::PopAndDestroy(guid);
+	}
+	
+void CAgnServerSession::CommitL()
+	{
+	TUint8 fileId = iMessage.Int0();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	file->Model()->CommitL();
+	}	
+
+void CAgnServerSession::RollbackL()
+	{
+	TUint8 fileId = iMessage.Int0();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId);
+
+	//We cannot allow Rollback to happen if a file is locked.
+	//A change requested by one client if not committed, can be undone when another client requests a RollBack.
+	//This cannot be shifted to "RequiresFileLock" section as this operation can be allowed if session is not ready. 
+	if(file->IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	file->Model()->Rollback();
+	}
+
+CAgnServFile* CAgnServerSession::GetFileL(TInt aSlot)
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(aSlot, fileId);
+	return iAgnServer.FileMgr()->GetFileL(fileId());
+	}
+
+void CAgnServerSession::TzRulesLastModifiedDateTimeL()
+	{
+	TPckgBuf<TInt64> fileId;
+	iMessage.ReadL(KSlot1, fileId);
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFileL(fileId());
+	TPckgBuf<TTime> time(file->Model()->TzRulesLastModifiedDateL());
+	iMessage.WriteL(KSlot0, time);
+	}
+
+TInt CAgnServerSession::FileIdCount()
+	{
+	TInt count = 0;
+	if(iAgnSessionFileManager)
+		{
+		count = iAgnSessionFileManager->FileIdCount();
+		}
+	return count;
+	}
+
+TInt64 CAgnServerSession::FileId(TInt aIndex)
+	{
+	TInt64 fileId = KNullFileId;
+	if(iAgnSessionFileManager)
+		{
+		fileId = iAgnSessionFileManager->FileId(aIndex);
+		}
+	return fileId;
+	}
+
+void CAgnServerSession::SetCalendarInfoL()
+	{
+	// Restore length
+	const TInt KBufferSize = iMessage.GetDesLength(KSlot1);
+
+	// Restore buffer
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot1, des);
+	RDesReadStream readStream(des);
+
+	CAgnCalendarInfo* info = CAgnCalendarInfo::NewL();
+	CleanupStack::PushL(info);
+	info->IpcInternalizeL(readStream);
+
+	// try to get the file if it is already open
+	HBufC* filename = ReadClientDesLC(KSlot0);
+	HBufC* parsedFilename = iAgnServer.FileMgr()->ParseFilenameLC(*filename);
+	parsedFilename->Des().Fold();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFile(*parsedFilename);
+
+	TBool closeFile(EFalse);
+
+	if (!file)
+		{
+		// the file is not open so we must open it now
+		CalCommon::TCalFileVersionSupport status;
+		file = &iAgnServer.FileMgr()->OpenAgendaL(*filename, iAgnServer, status);
+		closeFile = ETrue;
+		CleanupStack::PushL(TCleanupItem(CleanupCloseAgendaImmediately, file));
+		}
+
+	// we have the file open, now set the file name on the info
+	// before saving the info in a stream in the file.
+	TParsePtrC parse(*parsedFilename);
+	HBufC* shortFileName = HBufC::NewLC(parsedFilename->Length());
+	shortFileName->Des().Append(parse.Drive());
+	shortFileName->Des().Append(parse.NameAndExt());
+	info->SetFileNameL(*shortFileName);
+	TBool fileInfoExist = file->SetCalendarInfoL(*info);
+
+	// set the file name to the correct format
+	CAgnFileChangeInfo* changeInfo = NULL;
+	if(fileInfoExist)
+		{
+		changeInfo = CAgnFileChangeInfo::NewL(shortFileName, MCalFileChangeObserver::ECalendarInfoUpdated);
+		}
+	else
+		{
+		changeInfo = CAgnFileChangeInfo::NewL(shortFileName, MCalFileChangeObserver::ECalendarInfoCreated);
+		}
+	CleanupStack::Pop(shortFileName);
+	CleanupStack::PushL(changeInfo);
+	CalendarFileChangedL(*changeInfo);//add the change to the buffer
+	CleanupStack::PopAndDestroy(changeInfo);
+	if (closeFile)
+		{
+		// This will call CloseAgenda(ETrue)
+		CleanupStack::PopAndDestroy();
+		}
+
+	CleanupStack::PopAndDestroy(parsedFilename);
+	CleanupStack::PopAndDestroy(filename);
+	CleanupStack::PopAndDestroy(info);
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+	void CAgnServerSession::GetPropertyValueL()
+	{
+	// try to get the file if it is already open
+	HBufC* filename = ReadClientDesLC(KSlot2);
+	HBufC* parsedFilename = iAgnServer.FileMgr()->ParseFilenameLC(*filename);
+	parsedFilename->Des().Fold();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFile(*parsedFilename);
+
+	TBool closeFile(EFalse);
+
+	if (!file)
+		{
+		// the file is not open so we must open it now
+		CalCommon::TCalFileVersionSupport status;
+		TRAPD(err, file = &iAgnServer.FileMgr()->OpenAgendaL(*filename, iAgnServer, status));
+		
+		if (err == KErrNone)
+			{
+			// Everything was fine when opening the file
+			closeFile = ETrue;
+			CleanupStack::PushL(TCleanupItem(CleanupCloseAgendaImmediately, file));
+			}
+		else if (err == KErrNoMemory || err == KErrNotFound)
+			{
+			// Leave if we ran out of memory or the file does not exist
+			// for other leave types we assume that the file is corrupt
+			// and we will return some invalid metadata later
+			User::Leave(err);
+			}
+		}
+
+	HBufC8* value(NULL);
+
+	if (file)
+		{
+		TPckgBuf<TStreamId> streamId;
+		iMessage.ReadL(KSlot3, streamId);
+		value = file->GetPropertyValueLC(streamId());
+		}
+	else
+		{
+		// We failed to open the file
+		value = KNullDesC8().AllocLC();
+		}
+
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(1000);
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);   
+
+	// Externalize the calendar info
+	bufStream << *value;
+
+	bufStream.CommitL();    
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	CleanupStack::PopAndDestroy(value);
+
+	if (closeFile)
+		{
+		// This will call CloseAgenda(ETrue)
+		CleanupStack::PopAndDestroy();
+		}
+
+	CleanupStack::PopAndDestroy(parsedFilename);
+	CleanupStack::PopAndDestroy(filename);
+	}
+
+	void CAgnServerSession::GetCalendarInfoL()
+	{
+	// try to get the file if it is already open
+	HBufC* filename = ReadClientDesLC(KSlot2);
+	HBufC* parsedFilename = iAgnServer.FileMgr()->ParseFilenameLC(*filename);
+	parsedFilename->Des().Fold();
+	CAgnServFile* file = iAgnServer.FileMgr()->GetFile(*parsedFilename);
+
+	TBool closeFile(EFalse);
+
+	if (!file)
+		{
+		// the file is not open so we must open it now
+		CalCommon::TCalFileVersionSupport status;
+		TRAPD(err, file = &iAgnServer.FileMgr()->OpenAgendaL(*filename, iAgnServer, status));
+		
+		if (err == KErrNone)
+			{
+			// Everything was fine when opening the file
+			closeFile = ETrue;
+			CleanupStack::PushL(TCleanupItem(CleanupCloseAgendaImmediately, file));
+			}
+		else if (err == KErrNoMemory || err == KErrNotFound)
+			{
+			// Leave if we ran out of memory or the file does not exist
+			// for other leave types we assume that the file is corrupt
+			// and we will return some invalid metadata later
+			User::Leave(err);
+			}
+		}
+
+	CAgnCalendarInfo* info(NULL);
+
+	if (file)
+		{
+		info = file->GetCalendarInfoLC();
+		}
+	else
+		{
+		// We failed to open the file so send back some
+		// invalid calendar info
+		info = CAgnCalendarInfo::NewL();
+		CleanupStack::PushL(info);
+		info->SetIsValid(EFalse);
+		
+		// set the file name to the correct format
+		TParsePtrC parse(*parsedFilename);
+		TFileName shortFileName(parse.Drive());
+		shortFileName.Append(parse.NameAndExt());
+		info->SetFileNameL(shortFileName);
+		}
+
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(1000);
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);   
+
+	// Externalize the calendar info
+	info->IpcExternalizeL(bufStream);
+
+	bufStream.CommitL();    
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+
+	CleanupStack::PopAndDestroy(info);
+
+	if (closeFile)
+		{
+		// This will call CloseAgenda(ETrue)
+		CleanupStack::PopAndDestroy();
+		}
+
+	CleanupStack::PopAndDestroy(parsedFilename);
+	CleanupStack::PopAndDestroy(filename);
+	}
+
+void CAgnServerSession::CloseAgendas()
+	{
+	const TInt count = FileIdCount();
+	for (TInt ii =0; ii<count; ii++)
+		{
+		CAgnServFile* servFile = NULL;
+		TRAPD(err,  servFile = iAgnServer.FileMgr()->GetFileL(FileId(ii)));
+		if(servFile && err==KErrNone)
+			{
+			servFile->CloseAgenda(EFalse);
+			}
+		}
+	}
+
+//CAgnSessionFileManager
+CAgnSessionFileManager::CAgnSessionFileManager(CAgnServerSession& aAgnServerSession, CAgnServFileMgr& aAgnServFileMgr)
+	:iAgnServerSession(aAgnServerSession),iAgnServFileMgr(aAgnServFileMgr)
+	{
+	}
+
+CAgnSessionFileManager* CAgnSessionFileManager::NewL(CAgnServerSession& aAgnServerSession, CAgnServFileMgr& aAgnServFileMgr)
+	{
+	return new(ELeave) CAgnSessionFileManager(aAgnServerSession, aAgnServFileMgr);
+	}
+
+CAgnSessionFileManager::~CAgnSessionFileManager()
+	{
+	iSessionFiles.ResetAndDestroy();
+	}
+
+TBool CAgnSessionFileManager::AddClientL(TInt64 aFileId, TInt aSessionId)
+	{//return ETrue if an object of CAgnSessionFile has been added in the array iSessionFiles
+	TBool objectAdded = EFalse;
+	TInt index = GetSessionFile(aSessionId);
+	if(index < 0)
+		{
+		CAgnServFile* file = iAgnServFileMgr.GetFileL(aFileId);
+		CAgnSessionFile* SessionFile = CAgnSessionFile::NewL(aSessionId, aFileId, *(file->Model()), iAgnServerSession);
+		CleanupStack::PushL(SessionFile);
+		TLinearOrder<CAgnSessionFile> order(CompareFileId);
+		User::LeaveIfError(iSessionFiles.InsertInOrder(SessionFile, order));
+		CleanupStack::Pop(SessionFile);
+		objectAdded = ETrue;
+		}
+	else if (iSessionFiles[index]->FileId() == 0)
+	    {//CAgnSessionFile was added when the client start to observ the file change but file may not opened yet.
+	    CAgnServFile* file = iAgnServFileMgr.GetFileL(aFileId);
+	    iSessionFiles[index]->ResetModel(*file);//set the model and file Id.
+	    }
+	return objectAdded;
+	}
+	
+TInt CAgnSessionFileManager::FileIdCount()
+	{
+	return iSessionFiles.Count();
+	}
+
+TInt64 CAgnSessionFileManager::FileId(TInt aIndex)
+	{
+	return iSessionFiles[aIndex]->FileId();
+	}
+
+TInt CAgnSessionFileManager::CompareFileId(const CAgnSessionFile& aLeft, const CAgnSessionFile& aRight)
+	 {
+	 TInt64 key =aLeft.FileId();
+	 return CompareFileId(&key, aRight);
+	 }
+
+TInt CAgnSessionFileManager::CompareFileId(const TInt64* aKey, const CAgnSessionFile& aAgnSessionFile)
+	 {
+	 if (*aKey > aAgnSessionFile.FileId())
+	     {
+	     return 1;
+	     }
+	 else if (*aKey < aAgnSessionFile.FileId())
+	     {
+	     return -1;
+	     }
+	 
+	 return 0;
+	 }
+
+TInt CAgnSessionFileManager::FindL(TInt64 aFileId) const
+	{
+	return iSessionFiles.FindInOrder(aFileId, CompareFileId);
+	}
+
+void CAgnSessionFileManager::AddChangeL(const TAgnChange& aChange)
+	{
+	TInt index = FindL(aChange.iFileId);
+	if(index >= 0)
+		{
+		(*iSessionFiles[index]).AddChangeToBufferL(aChange, &iAgnServerSession);
+		}
+	}
+
+void CAgnSessionFileManager::DeleteSessionFile(TInt aSessionId)
+	{
+	TInt index = GetSessionFile(aSessionId);
+	if(index >= 0)
+		{
+		delete iSessionFiles[index];
+		iSessionFiles.Remove(index);
+		}
+	}
+
+void CAgnSessionFileManager::DeleteSessionFileIfFileNotificationNotRequired(TInt aSessionId)
+    {//Delete the object ony if it doesn't request for file notification otherwise set its fileid = 0 which indicate the file is closed by this CCalSession object.
+    TInt index = GetSessionFile(aSessionId);
+    if(index >= 0)
+        {
+        if(!iSessionFiles[index]->FileNotificationIsReqested())
+            {
+            delete iSessionFiles[index];
+            iSessionFiles.Remove(index);
+            }
+        else
+            {
+            iSessionFiles[index]->SetFileId(KNullFileId);
+            }
+        }
+    }
+
+CAgnSessionFile& CAgnSessionFileManager::GetSessionFileL(TInt64 aFileId)
+	{
+	TInt index = FindL(aFileId);
+	if(index < 0)
+		{
+		User::Leave(KErrNotFound);
+		}
+	return *iSessionFiles[index];
+	}
+
+TInt CAgnSessionFileManager::GetSessionFile(TInt aSessionId)
+    {
+    const TInt count = iSessionFiles.Count();
+    for (TInt ii = 0; ii < count; ++ii)
+        {
+        if(iSessionFiles[ii]->SessionId() == aSessionId)
+            {
+            return ii;
+            }
+        }
+    
+    return KErrNotFound;
+    }
+
+CAgnSessionFile& CAgnSessionFileManager::GetSessionFileByIndex(TInt aIndex)
+    {
+    __ASSERT_ALWAYS(aIndex >= 0, User::Invariant());
+    return *iSessionFiles[aIndex];
+    }
+
+CAgnSessionFile& CAgnSessionFileManager::GetSessionFileL(TCalCollectionId aCollectionId)
+	{
+	TInt64 fileId = iAgnServFileMgr.GetLongFileIdL(aCollectionId);
+	return GetSessionFileL(fileId);
+	}
+
+void CAgnSessionFileManager::ReSetModel(TInt64 aFileId, const CAgnServFile& aServFile)
+    {
+    CAgnSessionFile& sessionFile = GetSessionFileL(aFileId);
+    sessionFile.ResetModel(aServFile);
+    }
+
+CAgnSessionFile::CAgnSessionFile(TInt aSessionId, TInt64 aFileId, CAgnEntryModel* aModel, CAgnServerSession& aAgnServerSession)
+	:iSessionId(aSessionId),
+    iFileId(aFileId),
+	iModel(aModel),
+	iChangeNotificationPending(ENotificationNotRequested),
+	iBulkChangeInProgress(EFalse),
+	iChangeFilter(aAgnServerSession),
+	iBufferedNotificationsCount(0),
+	iNotificationBufferFull(EFalse)
+	{
+	}
+
+TInt64 CAgnSessionFile::FileId() const 
+	{
+	return iFileId;
+	}
+
+CAgnSessionFile* CAgnSessionFile::NewL(TInt aSessionId, TInt64 aFileId, CAgnEntryModel& aModel, CAgnServerSession& aAgnServerSession)
+	{
+	return new(ELeave) CAgnSessionFile(aSessionId, aFileId, &aModel, aAgnServerSession);
+	}
+
+CAgnSessionFile* CAgnSessionFile::NewL(TInt aSessionId, CAgnServerSession& aAgnServerSession)
+    {
+    return new(ELeave) CAgnSessionFile(aSessionId, 0, NULL, aAgnServerSession);
+    }
+
+CAgnSessionFile::~CAgnSessionFile()
+	{
+	iBufferedNotificationStream.Close();
+	delete iBufferedNotification;
+	delete iEntryIter;
+	}
+
+void CAgnSessionFile::TidyByDateStartL(TAgnMessageToComplete& aMessageToComplete, CAgnServFile& aServerFile)
+	{
+	aServerFile.TidyByDateStartL(aMessageToComplete, iChangeFilter);
+	iBulkChangeInProgress = ETrue;
+	}
+
+void CAgnSessionFile::BulkChangeCompletedL(const CAgnServerSession& aSession, TInt aErr)
+	{
+	if ( iBulkChangeInProgress )
+		{
+		if ( aErr == KErrNone )
+			{
+			if ( iChangeFilter.ChangeBroadcastEnabled() )
+				{
+				iModel->NotifyChangeL(aSession, NULL, MCalChangeCallBack2::EChangeUndefined, NULL);
+				iChangeFilter.SetChangeMadeWhileDisabled(EFalse);
+				}
+			else
+				{
+				iChangeFilter.SetChangeMadeWhileDisabled(ETrue);	
+				}
+
+			iModel->NotifyPublishAndSubscribeL(iChangeFilter);
+			}
+
+		iBulkChangeInProgress = EFalse;
+		}
+
+	iModel->SetUpdateAlarmL(ETrue);
+	}
+
+void CAgnSessionFile::SetEnablePubSubNotificationL(TBool aEnablePubSub)
+	{
+	iChangeFilter.SetEnablePubSubNotification(aEnablePubSub);
+	iModel->NotifyPublishAndSubscribeL(iChangeFilter);
+	}
+
+void CAgnSessionFile::EnableChangeBroadcastL(const CAgnServerSession& aAgnServerSession)
+	{
+	TBool changeMadeWhileDisabled = iChangeFilter.ChangeMadeWhileDisabled();
+	iChangeFilter.SetEnableChangeBroadcast(ETrue);
+	if ( changeMadeWhileDisabled )
+		{
+		iModel->NotifyChangeL(aAgnServerSession, NULL, MCalChangeCallBack2::EChangeUndefined, NULL);
+		iChangeFilter.SetChangeMadeWhileDisabled(EFalse);
+		}
+	}
+
+void CAgnSessionFile::DisableChangeBroadcast()
+	{
+	iChangeFilter.SetEnableChangeBroadcast(EFalse);
+	}
+
+void CAgnSessionFile::UpdateEntryL(CAgnEntry& aEntry, TBool aDeleteChildren)
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+	
+	iModel->UpdateEntryL(aEntry, &iChangeFilter, aDeleteChildren);
+	}
+
+TAgnEntryId CAgnSessionFile::StoreEntryL(CAgnEntry& aEntry)
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	return iModel->StoreL(aEntry, &iChangeFilter);
+	}
+
+void CAgnSessionFile::DeleteEntryL(CAgnEntry& aEntry)
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	iModel->DeleteEntryL(aEntry, ETrue, &iChangeFilter);
+	}
+
+void CAgnSessionFile::DeleteEntryByGuidL(const TDesC8& aGuid, TBool aCommit)
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	CAgnEntry* entry = iModel->FetchEntryL(aGuid);
+
+	if( entry )
+		{
+		CleanupStack::PushL(entry);
+		iModel->DeleteEntryL(*entry, ETrue, NULL);
+		if (aCommit)
+			{
+			iModel->CommitAndNotifyDeletesL(iChangeFilter);
+			}
+		CleanupStack::PopAndDestroy(entry);
+		}
+	else
+		{
+		User::Leave(KErrNotFound);
+		}
+	}
+
+void CAgnSessionFile::RequestChangeNotification(const RMessage2 aMessage)
+	{
+	iChangeNotificationMessage = aMessage;
+	iChangeNotificationPending = ENotificationRequested;
+    TUint8 whichNotification = aMessage.Int1();   
+    if(whichNotification&EEntryChangeInSameFile )
+        {
+        RequestEntryChangeNotification();
+        }
+    
+    if(whichNotification&EFileChange  )
+        {
+        RequestFileChangeNotification();
+        }
+	}
+
+void CAgnSessionFile::RequestEntryChangeNotification()
+    {
+    iChangeIterested = iChangeIterested|EEntryChangeInSameFile;
+	if (iChangeNotificationPending == ENotificationRequested && iBufferedNotification && iBufferedNotification->Size() > 0 )
+		{
+		iChangeNotificationMessage.Complete(EEntryChangeInSameFile);
+		iChangeNotificationPending = ENotificationAwaitingRequest;
+		}
+	}
+
+void CAgnSessionFile::RequestFileChangeNotification()
+    {
+    iChangeIterested = iChangeIterested|EFileChange;
+    if ( iChangeNotificationPending == ENotificationRequested && iFileBufferedNotification && iFileBufferedNotification->Size() > 0 )
+        {
+        iChangeNotificationMessage.Complete(EFileChange);
+        iChangeNotificationPending = ENotificationAwaitingRequest;
+        }
+      }
+
+void CAgnSessionFile::CancelChangeNotification(TUint8 aNotificationType)
+	{
+	if (iChangeNotificationPending != ENotificationNotRequested)
+	    {
+        if(aNotificationType&EEntryChangeInSameFile)
+            {
+            iChangeIterested =iChangeIterested&~EEntryChangeInSameFile;
+            }    
+        if(aNotificationType&EFileChange)
+            {
+            iChangeIterested = iChangeIterested&~EFileChange;
+            }
+        if(iChangeIterested == 0)
+            {
+            iChangeNotificationPending = ENotificationNotRequested;
+            if ( ! iChangeNotificationMessage.IsNull())
+                {
+                iChangeNotificationMessage.Complete(KErrCancel);
+                }
+            }
+	    }
+	}
+
+void CAgnSessionFile::SetChangeNotificationParametersL(const TTime aStart, const TTime aEnd,MCalChangeCallBack2::TChangeEntryType aChangeType)
+	{
+	iChangeFilter.SetChangeParameter(aStart, aEnd, aChangeType);
+	}
+
+TInt CAgnSessionFile::GetChangesSinceLastNotificationL( CBufFlat*& aDataBuffer)
+	{
+	iBufferedNotificationStream.Close();
+		
+	// Send it back to the client
+	TInt bufferSize = 0;
+	if (iBufferedNotification)
+		{
+		bufferSize = iBufferedNotification->Size();
+		}
+	
+	aDataBuffer = iBufferedNotification ;
+	iBufferedNotification = NULL;
+	iBufferedNotificationsCount = 0;
+	iNotificationBufferFull = EFalse;
+	
+	return bufferSize;
+	}
+
+TInt CAgnSessionFile::GetFileChangesSinceLastNotificationL( CBufFlat*& aDataBuffer)
+    {
+    iFileBufferedNotificationStream.Close();
+        
+    // Send it back to the client
+    TInt bufferSize = 0;
+    if (iFileBufferedNotification)
+        {
+        bufferSize = iFileBufferedNotification->Size();
+        }
+    
+    aDataBuffer = iFileBufferedNotification ;
+    iFileBufferedNotification = NULL;
+    iFileBufferedNotificationsCount = 0;
+    return bufferSize;
+    }
+
+TBool CAgnSessionFile::ToNotifyL(const TAgnChange& aChange, CAgnServerSession* aAgnServerSession)
+    {
+    if(iChangeNotificationPending == ENotificationNotRequested || !(iChangeIterested &EEntryChangeInSameFile))
+        {
+        //Notification is not required.
+        return EFalse;
+        }
+    
+    if(aChange.iOperationType == MCalChangeCallBack2::EChangeTzRules ||
+            aChange.iOperationType == MCalChangeCallBack2::EBackupStart ||
+            aChange.iOperationType == MCalChangeCallBack2::ERestoreStart ||
+            aChange.iOperationType == MCalChangeCallBack2::EBackupEnd ||
+            aChange.iOperationType == MCalChangeCallBack2::ERestoreEnd) 
+        {
+        //Tz rule has been changed or backup-restore state has been changed.
+        return ETrue;
+        }
+    
+    if(aAgnServerSession == aChange.iSession)
+        {
+        //Calendar entry has been changed but the change came from the same session
+        return EFalse;
+        }
+    
+    // It is Calendar entry change come from another session
+    return iChangeFilter.IsValidChangeL(aChange);
+    }
+
+void CAgnSessionFile::AddChangeToBufferL(const TAgnChange& aChange, CAgnServerSession* aAgnServerSession)
+	{
+	if(iChangeNotificationPending == ENotificationRequested && aChange.iOperationType == MCalChangeCallBack2::ERestoredFileCanNotBeOpened)
+	    {
+        iChangeNotificationMessage.Complete(KErrCorrupt);
+        iChangeNotificationPending = ENotificationAwaitingRequest;
+	    }
+	else if (ToNotifyL(aChange, aAgnServerSession))         
+		{
+		// store the change in the notification buffer
+		if (!iBufferedNotification)
+			{
+			iBufferedNotification = CBufFlat::NewL(KGranNotificationBuffer);
+			iBufferedNotificationsCount = 0;
+			iNotificationBufferFull = EFalse;
+			iBufferedNotificationStream.Open(*iBufferedNotification);
+			}
+
+		if (iBufferedNotificationsCount < KMaxNumberOfBufferedNotifications)
+			{
+			if(!iNotificationBufferFull)
+				{
+				iBufferedNotificationStream.WriteUint32L(aChange.iEntryId);
+				iBufferedNotificationStream.WriteInt8L(aChange.iOperationType);
+				iBufferedNotificationStream.WriteInt8L(aChange.iEntryType);
+				iBufferedNotificationStream.CommitL();
+			
+				++iBufferedNotificationsCount;
+		
+				// notify client that a change has occured
+				if (iChangeNotificationPending == ENotificationRequested)
+					{
+					iChangeNotificationMessage.Complete(EEntryChangeInSameFile);
+					iChangeNotificationPending = ENotificationAwaitingRequest;
+					}
+				}
+			}
+		else
+			{
+			iNotificationBufferFull = ETrue;
+
+			// Clear all the notifications in the buffer
+			iBufferedNotification->Reset();
+			iBufferedNotificationStream.Open(*iBufferedNotification);		
+		
+			// Add a single 'Undefined Change' notification to the notification buffer
+			iBufferedNotificationStream.WriteUint32L(0);
+			iBufferedNotificationStream.WriteInt8L(MCalChangeCallBack2::EChangeUndefined);
+			iBufferedNotificationStream.WriteInt8L(MCalChangeCallBack2::EChangeEntryAll);
+			iBufferedNotificationStream.CommitL();
+	
+			// Reset the count to 1 - Undefined Change
+			iBufferedNotificationsCount = 1;
+			}
+		}
+	}
+
+void CAgnSessionFile::AddFileChangeToBufferL(CAgnFileChangeInfo& aFileChangeInfo)
+    {
+    if(iChangeNotificationPending != ENotificationNotRequested && iChangeIterested &EFileChange)
+       {
+        // store the change in the notification buffer
+        if (!iFileBufferedNotification)
+            {
+            iFileBufferedNotification = CBufFlat::NewL(KGranNotificationBuffer);
+            iFileBufferedNotificationsCount = 0;
+            iFileBufferedNotificationStream.Open(*iFileBufferedNotification);
+            iFileBufferedNotificationStream.WriteInt32L(0);
+            }
+        MStreamBuf * streamBuf = iFileBufferedNotificationStream.Sink();
+        TStreamPos posStart(0);
+ 
+        if (iFileBufferedNotificationsCount < KMaxNumberOfBufferedNotifications)
+            {
+            aFileChangeInfo.ExternalizeL(iFileBufferedNotificationStream);
+            //bring the stream write position to the start
+            streamBuf->SeekL(MStreamBuf::EWrite, posStart); 
+            iFileBufferedNotificationStream.WriteInt32L(++iFileBufferedNotificationsCount);
+            iFileBufferedNotificationStream.CommitL();           
+            }
+        else
+            {
+             // Clear all the notifications in the buffer
+            iFileBufferedNotification->Reset();
+            iFileBufferedNotificationStream.Open(*iBufferedNotification);       
+        
+            // Add a single 'Undefined Change' notification to the notification buffer
+            CAgnFileChangeInfo* fileChang = CAgnFileChangeInfo::NewL(NULL, MCalFileChangeObserver::ECalendarInfoUpdated);
+            CleanupStack::PushL(fileChang);
+            aFileChangeInfo.ExternalizeL(iFileBufferedNotificationStream);
+            //bring the stream write position to the start
+            streamBuf->SeekL(MStreamBuf::EWrite, posStart); 
+            iFileBufferedNotificationStream.WriteInt32L(++iFileBufferedNotificationsCount);
+            iFileBufferedNotificationStream.CommitL();
+            CleanupStack::PopAndDestroy(fileChang);
+            // Reset the count to 1 - Undefined Change
+            iFileBufferedNotificationsCount = 1;
+            }
+        // notify client that a change has occured
+        if (iChangeNotificationPending == ENotificationRequested)
+            {
+            iChangeNotificationMessage.Complete(EFileChange);
+            iChangeNotificationPending = ENotificationAwaitingRequest;
+            }
+        //bring the stream write position to the end
+       streamBuf->SeekL(MStreamBuf::EWrite, posStart + iFileBufferedNotification->Size());
+       }
+    }
+
+TBool CAgnSessionFile::CreateEntryIterL()
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	if(!iEntryIter)
+		{
+		iEntryIter = iModel->CreateEntryIterL();
+		}
+	return  iEntryIter->SetToFirstL();
+	}
+
+TBool CAgnSessionFile::IsEntryAvailableAtIteratorL()
+	{
+	if(iModel->AgnServFile().IsLocked())
+		{
+		User::Leave(KErrLocked);
+		}
+
+	__ASSERT_ALWAYS(iEntryIter, User::Leave(KErrCorrupt));
+	return iEntryIter->NextL();
+	}
+
+CAgnEntry* CAgnSessionFile::FetchEntryAtIteratorL()
+	{
+	__ASSERT_ALWAYS(iEntryIter, User::Leave(KErrCorrupt));
+	return iModel->FetchEntryL(iEntryIter->At());
+	}
+
+void CAgnSessionFile::ResetModel(const CAgnServFile& aServFile)
+    {
+    delete iEntryIter;
+    iEntryIter = NULL;
+    iModel = aServFile.Model();
+    iFileId = iModel->GetFileIdL();
+    }
+
+TInt CAgnSessionFile::SessionId()
+    {
+    return iSessionId;
+    }
+
+TBool CAgnSessionFile::FileNotificationIsReqested()
+    {
+    return iChangeIterested& EFileChange;
+    }
+
+void CAgnSessionFile::SetFileId(TCalFileId aFileId)
+    {
+    iFileId = aFileId;
+    }
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+TBool CAgnServerSession::IsReadOnlyOperation()
+	{
+	//Only operations that have read user data permissions are allowed once a shutdown notification
+	//is received. The Rollback operation is still allowed.
+	TInt operation = iMessage.Function();
+	if (operation == ERollback || operation < KCapabilityWriteUserData)
+		{
+		return KErrNone;
+		}
+	else
+		{
+		return KErrLocked; 
+		}
+	}
+#endif
+
+
+void CAgnServerSession::CreateInstanceIteratorL()
+	{
+
+	//TFindInstanceParams buffer, CCalSortCriteria buffer, iteratorId
+	//Do this first, so it can be pushed off the cleanup stack last
+	CAgnSortCriteria* sortCriteria = CAgnSortCriteria::NewL();
+	CleanupStack::PushL(sortCriteria);
+	
+	TFindInstanceParams* parameters = new (ELeave) TFindInstanceParams();
+	CleanupStack::PushL(parameters);
+	
+	RArray<TInt64> fileIds;
+	CleanupClosePushL(fileIds);
+	
+	// Restore find instance parameter
+	const TInt KBufferSize = iMessage.GetDesLengthL(KSlot0);
+	CBufFlat* buffer = CBufFlat::NewL(KBufferSize);
+	CleanupStack::PushL(buffer);
+	buffer->ExpandL(0, KBufferSize);
+
+	TPtr8 des(buffer->Ptr(0));
+	iMessage.ReadL(KSlot0, des);
+
+	RDesReadStream readStream(des);
+	parameters->InternalizeL(readStream);
+	
+	// Restore sort criteria
+	const TInt KSortCriteriaSize = iMessage.GetDesLengthL(KSlot1);
+	CBufFlat* sortCriteriaBuffer = CBufFlat::NewL(KSortCriteriaSize);
+	CleanupStack::PushL(sortCriteriaBuffer);
+	sortCriteriaBuffer->ExpandL(0, KSortCriteriaSize);
+	TPtr8 desSortCriteria(sortCriteriaBuffer->Ptr(0));
+	iMessage.ReadL(KSlot1, desSortCriteria);
+	RBufReadStream sortCriteriaStream;
+	sortCriteriaStream.Open(*sortCriteriaBuffer);
+	sortCriteria->InternalizeL(sortCriteriaStream);
+
+	//Create iterator with specified finding and sorting settings.
+	
+	if(iInstanceIteratorMgr == NULL)
+		{
+		//Do this to protect server from fuzzy attacks.
+		iInstanceIteratorMgr = CAgsInstanceIteratorMgr::NewL();
+		}
+	
+	TInt filecount = sortCriteriaStream.ReadInt16L();
+	for(TInt ii=0;ii<filecount;++ii)
+		{
+		TInt64 fileId;
+		sortCriteriaStream >> fileId;
+		fileIds.AppendL(fileId);
+		}
+
+	CleanupStack::PopAndDestroy(sortCriteriaBuffer);
+	CleanupStack::PopAndDestroy(buffer);
+
+	TInt iteratorId = iInstanceIteratorMgr->CreateIteratorL(parameters, sortCriteria, fileIds, *iAgnServer.FileMgr());
+	//We are satisfied that the above line has taken ownership, so we can now pop these two
+	CleanupStack::PopAndDestroy(&fileIds);//doesn't destroy the content of the array
+	CleanupStack::Pop(parameters);
+	CleanupStack::Pop(sortCriteria);
+	
+	// Send the assigned iterator id back to the client
+	TPckg<TInt> id(iteratorId);
+	iMessage.WriteL(KSlot2, id);
+	}
+
+void CAgnServerSession::DestroyInstanceIteratorL()
+	{
+	TInt iteratorId = iMessage.Int0();
+	iInstanceIteratorMgr->DestroyIteratorL(iteratorId);
+	}
+	
+void CAgnServerSession::InstanceIteratorNextL()
+	{
+	TInt iteratorId = iMessage.Int2();
+	TInt startIndex = iMessage.Int3();
+	
+	RArray<TAgnInstance> instances;
+	CleanupClosePushL(instances);
+	iInstanceIteratorMgr->NextInstancesL(iteratorId, instances, startIndex);
+
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = instances.Count();
+
+	bufStream.WriteUint32L(KCount);
+	
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		bufStream << instances[ii];
+		}
+
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(&instances);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::InstanceIteratorPreviousL()
+	{
+	TInt iteratorId = iMessage.Int2();
+	TInt lastIndex = iMessage.Int3();
+	
+	RArray<TAgnInstance> instances;
+	CleanupClosePushL(instances);
+	iInstanceIteratorMgr->PreviousInstancesL(iteratorId, instances, lastIndex);
+
+	delete iBuffer;
+	iBuffer = NULL;
+	iBuffer = CBufFlat::NewL(KInitialBufferSize);
+	
+	RBufWriteStream bufStream;
+	bufStream.Open(*iBuffer);
+	CleanupClosePushL(bufStream);	
+
+	const TInt KCount = instances.Count();
+
+	bufStream.WriteUint32L(KCount);
+	
+	for ( TInt ii = 0; ii < KCount; ++ii )
+		{
+		bufStream << instances[ii];
+		}
+
+	bufStream.CommitL();
+	
+	CleanupStack::PopAndDestroy(&bufStream); // bufStream.Close();
+	CleanupStack::PopAndDestroy(&instances);
+
+	// Send it back to the client
+	TPckg<TInt> size(iBuffer->Size());
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::InstanceIteratorCountL()
+	{
+	TInt iteratorId = iMessage.Int0();
+	TInt count = iInstanceIteratorMgr->CountL(iteratorId);
+	TPckg<TInt> size(count);
+	iMessage.WriteL(KSlot1, size);
+	}
+
+void CAgnServerSession::InstanceIteratorLocateIndexL()
+	{
+	TInt iteratorId = iMessage.Int0();
+	TPckgBuf<TAgnInstance> instanceId;	
+	iMessage.ReadL(KSlot1,instanceId);
+	TInt index = iInstanceIteratorMgr->LocateIndexL(iteratorId, instanceId());
+	TPckg<TInt> size(index);
+	iMessage.WriteL(KSlot2, size);
+	}
+
+
+