// -----------------------------------------------------------------------------
// CPIMCardConverter::ConvertPropertyL
// Inserts a proprety from a vEvent to a PIM Event Item as a field
// -----------------------------------------------------------------------------
//
void CPIMEventPropertyConverter::ConvertPropertyL(
    const CParserProperty& aProperty, // property to convert
    CPIMEventItem& aItem, // item to insert the field to
    TPIMDate& aAlarm) // DALARM is stored here
{
    JELOG2(EPim);
    TUid valueTypeUid = aProperty.Uid();
    TInt valueType = valueTypeUid.iUid;

    // The following, rather ugly, cast makes it possible for us to access
    // the protected iArrayOfParams field.
    const CPIMParserProperty& property =
        static_cast<const CPIMParserProperty&>(aProperty);

    if (aProperty.Name().CompareF(KVersitTokenCLASS) == 0)
    {
        ConvertClassPropertyL(property, aItem);
    }
    else
    {
        switch (valueType)
        {
        case KVersitPropertyDateTimeUid:
        {
            // Start, End, DALARM
            ConvertDatePropertyL(property, aItem);
            break;
        }
        case KVersitPropertyHBufCUid:
        {
            // summary, location
            ConvertStringPropertyL(property, aItem);
            break;
        }
        case KVersitPropertyMultiDateTimeUid:
        {
            // exdate
            ConvertExDatePropertyL(property, aItem);
            break;
        }
        case KVCalPropertyRecurrenceUid:
        {
            // repeat rule
            ConvertRepeatRulePropertyL(property, aItem);
            break;
        }
        case KVCalPropertyAlarmUid:
        {
            // DALARM
            ConvertAlarmPropertyL(property, aAlarm);
            break;
        }
        default:
        {
            // don't support, don't care
        }
        }
    }
}
// ------------------------------------------------------------------------------------------------
// CNSmlDataModBase::MergeEntityL
// Merges data from old entity to new entity.
// ------------------------------------------------------------------------------------------------
void CNSmlDataModBase::MergeEntityL( CVersitParser* aNewEntity, CVersitParser* aOldEntity, TBool& aModified, TBool aFieldLevel ) const
	{
	_DBG_FILE("CNSmlDataModBase::MergeEntityL(): begin");

	// Remove all data that was not supposed to be supported by the partner but
	// it was still sent to us.
	StripAllNotOnPartnerListL( aNewEntity, aModified );
	
	if( !aFieldLevel )
		{
		// Remove all properties from old item that are supported by remote server.
		// If it is field level then old this is not done.
		StripAllOnPartnerListL( aOldEntity, aModified, ETrue );
		CArrayPtr<CParserProperty>* mergeProps = aOldEntity->ArrayOfProperties( ETrue );
		if( mergeProps )
		    {
			CleanupStack::PushL( mergeProps );
			
			for( TInt i = 0; i < mergeProps->Count(); i++ )
				{
				aNewEntity->AddPropertyL( mergeProps->At( i ), ETrue );
				}
			
			CleanupStack::PopAndDestroy(); // mergeProps
		    }
		}
    else // Support for Field level merge
        {
        //Field level merge. Merge new item with old item. Properties of 
        //the old item are copied to new item if the new item entity does not 
        //contain certain property.
        //------------------------------------------------------------------------
        // Old                 New                          Merged                 
        //------------------------------------------------------------------------
        // BEGIN:VCARD       -> BEGIN:VCARD                 = BEGIN:VCARD 
        // VERSION:2.1       -> VERSION:2.1                 = VERSION:2.1
        // N:Smith;John      -> N:White;John                = N:White;John
        // ORG:Firm                                         = ORG:Firm
        // TITLE:Boss                                       = TITLE:Boss
        //                   -> TEL;CELL;VOICE:1234         = TEL;CELL;VOICE:1234
        // END:VCARD         -> END:VCARD                   = END:VCARD

        CArrayPtr<CParserProperty>* newProps = aNewEntity->ArrayOfProperties( EFalse );
        if( newProps )
            {
            CArrayPtr<CParserProperty>* oldProps = aOldEntity->ArrayOfProperties( EFalse );

            // Iterate through old list of properties. Add missing properties from old 
            // contact item, if some of the properties is not included in new item. 
            for( TInt i = 0; i < oldProps->Count(); ) 
                {
                CParserProperty* oldProperty = oldProps->At( i );
                
                //Check if the property is included in received vCard
                CArrayPtr<CParserProperty>* properties = aNewEntity->PropertyL( 
                    oldProperty->Name(), oldProperty->Uid(), EFalse );

                if ( !properties )
                    {
                    // New vCard does not include certain property. Copy all matching properties from 
                    // existing contact item.
                    CArrayPtr<CParserProperty>* oldProperties =
                        aOldEntity->PropertyL( oldProperty->Name(), oldProperty->Uid(), ETrue );
                    CleanupPtrArrayPushL( oldProperties );
                    
                    for ( TInt j = oldProperties->Count()-1; j >= 0; --j )
                        {
                        CParserProperty* property = oldProperties->At( j );
                        oldProperties->Delete( j );
                        CleanupStack::PushL( property );
                        aNewEntity->AddPropertyL( property, EFalse );
                        CleanupStack::Pop( property );
                        aModified = ETrue;
                        }       
                    CleanupStack::PopAndDestroy( oldProperties );
                    }
                else
                    {
                    // If new vCard includes at least one property with same name we will not copy 
                    // any any property with same name from existing contact item.
                    delete properties;
                     ++i;
                    }
                }
            }
		}
	
	#ifdef __NSML_DEBUG__
		CArrayPtr<CParserProperty>* props = aNewEntity->ArrayOfProperties( EFalse );
		for( TInt i = 0; i < props->Count(); i++ )
			{
			TBuf8<512> b;
			const CParserProperty* p = props->At( i );
			b = p->Name();
			const CArrayPtr<CParserParam>* pa = ( ( CNSmlProperty* )p )->Parameters();
			if( pa )
				{
				for( TInt i2 = 0; i2 < pa->Count(); i2++ )
					{
					b.Append( _L8(":") );
					b.Append( pa->At( i2 )->Name() );
					}
				}
			DBG_ARGS8(_S8("CNSmlDataModBase::MergeEntityL(): %S"), &b);
			}
	#endif // __NSML_DEBUG__
	_DBG_FILE("CNSmlDataModBase::MergeEntityL(): end");
	}