pimappservices/calendarvcalplugin/src/agmvcali.cpp
changeset 0 f979ecb2b13e
child 18 c198609911f9
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include <s32file.h>
       
    18 #include <s32mem.h>
       
    19 #include <bassnd.h>
       
    20 #include <calentry.h>
       
    21 #include <vtzrules.h>
       
    22 #include "agnversit.h"
       
    23 #include <utf.h>
       
    24 #include <tz.h> //Conversion between local and UTC times
       
    25 #include <calalarm.h>
       
    26 #include <calcontent.h>
       
    27 #include <calrrule.h>
       
    28 #include <caluser.h>
       
    29 #include <calattachment.h>
       
    30 
       
    31 #include "agmvcal.h"
       
    32 
       
    33 const TInt KCountDigits = 8;
       
    34 _LIT(KDateStringFormat, "%F%D%M%Y%H%T%S%C"); // locale-independent formatting DDMMYYHHMMSSUUUUUU (day,month,year,hour,minute,second,usec
       
    35 _LIT(KVersitTokenMailTo,"MAILTO:");
       
    36 
       
    37 HBufC* AgnConvertUtil::EncodeL(const TDesC& aText,TUid aConversion)
       
    38 	{
       
    39 	HBufC8* text=HBufC8::NewLC(aText.Length()*2);
       
    40 	TPtr8 ptr = text->Des();
       
    41 	TInt i;
       
    42 	for (i=0; i < aText.Length(); i++)
       
    43 		{
       
    44 		ptr.Append(aText[i] & 0x00FF);
       
    45 		ptr.Append((aText[i] >> 8) & 0x00FF);
       
    46 		}
       
    47 	CCnaConverterList* convList=CCnaConverterList::NewLC(); 
       
    48 	CConverterBase* conv = convList->NewConverterL(aConversion); 
       
    49 	if (!conv)
       
    50 		{
       
    51 		CleanupStack::PopAndDestroy();          // convList 
       
    52 		User::Leave(KErrNotSupported);
       
    53 		}
       
    54 	CleanupStack::PushL(conv);
       
    55 	CBufFlat* decodeBuffer = CBufFlat::NewL(256); 
       
    56 	CleanupStack::PushL(decodeBuffer);
       
    57 	CBufFlat* encodedBuffer = CBufFlat::NewL(256); 
       
    58 	CleanupStack::PushL(encodedBuffer);
       
    59 	decodeBuffer->InsertL(0,ptr);
       
    60 	RBufReadStream readStream;
       
    61 	RBufWriteStream writeStream;
       
    62 	readStream.Open(*decodeBuffer);
       
    63 	writeStream.Open(*encodedBuffer);
       
    64 	conv->ConvertObjectL(readStream, writeStream); 
       
    65 	readStream.Close();
       
    66 	TInt size=encodedBuffer->Size();
       
    67 	HBufC* writeBuf=HBufC::NewLC(size); 
       
    68 	TPtr resulttext = writeBuf->Des();
       
    69 	for(i = 0; i < (size - 1); i += 2)
       
    70 		{
       
    71 		resulttext.Append((encodedBuffer->Ptr(0)[i + 1] << 8) | 
       
    72 			encodedBuffer->Ptr(0)[i]);
       
    73 		}
       
    74 
       
    75 	writeStream.CommitL();
       
    76 	writeStream.Close();
       
    77 	CleanupStack::Pop(writeBuf); // writebuf
       
    78 	CleanupStack::PopAndDestroy(2,decodeBuffer); // buffers 
       
    79 	CleanupStack::PopAndDestroy(2,convList); //conv+convList
       
    80 	CleanupStack::PopAndDestroy(text);  //text
       
    81 	return (writeBuf);
       
    82 	}
       
    83 
       
    84 // This method imports a vCalendar entity from aParser and returns a pointer to a CAgnEntry
       
    85 // if successful or NULL if it wasn't possible to import the vCalendar. It reads the
       
    86 // relevant properties from aParser entity and builds up a corresponding agenda entry.
       
    87 // It allows to import vCal file without Summary and Description fields
       
    88 void CVCalToAgendaEntryConverter::ImportVCalL(CVersitParser& aParser, RPointerArray<CCalEntry>& aEntryArray)
       
    89 	{
       
    90 	CCalEntry::TType entryType = GetEntryTypeL(aParser);
       
    91 	
       
    92 		// Group Scheduling Data
       
    93 	
       
    94 	//Import UID
       
    95 	HBufC* guid16 = ImportDesPropertyL(aParser, KVersitTokenUID);
       
    96 	
       
    97 	if (!guid16) // non cal entry 
       
    98 		{
       
    99 		// create our a UID based on the current time (UTC, microsecond precision)
       
   100 		TTime now;
       
   101 		now.UniversalTime();  
       
   102 		TBuf<KMaxTimeStringSize+KCountDigits> dateString;
       
   103 		now.FormatL(dateString,KDateStringFormat);
       
   104 		
       
   105 		TInt threeDidgit=Math::Random() % 1000;
       
   106 		dateString.Append(threeDidgit);
       
   107 		
       
   108 		guid16 = dateString.AllocL();	
       
   109 		}
       
   110 		
       
   111 	CleanupStack::PushL(guid16);
       
   112 	
       
   113 	// the UID is stored as an 8-bit descriptor, so convert from 16-bit to 8-bit
       
   114 	HBufC8* guid8= CnvUtfConverter::ConvertFromUnicodeToUtf8L(guid16->Des());				 
       
   115 	CleanupStack::PopAndDestroy(guid16);  
       
   116 	CleanupStack::PushL(guid8);		
       
   117 		
       
   118 	// Import Sequence Number
       
   119 	TInt seqNumber;	
       
   120 	
       
   121 	// if no sequence number
       
   122 	if (!ImportIntegerPropertyL(aParser, KVersitTokenSEQUENCE, seqNumber))
       
   123 		{
       
   124 		seqNumber = 0;
       
   125 		}
       
   126 	
       
   127 	// Import Method
       
   128 	CCalEntry::TMethod methodStatus(CCalEntry::EMethodNone);
       
   129 	HBufC* method = ImportDesPropertyL(aParser, KVersitTokenXMETHOD);
       
   130 	
       
   131 	if (method)
       
   132 		{
       
   133 		CleanupStack::PushL(method);
       
   134 		if (*method == KVCalTokenMethodStatusENone)	
       
   135 			{
       
   136 			methodStatus = CCalEntry::EMethodNone;
       
   137 			}
       
   138 		else if (*method == KVCalTokenMethodStatusEPublish)	
       
   139 			{
       
   140 			methodStatus = CCalEntry::EMethodPublish;
       
   141 			}
       
   142 		else if (*method == KVCalTokenMethodStatusERequest)	
       
   143 			{
       
   144 			methodStatus = CCalEntry::EMethodRequest;
       
   145 			}
       
   146 		else if (*method == KVCalTokenMethodStatusEReply)	
       
   147 			{
       
   148 			methodStatus = CCalEntry::EMethodReply;
       
   149 			}
       
   150 		else if (*method == KVCalTokenMethodStatusEAdd)	
       
   151 			{
       
   152 			methodStatus = CCalEntry::EMethodAdd;
       
   153 			}
       
   154 		else if (*method == KVCalTokenMethodStatusECancel)	
       
   155 			{
       
   156 			methodStatus = CCalEntry::EMethodCancel;
       
   157 			}
       
   158 		else if (*method == KVCalTokenMethodStatusERefresh)	
       
   159 			{
       
   160 			methodStatus = CCalEntry::EMethodRefresh;
       
   161 			}
       
   162 		else if (*method == KVCalTokenMethodStatusECounter)	
       
   163 			{
       
   164 			methodStatus = CCalEntry::EMethodCounter;
       
   165 			}
       
   166 		else if (*method == KVCalTokenMethodStatusEDeclineCounter)	
       
   167 			{
       
   168 			methodStatus = CCalEntry::EMethodDeclineCounter;
       
   169 			}
       
   170 		else
       
   171 			{
       
   172 			// do nothing if method is invalid - it will be None by default
       
   173 			}	
       
   174 
       
   175 		
       
   176 		CleanupStack::PopAndDestroy(method);
       
   177 		}		
       
   178 	
       
   179 	// Import X-Recurrence-Id
       
   180 	TVersitDateTime::TRelativeTime relativeTime = TVersitDateTime::EIsUTC;
       
   181 	TTime recurrenceId;
       
   182 	TBool isRecurrenceIdPresent = ImportDateTimePropertyL(aParser, KVersitTokenXRECURRENCEID, recurrenceId, relativeTime);
       
   183 	if (!isRecurrenceIdPresent)
       
   184 		{
       
   185 		iEntry = CCalEntry::NewL(entryType,guid8, methodStatus, seqNumber);
       
   186 		}
       
   187 	else
       
   188 		{
       
   189 		TCalTime caltime;
       
   190 		if(GetTimeModeL(aParser) == TCalTime::EFloating)
       
   191 			{
       
   192 			caltime.SetTimeLocalFloatingL(recurrenceId);
       
   193 			}
       
   194 		else
       
   195 			{
       
   196 			caltime.SetTimeUtcL(recurrenceId);
       
   197 			}
       
   198 	
       
   199 		iEntry = CCalEntry::NewL(entryType,guid8, methodStatus, seqNumber, caltime, CalCommon::EThisOnly);
       
   200 		}
       
   201 		
       
   202 	CleanupStack::Pop(guid8); // ownership was passed to calGSData	
       
   203 	// Fill in the entry description from the SUMMARY property
       
   204 	// If this doesn't exist, use the DESCRIPTION property, and if this
       
   205 	// doesn't exist, return a NULL entry
       
   206 
       
   207  	// get properties but don't take ownership of the elements of the array
       
   208  	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenSUMMARY, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
       
   209 
       
   210 	if (!properties)
       
   211 		{
       
   212 		// get properties but don't take ownership of the elements of the array
       
   213 		properties = aParser.PropertyL(KVersitTokenDESCRIPTION, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
       
   214 		}
       
   215 	CleanupStack::PushL(properties);
       
   216 	
       
   217 	// Use the value found from the Summary/Description 
       
   218 	// Both Summary and Description are not found in imported vCal file 
       
   219 	//then insert empty enties for summary and description
       
   220 	//  these empty entries will be descarded while exporting vCal file
       
   221 	TPtrC summary;
       
   222 	if (properties)
       
   223 		{
       
   224 		summary.Set(static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value())->Value());
       
   225 		}
       
   226 		
       
   227 	HBufC* summaryBuf = AgnConvertUtil::EncodeL(summary,KUidTextToEtextNoTrim);
       
   228 	CleanupStack::PushL(summaryBuf);
       
   229 	if (summaryBuf)
       
   230 		{
       
   231 		iEntry->SetSummaryL(*summaryBuf);
       
   232 		}
       
   233 	CleanupStack::PopAndDestroy(summaryBuf);
       
   234 
       
   235 	HBufC* description =ImportDesPropertyL(aParser,KVersitTokenDESCRIPTION);
       
   236 	CleanupStack::PushL(description);
       
   237 	if (description != NULL)
       
   238 		{
       
   239 		iEntry->SetDescriptionL(*description); // Takes ownership
       
   240 		}
       
   241 	CleanupStack::PopAndDestroy(description);
       
   242 
       
   243 	TBool validEntry = EFalse;
       
   244 	if (entryType == CCalEntry::ETodo)
       
   245 		{
       
   246 		validEntry = ImportTodoPropertiesL(aParser);
       
   247 		}
       
   248 	else
       
   249 		{
       
   250 		validEntry = ImportEventPropertiesL(aParser);
       
   251 		}
       
   252 			
       
   253 	if (!validEntry)
       
   254 		{
       
   255 		CleanupStack::PopAndDestroy(properties);
       
   256 		delete iEntry;
       
   257 		iEntry = NULL;
       
   258 		return;
       
   259 		}
       
   260 
       
   261 	// Import CLASS property
       
   262 	HBufC* property=ImportDesPropertyL(aParser, KVersitTokenCLASS);
       
   263 	if (property)
       
   264 		{
       
   265 		CleanupStack::PushL(property);
       
   266 		if (*property == KVCalTokenPUBLIC)
       
   267 			iEntry->SetReplicationStatusL(CCalEntry::EOpen);
       
   268 		else if (*property == KVCalTokenPRIVATE)
       
   269 			iEntry->SetReplicationStatusL(CCalEntry::EPrivate);
       
   270 		else if (*property == KVCalTokenCONFIDENTIAL)
       
   271 			iEntry->SetReplicationStatusL(CCalEntry::ERestricted);
       
   272 		CleanupStack::PopAndDestroy(property);
       
   273 		}
       
   274 	// Import LOCATION property
       
   275 	property=ImportDesPropertyL(aParser, KVersitTokenLOCATION);
       
   276 	if (property)
       
   277 		{
       
   278 		CleanupStack::PushL(property);
       
   279 		iEntry->SetLocationL(*property);
       
   280 		CleanupStack::PopAndDestroy(property);
       
   281 		}
       
   282 	// Import DTSTAMP
       
   283 	TTime timeProperty;
       
   284 	if (ImportDateTimePropertyL(aParser, KVersitTokenXDTSTAMP, timeProperty, relativeTime))
       
   285 		{
       
   286 		TCalTime caltimeProperty;
       
   287 		caltimeProperty.SetTimeUtcL(timeProperty);
       
   288 		iEntry->SetDTStampL(caltimeProperty);
       
   289 		}
       
   290 	
       
   291 	// Attendee property
       
   292  	ImportAttendeePropertiesL(aParser, KVersitTokenATTENDEE);
       
   293 
       
   294 	// Categories property
       
   295 	ImportCategoriesPropertyL(aParser, KVersitTokenCATEGORIES);
       
   296 
       
   297 	
       
   298 		
       
   299 	TInt localId;
       
   300 	if (ImportIntegerPropertyL(aParser, KVersitTokenXLOCALUID, localId))
       
   301 		{
       
   302 		iEntry->SetLocalUidL(localId);
       
   303 		}
       
   304 	
       
   305 	// Additional stuff to comply with Versit Specs 1.0  
       
   306 	// All entries have a priority not just ToDo's
       
   307 	// Todo Functionality merged into this code block
       
   308 	TInt priority;
       
   309 	if (ImportIntegerPropertyL(aParser, KVersitTokenPRIORITY, priority))
       
   310 		{
       
   311 		iEntry->SetPriorityL(priority);  
       
   312 		}
       
   313 
       
   314 	// All entries have a status - will default to Needs Action if cannot be read
       
   315 	CCalEntry::TStatus entryStatus=CCalEntry::ENullStatus;
       
   316 	ImportStatusPropertyL(aParser, entryStatus);
       
   317 	//Now sync completed and ECompleted status to keep entry consistenty 
       
   318 	if(entryType==CCalEntry::ETodo && (iEntry->CompletedTimeL().TimeUtcL()) != Time::NullTTime())
       
   319 		{
       
   320 		iEntry->SetCompletedL(ETrue, iEntry->CompletedTimeL());
       
   321 		}
       
   322 	iEntry->SetStatusL(entryStatus);
       
   323 	
       
   324 	//Get last changed date from vcal
       
   325 	if (ImportDateTimePropertyL(aParser, KVersitTokenLASTMODIFIED, timeProperty, relativeTime))
       
   326 			{
       
   327 			if (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
       
   328 				{
       
   329 				iTzZone->ConvertToUtcL(timeProperty);
       
   330 				}
       
   331 			TCalTime lastModifiedDate;
       
   332 			lastModifiedDate.SetTimeUtcL(timeProperty);
       
   333 			iEntry->SetLastModifiedDateL(lastModifiedDate);
       
   334 			}
       
   335 		else
       
   336 			{
       
   337 			iEntry->SetLastModifiedDateL(); //set changed date to now
       
   338 			}
       
   339 		
       
   340 	TInt transp;
       
   341 	if (ImportIntegerPropertyL(aParser, KVersitTokenTRANSP, transp))
       
   342 		{
       
   343 		iEntry->SetTimeTransparencyL(static_cast<CCalEntry::TTransp>(transp));
       
   344 		}
       
   345 	
       
   346 	ImportAttachmentPropertyL(aParser);
       
   347 	
       
   348 	// Import GEO
       
   349 	HBufC* geoString=ImportDesPropertyL(aParser,KVersitTokenGEO);
       
   350 	
       
   351 	if (geoString != NULL)
       
   352 		{
       
   353 		CleanupStack::PushL(geoString);
       
   354 		// Determine the position of the delimiter for extraction of the geo latitude and longitude values
       
   355 		TInt delimiterPos = geoString->Locate(KVersitTokenCommaVal);
       
   356 		
       
   357 		if(delimiterPos!=KErrNotFound)
       
   358 			{
       
   359 			// Extract the latitude
       
   360 			TLex geoLatitudeLex(geoString->Left(delimiterPos));
       
   361 			// Extract the latitude by excluding the delimiter
       
   362 			TLex geoLongitudeLex(geoString->Right(geoString->Length()-(delimiterPos+1)));
       
   363 			
       
   364 			TReal geoLatitude;
       
   365 			TReal geoLongitude;
       
   366 			
       
   367 			if((geoLatitudeLex.Val(geoLatitude)==KErrNone) && (geoLongitudeLex.Val(geoLongitude)==KErrNone))
       
   368 				{
       
   369 				CCalGeoValue* importedGeoValue=CCalGeoValue::NewL();
       
   370 				CleanupStack::PushL(importedGeoValue);
       
   371 				TRAPD(err, importedGeoValue->SetLatLongL(geoLatitude,geoLongitude));
       
   372 				if(err==KErrNone)
       
   373 					{
       
   374 					iEntry->SetGeoValueL(*importedGeoValue);
       
   375 					}
       
   376 				CleanupStack::PopAndDestroy(importedGeoValue);
       
   377 				}
       
   378 			}
       
   379 		CleanupStack::PopAndDestroy(geoString);
       
   380 		}
       
   381 	
       
   382 	CleanupStack::PopAndDestroy(properties);
       
   383 	aEntryArray.AppendL(iEntry); // takes ownership of entry
       
   384 	iEntry = NULL;
       
   385 	}
       
   386 
       
   387 CVCalToAgendaEntryConverter::~CVCalToAgendaEntryConverter()
       
   388 	{
       
   389 	delete iEntry;
       
   390 	delete iTzZone;
       
   391 	}
       
   392 
       
   393 void CVCalToAgendaEntryConverter::SetTzConverter(RTz* aTzConverter)
       
   394 	{
       
   395 	iTzConverter = aTzConverter;
       
   396 	}
       
   397 	
       
   398 void CVCalToAgendaEntryConverter::SetTzRules(CTzRules* aTzZone)
       
   399 	{
       
   400 	// this function should only ever be called once so this shouldn't be needed
       
   401 	if (iTzZone)
       
   402 		{
       
   403 		delete iTzZone;
       
   404 		iTzZone = NULL;
       
   405 		}
       
   406 	iTzZone = aTzZone;
       
   407 	}
       
   408 	
       
   409 TCalTime::TTimeMode CVCalToAgendaEntryConverter::GetTimeModeL(CVersitParser& aParser)
       
   410 	{
       
   411 	TTime dummyTime;
       
   412 	TVersitDateTime::TRelativeTime relativeTime;
       
   413 	
       
   414 	if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, dummyTime, relativeTime))
       
   415 		{
       
   416 		if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTEND, dummyTime, relativeTime))
       
   417 			{
       
   418 			if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDUE, dummyTime, relativeTime))
       
   419 				{
       
   420 				// no time
       
   421 				relativeTime = TVersitDateTime::EIsUTC;
       
   422 				}
       
   423 			}
       
   424 		}
       
   425 	
       
   426 	if (iTzZone || relativeTime == TVersitDateTime::EIsUTC)
       
   427 		{
       
   428 		return TCalTime::EFixedUtc;
       
   429 		}
       
   430 	return TCalTime::EFloating;
       
   431 	}
       
   432 
       
   433 // Try and find out which Epoc Agenda entry type this belongs to.
       
   434 // At the moment, relies on having an 'X-EPOCAGENDAENTRYTYPE' field, and defaults to a appointment
       
   435 // type if this isn't present.
       
   436 // Maybe some heuristics should be used to try and ascertain which entry type is most appropriate
       
   437 // e.g. if the entry has a yearly repeat, then maybe it should be an anniversary type.
       
   438 //
       
   439 // A call to this function resets iVcalTokenTypeReminder flag (unless the vCal entry is actually a Reminder).
       
   440 //
       
   441 CCalEntry::TType CVCalToAgendaEntryConverter::GetEntryTypeL(CVersitParser& aParser)
       
   442 	{
       
   443 	// If the entry type is a Todo, return immediately
       
   444 	if (aParser.EntityName()==KVersitVarTokenVTODO)
       
   445 		{
       
   446 		return CCalEntry::ETodo;
       
   447 		}
       
   448 	
       
   449 	// get properties but don't take ownership of the elements of the array
       
   450 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVCalToken8XDASHENTRYTYPE, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
       
   451 	if (properties)
       
   452 		{
       
   453 		TPtrC type = static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value())->Value();
       
   454 		delete properties;
       
   455 
       
   456 		if (type == KVCalTokenTypeAPPT)
       
   457 			{
       
   458 			return CCalEntry::EAppt;
       
   459 			}
       
   460 
       
   461 		if (type == KVCalTokenTypeEVENT)
       
   462 			{
       
   463 			return CCalEntry::EEvent;
       
   464 			}
       
   465 
       
   466 		if (type == KVCalTokenTypeANNIV)
       
   467 			{
       
   468 			return CCalEntry::EAnniv;
       
   469 			}
       
   470 
       
   471 		if (type == KVCalTokenTypeTODO)
       
   472 			{
       
   473 			return CCalEntry::ETodo;
       
   474 			}
       
   475 		
       
   476 		if (type == KVCalTokenTypeREMINDER)
       
   477 			{
       
   478 			return CCalEntry::EReminder;
       
   479 			}
       
   480 		
       
   481 		}
       
   482 
       
   483 	// return an appointment as default type
       
   484 	return (CCalEntry::EAppt);
       
   485 	}
       
   486 
       
   487 TBool CVCalToAgendaEntryConverter::IsValidTime(const TTime& aTime)
       
   488 	{
       
   489 	if (aTime < TCalTime::MinTime() || aTime > TCalTime::MaxTime())
       
   490 		{
       
   491 		return EFalse;
       
   492 		}
       
   493 	return ETrue;
       
   494 	}
       
   495 
       
   496 // Import Recurrence Dates property
       
   497 //
       
   498 void CVCalToAgendaEntryConverter::ImportRDatePropertyL(CVersitParser& aParser, const TDesC8& aToken)
       
   499 	{
       
   500 	// get properties but don't take ownership of the elements of the array
       
   501 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyMultiDateTimeUid), EFalse);
       
   502 	
       
   503 	if (properties)
       
   504 		{
       
   505 		CleanupStack::PushL(properties);
       
   506 		CArrayPtr<TVersitDateTime>* rDates = static_cast<CParserPropertyValueMultiDateTime*>((*properties)[0]->Value())->Value();
       
   507 			
       
   508 		if (rDates)	
       
   509 			{
       
   510 			RArray<TCalTime>calrdates;
       
   511 			CleanupClosePushL(calrdates);
       
   512 			const TInt KSize = rDates->Count();
       
   513 			for (TInt count = 0; count < KSize; ++count)
       
   514 				{
       
   515 				TVersitDateTime* time = (*rDates)[count];
       
   516 				TTime timeProperty(time->iDateTime);
       
   517 				
       
   518 				if (IsValidTime(timeProperty))
       
   519 					{
       
   520 					TVersitDateTime::TRelativeTime relativeTime = time->iRelativeTime;
       
   521 					if (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
       
   522 						{
       
   523 						//Convert to utc time using imported TZ rules
       
   524 						iTzZone->ConvertToUtcL(timeProperty);   
       
   525 						relativeTime = TVersitDateTime::EIsUTC;
       
   526 						}
       
   527 				
       
   528 					TCalTime calrdate;
       
   529 					if (relativeTime == TVersitDateTime::EIsVCardLocal)
       
   530 						{
       
   531 						calrdate.SetTimeLocalFloatingL(timeProperty);
       
   532 						}
       
   533 					else
       
   534 						{
       
   535 						__ASSERT_DEBUG(relativeTime == TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
       
   536 						calrdate.SetTimeUtcL(timeProperty); //assume time as UTC for release build
       
   537 						}
       
   538 					calrdates.Append(calrdate);
       
   539 					}
       
   540 				}
       
   541 			iEntry->SetRDatesL(calrdates);
       
   542 			CleanupStack::PopAndDestroy();//close RArray
       
   543 			}
       
   544 		CleanupStack::PopAndDestroy(properties);
       
   545 		}
       
   546 
       
   547 	}
       
   548 	
       
   549 // Import the start and end dates of the vCalendar
       
   550 // This method returns EFalse if there is no start date or end date, or if the start date 
       
   551 // is after the end date. If the start date is missing but an end date is present, the 
       
   552 // start date is set to the end date. If the end date is missing but there is a start
       
   553 // date, the end date is set to the start date.
       
   554 //
       
   555 TBool CVCalToAgendaEntryConverter::GetStartAndEndDatesL(CVersitParser& aParser, TTime& aStartDate, TTime& aEndDate, TVersitDateTime::TRelativeTime& aRelativeTime)
       
   556 	{
       
   557 	TBool startValid = ETrue;
       
   558 	TBool endValid = ETrue;
       
   559 	
       
   560 	if (!ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, aStartDate,aRelativeTime))
       
   561 		{
       
   562 		startValid = EFalse;
       
   563 		}
       
   564 
       
   565 	TVersitDateTime::TRelativeTime relativeTime;
       
   566 	
       
   567 	if (!ImportDateTimePropertyL(aParser, KVersitTokenDTEND, aEndDate, relativeTime))
       
   568 		{
       
   569 		endValid = EFalse;
       
   570 		}
       
   571 
       
   572 	if (!startValid && !endValid)
       
   573 		{
       
   574 		// Neither times exist, so return Invalid Entry
       
   575 		return EFalse;
       
   576 		}
       
   577 
       
   578 	if (startValid && !endValid)
       
   579 		{
       
   580 		// Start time but no end time
       
   581 		aEndDate = aStartDate;
       
   582 		}
       
   583 	else if (!startValid && endValid)
       
   584 		{
       
   585 		// End time but no start time
       
   586 		aStartDate = aEndDate;
       
   587 		aRelativeTime = relativeTime;
       
   588 		}
       
   589 
       
   590 	if (aStartDate>aEndDate)
       
   591 		return EFalse;
       
   592 
       
   593 	return ETrue;
       
   594 	}
       
   595 
       
   596 // Import appointment properties
       
   597 //
       
   598 TBool CVCalToAgendaEntryConverter::ImportEventPropertiesL(CVersitParser& aParser)
       
   599 	{
       
   600 	TTime startDate;
       
   601 	TTime endDate;
       
   602 	TVersitDateTime::TRelativeTime relativeTime;
       
   603 	if (!GetStartAndEndDatesL(aParser, startDate, endDate, relativeTime))
       
   604 		{
       
   605 		return EFalse;
       
   606 		}
       
   607 
       
   608 	if(iEntry->EntryTypeL()==CCalEntry::EReminder)
       
   609 		{
       
   610 		endDate = startDate;
       
   611 		}
       
   612 
       
   613 	TCalTime caltimeStart;
       
   614 	TCalTime caltimeEnd;
       
   615 	if (relativeTime == TVersitDateTime::EIsVCardLocal)
       
   616 		{
       
   617 		caltimeStart.SetTimeLocalFloatingL(startDate);
       
   618 		caltimeEnd.SetTimeLocalFloatingL(endDate);
       
   619 		}
       
   620 	else
       
   621 		{
       
   622 		__ASSERT_DEBUG(relativeTime==TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
       
   623 		caltimeStart.SetTimeUtcL(startDate); //assume time as UTC for release build
       
   624 		caltimeEnd.SetTimeUtcL(endDate); //assume time as UTC for release build
       
   625 		}
       
   626 	
       
   627 	if (startDate > endDate && endDate != Time::NullTTime())
       
   628 		{
       
   629 		return EFalse;
       
   630 		}
       
   631 	iEntry->SetStartAndEndTimeL(caltimeStart,caltimeEnd);
       
   632 
       
   633 	// Attempt to import alarm/repeat properties
       
   634 	ImportRepeatPropertyL(aParser, KVersitTokenRRULE, startDate, relativeTime);
       
   635 	ImportAlarmPropertyL(aParser, startDate, relativeTime);
       
   636 	return ETrue;
       
   637 	}
       
   638 
       
   639 //
       
   640 TBool CVCalToAgendaEntryConverter::ImportTodoPropertiesL(CVersitParser& aParser)
       
   641 	{
       
   642 	TVersitDateTime::TRelativeTime relativeTime;//EIsUTC is the default
       
   643 	TTime startDate = Time::NullTTime();
       
   644 	TTime endDate = Time::NullTTime();
       
   645 	
       
   646 	if (!ImportDateTimePropertyL(aParser, KVersitTokenDUE, endDate, relativeTime))
       
   647 		{
       
   648 		if (!ImportDateTimePropertyL(aParser, KVersitTokenDTEND, endDate, relativeTime))
       
   649 			{
       
   650 			endDate = Time::NullTTime();
       
   651 			}
       
   652 		}
       
   653 	
       
   654 	if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, startDate, relativeTime))
       
   655 		{
       
   656 		startDate = endDate;
       
   657 		}
       
   658 
       
   659 	if (startDate > endDate && endDate != Time::NullTTime())
       
   660 		{
       
   661 		return EFalse;
       
   662 		}
       
   663 
       
   664 
       
   665 
       
   666 	if (endDate == Time::NullTTime())
       
   667 		{
       
   668 		endDate = startDate;
       
   669 		}
       
   670 	else if (startDate == Time::NullTTime() || startDate > endDate)
       
   671 		{
       
   672 		startDate = endDate;
       
   673 		}
       
   674 
       
   675 	TTime completedDate;
       
   676 	if (ImportDateTimePropertyL(aParser, KVCalTokenCOMPLETED,completedDate, relativeTime))
       
   677 		{
       
   678 		TCalTime calcompletedDate;
       
   679 		calcompletedDate.SetTimeUtcL(completedDate);
       
   680 		iEntry->SetCompletedL(ETrue, calcompletedDate);
       
   681 		}
       
   682 
       
   683 	TCalTime caltimeStart;
       
   684 	TCalTime caltimeEnd;
       
   685 	
       
   686 	if (relativeTime == TVersitDateTime::EIsUTC)
       
   687 		{
       
   688 		caltimeStart.SetTimeUtcL(startDate);
       
   689 		caltimeEnd.SetTimeUtcL(endDate);
       
   690 		}
       
   691 	else
       
   692 		{
       
   693 		caltimeStart.SetTimeLocalFloatingL(startDate);
       
   694 		caltimeEnd.SetTimeLocalFloatingL(endDate);
       
   695 		}
       
   696 	iEntry->SetStartAndEndTimeL(caltimeStart,caltimeEnd);
       
   697 
       
   698 // Attempt to import alarm properties
       
   699 	ImportAlarmPropertyL(aParser, endDate, relativeTime);
       
   700 		
       
   701 // Attempt to import repeat properties
       
   702 	ImportRepeatPropertyL(aParser, KVersitTokenRRULE, endDate, relativeTime);
       
   703 	
       
   704 	return ETrue;
       
   705 	}
       
   706 
       
   707 // Import a date/time 
       
   708 // This method returns true if a date/time exists and is within the standard agenda date range
       
   709 // If it doesn't exist or the date isn't valid this method returns EFalse. 
       
   710 //
       
   711 TBool CVCalToAgendaEntryConverter::ImportDateTimePropertyL(CVersitParser& aParser, const TDesC8& aToken, TTime& aValue, TVersitDateTime::TRelativeTime& aRelativeTime)
       
   712 	{
       
   713 	// get properties but don't take ownership of the elements of the array
       
   714 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyDateTimeUid), EFalse);
       
   715 
       
   716 	if (properties)
       
   717 		{
       
   718 		CleanupStack::PushL(properties);
       
   719 		TVersitDateTime* time = static_cast<CParserPropertyValueDateTime*>((*properties)[0]->Value())->Value();
       
   720 		aValue =  TTime(time->iDateTime);
       
   721 		TCalTime calTime;
       
   722 		if (IsValidTime(aValue))
       
   723 			{
       
   724 			aRelativeTime = time->iRelativeTime;
       
   725 			if  (iTzZone && ( aRelativeTime== TVersitDateTime::EIsVCardLocal))
       
   726 				{
       
   727 				//Convert to utc time using imported TZ rules
       
   728 				iTzZone->ConvertToUtcL(aValue);
       
   729 				aRelativeTime = TVersitDateTime::EIsUTC;
       
   730 				}
       
   731 			CleanupStack::PopAndDestroy(properties);
       
   732 			return ETrue;
       
   733 			}
       
   734 
       
   735 		CleanupStack::PopAndDestroy(properties);
       
   736 		}
       
   737 	
       
   738 	return EFalse;
       
   739 	}
       
   740 
       
   741 // Import an integer property
       
   742 //
       
   743 TBool CVCalToAgendaEntryConverter::ImportIntegerPropertyL(CVersitParser& aParser, const TDesC8& aToken, TInt& aValue)
       
   744 	{
       
   745 	// get properties but don't take ownership of the elements of the array
       
   746 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyIntUid), EFalse);
       
   747 
       
   748 	if (properties)
       
   749 		{
       
   750 		aValue = static_cast<CParserPropertyValueInt*>((*properties)[0]->Value())->Value();
       
   751 		delete properties; 
       
   752 		return ETrue;
       
   753 		}
       
   754 	else
       
   755 		{
       
   756 		// If there is no property available, return EFalse to signal that this property doesn't exist
       
   757 		return EFalse;
       
   758 		}
       
   759 	}
       
   760 
       
   761 // Import a descriptor property
       
   762 //
       
   763 HBufC* CVCalToAgendaEntryConverter::ImportDesPropertyL(CVersitParser& aParser, const TDesC8& aToken)
       
   764 	{
       
   765 	// get properties but don't take ownership of the elements of the array
       
   766 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
       
   767 	// If there is no property available, return NULL to signal that this property doesn't exist
       
   768 	HBufC* aHBufC = NULL;
       
   769 	
       
   770 	if (properties)
       
   771 		{
       
   772 		CleanupStack::PushL(properties);
       
   773 		CParserPropertyValueHBufC* propertyValue = static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value());
       
   774 		aHBufC=propertyValue->TakeValueOwnership();
       
   775 		CleanupStack::PopAndDestroy(properties);
       
   776 		if (aHBufC)
       
   777 			{
       
   778 			CleanupStack::PushL(aHBufC);
       
   779 			HBufC* temp=AgnConvertUtil::EncodeL(aHBufC->Des(),KUidTextToEtextNoTrim);
       
   780 			CleanupStack::PopAndDestroy(aHBufC);
       
   781 			aHBufC=temp;
       
   782 			}
       
   783 		}
       
   784 	return aHBufC;
       
   785 	}
       
   786 
       
   787 // Import an alarm property
       
   788 //
       
   789 TBool CVCalToAgendaEntryConverter::ImportAlarmPropertyL(CVersitParser& aParser, TTime& aEntryTime, TVersitDateTime::TRelativeTime& aRelativeTime)
       
   790 	{
       
   791 	// Get properties but don't take ownership of the elements of the array. 
       
   792 	// Check if there is an AALARM first.
       
   793 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenAALARM, 
       
   794 	    TUid::Uid(KVCalPropertyAlarmUid), EFalse);
       
   795 
       
   796 	// If there is no AALARM then try with a DALARM. They are treated the same.
       
   797 	if (!properties)
       
   798 	    {
       
   799 	    properties = aParser.PropertyL(KVersitTokenDALARM, 
       
   800 	        TUid::Uid(KVCalPropertyAlarmUid), EFalse);
       
   801 	    }
       
   802 
       
   803 	if (properties)
       
   804 		{
       
   805 		CleanupStack::PushL(properties);
       
   806 		CParserPropertyValueAlarm* alarmProperty = static_cast<CParserPropertyValueAlarm*>((*properties)[0]->Value());
       
   807 		CVersitAlarm* alarm = alarmProperty->Value();
       
   808 		if (!alarm->iRunTime)
       
   809 			{
       
   810 			CleanupStack::PopAndDestroy(properties);
       
   811 			return EFalse;
       
   812 			}
       
   813 		TTime alarmTime	= TTime(alarm->iRunTime->iDateTime);
       
   814 		TVersitDateTime::TRelativeTime relativeTime = alarm->iRunTime->iRelativeTime;
       
   815 		if (iTzZone && (alarm->iRunTime->iRelativeTime == TVersitDateTime::EIsVCardLocal))
       
   816 			{
       
   817 			//Convert to utc time using imported TZ rules
       
   818 			iTzZone->ConvertToUtcL(alarmTime);
       
   819 			relativeTime = TVersitDateTime::EIsUTC;
       
   820 			}
       
   821 
       
   822 		if(aEntryTime==Time::NullTTime())
       
   823 			{//It is only possible if it is a undated doto entry, in which, the due time should be set before the alarm time is set
       
   824 			__ASSERT_DEBUG(iEntry->EntryTypeL()==CCalEntry::ETodo, Panic(EAgnVersitWrongAttribute));
       
   825 
       
   826 			aEntryTime = alarmTime;	
       
   827 			aRelativeTime = relativeTime;
       
   828 			
       
   829 			TCalTime endTime;
       
   830 			if (relativeTime==TVersitDateTime::EIsVCardLocal || relativeTime==TVersitDateTime::EIsMachineLocal)
       
   831 				{
       
   832 				endTime.SetTimeLocalFloatingL(aEntryTime);
       
   833 				}
       
   834 			else
       
   835 				{
       
   836 				__ASSERT_DEBUG(relativeTime==TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
       
   837 				endTime.SetTimeUtcL(aEntryTime);
       
   838 				}
       
   839 			iEntry->SetStartAndEndTimeL(iEntry->StartTimeL(), endTime);
       
   840 			}
       
   841 	
       
   842 		
       
   843 		TTimeIntervalMinutes minutes;
       
   844 		aEntryTime.MinutesFrom(alarmTime, minutes);
       
   845 		
       
   846 		CCalAlarm* calalarm = CCalAlarm::NewL();
       
   847 		CleanupStack::PushL(calalarm);
       
   848 
       
   849 		const TInt KMinValidAlarmTime = -1440; // can have an alarm up to one day after an event
       
   850 		if(minutes.Int() >= KMinValidAlarmTime)
       
   851 			{
       
   852 			calalarm->SetTimeOffset(minutes);
       
   853 			}
       
   854 		else
       
   855 			{
       
   856 			// Alarm run-time is not valid - return EFalse since there is no valid alarm property
       
   857 			CleanupStack::PopAndDestroy(2,properties);
       
   858 			return EFalse;
       
   859 			}
       
   860 
       
   861 		HBufC* soundName=NULL;
       
   862 		// Check if the sound type is an Epoc Sound
       
   863 		CParserParam* param = ((*properties)[0])->Param(KVCalToken8TYPE);
       
   864 		if (param)
       
   865 			{
       
   866 			if (param->Value() == KVCalValue8EPOCSOUND)
       
   867 				{
       
   868 				soundName = alarm->iAudioContent;
       
   869 				if (soundName)
       
   870 					{
       
   871 					calalarm->SetAlarmSoundNameL(*soundName);
       
   872 					}
       
   873 				}
       
   874 			}
       
   875 			
       
   876 		TBool hasExtenedAlarm =	ImportExtendedAlarmPropertyL(calalarm, aParser, KVersitTokenXALARM);
       
   877 	
       
   878 		if (!soundName && !hasExtenedAlarm)
       
   879 			{
       
   880 			TBaSystemSoundType type(KSystemSoundAlarmUID);
       
   881 			TBaSystemSoundInfo info;
       
   882 			RFs s;
       
   883 			User::LeaveIfError(s.Connect());
       
   884 			BaSystemSound::GetSound(s,type,info); //don't check err as info will always be filled in
       
   885 			s.Close();
       
   886 			calalarm->SetAlarmSoundNameL(info.FileName());
       
   887 			}
       
   888 
       
   889 		iEntry->SetAlarmL(calalarm);
       
   890 		
       
   891 		CleanupStack::PopAndDestroy(2,properties);
       
   892 		return ETrue;
       
   893 		}
       
   894 	else
       
   895 		{
       
   896 		// If there is no property available, return EFalse to signal that this property doesn't exist
       
   897 		return EFalse;
       
   898 		}
       
   899 	}
       
   900 	
       
   901 // Import an extended alarm property (X-EPOCALARM) - containing the rich alarm data; it does not import the 
       
   902 // timing control parameters because the AALARM property would have been imported and written to the agenda 
       
   903 // model entry; no need to re-populate the timing controls since both audio sound and extended alarm share the 
       
   904 // same timing controls. The audio alarm timing controls override the rich alarm's timing controls (not used).
       
   905 TBool CVCalToAgendaEntryConverter::ImportExtendedAlarmPropertyL(CCalAlarm* aAlarm, CVersitParser& aParser, const TDesC8& aToken )
       
   906 	{
       
   907 	// get properties but don't take ownership of the elements of the array
       
   908 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVCalPropertyExtendedAlarmUid), EFalse);
       
   909 
       
   910 	if (properties)
       
   911 		{
       
   912 		CleanupStack::PushL(properties);
       
   913 		CParserPropertyValueExtendedAlarm* extendedAlarmProperty = static_cast<CParserPropertyValueExtendedAlarm*>((*properties)[0]->Value());
       
   914 		CVersitExtendedAlarm* extendedAlarm = extendedAlarmProperty->Value();
       
   915 		// get properties but don't take ownership of the elements of the array
       
   916 		CArrayPtr<CParserProperty>* audioAlarmProperties = aParser.PropertyL(KVersitTokenAALARM, TUid::Uid(KVCalPropertyAlarmUid), EFalse);
       
   917 
       
   918 		if (extendedAlarm && audioAlarmProperties)
       
   919 			{
       
   920 			CleanupStack::PushL(audioAlarmProperties);
       
   921 
       
   922 			// Convert X-EPOC-ALARM to alarm content and add to entry
       
   923 			CCalContent* alarmAction = CCalContent::NewL();
       
   924 			CleanupStack::PushL(alarmAction);
       
   925 			HBufC8* content = NULL;
       
   926 			if (extendedAlarm->iContent != NULL)
       
   927 				{
       
   928 				content = extendedAlarm->iContent->AllocL();
       
   929 				CleanupStack::PushL(content);
       
   930 				}
       
   931 			HBufC8* mimeType = NULL;
       
   932 			if (extendedAlarm->iMimeType != NULL)
       
   933 				{
       
   934 				mimeType = extendedAlarm->iMimeType->AllocL();
       
   935 				CleanupStack::PushL(mimeType);
       
   936 				}
       
   937 			alarmAction->SetContentL(content, mimeType, static_cast<CCalContent::TDisposition>(extendedAlarm->iDisposition)); //Takes ownership of content & mimeType
       
   938 
       
   939 			if (mimeType != NULL)
       
   940 				{
       
   941 				CleanupStack::Pop(mimeType);
       
   942 				}
       
   943 			if (content != NULL)
       
   944 				{
       
   945 				CleanupStack::Pop(content);
       
   946 				}	
       
   947 			aAlarm->SetAlarmAction(alarmAction); // takes ownership of alarmAction
       
   948 			CleanupStack::Pop(alarmAction);
       
   949 			
       
   950 			CleanupStack::PopAndDestroy(audioAlarmProperties);
       
   951 			CleanupStack::PopAndDestroy(properties);
       
   952 			return ETrue;
       
   953 			}
       
   954 		else
       
   955 			{
       
   956 			// If there is no rich alarm available, return EFalse to signal that this property doesn't exist
       
   957 			CleanupStack::PopAndDestroy(properties);
       
   958 			return EFalse;
       
   959 			}
       
   960 		}
       
   961 	else
       
   962 		{
       
   963 		// If there is no property available, return EFalse to signal that this property doesn't exist
       
   964 		return EFalse;
       
   965 		}
       
   966 	}
       
   967 
       
   968 void CVCalToAgendaEntryConverter::ImportAttachmentPropertyL(CVersitParser& aParser)
       
   969 	{
       
   970 	// get properties but don't take ownership of the elements of the array
       
   971 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenATTACH, KNullUid, EFalse);//We past KNullUid since we don't know whether it is a binary or URI - versit will have the informantion.
       
   972 
       
   973 	if (!properties)
       
   974 		{
       
   975 		return;
       
   976 		}
       
   977 
       
   978 	CleanupStack::PushL(properties);
       
   979 	const TInt KCount = properties->Count();	// no. of attachments
       
   980 	for (TInt i = 0; i < KCount; ++i)
       
   981 		{
       
   982 		CParserParam* attachValueType = (*properties)[i]->Param(KVersitTokenVALUE);
       
   983 		TPtrC8 valueType;
       
   984 		if(attachValueType && attachValueType->Value().Length() > 0)
       
   985 			{
       
   986 			valueType.Set(attachValueType->Value());
       
   987 			}
       
   988 		
       
   989 		CCalAttachment* attachment = NULL;
       
   990 		if(!attachValueType || valueType == KVersitTokenINLINE || valueType == KVersitTokenBINARY)
       
   991 			{
       
   992 			CParserPropertyValueBinary* attachValueBinary = static_cast<CParserPropertyValueBinary*>((*properties)[i]->Value());
       
   993 			if (attachValueBinary)
       
   994 				{
       
   995 				CBufSeg* binary=(CBufSeg*)(attachValueBinary->Value());
       
   996 				const TInt KBinaryLength = binary->Size();
       
   997 				if(KBinaryLength>0)
       
   998 					{
       
   999 					HBufC8* bufValue = HBufC8::NewLC(KBinaryLength);
       
  1000 					TPtr8 pBufValue = bufValue->Des();
       
  1001 					binary->Read(0, pBufValue, KBinaryLength);
       
  1002 					attachment = CCalAttachment::NewFileL(bufValue);
       
  1003 					CleanupStack::Pop(bufValue);
       
  1004 					}
       
  1005 				}
       
  1006 			}
       
  1007 		else 
       
  1008 			{
       
  1009 			CParserPropertyValueHBufC* attachValueDes = static_cast<CParserPropertyValueHBufC*>((*properties)[i]->Value());
       
  1010 			if (attachValueDes && attachValueDes->Value().Length() > 0)
       
  1011 				{
       
  1012 				TPtrC des16Value = attachValueDes->Value();
       
  1013 				HBufC8* buf8Value = HBufC8::NewLC(des16Value.Length());
       
  1014 				buf8Value->Des().Copy(des16Value);
       
  1015 				if ( ! valueType.Compare(KVCalContentValueContentId) || ! valueType.Compare(KVCalContentValueContentIdShort))
       
  1016 					{
       
  1017 					attachment = CCalAttachment::NewFileByContentIdL(*buf8Value);
       
  1018 					}
       
  1019 				else
       
  1020 					{
       
  1021 					attachment = CCalAttachment::NewUriL(*buf8Value);
       
  1022 					}
       
  1023 				CleanupStack::PopAndDestroy(buf8Value);
       
  1024 				}
       
  1025 			}
       
  1026 		if (attachment)
       
  1027 			{
       
  1028 			CleanupStack::PushL(attachment);
       
  1029 			//Set paramenters
       
  1030 			CParserParam* mimeTypeParam = (*properties)[i]->Param(KVersitAttachMimeType);	
       
  1031 			if(mimeTypeParam && mimeTypeParam->Value().Length() > 0)
       
  1032 				{
       
  1033 				attachment->SetMimeTypeL(mimeTypeParam->Value());
       
  1034 				}
       
  1035 				
       
  1036 			CParserParam* attachName = (*properties)[i]->Param(KVersitAttachLabel);
       
  1037 			if(attachName && attachName->Value().Length() > 0)
       
  1038 				{
       
  1039 				TPtrC8 attachnameNarror = attachName->Value();
       
  1040 				HBufC* attachname16 = HBufC::NewLC(attachnameNarror.Length());
       
  1041 				TPtr pattachname16 = attachname16->Des();
       
  1042 				User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(pattachname16, attachnameNarror));
       
  1043 				attachment->SetLabelL(*attachname16);
       
  1044 				CleanupStack::PopAndDestroy(attachname16);
       
  1045 				}
       
  1046 
       
  1047 			CParserParam* attachDate = (*properties)[i]->Param(KVCalAttachFileDate);
       
  1048 			if(attachDate && attachment->FileAttachment() && attachDate->Value().Length() > 0)
       
  1049 				{
       
  1050 				TPtrC8 pAttachDate = attachDate->Value();
       
  1051 				TBuf<KMaxTimeStringSize>date16; 
       
  1052 				date16.Copy(pAttachDate);
       
  1053 				TVersitDateTime* datetime = aParser.DecodeDateTimeL(date16);
       
  1054 				CleanupStack::PushL(datetime);
       
  1055 				TTime fileTtime(datetime->iDateTime);
       
  1056 				if(iTzZone && datetime->iRelativeTime != TVersitDateTime::EIsUTC)
       
  1057 					{
       
  1058 					iTzZone->ConvertToUtcL(fileTtime);
       
  1059 					}
       
  1060 				attachment->FileAttachment()->SetLastModifiedTimeUtc(fileTtime);
       
  1061 				CleanupStack::PopAndDestroy(datetime);
       
  1062 				}
       
  1063 			iEntry->AddAttachmentL(*attachment);	
       
  1064 			CleanupStack::Pop(attachment);
       
  1065 			}
       
  1066 		}// for loop
       
  1067 		
       
  1068 	CleanupStack::PopAndDestroy(properties);
       
  1069 	}
       
  1070 
       
  1071 // Import repeat property
       
  1072 //
       
  1073 void CVCalToAgendaEntryConverter::ImportRepeatPropertyL(CVersitParser& aParser, const TDesC8& aToken, const TTime& aRepeatTime, TVersitDateTime::TRelativeTime aRelativeTime)
       
  1074 	{
       
  1075 	if (aRepeatTime != Time::NullTTime())
       
  1076 		{
       
  1077 		ImportRepeatRuleL(aParser, aToken, aRepeatTime, aRelativeTime);
       
  1078 	
       
  1079 		//check for RDates - this operation must be carried out after any rule has been imported
       
  1080 		ImportRDatePropertyL(aParser, KVersitTokenRDATE);
       
  1081 
       
  1082 		ImportRepeatExceptionPropertiesL(aParser, KVersitTokenEXDATE);
       
  1083 		}
       
  1084 	}
       
  1085 
       
  1086 // Repeat end date behaviour
       
  1087 // - If the repeat end date is within the agenda range it is set
       
  1088 // - If the repeat end date is greater than the maximum agenda date then the entry is set to repeat forever
       
  1089 // - If the repeat end date is less than the minimum agenda date then the entry is made non-repeating
       
  1090 //
       
  1091 // Current implementation follows these policies:
       
  1092 //	1) time mode of repeat always matches time mode of the entry:
       
  1093 //		if entry's time mode is EFloating, then repeat's time mode is EFloating;
       
  1094 //		if entry's time mode is EFixedUTC, then repeat's time mode is EFixedTimeZone.
       
  1095 //	2) time format of DTSTART determines time mode of the entry. 
       
  1096 //		if DTSTART is not valid, then time format of DTEND/DUE is used.
       
  1097 //
       
  1098 void CVCalToAgendaEntryConverter::ImportRepeatRuleL(CVersitParser& aParser, const TDesC8& aToken, const TTime& aStartDate, TVersitDateTime::TRelativeTime aRelativeTime)
       
  1099 	{
       
  1100 	// get properties but don't take ownership of the elements of the array
       
  1101 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVCalPropertyRecurrenceUid), EFalse);
       
  1102 	if (properties)
       
  1103 		{
       
  1104 		CleanupStack::PushL(properties);
       
  1105 		CVersitRecurrence* recurrence = static_cast<CParserPropertyValueRecurrence*>((*properties)[0]->Value())->Value();
       
  1106 		if (!recurrence)
       
  1107 			{
       
  1108 			CleanupStack::PopAndDestroy(properties);
       
  1109 			return;
       
  1110 			}
       
  1111 			
       
  1112 	//Importing the start time of the repeating
       
  1113 		//startTimeLoc & startTimeUtc will be same if it is floating entry or when iTzZone is not specified.
       
  1114 		TTime startTimeLoc = aStartDate;
       
  1115 		TTime startTimeUtc = aStartDate;
       
  1116 		TBool isFloatingEntry = (!iTzZone && aRelativeTime != TVersitDateTime::EIsUTC); 
       
  1117 		
       
  1118 		if  (iTzZone)
       
  1119 			{
       
  1120 			if (aRelativeTime == TVersitDateTime::EIsUTC)
       
  1121 				{
       
  1122 				iTzZone->ConvertToLocalL(startTimeLoc);
       
  1123 				}
       
  1124 			else
       
  1125 				{
       
  1126 				iTzZone->ConvertToUtcL(startTimeUtc);
       
  1127 				}	
       
  1128 			}
       
  1129 		
       
  1130 		TCalRRule repeat;
       
  1131 		TCalTime calstart;
       
  1132 
       
  1133 		if (isFloatingEntry)
       
  1134 			{
       
  1135 			calstart.SetTimeLocalFloatingL(startTimeLoc);
       
  1136 			}
       
  1137 		else
       
  1138 			{
       
  1139 			calstart.SetTimeUtcL(startTimeUtc);
       
  1140 			}
       
  1141 			
       
  1142 	repeat.SetDtStart(calstart);
       
  1143 	
       
  1144 	//Importing the recurrence of the repeating			
       
  1145 		switch(recurrence->iRepeatType)
       
  1146 			{
       
  1147 			case CVersitRecurrence::EDaily:
       
  1148 				repeat.SetType(TCalRRule::EDaily);
       
  1149 				break;
       
  1150 			case CVersitRecurrence::EYearlyByMonth:
       
  1151 				repeat.SetType(TCalRRule::EYearly);
       
  1152 				break;
       
  1153 			case CVersitRecurrence::EWeekly:
       
  1154 				ImportWeeklyRepeatPropertiesL(static_cast<CVersitRecurrenceWeekly*>(recurrence), repeat, startTimeLoc.DayNoInWeek());
       
  1155 				break;
       
  1156 			case CVersitRecurrence::EMonthlyByPos:
       
  1157 				ImportMonthlyByPosRepeatPropertiesL(static_cast<CVersitRecurrenceMonthlyByPos*>(recurrence), repeat, startTimeLoc);
       
  1158 				break;
       
  1159 			case CVersitRecurrence::EMonthlyByDay:
       
  1160 				ImportMonthlyByDayRepeatPropertiesL(static_cast<CVersitRecurrenceMonthlyByDay*>(recurrence), repeat, startTimeLoc.DayNoInMonth());
       
  1161 				break;
       
  1162 			case CVersitRecurrence::EYearlyByDay:
       
  1163 				// Not supported, since an event cannot repeat on the 100th day of a year, etc
       
  1164 				// -- intentional drop through to default case --
       
  1165 			default:
       
  1166 				// Don't understand the repeat type,
       
  1167 				// so cleanup and exit
       
  1168 				CleanupStack::PopAndDestroy(properties);
       
  1169 				return;
       
  1170 			}
       
  1171 
       
  1172 		// We allow only TVersitDateTime::EIsUTC and EIsVCardLocal, because 
       
  1173 		// EIsMachineLocal is never returned by parser,and EIsCorrect is not used
       
  1174 		__ASSERT_DEBUG(aRelativeTime == TVersitDateTime::EIsUTC || 
       
  1175 					   aRelativeTime == TVersitDateTime::EIsVCardLocal, Panic(EAgnVersitPanicWrongTimeType));
       
  1176 
       
  1177 	//Importing the until time of the repeating
       
  1178 		TVersitDateTime* rptEndDate = recurrence->iEndDate;
       
  1179 		TCalTime calUntil;
       
  1180 		TBool isUntilTimeValid = EFalse;
       
  1181 	
       
  1182 		if(!rptEndDate && recurrence->iDuration == 0)
       
  1183 			{//If no until time has been set and the count is 0, the repeating is forever
       
  1184 			calUntil.SetTimeUtcL(TCalTime::MaxTime());
       
  1185 			repeat.SetCount(0);
       
  1186 			isUntilTimeValid = ETrue;
       
  1187 			}
       
  1188 		else if(rptEndDate)
       
  1189 			{//Set the until time
       
  1190 			TDateTime untilDateTimeLoc = rptEndDate->iDateTime;
       
  1191 			//Adjust the local repeating until time according to the local start time 
       
  1192 			if (!isFloatingEntry && iTzZone && rptEndDate->iRelativeTime == TVersitDateTime::EIsUTC)
       
  1193 				{
       
  1194 				TTime time(untilDateTimeLoc);//create a temp object of TTime
       
  1195 				iTzZone->ConvertToLocalL(time);//convert the UTC until to local
       
  1196 				untilDateTimeLoc = time.DateTime();// set the local until
       
  1197 				}
       
  1198 			
       
  1199 			untilDateTimeLoc.SetHour(startTimeLoc.DateTime().Hour());
       
  1200 			untilDateTimeLoc.SetMinute(startTimeLoc.DateTime().Minute());
       
  1201 			untilDateTimeLoc.SetSecond(startTimeLoc.DateTime().Second());
       
  1202 			untilDateTimeLoc.SetMicroSecond(0);
       
  1203 			isUntilTimeValid = ETrue;
       
  1204 			
       
  1205 			if (isFloatingEntry)
       
  1206 				{
       
  1207 				if (TTime(untilDateTimeLoc) < TCalTime::MinTime())
       
  1208 					{
       
  1209 					isUntilTimeValid = EFalse;
       
  1210 					}
       
  1211 				else 
       
  1212 					{
       
  1213 					if (TTime(untilDateTimeLoc) > TCalTime::MaxTime())
       
  1214 						{
       
  1215 						untilDateTimeLoc = TCalTime::MaxTime().DateTime();
       
  1216 						}
       
  1217 					calUntil.SetTimeLocalFloatingL(untilDateTimeLoc);
       
  1218 					}
       
  1219 				}
       
  1220 			else 
       
  1221 				{
       
  1222 				TTime untilUtc(untilDateTimeLoc);
       
  1223 				if (iTzZone)
       
  1224 					{
       
  1225 					iTzZone->ConvertToUtcL(untilUtc);
       
  1226 					}
       
  1227 					
       
  1228 				if (untilUtc < TCalTime::MinTime())
       
  1229 					{
       
  1230 					isUntilTimeValid = EFalse;
       
  1231 					}
       
  1232 					
       
  1233 				else
       
  1234 					{
       
  1235 					if (untilUtc > TCalTime::MaxTime())
       
  1236 						{
       
  1237 						untilUtc = TCalTime::MaxTime().DateTime();
       
  1238 						}
       
  1239 					calUntil.SetTimeUtcL(untilUtc);
       
  1240 					}
       
  1241 				}
       
  1242 			
       
  1243 			}
       
  1244 			
       
  1245 		if (isUntilTimeValid)
       
  1246 			{
       
  1247 			repeat.SetUntil(calUntil);
       
  1248 			}
       
  1249 		
       
  1250 		if (recurrence->iDuration>0)
       
  1251 			{
       
  1252 			TInt instancesPerRepeat = CalculateInstancesPerRepeatL(repeat);
       
  1253 			
       
  1254 			TInt count = recurrence->iDuration * instancesPerRepeat;
       
  1255 			
       
  1256 			// it is possible to have both count and untiltime in an imported vcal
       
  1257 			//	we will import the shortest repeat of the two dates
       
  1258 			if(repeat.Until().TimeLocalL() != Time::NullTTime())
       
  1259 				{
       
  1260 				TCalTime countUntilTime = iEntry->FindRptUntilTimeL(count);
       
  1261 						
       
  1262 				if(countUntilTime.TimeLocalL() < repeat.Until().TimeLocalL())
       
  1263 					{
       
  1264 					//	if until time is already set, it will be replaced
       
  1265 					repeat.SetUntil(countUntilTime);
       
  1266 					}
       
  1267 				}
       
  1268 			else
       
  1269 				{
       
  1270 				repeat.SetCount(count);
       
  1271 				}
       
  1272 				
       
  1273 			isUntilTimeValid = ETrue;
       
  1274 			}
       
  1275 	
       
  1276 		if (isUntilTimeValid)
       
  1277 			{
       
  1278 			//Importing the interval		
       
  1279 			repeat.SetInterval(recurrence->iInterval);
       
  1280 			
       
  1281 			//Importing the repeating count
       
  1282 			
       
  1283 			TRAPD(err, iEntry->SetRRuleL(repeat));
       
  1284 			if (err != KErrArgument && err != KErrNotSupported)
       
  1285 				{
       
  1286 				User::LeaveIfError(err);
       
  1287 				}
       
  1288 				
       
  1289 			TCalRRule ruleGot;
       
  1290 			if(iEntry->GetRRuleL(ruleGot))
       
  1291 				{
       
  1292 				if(iTzZone)
       
  1293 					{
       
  1294 					// If there are DAYLIGHT and TZ properties, use these rules when converting
       
  1295 					// repeating dates to UTC for storage, otherwise the time zone device will be used
       
  1296 					// instead.
       
  1297 					iEntry->SetTzRulesL(*iTzZone);
       
  1298 					}
       
  1299 				}
       
  1300 			}
       
  1301 
       
  1302 		CleanupStack::PopAndDestroy(properties);
       
  1303 		}
       
  1304 	}
       
  1305 
       
  1306 TInt CVCalToAgendaEntryConverter::CalculateInstancesPerRepeatL(const TCalRRule& aRRule) const
       
  1307 	{
       
  1308 	TInt instancesPerRepeat = 1;
       
  1309 	switch (aRRule.Type())
       
  1310 		{
       
  1311 		case TCalRRule::EWeekly:
       
  1312 			{
       
  1313 			RArray<TDay> wkdays;
       
  1314 			CleanupClosePushL(wkdays);
       
  1315 			aRRule.GetByDayL(wkdays);
       
  1316 			instancesPerRepeat = wkdays.Count();
       
  1317 			CleanupStack::PopAndDestroy(&wkdays);
       
  1318 			}
       
  1319 			break;
       
  1320 		case TCalRRule::EMonthly:
       
  1321 			{
       
  1322 			RArray<TCalRRule::TDayOfMonth> monthdays;
       
  1323 			CleanupClosePushL(monthdays);
       
  1324 			aRRule.GetByDayL(monthdays);
       
  1325 			instancesPerRepeat = monthdays.Count();
       
  1326 			CleanupStack::PopAndDestroy(&monthdays);
       
  1327 			if (instancesPerRepeat == 0)
       
  1328 				{
       
  1329 				RArray<TInt> monthdates;
       
  1330 				CleanupClosePushL(monthdates);
       
  1331 				aRRule.GetByMonthDayL(monthdates);
       
  1332 				instancesPerRepeat = monthdates.Count();
       
  1333 				CleanupStack::PopAndDestroy(&monthdates);
       
  1334 				}
       
  1335 			}
       
  1336 			break;
       
  1337 		case TCalRRule::EYearly:
       
  1338 			{
       
  1339 			RArray<TCalRRule::TDayOfMonth> yrdays;
       
  1340 			CleanupClosePushL(yrdays);
       
  1341 			aRRule.GetByDayL(yrdays);
       
  1342 			instancesPerRepeat = yrdays.Count();
       
  1343 			CleanupStack::PopAndDestroy(&yrdays);
       
  1344 			if (instancesPerRepeat == 0)
       
  1345 				{
       
  1346 				RArray<TMonth> yrmonths;
       
  1347 				CleanupClosePushL(yrmonths);
       
  1348 				aRRule.GetByMonthL(yrmonths);
       
  1349 				instancesPerRepeat = yrmonths.Count();
       
  1350 				CleanupStack::PopAndDestroy(&yrmonths);
       
  1351 				}
       
  1352 			}
       
  1353 			break;
       
  1354 		case TCalRRule::EDaily:
       
  1355 		default:
       
  1356 			// do nothing
       
  1357 			break;
       
  1358 		}
       
  1359 	if (instancesPerRepeat == 0)
       
  1360 		{
       
  1361 		instancesPerRepeat = 1;
       
  1362 		}
       
  1363 	return instancesPerRepeat;
       
  1364 	}
       
  1365 
       
  1366 void CVCalToAgendaEntryConverter::ImportWeeklyRepeatPropertiesL(CVersitRecurrenceWeekly* aRepeat, TCalRRule& aRpt, TDay aDefaultDayOfWeek)
       
  1367 	{
       
  1368 	aRpt.SetType(TCalRRule::EWeekly);
       
  1369 	CWeekDayArray* weekdayArray = aRepeat->iArrayOfWeekDayOccurrences;
       
  1370 	RArray<TDay> daysinweek;
       
  1371 	CleanupClosePushL(daysinweek);
       
  1372 
       
  1373 	if (weekdayArray)
       
  1374 		{
       
  1375 		CArrayFix<TDay>* dayList = weekdayArray->iArray;
       
  1376 
       
  1377 		TInt size = dayList->Count();
       
  1378 		for (TInt count=0; count<size; count++)
       
  1379 			{
       
  1380 			TDay day = (*dayList)[count];
       
  1381 			daysinweek.AppendL(day);
       
  1382 			}
       
  1383 		}
       
  1384 	else
       
  1385 		{
       
  1386 		daysinweek.AppendL(aDefaultDayOfWeek);
       
  1387 		}
       
  1388 		
       
  1389 	aRpt.SetByDay(daysinweek);
       
  1390 	CleanupStack::PopAndDestroy();//close rarray
       
  1391 	}
       
  1392 
       
  1393 
       
  1394 void CVCalToAgendaEntryConverter::ImportMonthlyByDayRepeatPropertiesL(CVersitRecurrenceMonthlyByDay* aRepeat, TCalRRule& aRpt, TInt aDefaultDayOfMonth)
       
  1395 	{
       
  1396 	aRpt.SetType(TCalRRule::EMonthly);
       
  1397 
       
  1398 	// Specify which dates to repeat on
       
  1399 	// Only days from the start of the month are supported
       
  1400 	CArrayFix<TInt>* dayList = aRepeat->iArrayOfOccurrencesInDaysFromStartOfMonth;
       
  1401 	CArrayFix<TInt>* endDayList = aRepeat->iArrayOfOccurrencesInDaysFromEndOfMonth;
       
  1402 	RArray<TInt> monthdays;
       
  1403 	CleanupClosePushL(monthdays);
       
  1404 	if (dayList)
       
  1405 		{
       
  1406 		TInt size = dayList->Count();
       
  1407 		for (TInt count=0; count<size; count++)
       
  1408 			{
       
  1409 			TInt day = (*dayList)[count]-1;			
       
  1410 			// Set only valid dates
       
  1411 			// 0 = the first day of a month, 30 = the 31st day of the month
       
  1412 			if (day >= 0 && day <= 30)
       
  1413 				{
       
  1414 				monthdays.AppendL(day);
       
  1415 				}
       
  1416 			}
       
  1417 		}
       
  1418 	else if(endDayList) 
       
  1419 		{ 
       
  1420 		TInt size = endDayList->Count(); 
       
  1421 		for (TInt count=0;count<size;++count) 
       
  1422         	{ 
       
  1423         	TInt day = (*endDayList)[count]; 
       
  1424        		 if(day==1) 
       
  1425 	       	 	{	//set 31st day in the monthlyByDates list as its the last day of the month
       
  1426 	       	 	monthdays.AppendL(30); 
       
  1427 	        	break; 
       
  1428 	       	 	} 
       
  1429         	}
       
  1430 		}
       
  1431 	
       
  1432 	
       
  1433 	if(monthdays.Count()<1)	
       
  1434 		{ 
       
  1435 		monthdays.AppendL(aDefaultDayOfMonth); 
       
  1436 		} 
       
  1437 		
       
  1438 	aRpt.SetByMonthDay(monthdays);
       
  1439 	CleanupStack::PopAndDestroy();//close RArray
       
  1440 	}
       
  1441 
       
  1442 
       
  1443 void CVCalToAgendaEntryConverter::ImportMonthlyByPosRepeatPropertiesL(CVersitRecurrenceMonthlyByPos* aRepeat, TCalRRule& aRpt, const TTime& aDate)
       
  1444 	{
       
  1445 	aRpt.SetType(TCalRRule::EMonthly);
       
  1446 
       
  1447 	TInt size = aRepeat->iMonthPositions->Count();
       
  1448 	RArray<TCalRRule::TDayOfMonth> dayofmonthArray;
       
  1449 	CleanupClosePushL(dayofmonthArray);
       
  1450 	
       
  1451 	if (size > 0)
       
  1452 		{
       
  1453 		for (TInt count=0; count<size; count++)
       
  1454 			{
       
  1455 			CArrayFix<TDay>* dayList = (*(aRepeat->iMonthPositions))[count]->iArrayOfWeekDays->iArray;
       
  1456 			TInt weekNo = (*(aRepeat->iMonthPositions))[count]->iWeekNo;
       
  1457 			TInt sign = (*(aRepeat->iMonthPositions))[count]->iSign;
       
  1458 
       
  1459 			if (weekNo == 1 && sign == CVersitRecurrenceMonthlyByPos::CMonthPosition::EWeeksFromEndOfMonth)
       
  1460 				{
       
  1461 				// If the poisiton is in the last week of the month
       
  1462 				weekNo = -1;
       
  1463 				}
       
  1464 			else if (weekNo > 5 || sign == CVersitRecurrenceMonthlyByPos::CMonthPosition::EWeeksFromEndOfMonth)
       
  1465 				{
       
  1466 				// We can't model this setting, so ignore it
       
  1467 				continue;
       
  1468 				}
       
  1469 
       
  1470 			// Now set the days for the week setting
       
  1471 			TInt dayCount = dayList->Count();
       
  1472 			for (TInt ii=0; ii<dayCount; ii++)
       
  1473 				{
       
  1474 				TDay day = (*dayList)[ii];
       
  1475 				TCalRRule::TDayOfMonth monthday(day, weekNo);
       
  1476 				dayofmonthArray.AppendL(monthday);
       
  1477 				}
       
  1478 			}
       
  1479 		}
       
  1480 	else
       
  1481 		{
       
  1482 		TDay day = aDate.DayNoInWeek();
       
  1483 		TInt week = aDate.DayNoInMonth() / 7 + 1;
       
  1484 		TCalRRule::TDayOfMonth monthday(day, week);
       
  1485 		dayofmonthArray.AppendL(monthday);
       
  1486 		}
       
  1487 
       
  1488 	aRpt.SetByDay(dayofmonthArray);
       
  1489 	CleanupStack::PopAndDestroy();//close the RArray
       
  1490 	}
       
  1491 
       
  1492 void CVCalToAgendaEntryConverter::ImportRepeatExceptionPropertiesL(CVersitParser& aParser, const TDesC8& aToken)
       
  1493 	{
       
  1494 	// get properties but don't take ownership of the elements of the array
       
  1495 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyMultiDateTimeUid), EFalse);
       
  1496 
       
  1497 	if (properties)
       
  1498 		{
       
  1499 		CleanupStack::PushL(properties);
       
  1500 		CArrayPtr<TVersitDateTime>* exDates = static_cast<CParserPropertyValueMultiDateTime*>((*properties)[0]->Value())->Value();
       
  1501 		if (exDates)
       
  1502 			{
       
  1503 			TInt size = exDates->Count();
       
  1504 			RArray<TCalTime> exceptionlist;
       
  1505 			CleanupClosePushL(exceptionlist);
       
  1506 			
       
  1507 			for (TInt count=0; count<size; count++)
       
  1508 				{
       
  1509 				TCalTime exception;
       
  1510 				TVersitDateTime* time = (*exDates)[count];
       
  1511 				TTime timeProperty(time->iDateTime);
       
  1512 				if (IsValidTime(timeProperty))
       
  1513 					{
       
  1514 					TVersitDateTime::TRelativeTime relativeTime = time->iRelativeTime;
       
  1515 					
       
  1516 					if  (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
       
  1517 						{
       
  1518 						//Convert to utc time
       
  1519 						iTzZone->ConvertToUtcL(timeProperty);
       
  1520 						relativeTime = TVersitDateTime::EIsUTC;
       
  1521 						}
       
  1522 				
       
  1523 					if (iEntry->StartTimeL().TimeMode() == TCalTime::EFloating)
       
  1524 						{
       
  1525 						exception.SetTimeLocalFloatingL(timeProperty);
       
  1526 						}
       
  1527 					else
       
  1528 						{
       
  1529 						// the EXDATE is floating but the entry is UTC
       
  1530 						exception.SetTimeUtcL(timeProperty);
       
  1531 						}
       
  1532 
       
  1533 					exceptionlist.AppendL(exception);
       
  1534 					}
       
  1535 				}
       
  1536 			iEntry->SetExceptionDatesL(exceptionlist);
       
  1537 			CleanupStack::PopAndDestroy();//close the RArray
       
  1538 			}
       
  1539 		CleanupStack::PopAndDestroy(properties);
       
  1540 		}
       
  1541 	}
       
  1542 
       
  1543 void CVCalToAgendaEntryConverter::ImportAttendeePropertiesL(CVersitParser& aParser, const TDesC8& aToken)
       
  1544 	{
       
  1545 	TBool mailto;
       
  1546 	TInt propLen;
       
  1547 	// get properties but don't take ownership of the elements of the array
       
  1548 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
       
  1549 	CleanupStack::PushL(properties);
       
  1550 
       
  1551 	if (properties)
       
  1552 		{
       
  1553 		TInt size = properties->Count();	// no. of attendees
       
  1554 		for (TInt count=0; count<size; count++)
       
  1555 			{
       
  1556 			CParserPropertyValueHBufC* attendeeProperty = static_cast<CParserPropertyValueHBufC*>((*properties)[count]->Value()); 
       
  1557 
       
  1558 			mailto = EFalse;
       
  1559 			propLen = 0;
       
  1560 			if (attendeeProperty->Value().FindF(KVersitTokenMailTo) == 0)
       
  1561 				{
       
  1562 				mailto = ETrue;
       
  1563 				propLen = attendeeProperty->Value().Length() - KVersitTokenMailTo().Length();
       
  1564 				}
       
  1565 			
       
  1566 			CParserParam* sentBy = (*properties)[count]->Param(KICalAttendeeSentBy8);	
       
  1567 		
       
  1568 			CCalAttendee* attendee = NULL;
       
  1569 			CCalUser* user = NULL;
       
  1570 			CParserParam* role = (*properties)[count]->Param(KVCalAttendee8ROLE);
       
  1571 
       
  1572 			const TDesC& KAttendeeProperty = mailto ? attendeeProperty->Value().Right(propLen) : attendeeProperty->Value();
       
  1573 			if (sentBy)
       
  1574 				{
       
  1575 				HBufC* sentByDesc = sentBy->ValueL();
       
  1576 				CleanupStack::PushL(sentByDesc);
       
  1577 				if (role && role->Value() == KVCalAttendeeRole8ORGANIZER)
       
  1578 					{
       
  1579 					user = CCalUser::NewL(KAttendeeProperty, *sentByDesc);
       
  1580 					iEntry->SetOrganizerL(user);
       
  1581 					}
       
  1582 				else
       
  1583 					{
       
  1584 					attendee = CCalAttendee::NewL(KAttendeeProperty, *sentByDesc);
       
  1585 					iEntry->AddAttendeeL(attendee);
       
  1586 					}
       
  1587 				CleanupStack::PopAndDestroy(sentByDesc);
       
  1588 				}
       
  1589 			else
       
  1590 				{
       
  1591 				if (role && role->Value() == KVCalAttendeeRole8ORGANIZER)
       
  1592 					{
       
  1593 					user = CCalUser::NewL(KAttendeeProperty);
       
  1594 					iEntry->SetOrganizerL(user);
       
  1595 					}
       
  1596 				else
       
  1597 					{
       
  1598 					attendee = CCalAttendee::NewL(KAttendeeProperty);
       
  1599 					iEntry->AddAttendeeL(attendee);
       
  1600 					}
       
  1601 				}
       
  1602 	
       
  1603 			if (attendee)
       
  1604 				{
       
  1605 				CParserParam* calrole = (*properties)[count]->Param(KICalAttendeeCalRole8);
       
  1606 				TBool roleSet = EFalse;
       
  1607 				//	Check for iCal roles values
       
  1608 				if (calrole)
       
  1609 					{
       
  1610  					if(calrole->Value() == KICalAttendeeCalRole8CHAIR)
       
  1611 						{
       
  1612 						attendee->SetRoleL(CCalAttendee::EChair);
       
  1613 						roleSet = ETrue;
       
  1614   						}
       
  1615 					else if(calrole->Value() == KICalAttendeeCalRole8REQUIRED)
       
  1616 						{
       
  1617 						attendee->SetRoleL(CCalAttendee::EReqParticipant);
       
  1618 						roleSet = ETrue;
       
  1619 						}
       
  1620 					else if(calrole->Value() == KICalAttendeeCalRole8OPTIONAL)
       
  1621 						{
       
  1622 						attendee->SetRoleL(CCalAttendee::EOptParticipant);				
       
  1623 						roleSet = ETrue;
       
  1624 						}
       
  1625 					else if(calrole->Value() == KICalAttendeeCalRole8NONPARTICIPANT)
       
  1626 						{
       
  1627 						attendee->SetRoleL(CCalAttendee::ENonParticipant);				
       
  1628 						roleSet = ETrue;
       
  1629 						}
       
  1630 					}
       
  1631 				if ( ! roleSet && role)
       
  1632 					{
       
  1633 					if (role->Value() == KVCalAttendeeRole8OWNER)
       
  1634 						{
       
  1635 						attendee->SetRoleL(CCalAttendee::EVCalOwner);
       
  1636 						roleSet = ETrue;
       
  1637 						}
       
  1638 					else if (role->Value() == KVCalAttendeeRole8DELEGATE)
       
  1639 						{
       
  1640 						attendee->SetRoleL(CCalAttendee::EVCalDelegate);
       
  1641 						roleSet = ETrue;
       
  1642 						}
       
  1643 					else if (role->Value() == KVCalAttendeeRole8ATTENDEE)
       
  1644 						{
       
  1645 						attendee->SetRoleL(CCalAttendee::EVCalAttendee);
       
  1646 						roleSet = ETrue;
       
  1647 						}
       
  1648 					}
       
  1649 				if ( ! roleSet)
       
  1650 					{
       
  1651 					attendee->SetRoleL(CCalAttendee::EReqParticipant);
       
  1652 					}
       
  1653 			
       
  1654 				// Check for vCal status values
       
  1655 				CParserParam* calStatus = (*properties)[count]->Param(KICalAttendeeCalStatus8);
       
  1656 				CParserParam* status = (*properties)[count]->Param(KVCalAttendee8STATUS);
       
  1657 				if (calStatus)
       
  1658 					{
       
  1659 					if (calStatus->Value() == KVCalAttendeeStatus8ACCEPTED)
       
  1660 						attendee->SetStatusL(CCalAttendee::EAccepted);
       
  1661 					else if (calStatus->Value() == KVCalAttendeeStatus8NEEDSACTION)
       
  1662 						attendee->SetStatusL(CCalAttendee::ENeedsAction);
       
  1663 					else if (calStatus->Value() == KVCalAttendeeStatus8TENTATIVE)
       
  1664 						attendee->SetStatusL(CCalAttendee::ETentative);
       
  1665 					else if (calStatus->Value() == KVCalAttendeeStatus8CONFIRMED)
       
  1666 						attendee->SetStatusL(CCalAttendee::EConfirmed);
       
  1667 					else if (calStatus->Value() == KVCalAttendeeStatus8DECLINED)
       
  1668 						attendee->SetStatusL(CCalAttendee::EDeclined);
       
  1669 					else if (calStatus->Value() == KVCalAttendeeStatus8COMPLETED)
       
  1670 						attendee->SetStatusL(CCalAttendee::ECompleted);
       
  1671 					else if (calStatus->Value() == KVCalAttendeeStatus8DELEGATED)
       
  1672 						attendee->SetStatusL(CCalAttendee::EDelegated);
       
  1673 					else if (calStatus->Value() == KICalAttendeeCalStatus8INPROCESS)
       
  1674 						attendee->SetStatusL(CCalAttendee::EInProcess);
       
  1675 					}
       
  1676 				else if (status)
       
  1677 					{
       
  1678 					if (status->Value() == KVCalAttendeeStatus8ACCEPTED)
       
  1679 						attendee->SetStatusL(CCalAttendee::EAccepted);
       
  1680 					else if (status->Value() == KVCalAttendeeStatus8NEEDSACTION)
       
  1681 						attendee->SetStatusL(CCalAttendee::ENeedsAction);
       
  1682 					else if (status->Value() == KVCalAttendeeStatus8SENT)
       
  1683 						attendee->SetStatusL(CCalAttendee::EVCalSent);
       
  1684 					else if (status->Value() == KVCalAttendeeStatus8XDASHRECEIVED)
       
  1685 						attendee->SetStatusL(CCalAttendee::EVCalXReceived);
       
  1686 					else if (status->Value() == KVCalAttendeeStatus8TENTATIVE)
       
  1687 						attendee->SetStatusL(CCalAttendee::ETentative);
       
  1688 					else if (status->Value() == KVCalAttendeeStatus8CONFIRMED)
       
  1689 						attendee->SetStatusL(CCalAttendee::EConfirmed);
       
  1690 					else if (status->Value() == KVCalAttendeeStatus8DECLINED)
       
  1691 						attendee->SetStatusL(CCalAttendee::EDeclined);
       
  1692 					else if (status->Value() == KVCalAttendeeStatus8COMPLETED)
       
  1693 						attendee->SetStatusL(CCalAttendee::ECompleted);
       
  1694 					else if (status->Value() == KVCalAttendeeStatus8DELEGATED)
       
  1695 						attendee->SetStatusL(CCalAttendee::EDelegated);
       
  1696 					}
       
  1697 	
       
  1698 				// Check for RSVP parameter
       
  1699 				CParserParam* rsvp = (*properties)[count]->Param(KVCalAttendee8RSVP);
       
  1700 				if (rsvp)
       
  1701 					{
       
  1702 					if (rsvp->Value() == KVCalAttendeeRsvp8YES)
       
  1703 						attendee->SetResponseRequested(ETrue);
       
  1704 					else
       
  1705 						attendee->SetResponseRequested(EFalse);
       
  1706 					}
       
  1707 		
       
  1708 				// Check for EXPECT parameter
       
  1709 				CParserParam* expect = (*properties)[count]->Param(KVCalAttendee8EXPECT);
       
  1710 				if (expect)
       
  1711 					{
       
  1712 					if (expect->Value() == KVCalAttendeeExpect8FYI)
       
  1713 						attendee->SetVCalExpect(CCalAttendee::EVCalFyi);
       
  1714 					else if (expect->Value() == KVCalAttendeeExpect8REQUIRE)
       
  1715 						attendee->SetVCalExpect(CCalAttendee::EVCalRequire);
       
  1716 					else if (expect->Value() == KVCalAttendeeExpect8REQUEST)
       
  1717 						attendee->SetVCalExpect(CCalAttendee::EVCalRequest);
       
  1718 					else if (expect->Value() == KVCalAttendeeExpect8IMMEDIATE)
       
  1719 						attendee->SetVCalExpect(CCalAttendee::EVCalImmediate);
       
  1720 					}
       
  1721 				}
       
  1722 				
       
  1723 		//	Check for a common name 
       
  1724 			CParserParam* commonname = (*properties)[count]->Param(KICalAttendeeCommonName8);
       
  1725 			if (commonname)
       
  1726 				{
       
  1727 				HBufC* commonNameDesC = commonname->ValueL();
       
  1728 				CleanupStack::PushL(commonNameDesC);
       
  1729 				if(user)
       
  1730 					{
       
  1731 					user->SetCommonNameL(*commonNameDesC);
       
  1732 					}
       
  1733 				else if (attendee)
       
  1734 					{
       
  1735 					attendee->SetCommonNameL(*commonNameDesC);
       
  1736 					}
       
  1737 				CleanupStack::PopAndDestroy(commonNameDesC);
       
  1738 				}
       
  1739 		//Set phone owner
       
  1740 			CParserParam* phoneowner = (*properties)[count]->Param(KICalAttendee8XDASHPHONEOWNER);
       
  1741 			if(phoneowner)
       
  1742 				{
       
  1743 				if(user)
       
  1744 					{
       
  1745 					iEntry->SetPhoneOwnerL(user);
       
  1746 					}
       
  1747 				else if (attendee)
       
  1748 					{
       
  1749 					iEntry->SetPhoneOwnerL(attendee);
       
  1750 					}
       
  1751 				}
       
  1752 			}//for
       
  1753 		}//if property
       
  1754 		
       
  1755 	CleanupStack::PopAndDestroy(properties);
       
  1756 	}
       
  1757 
       
  1758 // Import the categories property
       
  1759 // For each category, try and match the name of the category with the standard category types.
       
  1760 // If this fails, the category is assumed to be an extended category type and the "X-" prefix 
       
  1761 // is removed
       
  1762 //
       
  1763 void CVCalToAgendaEntryConverter::ImportCategoriesPropertyL(CVersitParser& aParser, const TDesC8& aToken)
       
  1764 	{
       
  1765 	// get properties but don't take ownership of the elements of the array
       
  1766 	CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyCDesCArrayUid), EFalse);
       
  1767 	if (properties)
       
  1768 		{
       
  1769 		CleanupStack::PushL(properties);
       
  1770 		CDesCArray* categories = static_cast<CParserPropertyValueCDesCArray*>((*properties)[0]->Value())->Value();
       
  1771 		for (TInt count=0; count < categories->Count(); count++)
       
  1772 			{
       
  1773 			TPtrC categoryName=categories->MdcaPoint(count);
       
  1774 			CCalCategory* category = NULL;
       
  1775 			//match category name to standard ones
       
  1776 			CCalCategory::TCalCategoryType type = (CCalCategory::TCalCategoryType)(-1);
       
  1777 			if (categoryName.CompareF(KVCalCategoriesAPPOINTMENT)==0)
       
  1778 				{
       
  1779 				type = CCalCategory::ECalAppointment;
       
  1780 				}
       
  1781 			else if(categoryName.CompareF(KVCalCategoriesBUSINESS)==0)
       
  1782 				{
       
  1783 				type = CCalCategory::ECalBusiness;
       
  1784 				}
       
  1785 			else if(categoryName.CompareF(KVCalCategoriesEDUCATION)==0)
       
  1786 				{
       
  1787 				type = CCalCategory::ECalEducation;
       
  1788 				}
       
  1789 			else if(categoryName.CompareF(KVCalCategoriesHOLIDAY)==0)
       
  1790 				{
       
  1791 				type = CCalCategory::ECalHoliday;
       
  1792 				}
       
  1793 			else if(categoryName.CompareF(KVCalCategoriesMEETING)==0)
       
  1794 				{
       
  1795 				type = CCalCategory::ECalMeeting;
       
  1796 				}
       
  1797 			else if(categoryName.CompareF(KVCalCategoriesMISCELLANEOUS)==0)
       
  1798 				{
       
  1799 				type = CCalCategory::ECalMiscellaneous;
       
  1800 				}
       
  1801 			else if(categoryName.CompareF(KVCalCategoriesPERSONAL)==0)
       
  1802 				{
       
  1803 				type = CCalCategory::ECalPersonal;
       
  1804 				}
       
  1805 			else if(categoryName.CompareF(KVCalCategoriesPHONECALL)==0)
       
  1806 				{
       
  1807 				type = CCalCategory::ECalPhoneCall;
       
  1808 				}
       
  1809 			else if(categoryName.CompareF(KVCalCategoriesSICKDAY)==0)
       
  1810 				{
       
  1811 				type = CCalCategory::ECalSickDay;
       
  1812 				}
       
  1813 			else if(categoryName.CompareF(KVCalCategoriesSPECIALOCCASION)==0)
       
  1814 				{
       
  1815 				type = CCalCategory::ECalSpecialOccasion;
       
  1816 				}
       
  1817 			else if(categoryName.CompareF(KVCalCategoriesTRAVEL)==0)
       
  1818 				{
       
  1819 				type = CCalCategory::ECalTravel;
       
  1820 				}
       
  1821 			else if(categoryName.CompareF(KVCalCategoriesVACATION)==0)
       
  1822 				{
       
  1823 				type = CCalCategory::ECalVacation;
       
  1824 				}
       
  1825 			if(type>-1)
       
  1826 				{
       
  1827 				category = CCalCategory::NewL(type);
       
  1828 				}
       
  1829 			else if(categoryName.Length() > 0)
       
  1830 				{
       
  1831 				if (categoryName.Find(KVCalTokenXDash) == 0)
       
  1832 					{
       
  1833 					categoryName.Set(categoryName.Right(categoryName.Length() - 2));
       
  1834 					}
       
  1835 					
       
  1836 				if(categoryName.Length() > 0)
       
  1837 					{
       
  1838 					category = CCalCategory::NewL(categoryName);	
       
  1839 					}
       
  1840 				}
       
  1841 				
       
  1842 			if(category)
       
  1843 				{
       
  1844 				// AddCategoryL() takes ownership at the end of the function call (after calling leaving functions)
       
  1845 				iEntry->AddCategoryL(category);
       
  1846 				}
       
  1847 			}
       
  1848 		CleanupStack::PopAndDestroy(properties);
       
  1849 		}
       
  1850 	}	
       
  1851 		
       
  1852 
       
  1853 
       
  1854 
       
  1855 // Utility method to ensure proper cleanup in OOM 
       
  1856 //
       
  1857 void ResetAndDestroyArrayOfEntries(TAny* aObject)
       
  1858 	{
       
  1859 	CArrayPtrFlat<CCalEntry>* array=reinterpret_cast<CArrayPtrFlat<CCalEntry>*>(aObject);
       
  1860 	if (array)
       
  1861 		array->ResetAndDestroy();
       
  1862 	delete array;
       
  1863 	}
       
  1864 
       
  1865 
       
  1866 void CVCalToAgendaEntryConverter::SetImportVCalendarValues(TBool aImportVCalendar)
       
  1867 	{
       
  1868 	iImportVCalendarValues = aImportVCalendar;
       
  1869 	}
       
  1870 
       
  1871 void CVCalToAgendaEntryConverter::ImportStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
       
  1872 	{
       
  1873 	if (iImportVCalendarValues)
       
  1874 		{
       
  1875 		ImportVCalStatusPropertyL(aParser, aStatus);
       
  1876 		}
       
  1877 	else
       
  1878 		{
       
  1879 		ImportICalStatusPropertyL(aParser, aStatus);
       
  1880 		}
       
  1881 	}
       
  1882 
       
  1883 void CVCalToAgendaEntryConverter::ImportICalStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
       
  1884 	{
       
  1885 	HBufC* property=ImportDesPropertyL(aParser, KVCalTokenSTATUS);
       
  1886 	if (!property)
       
  1887 		{
       
  1888 		aStatus = CCalEntry::ENullStatus;
       
  1889 		return;
       
  1890 		}	
       
  1891 // BB mapped according to CCalEntryImpl::StatusL() which should be reconsidered 
       
  1892 	if (property->Length() ==0)  // Property value not found - use default setting
       
  1893 		{
       
  1894 		aStatus = CCalEntry::ENullStatus;
       
  1895 		}
       
  1896 	else if (property->CompareF(KVCalStatusNEEDSACTION) == 0)
       
  1897 		{
       
  1898 		if (iEntry->EntryTypeL()==CCalEntry::ETodo)
       
  1899 			{
       
  1900 			aStatus = CCalEntry::ETodoNeedsAction;
       
  1901 			}
       
  1902 		else
       
  1903 			{
       
  1904 			aStatus = CCalEntry::EConfirmed;
       
  1905 			}
       
  1906 		}
       
  1907 	else if (property->CompareF(KVCalStatusSENT) ==0 || property->CompareF(KVCalStatusDELEGATED)==0 || property->CompareF(KVCalStatusCONFIRMED) ==0 || property->CompareF(KVCalStatusACCEPTED) == 0)
       
  1908 		{
       
  1909 		if (iEntry->EntryTypeL()==CCalEntry::ETodo)
       
  1910 			{
       
  1911 			aStatus = CCalEntry::ETodoInProcess;
       
  1912 			}
       
  1913 		else
       
  1914 			{
       
  1915 			aStatus = CCalEntry::EConfirmed;
       
  1916 			}
       
  1917 	
       
  1918 		}
       
  1919 	else if (property->CompareF(KVCalStatusTENTATIVE)==0)
       
  1920 		{
       
  1921 		if (iEntry->EntryTypeL()==CCalEntry::ETodo)
       
  1922 			{
       
  1923 			aStatus = CCalEntry::ETodoNeedsAction;
       
  1924 			}
       
  1925 		else
       
  1926 			{
       
  1927 			aStatus = CCalEntry::ETentative;
       
  1928 			}
       
  1929 	
       
  1930 		}
       
  1931 	else if (property->CompareF(KVCalStatusDECLINED)==0)
       
  1932 		{
       
  1933 		aStatus = CCalEntry::ECancelled;
       
  1934 		}
       
  1935 	else if (property->CompareF(KVCalStatusCOMPLETED)==0)
       
  1936 		{
       
  1937 		if(iEntry->EntryTypeL()==CCalEntry::ETodo)
       
  1938 			{
       
  1939 			aStatus = CCalEntry::ETodoCompleted;
       
  1940 			}
       
  1941 		else
       
  1942 			{
       
  1943 			aStatus = CCalEntry::EConfirmed;
       
  1944 			}
       
  1945 		
       
  1946 		}
       
  1947 	else // No Match found so use the default
       
  1948 		aStatus = CCalEntry::ENullStatus;
       
  1949 	delete property;
       
  1950 	}
       
  1951 
       
  1952 void CVCalToAgendaEntryConverter::ImportVCalStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
       
  1953 	{
       
  1954 	HBufC* property=ImportDesPropertyL(aParser, KVCalTokenSTATUS);
       
  1955 	if (!property || property->Length() == 0)
       
  1956 		{
       
  1957 		aStatus = CCalEntry::ENullStatus;
       
  1958 		}
       
  1959 	else if (property->CompareF(KVCalStatusNEEDSACTION) == 0)
       
  1960 		{
       
  1961 		aStatus = CCalEntry::EVCalNeedsAction;
       
  1962 		}
       
  1963 	else if (property->CompareF(KVCalStatusSENT) == 0)
       
  1964 		{
       
  1965 		aStatus = CCalEntry::EVCalSent;
       
  1966 		}
       
  1967 	else if (property->CompareF(KVCalStatusDELEGATED)== 0)
       
  1968 		{
       
  1969 		aStatus = CCalEntry::EVCalDelegated;
       
  1970 		}
       
  1971 	else if (property->CompareF(KVCalStatusCONFIRMED) == 0 && iEntry->EntryTypeL() != CCalEntry::ETodo)
       
  1972 		{
       
  1973 		aStatus = CCalEntry::EConfirmed;
       
  1974 		}
       
  1975 	else if (property->CompareF(KVCalStatusACCEPTED) == 0)
       
  1976 		{
       
  1977 		aStatus = CCalEntry::EVCalAccepted;
       
  1978 		}
       
  1979 	else if (property->CompareF(KVCalStatusTENTATIVE)==0 && iEntry->EntryTypeL() != CCalEntry::ETodo)
       
  1980 		{
       
  1981 		aStatus = CCalEntry::ETentative;
       
  1982 		}
       
  1983 	else if (property->CompareF(KVCalStatusDECLINED)==0)
       
  1984 		{
       
  1985 		aStatus = CCalEntry::EVCalDeclined;
       
  1986 		}
       
  1987 	else if (property->CompareF(KVCalStatusCOMPLETED)==0 && iEntry->EntryTypeL() == CCalEntry::ETodo)
       
  1988 		{
       
  1989 		aStatus = CCalEntry::ETodoCompleted;
       
  1990 		}
       
  1991 	delete property;
       
  1992 	}
       
  1993