omads/omadsextensions/adapters/agenda/src/nsmlagendadatastore.cpp
changeset 0 dab8a81a92de
child 1 95fdac6ccb5c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omads/omadsextensions/adapters/agenda/src/nsmlagendadatastore.cpp	Mon Nov 23 14:46:41 2009 +0200
@@ -0,0 +1,1770 @@
+/*
+* Copyright (c) 2005 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:  DS agenda data store
+*
+*/
+
+
+
+// INCLUDES
+#include "nsmldebug.h"
+#include "nsmlagendadatastore.h"
+#include "nsmlagendadataprovider.h"
+#include "nsmlchangefinder.h"
+#include "NSmlDataModBase.h"
+#include "nsmlagendadefines.hrh"
+#include <ecom.h>
+#include <barsc.h>
+#include <bautils.h>
+#include <calsession.h> 
+#include <caldataexchange.h> 
+#include <calentryview.h>
+#include <caliterator.h>
+#include <calentry.h>
+#include <caldataformat.h>
+#include <caltime.h>
+#include <nsmldsimpluids.h>
+#include <sysutil.h>
+#include <SmlDataProvider.h>
+#include <SmlDataFormat.h>
+#include <SmlDataSyncDefs.h>
+#include <data_caging_path_literals.hrh>
+#include <NSmlAgendaDataStore_1_1_2.rsg>
+#include <NSmlAgendaDataStore_1_2.rsg>
+#include <e32property.h>
+#include <DataSyncInternalPSKeys.h>
+#include <CalenImporter.h>
+#include <CalenInterimUtils2.h>
+
+#ifndef __WINS__
+// This lowers the unnecessary compiler warning (armv5) to remark.
+// "Warning:  #174-D: expression has no effect..." is caused by 
+// DBG_ARGS8 macro in no-debug builds.
+#pragma diag_remark 174
+#endif
+// ============================= MEMBER FUNCTIONS ==============================
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CNSmlAgendaDataStore
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore::CNSmlAgendaDataStore() :
+	iKey( TKeyArrayFix( _FOFF( TNSmlSnapshotItem, ItemId() ), ECmpTInt ) ),
+	iPos( -1 ),
+	iHasHistory( EFalse ),
+	iModificationCount( KNSmlCompactAfterChanges ),
+	iState( ENSmlClosed ),
+	iSnapshotRegistered( EFalse ),
+	iDrive( -1 ),
+	iReplaceItemId( -1 ),
+	iRXEntryType( ENSmlNotSet ),
+	iTXEntryType( ENSmlNotSet )
+	{
+	_DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): BEGIN");
+	_DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): END");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::ConstructL()
+	{
+	_DBG_FILE("CNSmlAgendaDataStore::ConstructL: BEGIN");
+
+	iStringPool.OpenL();
+	User::LeaveIfError( iRfs.Connect() );
+
+	iDataMod = new ( ELeave ) CNSmlVCalMod();
+	
+	iNewUids = new ( ELeave ) CNSmlDataItemUidSet();
+	iDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
+	iSoftDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
+	iMovedUids = new ( ELeave ) CNSmlDataItemUidSet();
+	iReplacedUids = new ( ELeave ) CNSmlDataItemUidSet();
+	
+	iDefaultStoreName = HBufC::NewL( KNSmlDefaultStoreNameMaxSize );
+	
+	iVersitTlsData = &CVersitTlsData::VersitTlsDataL();
+	// Create CalSession and CalEntryView instances
+	iVCalSession = CCalSession::NewL();
+	
+	TPtr obptr = iDefaultStoreName->Des();
+	obptr = iVCalSession->DefaultFileNameL(); 
+
+	iOwnFormat = DoOwnStoreFormatL();
+	iDataMod->SetOwnStoreFormat( *iOwnFormat );
+	
+    iInterimUtils = CCalenInterimUtils2::NewL();
+	
+	_DBG_FILE("CNSmlAgendaDataStore::ConstructL: END");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore* CNSmlAgendaDataStore::NewL()
+	{
+	_DBG_FILE("CNSmlAgendaDataStore::NewL: BEGIN");
+	
+	CNSmlAgendaDataStore* self = new ( ELeave ) CNSmlAgendaDataStore();
+	CleanupStack::PushL( self );
+	
+	self->ConstructL();
+	CleanupStack::Pop(); // self
+	
+	_DBG_FILE("CNSmlAgendaDataStore::NewL: END");
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::~CNSmlAgendaDataStore
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore::~CNSmlAgendaDataStore()
+	{
+	_DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): BEGIN");
+
+    // Enable notifications
+    TInt error( KErrNone );
+    if ( iVCalSession )
+        {
+        TRAP_IGNORE( iVCalSession->EnablePubSubNotificationsL() );
+        TRAP_IGNORE( iVCalSession->EnableChangeBroadcast() );
+        }
+
+	delete iOwnFormat;
+	iRfs.Close();
+	iStringPool.Close();
+	
+    if ( iChangeFinder )
+		{
+		TRAP( error, iChangeFinder->CloseL() );
+		}
+	if (iVersitTlsData)
+			{
+			iVersitTlsData->VersitTlsDataClose();
+			}
+	delete iChangeFinder;
+	delete iNewUids;
+	delete iDeletedUids;
+	delete iSoftDeletedUids;
+	delete iMovedUids;
+	delete iReplacedUids;
+
+    delete iDefaultStoreName;
+    delete iOpenedStoreName;
+	delete iDataMod;
+	delete iItemData;
+
+    delete iAgendaProgressview;
+    
+	delete iImporter;
+    delete iExporter;
+    
+    delete iEntryView;
+    delete iVCalSession;
+    delete iInterimUtils;
+    
+    
+    // REComSession::FinalClose();
+	
+	_DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): END");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOpenL
+// Open calendar database for access.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoOpenL( const TDesC& aStoreName,
+                MSmlSyncRelationship& aContext, TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoOpenL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlClosed )
+		{
+		User::RequestComplete( iCallerStatus, KErrInUse );
+		return;
+		}
+
+	if( RFs::CharToDrive( aStoreName[0], iDrive ) != KErrNone )
+		{
+		RFs::CharToDrive( KNSmlDriveC()[0], iDrive );
+		}
+    
+    // Open database
+	TInt err( KErrNone );	
+	if ( aStoreName == KNSmlAgendaStoreNameForDefaultDB )
+		{
+		TRAP( err, iVCalSession->OpenL( *iDefaultStoreName ) );
+		}
+    else 
+    	{
+    	TRAP( err, iVCalSession->OpenL( aStoreName ) );
+    	}
+	if ( err )
+	    {
+	    User::RequestComplete( iCallerStatus, err );
+	    return;
+	    }
+	
+	// Disable notifications
+	TRAP_IGNORE( iVCalSession->DisablePubSubNotificationsL() );
+	TRAP_IGNORE( iVCalSession->DisableChangeBroadcast() );
+	    
+	if ( iOpenedStoreName )
+		{
+		delete iOpenedStoreName;
+		iOpenedStoreName = NULL;
+		}
+	iOpenedStoreName = aStoreName.AllocL();
+	
+	// Initialize some member variables
+	// Create importer and exporter
+    iImporter = CCalenImporter::NewL( *iVCalSession );
+	iExporter = CCalenExporter::NewL( *iVCalSession );
+
+    // Progress view
+	iAgendaProgressview = CNSmlAgendaProgressview::NewL();
+
+    iEntryView = CCalEntryView::NewL( *iVCalSession, *iAgendaProgressview );
+    CActiveScheduler::Start();
+    TInt completedStatus = iAgendaProgressview->GetCompletedStatus();
+    if ( completedStatus != KErrNone )
+        {
+        User::RequestComplete( iCallerStatus, completedStatus );
+        return;
+        }
+
+	if ( iChangeFinder )
+		{
+		iChangeFinder->CloseL();
+		delete iChangeFinder;
+		iChangeFinder = NULL;
+		}
+	iChangeFinder = CNSmlChangeFinder::NewL( aContext, iKey, iHasHistory,
+	                                         KNSmlAgendaAdapterImplUid );
+    
+    // Get ID of database
+	iVCalSession->FileIdL( iOpenedStoreId );
+	
+	if( !iSnapshotRegistered )
+		{
+		RegisterSnapshotL();
+		}
+     	
+	iState = ENSmlOpenAndWaiting;
+    User::RequestComplete( iCallerStatus, err );
+	    
+	_DBG_FILE("CNSmlAgendaDataStore::DoOpenL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCancelRequest
+// Set internal module state to previous state.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCancelRequest()
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: BEGIN");
+    if ( iState == ENSmlOpenAndWaiting )
+        {
+    	iState = ENSmlClosed;
+        }
+    else
+        {
+	    iState = ENSmlOpenAndWaiting;
+        }
+	_DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoStoreName
+// Returns previously opened database name.
+// -----------------------------------------------------------------------------
+//
+const TDesC& CNSmlAgendaDataStore::DoStoreName() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoStoreName: BEGIN");
+	_DBG_FILE("CNSmlAgendaDataStore::DoStoreName: END");
+	return *iOpenedStoreName;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoBeginTransactionL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoBeginTransactionL()
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: BEGIN");
+	User::Leave( KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitTransactionL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitTransactionL( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	User::RequestComplete( iCallerStatus, KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoRevertTransaction
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoRevertTransaction( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	User::RequestComplete( iCallerStatus, KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoBeginBatchL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoBeginBatchL()
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: BEGIN");
+	User::Leave( KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitBatchL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/,
+                TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	User::RequestComplete( iCallerStatus, KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCancelBatch
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCancelBatch()
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: BEGIN");
+	// Nothing to do
+	_DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSetRemoteStoreFormatL
+// Set SyncML Remote Server data store format.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSetRemoteStoreFormatL(
+                const CSmlDataStoreFormat& aServerDataStoreFormat )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: BEGIN");
+	
+	if ( iOwnFormat )
+	    {
+	    delete iOwnFormat;
+	    iOwnFormat = NULL;    
+	    }
+	
+	iOwnFormat = DoOwnStoreFormatL();
+	iDataMod->SetOwnStoreFormat( *iOwnFormat );
+	
+    iDataMod->SetPartnerStoreFormat( ( CSmlDataStoreFormat& )
+                aServerDataStoreFormat );
+    
+    // Check which calendar type (vCal/iCal) is used
+    // If server supports iCal then it is used
+    // Otherwise vCal is used
+    TInt returnValue( KErrNotSupported );
+
+#ifdef __NSML_USE_ICAL_FEATURE
+
+    _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support iCal");
+   	returnValue = iDataMod->SetUsedMimeType(
+       	    iOwnFormat->MimeFormat( 1 ).MimeType(),
+           	iOwnFormat->MimeFormat( 1 ).MimeVersion() );
+
+#endif // __NSML_USE_ICAL_FEATURE
+
+    if ( returnValue == KErrNone )
+        {
+        _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets iCal");
+        iRXEntryType = ENSmlICal;
+        iTXEntryType = ENSmlICal;
+        }
+    else
+        {
+        _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support vCal");
+        returnValue = iDataMod->SetUsedMimeType(
+            iOwnFormat->MimeFormat( 0 ).MimeType(),
+            iOwnFormat->MimeFormat( 0 ).MimeVersion() );
+        if ( returnValue == KErrNone )
+            {
+            _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets vCal");
+            iRXEntryType = ENSmlVCal;
+            iTXEntryType = ENSmlVCal;
+            }
+        }
+    if ( iRXEntryType == ENSmlNotSet || iTXEntryType == ENSmlNotSet )
+        {
+        // Leave if server does not support either vCal or iCal
+        _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: MimeType Not supported");
+        User::Leave( KErrNotFound );        
+        }
+    
+	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize
+// Set SyncML Remote Server maximum object size.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize( TInt aServerMaxObjectSize )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: BEGIN");
+	iServerMaxObjectSize = aServerMaxObjectSize;
+	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMaxObjectSize
+// Set SyncML Component maximum object size.
+// -----------------------------------------------------------------------------
+//
+TInt CNSmlAgendaDataStore::DoMaxObjectSize() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize: BEGIN");
+	_DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize - Default: END");
+	return KNSmlAgendaOwnMaxObjectSize;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOpenItemL
+// Open calendar item for reading.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoOpenItemL( TSmlDbItemUid aUid, TBool& aFieldChange,
+                TInt& aSize, TSmlDbItemUid& /*aParent*/, TDes8& aMimeType,
+                TDes8& aMimeVer, TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: BEGIN");
+    iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+		
+ 	iReplaceItemId = aUid;
+ 	
+	CCalEntry* entry = NULL;
+	TInt err( KErrNone );
+    TRAP( err, entry = iEntryView->FetchL( aUid ) );
+	CleanupStack::PushL( entry );
+	
+	if ( err || !entry )
+		{
+		CleanupStack::PopAndDestroy( entry ); // entry
+		User::RequestComplete( iCallerStatus, KErrNotFound );
+		return;
+		}
+		
+	if ( !iSnapshotRegistered )
+		{
+		RegisterSnapshotL();
+		}
+	delete iItemData;
+	iItemData = NULL;
+	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+
+	RBufWriteStream writeStream( *iItemData );
+	writeStream.PushL();
+	
+	// Export item from database
+	if ( iTXEntryType == ENSmlICal )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - iCal DB");
+	    iExporter->ExportICalL( *entry, writeStream );
+	    aMimeType = iOwnFormat->MimeFormat( 1 ).MimeType().DesC();
+	    aMimeVer = iOwnFormat->MimeFormat( 1 ).MimeVersion().DesC();
+	    }
+    else if ( iTXEntryType == ENSmlVCal )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - vCal DB");
+	    iExporter->ExportVCalL( *entry, writeStream );
+	    aMimeType = iOwnFormat->MimeFormat( 0 ).MimeType().DesC();
+	    aMimeVer = iOwnFormat->MimeFormat( 0 ).MimeVersion().DesC();
+	    }
+	else
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - DB Not Supported");
+	    CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
+	    User::RequestComplete( iCallerStatus, KErrNotSupported );
+		return;
+	    }
+	
+	writeStream.CommitL();
+	iItemData->Compress();
+	iPos = 0;
+	
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+	         _S8( "Item from database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+	
+	iDataMod->StripTxL( *iItemData );
+	CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
+	
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+	         _S8( "Item from database after strip:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+	
+	aFieldChange = EFalse;
+	aSize = iItemData->Size();
+	
+	iState = ENSmlItemOpen;
+	
+	if ( iServerMaxObjectSize == 0 || aSize <= iServerMaxObjectSize )
+		{
+		User::RequestComplete( iCallerStatus, KErrNone );
+		}
+	else
+		{
+		User::RequestComplete( iCallerStatus, KErrTooBig );
+		}
+		
+	_DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCreateItemL
+// Prepare item data for writing to database. WriteItemL() writes item's data as
+// buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCreateItemL( TSmlDbItemUid& aUid, TInt aSize,
+                TSmlDbItemUid /*aParent*/, const TDesC8& aMimeType,
+                const TDesC8& /*aMimeVer*/, TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	iAddItemId = &aUid;
+	
+	if ( iState != ENSmlOpenAndWaiting )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrNotReady: END");
+		return;
+		}
+		
+	if ( KNSmlAgendaOwnMaxObjectSize < aSize )
+		{
+		User::RequestComplete( iCallerStatus, KErrTooBig );
+		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrTooBig: END");
+		return;
+		}
+		
+	if( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
+		{
+		User::RequestComplete( iCallerStatus, KErrDiskFull );
+		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrDiskFull: END");
+		return;
+		}
+
+    // Check if MIME type of new item is supported
+	TBool mimeFound( EFalse );
+	// vCal
+    if ( iOwnFormat->MimeFormat( 0 ).MimeType().DesC().Compare( aMimeType )
+         == 0 )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received vCal");
+	    mimeFound = ETrue;
+	    iRXEntryType = ENSmlVCal;
+	    }
+	        
+#ifdef __NSML_USE_ICAL_FEATURE
+
+     // iCal
+    else if ( iOwnFormat->MimeFormat( 1 ).MimeType().DesC().Compare( aMimeType )
+              == 0 ) 
+        {
+        _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received iCal");
+        mimeFound = ETrue;
+	    iRXEntryType = ENSmlICal;
+        }
+
+#endif // __NSML_USE_ICAL_FEATURE
+
+    // Else use original iRXEntryType
+    else
+        {
+        _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: \
+                   mime type not received");
+        iRXEntryType = iTXEntryType;
+        }
+
+	if ( !mimeFound )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotSupported );
+		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL -KErrNotSupported: END");
+		return;
+		}
+
+	if( !iSnapshotRegistered )
+		{
+		RegisterSnapshotL();
+		}
+	delete iItemData;
+	iItemData = NULL;
+	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+	iPos = 0;
+	
+	iState = ENSmlItemCreating;
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoReplaceItemL
+// Prepare item data for writing and replacing item in database. WriteItemL()
+// writes item's data as buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoReplaceItemL( TSmlDbItemUid aUid, TInt aSize,
+                TSmlDbItemUid /*aParent*/, TBool aFieldChange,
+                TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	
+	if ( iState != ENSmlOpenAndWaiting )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotReady: END");
+		return;
+		}
+
+	if ( KNSmlAgendaOwnMaxObjectSize < aSize )
+		{
+		User::RequestComplete( iCallerStatus, KErrTooBig );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrTooBig: END");
+		return;
+		}
+
+	if ( aFieldChange )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotSupported );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL \
+		           - KErrNotSupported: END");
+		return;
+		}
+	if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
+		{
+		User::RequestComplete( iCallerStatus, KErrDiskFull );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrDiskFull: END");
+		return;
+		}
+	
+ 	iReplaceItemId = aUid;
+
+ 	CCalEntry* entry = NULL;
+ 	TInt err( KErrNone );
+    TRAP( err, entry = iEntryView->FetchL( aUid ) );
+	CleanupStack::PushL( entry );
+ 		
+	if ( !entry || err == KErrNotFound )
+		{
+		CleanupStack::PopAndDestroy( entry ); // entry
+		User::RequestComplete( iCallerStatus, KErrNotFound );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotFound: END");
+		return;
+		}
+    else if ( err )
+        {
+		CleanupStack::PopAndDestroy( entry ); // entry
+		User::RequestComplete( iCallerStatus, err );
+		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - Error: END");
+		return;
+        }
+
+	CleanupStack::PopAndDestroy( entry ); // entry
+		
+	if ( !iSnapshotRegistered )
+		{
+		RegisterSnapshotL();
+		}
+		
+	delete iItemData;
+	iItemData = NULL;
+	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+	iPos = 0;
+	iReplaceItemId = aUid;
+	
+	iState = ENSmlItemUpdating;
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoReadItemL
+// Read item data to given buffer.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoReadItemL( TDes8& aBuffer )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: BEGIN");
+    if ( iState != ENSmlItemOpen || !iItemData )
+        {
+        iPos = -1;
+        User::Leave( KErrNotReady );
+        }
+
+    if ( iPos == -1 )
+        {
+        User::Leave( KErrEof );
+        }
+
+    if ( aBuffer.Size() < iItemData->Size() - iPos )
+        {
+        iItemData->Read( iPos, aBuffer );
+        iPos += aBuffer.Size();
+        }
+    else
+        {
+        iItemData->Read( iPos, aBuffer, iItemData->Size() - iPos );
+        iPos = -1;
+        }
+	_DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoWriteItemL
+// Write item data as buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoWriteItemL( const TDesC8& aData )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: BEGIN");
+	if ( iState == ENSmlItemCreating || iState == ENSmlItemUpdating )
+		{
+		if ( iItemData )
+			{
+			if ( iPos == -1 )
+				{
+				User::Leave( KErrEof );
+				}
+			iItemData->InsertL( iPos, aData );
+			iPos += aData.Size();
+			return;
+			}
+		}
+	User::Leave( KErrNotReady );
+	_DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitItemL
+// Commit item data to database when adding or replacing item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitItemL( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	
+	if ( iState != ENSmlItemCreating && iState != ENSmlItemUpdating )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL - KErrNotReady: END");
+		return;
+		}
+	
+	iItemData->Compress();
+	TInt error( KErrNone );
+	
+	if ( iState == ENSmlItemCreating )
+		{
+		TRAP( error, DoCommitCreateItemL() );
+		}
+	else // ENSmlItemUpdating
+		{
+        TRAP( error, DoCommitReplaceItemL() );
+		}
+	iReplaceItemId = -1;
+	iPos = -1;
+	iState = ENSmlOpenAndWaiting;
+	iRXEntryType = iTXEntryType;
+    User::RequestComplete( iCallerStatus, error );    
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCloseItem
+// Return to previous state and clean item buffer.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCloseItem()
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: BEGIN");
+	if ( iState == ENSmlItemOpen )
+		{
+		iPos = -1;
+		iState = ENSmlOpenAndWaiting;
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMoveItemL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoMoveItemL( TSmlDbItemUid /*aUid*/,
+            TSmlDbItemUid /*aNewParent*/, TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+	User::RequestComplete( iCallerStatus, KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeleteItemL
+// Delete item from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoDeleteItemL( TSmlDbItemUid aUid,
+                TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting )
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+
+    CCalEntry* entry = NULL;
+    TInt err( KErrNone );
+    TRAP( err, entry = iEntryView->FetchL( aUid ) );
+    CleanupStack::PushL( entry );	
+
+	if ( !entry || err == KErrNotFound )
+		{
+		CleanupStack::PopAndDestroy( entry ); // entry
+		User::RequestComplete( iCallerStatus, KErrNotFound );
+		return;
+		}
+	else if ( err )
+	    {
+	    CleanupStack::PopAndDestroy( entry ); // entry
+		User::RequestComplete( iCallerStatus, err );
+		return;
+	    }
+	    
+    iEntryView->DeleteL( *entry );
+	CleanupStack::PopAndDestroy( entry ); // entry
+	
+	if ( iChangeFinder )
+		{
+		TNSmlSnapshotItem item( aUid );
+		iChangeFinder->ItemDeleted( item );
+		}
+		
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSoftDeleteItemL
+// Delete item from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSoftDeleteItemL( TSmlDbItemUid /*aUid*/,
+                TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	User::RequestComplete( iCallerStatus, KErrNotSupported );
+	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeleteAllItemsL
+// Delete all items from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting ) 
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+
+	// Delete all items
+	// First searh every UIDs ...
+	TInt aNumSuccessfulDeleted( 0 );
+	RArray<TCalLocalUid> uidArray;
+	CleanupClosePushL( uidArray );
+	TCalTime zeroTime;
+	zeroTime.SetTimeUtcL( Time::NullTTime() );
+	iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
+	
+	
+	// ... and then delete them
+    iEntryView->DeleteL( uidArray, aNumSuccessfulDeleted );
+	CleanupStack::PopAndDestroy( &uidArray ); // uidArray
+
+    // Update changefinder
+	if ( iChangeFinder )
+		{
+		iChangeFinder->ResetL();
+		}
+	iSnapshotRegistered = EFalse;
+	RegisterSnapshotL();
+	
+	User::RequestComplete( iCallerStatus, KErrNone );
+	
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoHasSyncHistory
+// Return ETrue if syncronization history is available.
+// -----------------------------------------------------------------------------
+//
+TBool CNSmlAgendaDataStore::DoHasSyncHistory() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: BEGIN");
+	TBool ret = EFalse;
+	if ( iHasHistory )
+		{
+		if ( iOpenedStoreId != iChangeFinder->DataStoreUid() )
+			{
+			iChangeFinder->SetDataStoreUid( iOpenedStoreId );
+			}
+		else
+			{
+			ret = ETrue;
+			}
+		}
+	else
+		{
+		iChangeFinder->SetDataStoreUid( iOpenedStoreId );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: END");
+	return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoAddedItems
+// Give uid list of added items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoAddedItems() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: BEGIN");
+	if ( iState == ENSmlOpenAndWaiting )
+		{
+		iNewUids->Reset();
+		TRAP_IGNORE( iChangeFinder->FindNewItemsL( *iNewUids ) );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: END");
+	return *iNewUids;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeletedItems
+// Give uid list of deleted items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoDeletedItems() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: BEGIN");
+	if ( iState == ENSmlOpenAndWaiting )
+		{
+		iDeletedUids->Reset();
+		TRAP_IGNORE( iChangeFinder->FindDeletedItemsL( *iDeletedUids ) );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: END");
+	return *iDeletedUids;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSoftDeletedItems
+// Give uid list of deleted items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoSoftDeletedItems() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: BEGIN");
+	if ( iState == ENSmlOpenAndWaiting )
+		{
+		iSoftDeletedUids->Reset();
+		TRAP_IGNORE(
+		    iChangeFinder->FindSoftDeletedItemsL( *iSoftDeletedUids ) );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: END");
+	return *iSoftDeletedUids;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoModifiedItems
+// Give uid list of modified items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoModifiedItems() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: BEGIN");
+	if ( iState == ENSmlOpenAndWaiting )
+		{
+		iReplacedUids->Reset();
+		TRAP_IGNORE( iChangeFinder->FindChangedItemsL( *iReplacedUids ) );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: END");
+	return *iReplacedUids;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMovedItems
+// Give uid list of moved items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoMovedItems() const
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: BEGIN");
+	if ( iState == ENSmlOpenAndWaiting )
+		{
+		iMovedUids->Reset();
+		TRAP_IGNORE( iChangeFinder->FindMovedItemsL( *iMovedUids ) );
+		}
+	_DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: END");
+	return *iMovedUids;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoResetChangeInfoL
+// Reset change info that exist since last syncronization.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoResetChangeInfoL( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting ) 
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+	iChangeFinder->ResetL();
+	iSnapshotRegistered = EFalse;
+	if( !iSnapshotRegistered )
+		{
+		RegisterSnapshotL();
+		}
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitChangeInfoL
+// Commit change info that exist since last syncronization for given uid list.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus,
+                const MSmlDataItemUidSet& aItems )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting ) 
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+	iChangeFinder->CommitChangesL( aItems );
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitChangeInfoL
+// Commit change info that exist since last syncronization.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus )
+    {
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
+	iCallerStatus = &aStatus;
+	*iCallerStatus = KRequestPending;
+	if ( iState != ENSmlOpenAndWaiting ) 
+		{
+		User::RequestComplete( iCallerStatus, KErrNotReady );
+		return;
+		}
+	iChangeFinder->CommitChangesL();
+	User::RequestComplete( iCallerStatus, KErrNone );
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
+    }
+    
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::RegisterSnapshotL
+// Register snapshot.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::RegisterSnapshotL()
+    {
+	_DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): begin");
+	CArrayFixSeg<TNSmlSnapshotItem>* snapshot =
+	                new ( ELeave ) CArrayFixSeg<TNSmlSnapshotItem>( 64 );
+	CleanupStack::PushL( snapshot );
+	
+    // First find all entries ...
+	RArray<TCalLocalUid> uidArray;
+	CleanupClosePushL( uidArray );
+	TCalTime zeroTime;
+	zeroTime.SetTimeUtcL( Time::NullTTime() );
+	iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
+	
+	// ... and then create snapshot items
+	for ( TInt i = 0; i < uidArray.Count(); i++ )
+	    {
+	    TNSmlSnapshotItem newItem = CreateSnapshotItemL( uidArray[i] );
+	    if ( newItem.ItemId() != 0 )
+	        {
+	        snapshot->InsertIsqL( newItem, iKey );
+	        }
+	    }
+	
+	CleanupStack::PopAndDestroy( &uidArray );
+		
+	iChangeFinder->SetNewSnapshot( snapshot );
+	
+	// iChangeFinder takes ownership of items
+	CleanupStack::Pop( snapshot );
+	iSnapshotRegistered = ETrue;
+	
+	_DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): end");
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CreateSnapshotItemL
+// Creates new snapshot. Method gets data from database.
+// -----------------------------------------------------------------------------
+TNSmlSnapshotItem CNSmlAgendaDataStore::CreateSnapshotItemL(
+                const TCalLocalUid& aUid )
+    {
+    TNSmlSnapshotItem item( 0 );
+    CCalEntry* entry = iEntryView->FetchL( aUid );
+    CleanupStack::PushL( entry );
+
+    if( entry )
+		{
+		CCalEntry::TReplicationStatus replicationStatus =
+		                    entry->ReplicationStatusL();
+		if ( CanBeSynchronized( replicationStatus ) )
+			{
+			TUint intUid = entry->LocalUidL();
+			item.SetItemId( intUid );
+			item.SetLastChangedDate(
+			                entry->LastModifiedDateL().TimeUtcL() );
+			item.SetSoftDelete( EFalse );
+			}
+		}
+		
+    CleanupStack::PopAndDestroy( entry ); // entry
+	return item;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoListAgendaFilesL
+// List possible calendar database file names.
+// -----------------------------------------------------------------------------
+//
+CDesCArray* CNSmlAgendaDataStore::DoListAgendaFilesLC() const
+    {
+    CDesCArray* array = iVCalSession->ListCalFilesL();    
+	CleanupStack::PushL( array );
+	return array;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoGetDefaultFileNameL
+// Return default calendar database name.
+// -----------------------------------------------------------------------------
+//
+const TDesC& CNSmlAgendaDataStore::DoGetDefaultFileNameL() const
+    {
+	if ( !iDefaultStoreName )
+		{
+        User::Leave( KErrGeneral );
+		}
+	return *iDefaultStoreName;
+    }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CanBeSynchronized
+// Return ETrue if entry can be synchronized.
+// -----------------------------------------------------------------------------
+//
+TBool CNSmlAgendaDataStore::CanBeSynchronized(
+            const CCalEntry::TReplicationStatus&
+            aReplicationStatus ) const
+	{
+	return ( aReplicationStatus != CCalEntry::ERestricted );	
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOwnStoreFormatL
+// Returns adapters supported store format which is read from Calendar Plug
+// In Adapter own resource file.
+// -----------------------------------------------------------------------------
+//
+CSmlDataStoreFormat* CNSmlAgendaDataStore::DoOwnStoreFormatL()
+	{
+	_DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): BEGIN");
+	TFileName fileName;
+	TParse parse;
+	
+	// Check correct Data Sync protocol
+	TInt value( EDataSyncNotRunning );
+	TInt error = RProperty::Get( KPSUidDataSynchronizationInternalKeys,
+                                 KDataSyncStatus,
+                                 value );
+	if ( error == KErrNone &&
+	     value == EDataSyncRunning )
+	    {
+	    parse.Set( KNSmlDSAgendaDataStoreRsc_1_1_2,
+	               &KDC_RESOURCE_FILES_DIR, NULL );
+	    }
+	else // error or protocol version 1.2 
+	    {
+	    parse.Set( KNSmlDSAgendaDataStoreRsc_1_2,
+	               &KDC_RESOURCE_FILES_DIR, NULL );
+	    }
+	
+	fileName = parse.FullName();
+	RResourceFile resourceFile;
+	BaflUtils::NearestLanguageFile( iRfs, fileName );
+
+	TRAPD( leavecode, resourceFile.OpenL( iRfs,fileName ) );
+	if ( leavecode != 0 )
+		{
+		CleanupStack::PopAndDestroy(); // parse
+		_DBG_FILE("CNSmlAgendaDataProvider::DoStoreFormatL(): END");
+		User::Leave( leavecode );
+		}
+	CleanupClosePushL( resourceFile );
+	HBufC8* profileRes = resourceFile.AllocReadLC( NSML_AGENDA_DATA_STORE );
+	TResourceReader reader;
+	reader.SetBuffer( profileRes );
+
+	CSmlDataStoreFormat* dsFormat = CSmlDataStoreFormat::NewLC( iStringPool,
+	                                                            reader );
+	CleanupStack::Pop();
+	CleanupStack::PopAndDestroy( 2 ); // resourceFile, profileRes
+	_DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): END");
+	return dsFormat;
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitCreateItemL
+// Commit item data to database when adding item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitCreateItemL()
+    {
+    _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: BEGIN");
+    iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
+	CCalEntry::TReplicationStatus  replicationStatus;
+	
+	RBufReadStream readStream;
+	readStream.Open( *iItemData );
+	readStream.PushL();
+
+    RPointerArray<CCalEntry> rdArray;
+	CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
+	if ( iRXEntryType == ENSmlICal )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportICalendarL");
+	    iImporter->ImportICalendarL( readStream, rdArray );
+	    }
+    else if ( iRXEntryType == ENSmlVCal )
+        {
+        _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportVCalendarL");
+        iImporter->ImportVCalendarL( readStream, rdArray );
+        }
+    else
+        {
+        CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+		           KErrNotSupported: END");
+        User::Leave( KErrNotSupported );
+        }
+    
+    // If rdArray is empty or there is multiple items then return error
+	// Multiple items are not supported
+	if ( rdArray.Count() != 1 )
+	    {
+	    CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+		           Multiple items are not supported: END");
+        User::Leave( KErrNotSupported );
+	    }
+	    
+    TInt err( KErrNone );
+
+    _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: before StoreL");
+    TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
+    DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
+    if ( err )
+        {
+        CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+		           Error at storing item to database: END");
+        User::Leave( KErrGeneral );
+        }
+
+    *iAddItemId = rdArray[0]->LocalUidL();
+    
+    CCalEntry* newEntry = iEntryView->FetchL( *iAddItemId );
+    
+    if( newEntry )
+    	{
+	    CleanupStack::PushL( newEntry );
+        
+		replicationStatus = newEntry->ReplicationStatusL();
+	
+    	if ( CanBeSynchronized( replicationStatus ) )
+			{
+			if ( iChangeFinder )
+				{
+				TNSmlSnapshotItem item( *iAddItemId );
+        			item.SetLastChangedDate(
+                   	newEntry->LastModifiedDateL().TimeUtcL() );
+            	item.SetSoftDelete( EFalse );
+				TRAPD( changeFinderError, iChangeFinder->ItemAddedL( item ) );
+				if ( changeFinderError == KErrAlreadyExists )
+			    	{
+			    	iChangeFinder->ItemUpdatedL( item );
+			    	}
+				else
+			    	{
+			    	User::LeaveIfError( changeFinderError );    
+			    	}
+				}
+			}
+    	CleanupStack::PopAndDestroy();// newEntry,
+    	}
+    CleanupStack::PopAndDestroy( 2 ); //  rdArray, readStream   
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: END");
+    }
+    
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitReplaceItemL
+// Commit item data to database when replacing item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitReplaceItemL()
+    {
+    _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: BEGIN");
+    iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
+	CBufFlat* oldItem = CBufFlat::NewL( KNSmlItemDataExpandSize );
+	CleanupStack::PushL( oldItem );
+	RBufWriteStream writeStream( *oldItem );
+	writeStream.PushL();
+	
+	CCalEntry* entry = NULL;
+	TInt error( KErrNone );
+    TRAP( error, entry = iEntryView->FetchL( iReplaceItemId ) );
+	if ( error || !entry )
+	{
+    	CleanupStack::PopAndDestroy( 2 ); // writeStream, oldItem
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+		           Error in fetching the item: END");
+    	User::Leave( KErrGeneral );
+    }
+    CleanupStack::PushL( entry );
+	
+	// Export item from database depending on transmitted item entry type
+	if ( iTXEntryType == ENSmlVCal )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportVCalL");
+    	iExporter->ExportVCalL( *entry, writeStream );        
+    	}
+#ifdef __NSML_USE_ICAL_FEATURE
+	else if ( iTXEntryType == ENSmlICal )
+	    {
+	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportICalL");
+    	iExporter->ExportICalL( *entry, writeStream );
+	    }
+#endif // __NSML_USE_ICAL_FEATURE
+	else
+        {
+        CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+		           KErrNotSupported: END");
+        User::Leave( KErrNotSupported );
+        }
+        
+	writeStream.CommitL();
+	oldItem->Compress();
+
+	CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
+	
+	// Get original UID, geoId and Recurrence-ID properties
+	HBufC8* uid = NULL;
+	HBufC8* recurrenceId = NULL;
+	HBufC8* xRecurrenceId = NULL;
+	HBufC8* geoId = NULL;
+	GetPropertiesFromDataL( oldItem, uid, KVersitTokenUID()  );
+	GetPropertiesFromDataL( oldItem, recurrenceId, KNSmlVersitTokenRecurrenceID() );
+	GetPropertiesFromDataL( oldItem, xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );
+	GetPropertiesFromDataL( oldItem, geoId, KNSmlVersitTokenGeoID() );
+	CleanupStack::PushL( uid );
+	CleanupStack::PushL( recurrenceId );
+	CleanupStack::PushL( xRecurrenceId );
+	CleanupStack::PushL( geoId );
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+	DBG_DUMP( ( void* )oldItem->Ptr( 0 ).Ptr(), oldItem->Size(),
+	          _S8( "Old item from database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+   	if ( iDataMod->NeedsMerge() )
+		{
+    	// Merge data
+    	iDataMod->MergeRxL( *iItemData, *oldItem );
+		}
+	
+	// Add original UID and Recurrence-ID to merged data
+	// This first removes UID and Recurrence-ID from merged data
+	// and then adds original ones
+	if ( uid )
+	    {
+	    SetPropertiesToDataL( uid, KVersitTokenUID() );    
+	    }
+    else
+        {
+        User::Leave( KErrNotSupported );
+        }
+	if ( recurrenceId )
+	    {
+	    SetPropertiesToDataL( recurrenceId, KNSmlVersitTokenRecurrenceID() );    
+	    }
+	if ( xRecurrenceId )
+	    {
+	    SetPropertiesToDataL( xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );    
+	    }
+	if ( geoId )
+	    {
+	    SetPropertiesToDataL( geoId, KNSmlVersitTokenGeoID() );    
+	    }
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+	          _S8( "New item to database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+	
+	CleanupStack::PopAndDestroy( 5 ); // xRecurrenceId, recurrenceId,
+	                                  // uid, oldItem, geoId
+    
+	// Replace item to database
+	RBufReadStream readStream;
+	readStream.Open( *iItemData );
+	readStream.PushL();
+
+	RPointerArray<CCalEntry> rdArray;
+	CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
+
+	// Import item to database depending on received item entry type
+	if ( iRXEntryType == ENSmlVCal )
+        {
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportVCalendarL");
+    	iImporter->ImportVCalendarL( readStream, rdArray );
+        }
+#ifdef __NSML_USE_ICAL_FEATURE
+	else if ( iRXEntryType == ENSmlICal )
+		{
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportICalendarL");
+		iImporter->ImportICalendarL( readStream, rdArray );
+		}
+#endif // __NSML_USE_ICAL_FEATURE
+    else
+        {
+        CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+		           KErrNotSupported: END");
+        User::Leave( KErrNotSupported );
+        }
+
+    // If rdArray is empty or there is multiple items then return error
+	// Multiple items are not supported
+	if ( rdArray.Count() != 1 )
+	    {
+	    CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+		           Multiple items are not supported: END");
+        User::Leave( KErrNotSupported );
+	    }
+	    
+	TInt err( KErrNone );
+
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: before StoreL");
+    TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
+    DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
+    if ( err )
+        {
+        CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+		           Error at storing item to database: END");
+        User::Leave( KErrGeneral );
+        }
+
+	CCalEntry::TReplicationStatus  replicationStatus;
+	
+	CCalEntry* replacedEntry = iEntryView->FetchL( iReplaceItemId );
+	if( replacedEntry )
+	{
+    CleanupStack::PushL( replacedEntry );
+	
+    replicationStatus = replacedEntry->ReplicationStatusL();
+	            
+	if ( CanBeSynchronized( replicationStatus ) )
+		{
+		if ( iChangeFinder )
+			{
+			TNSmlSnapshotItem item( iReplaceItemId );
+			item.SetLastChangedDate(
+			            replacedEntry->LastModifiedDateL().TimeUtcL());
+			item.SetSoftDelete( EFalse );
+			iChangeFinder->ItemUpdatedL( item );
+			}
+		}
+	CleanupStack::PopAndDestroy(); // replacedEntry
+	}
+	
+	CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+
+	_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: END");
+    }
+    
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::GetPropertiesFromDataL
+// Gets property from old item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::GetPropertiesFromDataL( CBufFlat* aOldItem,
+                                                   HBufC8*& aValue,
+	                                               const TDesC8& aProperty )
+    {
+    _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): begin");
+    
+    // Gemerate property that is searched (Linebreak + property + tokencolon)
+    HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+                                         aProperty.Length() );
+    TPtr8 startBufferPtr( startBuffer->Des() );
+	startBufferPtr.Append( KVersitTokenCRLF() );
+	startBufferPtr.Append( aProperty );
+	
+	// Get start position of property value
+	TInt startPos = aOldItem->Ptr( 0 ).Find( startBufferPtr );
+	
+	TInt endPos( KErrNotFound );
+	if ( startPos != KErrNotFound )
+	    {
+	    // startPos is before UID word
+	    startPos = startPos + KVersitTokenCRLF().Length();
+	    
+	    // End end position of property value
+	    endPos = startPos + 
+	             aOldItem->Ptr( startPos ).Find( KVersitTokenCRLF() );
+	    
+	    TPtrC8 tempPtr( aOldItem->Ptr( 0 ).Mid( endPos ) );
+	    
+	    // If next char after linebreak is ' ' or '=' then it is only
+	    // linebreak inside of value. This does not work with base64 coding!
+	    while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
+	            tempPtr[KVersitTokenCRLF().Length()] == '=' )
+	        {
+	        endPos = endPos + KVersitTokenCRLF().Length();
+	        TInt tempPos = aOldItem->Ptr( endPos ).Find( KVersitTokenCRLF() );
+	        endPos = endPos + tempPos;
+	        tempPtr.Set( aOldItem->Ptr( 0 ).Mid( endPos ) );
+	        }
+        
+        // Then cut value to value parameter
+        delete aValue;
+		aValue = NULL;
+		TInt length = endPos - startPos;
+		aValue = HBufC8::NewLC( length );
+		TPtr8 valuePtr( aValue->Des() );
+		aOldItem->Read( startPos, valuePtr, length );
+		CleanupStack::Pop( aValue ); // aValue
+	    }
+    CleanupStack::PopAndDestroy( startBuffer ); // startBuffer
+    
+    _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): end");
+    }
+  
+// -----------------------------------------------------------------------------
+// Adds property and it's value to new item.
+// This method also removes original property and it's value.
+// -----------------------------------------------------------------------------
+//  
+void CNSmlAgendaDataStore::SetPropertiesToDataL( HBufC8*& aValue,
+	                                             const TDesC8& aProperty )
+    {
+    _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): begin");
+    
+    // Gemerate property that is searched (Linebreak + property + tokencolon)
+    HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+                                         aProperty.Length() );
+    TPtr8 startBufferPtr( startBuffer->Des() );
+	startBufferPtr.Append( KVersitTokenCRLF() );
+	startBufferPtr.Append( aProperty );
+	
+	// Get start position of property value
+	TInt startPos = iItemData->Ptr( 0 ).Find( startBufferPtr );
+	
+	TInt endPos( KErrNotFound );
+	if ( startPos != KErrNotFound )
+	    {
+	    // startPos is before UID word
+	    startPos = startPos + KVersitTokenCRLF().Length();
+	    
+	    // End end position of property value
+	    endPos = startPos + 
+	             iItemData->Ptr( startPos ).Find( KVersitTokenCRLF() );
+	    
+	    TPtrC8 tempPtr( iItemData->Ptr( 0 ).Mid( endPos ) );
+	    
+	    // If next char after linebreak is ' ' or '=' then it is only
+	    // linebreak inside of value. This does not work with base64 coding!
+	    while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
+	            tempPtr[KVersitTokenCRLF().Length()] == '=' )
+	        {
+	        endPos = endPos + KVersitTokenCRLF().Length();
+	        TInt tempPos = iItemData->Ptr( endPos ).Find( KVersitTokenCRLF() );
+	        endPos = endPos + tempPos;
+	        tempPtr.Set( iItemData->Ptr( 0 ).Mid( endPos ) );
+	        }
+        
+        // Delete original property and value
+        iItemData->Delete( startPos, endPos - startPos );
+        
+	    }
+
+    // Add property and new value from parameter.
+    // First find end of VEVENT or VTODO
+    
+    // Generate VEVENT END property
+    HBufC8* endVEvent = HBufC8::NewLC( KVersitTokenCRLF().Size() + 
+                                     KVersitTokenEND().Length() +
+                                     KVersitTokenColon().Length() +
+                                     KVersitVarTokenVEVENT().Length() );
+	TPtr8 endVEventPtr( endVEvent->Des() );
+	endVEventPtr.Append( KVersitTokenCRLF() );
+	endVEventPtr.Append( KVersitTokenEND() );
+	endVEventPtr.Append( KVersitTokenColon() );
+	endVEventPtr.Append( KVersitVarTokenVEVENT() );
+	
+	// Generate VTODO END property
+    HBufC8* endVTodo = HBufC8::NewLC( KVersitTokenCRLF().Size() + 
+                                     KVersitTokenEND().Length() +
+                                     KVersitTokenColon().Length() +
+                                     KVersitVarTokenVTODO().Length() );
+	TPtr8 endVTodoPtr( endVTodo->Des() );
+	endVTodoPtr.Append( KVersitTokenCRLF() );
+	endVTodoPtr.Append( KVersitTokenEND() );
+	endVTodoPtr.Append( KVersitTokenColon() );
+	endVTodoPtr.Append( KVersitVarTokenVTODO() );
+    
+    // Find end of VEVENT or VTODO
+    endPos = iItemData->Ptr( 0 ).Find( endVEventPtr );
+    if ( endPos == KErrNotFound )
+        {
+        endPos = iItemData->Ptr( 0 ).Find( endVTodoPtr );
+        if ( endPos == KErrNotFound )
+            {
+            User::Leave( KErrNotFound );
+            }
+        }
+
+    // Add property and value from parameter
+	iItemData->InsertL( endPos, KVersitTokenCRLF() );
+	iItemData->InsertL( endPos + KVersitTokenCRLF().Size(),
+	                    aValue->Des() );
+    iItemData->Compress();
+    
+    CleanupStack::PopAndDestroy( 3 ); // endVTodo, endVEvent, startBuffer
+    
+    _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): end");
+    }
+	
+//  End of File